Repository navigation
Add media usage repair foundation - #1846
Conversation
🦋 Changeset detectedLatest commit: 5f71cde The changes in this PR will be included in the next version bump. This PR includes changesets to release 16 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 1,777 lines across 7 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. |
@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/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: |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | 5f71cde | Jul 06 2026, 03:49 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 5f71cde | Jul 06 2026, 03:47 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | 5f71cde | Jul 06 2026, 03:46 PM |
There was a problem hiding this comment.
This PR adds the internal media-usage repair foundation described in Discussion #1503: repository CAS/status primitives, a deterministic collection scanner, and a collection-level repair service. It stays within scope (no admin UI/REST/CLI) and includes tests.
What I checked:
- SQL safety: dynamic table names are built from
validateIdentifier-checked collection slugs and passed throughsql.ref(); user-supplied IDs are query parameters. No raw interpolation risk. - Concurrency: the in-process collection lock is now shared between repair and delete, and the repository-level CAS guard (
sourceMatchExpression) is narrow enough to catch the fields that actually change during concurrent writes (current_generation,source_completeness,updated_at, source metadata,revision_id, and attempt timestamps). - Status finalization:
beginIndexStatusRepair/finalizeIndexStatusRepairIfRunninguse thecursoras a run token and only finalize whenstatus = 'running'andcursor = runToken, which prevents stale runs from clobbering newer ones. - Locale/i18n: the scanner intentionally reads every content row (all locales) and each row is loaded by primary key; source keys carry
locale, so this is consistent with the row-per-locale model rather than a missing-locale-filter bug. - Tests: new integration tests cover happy path, empty collection, deleted rows, concurrent insert detection, orphan cleanup, and missing-collection short-circuit; repository tests cover the new CAS methods and guarded status transitions.
- Changeset is present and appropriate for an internal foundation change.
I found no correctness bugs or AGENTS.md violations. The code is careful with identifier validation, parameterized queries, and CAS semantics. A few low-risk performance/architecture suggestions are noted below, but none block merge.
What does this PR do?
Adds the internal media usage repair foundation for future Used In workflows.
This PR adds repository CAS/status primitives, a deterministic collection scanner, and a collection-level repair service foundation that can rebuild content-media usage rows and prove complete coverage for the happy path. It also tightens in-process delete/repair serialization and avoids repeated field-discovery queries during a repair run.
Out of scope for this PR: admin REST/client entry points, CLI, MCP, and admin UI. Those are planned follow-up PRs.
Closes: n/a
Related Discussion: #1503
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runmessages.pochanges except in translation PRs — a workflow extracts catalogs on merge tomain.i18n note: n/a, this PR adds no admin UI or user-facing strings.
AI-generated code disclosure
Screenshots / test output
No screenshots; no UI changes.
Verified:
Targeted tests passed: 58 tests.
Final lint-json diagnostic count: 0.
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
media-usage-repair-rebuild. Updated automatically when the playground redeploys.