Live crons

Functions that operate on live DynamoDB rather than only writing static artifacts. Most run on prod schedules and mutate data directly.

dashboard-cruft-cleanup

Schedule: 03:00 UTC daily
Source: src/functions/dashboard-cruft-cleanup.ts

Prunes stale dashboard index cruft (RECENTCOMPLETED#, orphan USERGAME#) for users inactive ≥ 1 year. Candidates come from the daily S3 ION dump; each user is confirmed live before cleanup. Sets USER.cleaned = true (cleared on me() login in node-backend).

See Dashboard cruft cleanup for full detail.

starttournaments

Schedule: 10:00 and 22:00 UTC daily
Source: src/functions/starttournaments.ts

Purpose

Automates the tournament lifecycle:

  1. Find tournaments that are ready to start (enough registered players, scheduled start time reached)
  2. Cancel tournaments that cannot start (insufficient players)
  3. Create initial games for started tournaments via GameFactory
  4. Send notification emails through SES

DynamoDB access

Queries and updates TOURNAMENT records on abstract-play-{stage}. Uses retry logic for throttling (ThrottlingException, etc.).

Gameslib integration

Email / i18n

Uses i18next with repo-root locales/*/apback.json bundled via @backend/lib/apbackI18n (see Getting started). Email templates reference tournament name, meta game, and player lists.

Related backend docs

Manual invoke

Scheduled runs sweep all eligible tournaments. For a single tournament (including resume after a partial start):

serverless invoke -f starttournaments --stage prod --path invoke-resume.json

Example invoke-resume.json:

{"tournamentId":"<uuid>","resume":true}

Resume requires started: false. Tournament start is not exposed via node-backend queries or the admin dashboard — only this Lambda. Ad-hoc prod ops scripts live under bin/ (gitignored, local only), e.g. bin/check-tournament-prod.mjs, bin/cleanup-tournament-prod.mjs.

inactive-challenge-cleanup

Schedule: 03:00 UTC daily
Source: src/functions/inactive-challenge-cleanup.ts

Revokes open (STANDINGCHALLENGE#) and direct (CHALLENGE) challenges issued by players inactive ≥ 14 days (USERS.lastSeen). Pauses matching REALSTANDING presets and notifies acceptors (email, push, in-app for direct).

See Inactive challenge cleanup for full detail.

yourturn

Schedule: 14:00 and 22:00 UTC daily
Source: src/functions/yourturn.ts (logic in utils/yourturn.ts)

Batch "your turn" emails for active multiplayer games. Uses SES and gameslib gameinfo for localized game names. See Notifications.

feedback-archive / feedback-attachment-cleanup

Schedules: 04:00 and 04:30 UTC daily
Sources: feedback-archive.ts, feedback-attachment-cleanup.ts (shared lib/feedback/* at repo root)

Nightly feedback lifecycle: archive terminal posts to S3, then purge attachment objects. Local dry runs: npm run feedback-archive / npm run feedback-attachment-cleanup from node-backend root.

standingchallenges

Schedule: 00:00 and 12:00 UTC daily
Source: src/functions/standingchallenges.ts

Purpose

Processes preset standing challenge requests stored as REALSTANDING records. When conditions are met (matching players online, preset rules satisfied), the cron creates challenge records in DynamoDB so the normal challenge flow in node-backend can pick them up.

DynamoDB access

Queries REALSTANDING and related user/challenge records. Does not use gameslib — pure DynamoDB document operations.

Related backend docs

Dev vs prod

Both functions deploy to dev stacks but EventBridge schedules are disabled on dev. Test by invoking manually:

serverless invoke -f dashboard-cruft-cleanup --stage prod
serverless invoke -f inactive-challenge-cleanup --stage prod
serverless invoke -f starttournaments --stage prod
serverless invoke -f standingchallenges --stage prod
serverless invoke -f yourturn --stage prod
serverless invoke -f feedback-archive --stage prod
serverless invoke -f feedback-attachment-cleanup --stage prod

Use prod with care — these mutate live data.

Related