Add media usage index write-side foundation - #1746
Conversation
…n handling and fingerprinting
…with generation checks
🦋 Changeset detectedLatest commit: 042c0e5 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 |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | 042c0e5 | Jul 03 2026, 05:38 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 042c0e5 | Jul 03 2026, 05:38 PM |
@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: |
ascorbic
left a comment
There was a problem hiding this comment.
Great stuff. Just a couple of notes. However this is a very large PR. For future ones, can you keep them smaller in scope so they're easier to review.
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. |
…ation) into mj/prod for live trial
|
Tested this on a real production site (masonjames.com — Ghost→EmDash migration, Node + SQLite, downstream fork with local media patches). Results:
Happy to re-test when the read API / rebuild phases land. |
|
@masonjames Thank you so much for testing this out! This is actually a really helpful validation :) Also, I agree URL attribution for configured media/public domains is worth considering in the rebuild/import follow-up. |
|
@khoinguyenpham04 awesome! I'm really excited about the media components in emdash. Feel free to tag me on PRs whenever you'd like additional testing. Always happy to do so. 🙌 |
ascorbic
left a comment
There was a problem hiding this comment.
Thanks! And thanks @masonjames for the review
* feat(media): add usage index tables * feat(media): add usage extractor * feat(media): add usage repository * chore(media): add usage foundation changeset * ci: update query-count snapshots * fix(media): skip path-like local usage refs * feat(media): add usage index status metadata * feat: enhance media usage index with new tracking and management features * feat(media): Rename Repository Fixtures To Storage Variants * feat(media): Add Source-Key Contract Tests * feat(media): refine extractor to focus on image subfields and update tests * feat(media): tightened the source-variant write/input type seam. * feat(media): implement content media usage field discovery and associated tests * feat(media): add content media usage snapshots loader and associated tests * feat(media): enhance content media usage snapshots with draft revision handling and fingerprinting * feat(media): update buildContentSource to conditionally include sourceFingerprint * feat(media): Add Content Usage Refresh Service * feat(media): Wire Runtime Create, Update, Duplicate, Revision Restore * Wire Publish, Unpublish, Schedule, Unschedule, Discard Draft * Wire Trash And Permanent Delete * Refresh I18n Non-Translatable Siblings * Mark Bypass And Schema Paths Stale * Add Refresh Failure Path Coverage * Implement guarded replace and delete methods in MediaUsageRepository with generation checks * Fix media usage lint issues * Fix media usage display title extraction * update guarded replace result handling and add test for replacement success signal * Implement retry logic for content media usage refresh to handle generation conflicts * Harden media usage failure handling --------- Co-authored-by: emdashbot[bot] <emdashbot[bot]@users.noreply.github.com>
What does this PR do?
Adds the write-side foundation for the Media Usage index. This includes the database tables/status metadata, content media reference extraction, content source snapshots for
columnsanddraft_overlay, repository APIs, runtime refresh wiring for normal content lifecycle writes, stale marking for known bypass paths, and generation-guarded source replacement/deletion so refresh races preserve current usage and mark coverage stale instead of failing content writes.This PR intentionally stops before repair/rebuild, the usage read API, admin Used In UI, safe delete, replace-in-place behavior, or media delete behavior changes.
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. N/A: no admin UI strings in this PR.AI-generated code disclosure
openai/gpt-5.5)Screenshots / test output
Non-visual backend/indexing change.
Verified:
pnpm lintpnpm typecheckpnpm formatpnpm --filter emdash exec vitest run tests/integration/database/media-usage-status-migration.test.ts tests/integration/database/media-usage-content-fields.test.ts tests/integration/database/media-usage-repository.test.ts tests/integration/database/media-usage-migration.test.ts tests/integration/database/media-usage-content-snapshots.test.ts tests/integration/database/media-usage-content-refresh.test.ts tests/integration/database/media-usage-runtime-refresh.test.ts tests/integration/database/media-usage-stale-bypass.test.ts tests/unit/media/usage-extractor.test.ts tests/unit/media/usage-source-key.test.ts(10 files, 98 tests)git diff --checkTry 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-index-core. Updated automatically when the playground redeploys.