fix(core): reconcile media usage indexes automatically - #2443
Conversation
…utomatic-reconciliation # Conflicts: # .changeset/safe-collection-deletion.md # packages/core/src/database/migrations/runner.ts # packages/core/src/database/repositories/media-usage.ts # packages/core/src/database/types.ts # packages/core/src/emdash-runtime.ts # packages/core/src/media/usage/collection-deletion-processor.ts # packages/core/src/media/usage/collection-deletion.ts # packages/core/tests/integration/database/media-usage-incremental-work-migration.test.ts # packages/core/tests/integration/database/migrations.test.ts # packages/core/tests/integration/runtime/media-usage-scheduled-driver.test.ts # packages/core/tests/workerd/media-usage-collection-deletion-d1.test.ts
🦋 Changeset detectedLatest commit: 29ae696 The changes in this PR will be included in the next version bump. This PR includes changesets to release 17 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Scope checkThis PR changes 3,519 lines across 40 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
docs | 7a3ff56 | Aug 13 2026, 10:50 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | 29ae696 | Aug 13 2026, 11:18 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 29ae696 | Aug 13 2026, 11:19 AM |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/auth-atproto
@emdash-cms/blocks
@emdash-cms/cloudflare
@emdash-cms/contentful-to-portable-text
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/plugin-cli
@emdash-cms/plugin-types
@emdash-cms/registry-client
@emdash-cms/registry-lexicons
@emdash-cms/registry-verification
@emdash-cms/sandbox-workerd
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-field-kit
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
There was a problem hiding this comment.
This PR completes the durable Media Usage indexing system by adding automatic, resumable, bounded background reconciliation. After reading the diff, the key implementation files, and tracing the scheduling/runtime wiring, the approach looks sound and well-fitted to EmDash: it reuses the existing lease/epoch/work machinery, keeps scans bounded to 50-row pages, fences stale claims, does not activate incremental capture automatically, and routes the new lane through the same Cloudflare Cron Trigger / Node scheduler paths already used for maintenance.
I checked:
- SQL safety: all dynamic table/identifier references go through
validateIdentifier()and Kyselysql.ref(); embedded fragments use Kysely template composition; nosql.raw()string interpolation. - Migration discipline:
066_media_usage_reconciliation.tsis sequential, registered inrunner.ts, creates indexes on the new coordinator table and on_emdash_media_usage_index_statusfor the reconciliation gate, and itsdown()guards against rollback after activation. - Locale correctness: the new content-table scans paginate by
content.idand only capture ID boundaries/source identity; locale is stored per-source via the existing_emdash_media_usage_sourcesrow, so no content query forgets the per-locale model. - Logged-out hot path: reconciliation/work is only driven by the Cloudflare
scheduled()handler or the Node timer scheduler, not by request handlers or middleware; no new queries are added to public page renders. - Cloudflare scheduling:
createScheduledHandler()remains backwards-compatible (no options = old behavior); the templated configuration correctly splits general and Media Usage cron expressions and validates they differ. - Comments / AGENTS conventions: no PR/issue references, narrative, or justification comments in the new code.
- Tests: new integration and Cloudflare worker scheduled-handler tests exercise observable behavior (lane dispatch, claim fencing, scan/source finalization) rather than asserting implementation details back at themselves.
No blocking issues. Good to merge.
Overlapping PRsThis PR modifies files that are also changed by other open PRs:
This may cause merge conflicts or duplicated work. A maintainer will coordinate. |
There was a problem hiding this comment.
This PR completes the durable Media Usage indexing system by adding automatic, resumable, bounded background reconciliation. Re-reading the diff after the prior review, the approach still looks sound and well-fitted to EmDash: it reuses the existing lease/epoch/work machinery, keeps scans bounded to 50-row pages, fences stale claims, does not activate incremental capture automatically, and correctly routes the new lane through both Cloudflare Cron Trigger and Node timer scheduler paths.
I re-checked:
- SQL safety: all dynamic table/identifier references go through
validateIdentifier()and Kyselysql.ref(); embedded fragments use Kysely template composition. - Migration discipline:
066_media_usage_reconciliation.tsis sequential, registered inrunner.ts, adds the required indexes, and itsdown()guards against rollback after activation. - Locale correctness: the new content-table scans paginate by
content.id; each source row stores its own locale, so no content query forgets the per-locale model. - Logged-out hot path: reconciliation/work is only driven by scheduled handlers, not by request handlers or middleware.
- Cloudflare scheduling:
createScheduledHandler()remains backwards-compatible, validates that general and Media Usage cron expressions differ, and dispatches exactly one lane per trigger. - AGENTS conventions: no narrative/issue-reference/justification comments; no untranslated UI strings; changeset is user-facing and correct.
- Tests: the new integration and scheduled-driver tests exercise observable behavior (lane dispatch, claim fencing, scan/source finalization, epoch restart) rather than asserting implementation details back at themselves.
No blockers, regressions, or convention violations were found. This re-review confirms the prior approval; the branch is ready to merge.
What does this PR do?
Makes Media Usage coverage recover automatically and resumably after activation.
This PR:
Builds on merged #2433.
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (targeted tests for this change)pnpm formathas been runAI-generated code disclosure
Screenshots / test output
No visual changes.
Verified after integrating merged #2433:
PostgreSQL runtime tests were not run because
EMDASH_TEST_PGis not configured locally.Try this PR
Open a fresh playground →
A full working EmDash site, deployed from this branch. Each visit gets its own session-scoped sandbox: no login needed and no shared state. Try the admin, edit content, hit the public site.
Tracks
feature/media-usage-automatic-reconciliation. Updated automatically when the playground redeploys.