feat(reminders): dogfood jobs' DB-stored cron schedules with a nightly stale-task sweep - #76
Merged
Merged
Conversation
…y stale-task sweep @nest-native/jobs 0.2.0 shipped DB-stored cron schedules as its headline feature, but this app — whose whole job is to put the libraries under realistic pressure — only exercised the enqueue-driven half. It now exercises the recurring half too. The sweep flags every task still 'open' more than 14 days after creation by recording a task.stale.flagged audit entry, following the existing convention that an audit entry stands in for a notification. What makes it worth having here is what it exercises rather than what it does: - nobody enqueues it. The claimer inserts each occurrence itself from a job_schedules row, in the same transaction that advances the schedule. - the schedule is declared by a boot-time upsert, the documented pattern — and the spec pins the two properties that make that safe: an omitted 'enabled' preserves an operator's runtime disable across a redeploy, and an unchanged cron preserves a pending catch-up. - the schedule carries a uniqueKey, so a slow night cannot stack runs; the spec proves a second occurrence is suppressed while one is active. - the handler is idempotent and reads the DB itself rather than trusting a payload, because schedule delivery is still at-least-once. Schedules are opt-in: app.module now passes a scheduleStore, and the job_schedules table comes from the library so the app and engine share byte-identical DDL (same precedent as the jobs and messaging tables).
The migration step prepares ./ci.db, but that DATABASE_URL was scoped to that step alone — so the generator, which boots the whole app, fell back to a fresh unmigrated temp database. That was invisible while nothing wrote at bootstrap; RemindersModule declaring its cron schedule at boot surfaced it as 'no such table: job_schedules'. Giving the step the database the previous step just migrated is what the migration step was there for.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@nest-native/jobs0.2.0 shipped DB-stored cron schedules as its headline feature, but this app only exercised the enqueue-driven half of the library. Since the app exists to put the libraries under realistic pressure, that gap was worth closing.What it adds
A nightly stale-task sweep: every task still
openmore than 14 days after creation gets atask.stale.flaggedaudit entry — reusing the app's existing convention that an audit entry stands in for a notification (same as the assignment reminder).What makes it worth having here is what it exercises, not what it does:
job_schedulesrow, in the same transaction that advances the schedule — a genuinely different path from the assignment reminder, which a projection enqueues.enabledpreserves an operator's runtime disable across a redeploy, and an unchanged cron preserves a pending catch-up instead of skipping it.uniqueKey, so a slow night cannot stack runs — the spec proves a second occurrence is suppressed while one is still active.Schedules are opt-in, so
app.modulenow passes ascheduleStore; thejob_schedulestable is imported from the library so the app and the engine share byte-identical DDL (the same precedent as thejobsand messaging tables). Migration0006is drizzle-kit generated.Verification
Per the repo guidelines (Docker was available, so full mode was run):
npm run test:full→ base suite 90/90 green, including the 4 new schedule specs.mainwith these changes stashed, so it is pre-existing and unrelated. It fails at file level with no assertion output; CI never runs it (it self-skips without a broker). Flagging it rather than papering over it.typecheck,lint,complexity:check,build,security:auditall clean.No library friction to report upstream this time — the boot-upsert +
uniqueKeycombination covered the app's needs without reaching past the public API.