Skip to content

Utility Scripts

Reference for all utility, cleanup, inspection, and recovery scripts.

Finds and removes duplicate member entries in Rondo Club by KNVB ID, keeping the oldest record.

Terminal window
node tools/delete-duplicates.js --verbose # Dry run (default)
node tools/delete-duplicates.js --apply # Actually delete

Safe by default: Dry-run mode shows what would be deleted without making changes.


Merges a parent record into a member record, reassigning all child relationships, then deletes the parent.

Terminal window
node tools/merge-duplicate-person.js --parent=123 --member=456

Destructive: Immediately performs the merge and deletion. No dry-run mode.


Scans all people and removes duplicate relationships (same person + type) and self-referential relationships.

Terminal window
node tools/cleanup-duplicate-relationships.js

Destructive: Immediately removes duplicates. No dry-run mode.


Finds people with relationships pointing to non-existent person IDs and removes those orphaned relationships.

Terminal window
node tools/cleanup-orphan-relationships.js --verbose # Dry run (default)
node tools/cleanup-orphan-relationships.js --fix # Remove orphaned relationships

Deletes teams whose names contain commas (artifact of bad sync data).

Terminal window
node tools/cleanup-comma-teams.js --verbose # Dry run (default)
node tools/cleanup-comma-teams.js # Delete bad teams

Compares Rondo Club records against expected Sportlink members and identifies/deletes members not in Sportlink.

Terminal window
node tools/cleanup-rondo-club-duplicates.js --verbose # Dry run (default)
node tools/cleanup-rondo-club-duplicates.js --delete # Delete duplicates

Clears the work_history field for all members who have active functions or committees. Used to reset commissie work history for a fresh re-sync.

Terminal window
node tools/clear-commissie-work-history.js

Destructive: Immediately clears work history. No dry-run mode.


DEPRECATED (v2.3): Birthdays now sync as acf.birthdate on person records, not as separate important_date posts.

Finds important dates (birthdays) that reference people who no longer exist in Rondo Club.

Terminal window
node tools/find-orphan-dates.js --verbose # List orphans (default)
node tools/find-orphan-dates.js --delete # Delete orphaned dates

Finds and removes duplicate parent entries (by email) across Laposta lists, keeping entries from the lowest-numbered list.

Terminal window
node tools/dedupe-laposta-list.js # Dry run, all lists
node tools/dedupe-laposta-list.js --apply # Delete duplicates, all lists
node tools/dedupe-laposta-list.js 2 --apply # Delete duplicates, list 2 only
node tools/dedupe-laposta-list.js --state=inactive # Target inactive members

Validates SQLite tracking data against Rondo Club. Identifies invalid rondo_club_id mappings, orphans, and missing mappings.

Terminal window
node tools/verify-rondo-club-data.js --verbose # Report only (default)
node tools/verify-rondo-club-data.js --fix --verbose # Nullify invalid IDs for re-sync

Checks: rondo_club_members, rondo_club_parents, rondo_club_teams, rondo_club_commissies, rondo_club_important_dates.


Simpler version of verify-rondo-club-data: validates that all tracked rondo_club_id values still exist in Rondo Club.

Terminal window
node tools/validate-rondo-club-ids.js # Dry run (default)
node tools/validate-rondo-club-ids.js --apply # Nullify invalid IDs

Verifies that photo files on disk match the photo_state in the database. Finds members marked as downloaded or synced whose files are missing.

Terminal window
node tools/check-photo-consistency.js --verbose # Report only (default)
node tools/check-photo-consistency.js --fix # Update database states

Fetches all people from Rondo Club API by KNVB ID and repopulates missing rondo_club_id mappings in the local database.

Terminal window
node tools/repopulate-rondo-club-ids.js --dry-run --verbose # Preview
node tools/repopulate-rondo-club-ids.js --verbose # Apply

Use this after database loss or corruption to restore ID mappings without creating duplicates.


Resets photo_state to pending_download for members marked as no_photo but who have photo URLs or image dates.

Terminal window
node tools/reset-photo-states.js # Dry run (default)
node tools/reset-photo-states.js --apply # Fix states

Shows pending Laposta sync changes with field-level diffs.

Terminal window
node tools/show-laposta-changes.js # Changes only, list 0
node tools/show-laposta-changes.js 2 # Changes only, list 2
node tools/show-laposta-changes.js --all # All members with diffs

Read-only: No modifications made.


Looks up a member in the Laposta tracking database by email.

Terminal window
node tools/show-laposta-member.js [email protected]
node tools/show-laposta-member.js [email protected] 2 # List 2

Read-only: No modifications made.


Looks up a member in cached Sportlink data by email.

Terminal window
node tools/show-sportlink-member.js [email protected]

Read-only: No modifications made.


Displays Nikki contribution records with filtering options.

Terminal window
node tools/show-nikki-contributions.js # All records
node tools/show-nikki-contributions.js KNVB123456 # Specific member
node tools/show-nikki-contributions.js --year 2025 # Specific year
node tools/show-nikki-contributions.js --outstanding # Members with balance > 0
node tools/show-nikki-contributions.js --json # JSON output

Read-only: No modifications made.


Detects field changes in Rondo Club for reverse sync (currently disabled).

Terminal window
node tools/detect-rondo-club-changes.js --verbose

Read-only: Reports detected changes but doesn’t sync them.


Syncs a single member to Rondo Club by KNVB ID. Useful for debugging or fixing individual records.

Terminal window
node pipelines/sync-individual.js KNVB123456 --verbose # Full sync
node pipelines/sync-individual.js KNVB123456 --dry-run --verbose # Preview only
node pipelines/sync-individual.js KNVB123456 --fetch --verbose # Fetch fresh data from Sportlink first
node pipelines/sync-individual.js KNVB123456 --force --verbose # Ignore change detection
node pipelines/sync-individual.js KNVB123456 --skip-functions # Skip functions/commissie sync
node pipelines/sync-individual.js --search "Jan Jansen" # Search by name

Sends sync report logs as formatted HTML email via Postmark.

Terminal window
node scripts/send-email.js <log-file-path> [sync-type]

Requires POSTMARK_API_KEY, POSTMARK_FROM_EMAIL, OPERATOR_EMAIL in .env.


Interactive cron job installer. Prompts for Postmark credentials and installs all sync schedules.

Terminal window
npm run install-cron
# or
bash scripts/install-cron.sh

Unified sync wrapper for cron. Handles locking (flock), logging, and email report delivery.

Terminal window
scripts/sync.sh {people|photos|teams|functions|invoice|nikki|freescout|reverse|discipline|all}

Pass extra flags after the sync type:

Terminal window
scripts/sync.sh functions --all # Full functions sync

ScriptDefault ModePurpose
tools/delete-duplicates.jsDry-runRemove duplicate Rondo Club members
tools/merge-duplicate-person.jsDestructiveMerge parent into member
tools/cleanup-duplicate-relationships.jsDestructiveRemove duplicate relationships
tools/clear-commissie-work-history.jsDestructiveClear commissie work history
tools/find-orphan-dates.jsDry-runFind/delete orphaned birthdays (DEPRECATED v2.3)
tools/verify-rondo-club-data.jsReport-onlyValidate ID mappings
tools/reset-photo-states.jsDry-runFix photo state mismatches
tools/cleanup-rondo-club-duplicates.jsDry-runRemove non-Sportlink members
tools/cleanup-orphan-relationships.jsDry-runRemove orphaned relationships
tools/cleanup-comma-teams.jsDry-runDelete malformed teams
tools/check-photo-consistency.jsReport-onlyVerify photo files vs database
tools/validate-rondo-club-ids.jsDry-runValidate rondo_club_id existence
tools/repopulate-rondo-club-ids.jsDry-runRestore missing ID mappings
tools/dedupe-laposta-list.jsDry-runDeduplicate Laposta entries
pipelines/sync-individual.jsSyncSync single member
tools/show-laposta-changes.jsRead-onlyView pending Laposta changes
tools/show-laposta-member.jsRead-onlyLook up Laposta member
tools/show-sportlink-member.jsRead-onlyLook up Sportlink member
tools/show-nikki-contributions.jsRead-onlyView Nikki contributions
tools/detect-rondo-club-changes.jsRead-onlyDetect reverse sync changes