Utility Scripts
Reference for all utility, cleanup, inspection, and recovery scripts.
Cleanup Scripts
Section titled “Cleanup Scripts”delete-duplicates.js
Section titled “delete-duplicates.js”Finds and removes duplicate member entries in Rondo Club by KNVB ID, keeping the oldest record.
node tools/delete-duplicates.js --verbose # Dry run (default)node tools/delete-duplicates.js --apply # Actually deleteSafe by default: Dry-run mode shows what would be deleted without making changes.
merge-duplicate-person.js
Section titled “merge-duplicate-person.js”Merges a parent record into a member record, reassigning all child relationships, then deletes the parent.
node tools/merge-duplicate-person.js --parent=123 --member=456Destructive: Immediately performs the merge and deletion. No dry-run mode.
cleanup-duplicate-relationships.js
Section titled “cleanup-duplicate-relationships.js”Scans all people and removes duplicate relationships (same person + type) and self-referential relationships.
node tools/cleanup-duplicate-relationships.jsDestructive: Immediately removes duplicates. No dry-run mode.
cleanup-orphan-relationships.js
Section titled “cleanup-orphan-relationships.js”Finds people with relationships pointing to non-existent person IDs and removes those orphaned relationships.
node tools/cleanup-orphan-relationships.js --verbose # Dry run (default)node tools/cleanup-orphan-relationships.js --fix # Remove orphaned relationshipscleanup-comma-teams.js
Section titled “cleanup-comma-teams.js”Deletes teams whose names contain commas (artifact of bad sync data).
node tools/cleanup-comma-teams.js --verbose # Dry run (default)node tools/cleanup-comma-teams.js # Delete bad teamscleanup-rondo-club-duplicates.js
Section titled “cleanup-rondo-club-duplicates.js”Compares Rondo Club records against expected Sportlink members and identifies/deletes members not in Sportlink.
node tools/cleanup-rondo-club-duplicates.js --verbose # Dry run (default)node tools/cleanup-rondo-club-duplicates.js --delete # Delete duplicatesclear-commissie-work-history.js
Section titled “clear-commissie-work-history.js”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.
node tools/clear-commissie-work-history.jsDestructive: Immediately clears work history. No dry-run mode.
find-orphan-dates.js (DEPRECATED)
Section titled “find-orphan-dates.js (DEPRECATED)”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.
node tools/find-orphan-dates.js --verbose # List orphans (default)node tools/find-orphan-dates.js --delete # Delete orphaned datesdedupe-laposta-list.js
Section titled “dedupe-laposta-list.js”Finds and removes duplicate parent entries (by email) across Laposta lists, keeping entries from the lowest-numbered list.
node tools/dedupe-laposta-list.js # Dry run, all listsnode tools/dedupe-laposta-list.js --apply # Delete duplicates, all listsnode tools/dedupe-laposta-list.js 2 --apply # Delete duplicates, list 2 onlynode tools/dedupe-laposta-list.js --state=inactive # Target inactive membersValidation Scripts
Section titled “Validation Scripts”verify-rondo-club-data.js
Section titled “verify-rondo-club-data.js”Validates SQLite tracking data against Rondo Club. Identifies invalid rondo_club_id mappings, orphans, and missing mappings.
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-syncChecks: rondo_club_members, rondo_club_parents, rondo_club_teams, rondo_club_commissies, rondo_club_important_dates.
validate-rondo-club-ids.js
Section titled “validate-rondo-club-ids.js”Simpler version of verify-rondo-club-data: validates that all tracked rondo_club_id values still exist in Rondo Club.
node tools/validate-rondo-club-ids.js # Dry run (default)node tools/validate-rondo-club-ids.js --apply # Nullify invalid IDscheck-photo-consistency.js
Section titled “check-photo-consistency.js”Verifies that photo files on disk match the photo_state in the database. Finds members marked as downloaded or synced whose files are missing.
node tools/check-photo-consistency.js --verbose # Report only (default)node tools/check-photo-consistency.js --fix # Update database statesRecovery Scripts
Section titled “Recovery Scripts”repopulate-rondo-club-ids.js
Section titled “repopulate-rondo-club-ids.js”Fetches all people from Rondo Club API by KNVB ID and repopulates missing rondo_club_id mappings in the local database.
node tools/repopulate-rondo-club-ids.js --dry-run --verbose # Previewnode tools/repopulate-rondo-club-ids.js --verbose # ApplyUse this after database loss or corruption to restore ID mappings without creating duplicates.
reset-photo-states.js
Section titled “reset-photo-states.js”Resets photo_state to pending_download for members marked as no_photo but who have photo URLs or image dates.
node tools/reset-photo-states.js # Dry run (default)node tools/reset-photo-states.js --apply # Fix statesInspection Scripts
Section titled “Inspection Scripts”show-laposta-changes.js
Section titled “show-laposta-changes.js”Shows pending Laposta sync changes with field-level diffs.
node tools/show-laposta-changes.js # Changes only, list 0node tools/show-laposta-changes.js 2 # Changes only, list 2node tools/show-laposta-changes.js --all # All members with diffsRead-only: No modifications made.
show-laposta-member.js
Section titled “show-laposta-member.js”Looks up a member in the Laposta tracking database by email.
Read-only: No modifications made.
show-sportlink-member.js
Section titled “show-sportlink-member.js”Looks up a member in cached Sportlink data by email.
Read-only: No modifications made.
show-nikki-contributions.js
Section titled “show-nikki-contributions.js”Displays Nikki contribution records with filtering options.
node tools/show-nikki-contributions.js # All recordsnode tools/show-nikki-contributions.js KNVB123456 # Specific membernode tools/show-nikki-contributions.js --year 2025 # Specific yearnode tools/show-nikki-contributions.js --outstanding # Members with balance > 0node tools/show-nikki-contributions.js --json # JSON outputRead-only: No modifications made.
detect-rondo-club-changes.js
Section titled “detect-rondo-club-changes.js”Detects field changes in Rondo Club for reverse sync (currently disabled).
node tools/detect-rondo-club-changes.js --verboseRead-only: Reports detected changes but doesn’t sync them.
Sync Scripts
Section titled “Sync Scripts”sync-individual.js
Section titled “sync-individual.js”Syncs a single member to Rondo Club by KNVB ID. Useful for debugging or fixing individual records.
node pipelines/sync-individual.js KNVB123456 --verbose # Full syncnode pipelines/sync-individual.js KNVB123456 --dry-run --verbose # Preview onlynode pipelines/sync-individual.js KNVB123456 --fetch --verbose # Fetch fresh data from Sportlink firstnode pipelines/sync-individual.js KNVB123456 --force --verbose # Ignore change detectionnode pipelines/sync-individual.js KNVB123456 --skip-functions # Skip functions/commissie syncnode pipelines/sync-individual.js --search "Jan Jansen" # Search by nameInfrastructure Scripts
Section titled “Infrastructure Scripts”send-email.js
Section titled “send-email.js”Sends sync report logs as formatted HTML email via Postmark.
node scripts/send-email.js <log-file-path> [sync-type]Requires POSTMARK_API_KEY, POSTMARK_FROM_EMAIL, OPERATOR_EMAIL in .env.
install-cron.sh
Section titled “install-cron.sh”Interactive cron job installer. Prompts for Postmark credentials and installs all sync schedules.
npm run install-cron# orbash scripts/install-cron.shsync.sh
Section titled “sync.sh”Unified sync wrapper for cron. Handles locking (flock), logging, and email report delivery.
scripts/sync.sh {people|photos|teams|functions|invoice|nikki|freescout|reverse|discipline|all}Pass extra flags after the sync type:
scripts/sync.sh functions --all # Full functions syncQuick Reference
Section titled “Quick Reference”| Script | Default Mode | Purpose |
|---|---|---|
tools/delete-duplicates.js | Dry-run | Remove duplicate Rondo Club members |
tools/merge-duplicate-person.js | Destructive | Merge parent into member |
tools/cleanup-duplicate-relationships.js | Destructive | Remove duplicate relationships |
tools/clear-commissie-work-history.js | Destructive | Clear commissie work history |
tools/find-orphan-dates.js | Dry-run | Find/delete orphaned birthdays (DEPRECATED v2.3) |
tools/verify-rondo-club-data.js | Report-only | Validate ID mappings |
tools/reset-photo-states.js | Dry-run | Fix photo state mismatches |
tools/cleanup-rondo-club-duplicates.js | Dry-run | Remove non-Sportlink members |
tools/cleanup-orphan-relationships.js | Dry-run | Remove orphaned relationships |
tools/cleanup-comma-teams.js | Dry-run | Delete malformed teams |
tools/check-photo-consistency.js | Report-only | Verify photo files vs database |
tools/validate-rondo-club-ids.js | Dry-run | Validate rondo_club_id existence |
tools/repopulate-rondo-club-ids.js | Dry-run | Restore missing ID mappings |
tools/dedupe-laposta-list.js | Dry-run | Deduplicate Laposta entries |
pipelines/sync-individual.js | Sync | Sync single member |
tools/show-laposta-changes.js | Read-only | View pending Laposta changes |
tools/show-laposta-member.js | Read-only | Look up Laposta member |
tools/show-sportlink-member.js | Read-only | Look up Sportlink member |
tools/show-nikki-contributions.js | Read-only | View Nikki contributions |
tools/detect-rondo-club-changes.js | Read-only | Detect reverse sync changes |