Abandoned account deletion
Daily cron (prod, batched) that fully deletes human accounts inactive ≥ 1 year with no game participation, after live confirmation. Distinct from dashboard cruft cleanup (index prune only).
Schedule
| Handler | src/functions/abandoned-account-deletion.ts |
| Schedule | Daily 03:30 UTC (prod only) |
| Timeout / memory | 900 s / 10240 MB (full-table ION export, same class as records) |
| Layer | @abstractplay/gameslib (open-challenge live checks import gameslib) |
Eligibility
Inactive: USER.lastSeen numeric and older than ABANDONED_ACCOUNT_INACTIVE_MS (default 365 days).
Hard blockers (skip user): any COMPLETEDGAMES#<userId>, CURRENTGAMES#<userId>, or seated ARENAUSER row. Registered display name required; skip bots and admins.
Soft defer: open CHALLENGE / REALSTANDING involvement → skip with open_challenge until inactive-challenge-cleanup clears them.
Not blockers: tournament / ladder / org registrations — detached during delete via lib/abandonedAccountDeletion.ts.
Candidate discovery
Same S3 ION export as dashboard cruft (abstractplay-db-dump). Shared collector: lib/abandonedAccountDumpCandidates.ts / dumpExport.ts.
Environment
| Variable | Default | Purpose |
|---|---|---|
ABANDONED_ACCOUNT_DELETE_ENABLED |
true |
Must be true to run the job (dump + live path); set false to no-op |
ABANDONED_ACCOUNT_DELETE_DRY_RUN |
true |
When true, no DDB/Cognito mutations (log skips and would-delete only) |
ABANDONED_ACCOUNT_DELETE_BATCH_SIZE |
25 |
Max users per run |
ABANDONED_ACCOUNT_INACTIVE_MS |
31536000000 |
Inactivity threshold |
USERPOOL_ID |
stage pool id | Cognito AdminDeleteUser |
ABSTRACT_PLAY_TABLE |
abstract-play-{stage} |
Main table |
FEEDBACK_TABLE |
abstract-play-feedback-{stage} |
Removes USER# index partition |
Sizing (read-only)
From repo root (requires AWS profile with S3 access to abstractplay-db-dump; export is large):
npm run list-abandoned-account-candidates -- --download
npm run list-abandoned-account-candidates -- --dump-dir .local/abandoned-account-ion-dump/<exportUid> --out bin/abandoned-account-candidates.json --csv --include-deferred
Manual single-user delete
npm run abandoned-account-deletion -- --stage prod --user-id <cognito-sub> --dry-run
npm run abandoned-account-deletion -- --stage prod --user-id <cognito-sub> --apply
Rollout
- Run list script; review candidate counts.
- Deploy with
ABANDONED_ACCOUNT_DELETE_ENABLED=true,ABANDONED_ACCOUNT_DELETE_DRY_RUN=true(current prod default after first healthy runs). - Manual
--applyon one dev user, then enable prod with small batch.
Related
- Live crons
- Backend database schema — account removal vs
USER.cleaned