feat(core): add media usage repair tooling#2007
Conversation
🦋 Changeset detectedLatest commit: 0f84101 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 783 lines across 14 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 | 0f84101 | Jul 13 2026, 08:58 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 0f84101 | Jul 13 2026, 08:59 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-do | 0f84101 | Jul 13 2026, 08:59 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/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 | 0f84101 | Jul 13 2026, 09:00 AM |
There was a problem hiding this comment.
This is the right change for an approved Discussion: it surfaces the existing media-usage repair handler through the CLI and MCP server, reuses the complete/partial/failed/stale contracts, and ships contract tests plus operator docs. The implementation is clean and the test coverage is good.
I read the diff, the full changed files, the backing handler/route, and the client/MCP wiring. The main concern is authorization consistency: the new CLI docs and the MCP tool both say the repair requires an admin token scope, but the existing REST route they rely on (POST /_emdash/api/admin/media-usage/repair) only checks schema:manage and ignores token scopes. That means an Admin-owned token without the admin scope can still trigger a potentially expensive, write-heavy repair. The route should either be updated to enforce requireScope(locals, "admin") or the docs/MCP contract should be softened.
A couple of smaller suggestions: the integration global setup always runs pnpm build even when artifacts are fresh, and the MCP tool redeclares an input schema that already exists in #api/schemas.js.
No blocking code defects in the changed lines themselves, so the verdict is comment.
There was a problem hiding this comment.
This PR adds well-scoped operator-facing media usage repair tooling: a media repair-usage CLI command and a media_usage_repair MCP tool, both reusing the existing repair contracts and preserving the structured complete/partial/failed/stale status shapes. It links to the approved Discussion, includes docs and a changeset, and moves the integration/smoke build step into a Vitest globalSetup so the workspace is built once per test run. The approach is sound and fits EmDash’s architecture.
I traced the CLI/MCP wiring against the REST route (/_emdash/api/admin/media-usage/repair) and its schema:manage permission check, and against the auth middleware scope rules (["/_emdash/api/admin", "*", "admin"]). The MCP tool’s admin scope + Role.ADMIN requirement is effectively equivalent for token auth, and session auth is covered by the role check, so the two entry points are consistent in practice.
The one real gap is test wiring: the new MCP contract tests live under tests/integration/mcp/ but vitest.integration.config.ts only includes tests/integration/cli/** and tests/integration/client/**, so those tests will not run in CI’s integration job. They are also not excluded from the main vitest.config.ts, so they may run (and pass) as part of the unit suite instead, which is semantically wrong and duplicates work. The fix is to add the MCP directory to the integration config include and exclude it from the main unit config.
Otherwise the code looks clean: validation, error handling, exit codes, auth checks, and contract coverage are all in order, and I found no SQL, locale-filter, or API-envelope issues introduced by this PR.
ascorbic
left a comment
There was a problem hiding this comment.
Looks solid overall, but look at the bot reviews
ascorbic
left a comment
There was a problem hiding this comment.
Ah, I see you have now!
What does this PR do?
Adds operator-facing media usage index repair through the CLI and MCP server. Both interfaces support repairing one collection or every collection, reuse the existing repair contracts, preserve structured complete/partial/failed/stale results, and require the appropriate administrative authorization.
Includes CLI and MCP contract coverage, operator documentation, and integration-test setup that builds the workspace once per test run.
In this PR, the operators use this CLI/MCP repair tooling after imports or direct database writes; it makes the media usage index maintainable, with read APIs and the Media Library “Used in” UI still to come.
Related Discussion: #1503
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change)pnpm formathas been runAI-generated code disclosure
Screenshots / test output
No visual changes.
pnpm typecheckpnpm lint