Skip to content

fix: include runtime manual collections in admin manifest so their content routes resolve - #1645

Open
mvanhorn wants to merge 5 commits into
emdash-cms:mainfrom
mvanhorn:fix/1641-manual-collections-admin-manifest
Open

fix: include runtime manual collections in admin manifest so their content routes resolve#1645
mvanhorn wants to merge 5 commits into
emdash-cms:mainfrom
mvanhorn:fix/1641-manual-collections-admin-manifest

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

Summary

Collections created through the Admin UI (source: "manual") were absent from the admin manifest, so their content routes failed to resolve at runtime. This builds the manifest from the runtime manual collections via the SchemaRegistry, mapping schema field types to editor field kinds, so manual collections appear alongside file-defined ones.

Adds manifest-build.test.ts covering the manual-collection manifest path.

Fixes #1641

AI was used for assistance.

@changeset-bot

changeset-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5841a4f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 17 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/sandbox-workerd Patch
@emdash-cms/plugin-mcp-smoke Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
@emdash-cms/admin Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

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

@github-actions github-actions Bot added the review/needs-review No maintainer or bot review yet label Jun 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR template validation failed

Please fix the following issues by editing your PR description:

  • This PR does not use the required PR template. Please edit the description to use the PR template. Copy it into your PR description and fill out all sections.

See CONTRIBUTING.md for the full contribution policy.

@pkg-pr-new

pkg-pr-new Bot commented Jun 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@1645

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@1645

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@1645

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@1645

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@1645

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@1645

emdash

npm i https://pkg.pr.new/emdash@1645

create-emdash

npm i https://pkg.pr.new/create-emdash@1645

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@1645

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@1645

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@1645

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@1645

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@1645

@emdash-cms/registry-verification

npm i https://pkg.pr.new/@emdash-cms/registry-verification@1645

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@1645

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@1645

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@1645

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@1645

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@1645

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@1645

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@1645

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@1645

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@1645

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@1645

commit: 5841a4f

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is a sensible refactor at heart: it moves the DB-to-manifest field mapping into api/handlers/manifest.ts so the same code can build a manifest from config collections, runtime/manual DB collections, or both. That consolidation is the right direction.

I checked the changed files, call sites, and the admin/client manifest types. The code is SQL-safe, the runtime still uses this.db (ALS-aware), and the route envelope stays { data: manifest }. I found two concrete issues and one approach concern:

  1. Missing changeset. packages/core (the published emdash package) changed its public API/behavior, so AGENTS.md requires a changeset.
  2. Public return type is now a lie. generateManifest() returns ManifestResponse, but the objects it now produces carry extra fields (hasSeo, urlPattern, widget, id, validation) that the type does not declare. The admin/client types already know about these fields, so the server-side API type should be updated to match reality.
  3. The new merge path is not wired to the production admin manifest. EmDashRuntime._buildManifest() calls buildManifestCollections({}, this.db) with an empty config map, so the runtime manifest still derives only from the database. That already includes manual collections, so it does fix the stated symptom, but the newly-added config+DB merging in generateManifest() is only exercised by unit tests. If the intent is for the admin endpoint (or SSR bootstrap) to merge file-defined and manual collections, a production caller still needs to use generateManifest().

Nothing here is a security or data-loss regression, so I’m leaving this as a comment rather than request_changes.


Findings

  • [needs fixing] packages/core/package.json:2

    This PR changes the published emdash package (manifest generation API/behavior in packages/core). Per AGENTS.md, a user-facing change to a published package needs a changeset describing the observable effect.

    Please add a changeset such as .changeset/fix-manual-collections-manifest.md:

    ---
    "emdash": patch
    ---
    
    Fixes missing runtime manual collections in the admin manifest by building manifest descriptors from the live `_emdash_collections` / `_emdash_fields` tables.

@github-actions

Copy link
Copy Markdown
Contributor

Overlapping PRs

This PR modifies files that are also changed by other open PRs:

This may cause merge conflicts or duplicated work. A maintainer will coordinate.

@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-review No maintainer or bot review yet labels Jun 29, 2026
@ascorbic

Copy link
Copy Markdown
Collaborator

@mvanhorn could you cook at the review feedback. It looks all valid to me

ManifestResponse.collections now uses ManifestCollectionMap, so the public
type declares the fields the handler actually produces (hasSeo, urlPattern,
id, widget, validation). Types centralized in api/types.ts and re-exported.
Adds a changeset for the emdash package.
@mvanhorn

mvanhorn commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review:

  1. Added a changeset for the emdash package.
  2. ManifestResponse.collections now uses ManifestCollectionMap, so the public type declares the extra fields (hasSeo, urlPattern, id, widget, validation) instead of omitting them. The types are centralized in api/types.ts and re-exported from the package root.

On the third point — I dug into _buildManifest and the runtime doesn't carry a config collection map at manifest-build time (collections are DB-derived, which already includes the manual ones), so buildManifestCollections({}, db) is correct there and the merge path isn't needed in production. Happy to revisit if you'd rather thread config through.

@github-actions github-actions Bot added review/needs-rereview Author pushed changes since the last review cla: signed and removed review/awaiting-author Reviewed; waiting on the author to respond labels Jul 5, 2026
@ascorbic ascorbic added the bot:review Trigger an emdashbot code review on this PR label Jul 6, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR has been inactive for 14 days. It will be closed automatically in 7 days if there is no further activity.

If you're still working on this, please push an update or leave a comment.

@github-actions github-actions Bot added stale and removed stale labels Jul 20, 2026
@ascorbic ascorbic added bot:review Trigger an emdashbot code review on this PR and removed bot:review Trigger an emdashbot code review on this PR labels Jul 21, 2026

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This re-review covers the fixes pushed since the previous comment review.

The previous review raised three concerns: a missing changeset, generateManifest() returning objects wider than ManifestResponse, and the new config+DB merge helper not being wired to the production admin manifest. All three are now reasonably addressed:

  1. Changeset added. .changeset/manifest-field-mapping.md is present and describes the user-facing effect.
  2. Public types updated. packages/core/src/api/types.ts now declares ManifestCollectionMap, ManifestCollectionDescriptor, and ManifestFieldDescriptor, and ManifestResponse.collections uses them. These types match the fields actually produced (hasSeo, urlPattern, id, widget, validation). The new types are also re-exported from packages/core/src/index.ts.
  3. Merge wiring. The production runtime manifest (EmDashRuntime._buildManifest()) calls buildManifestCollections({}, this.db), i.e. it builds from the live database. Because file-defined collections are persisted into _emdash_collections along with manual ones, the database is the runtime source of truth for collections, so both collection sources already appear in the admin manifest. The generateManifest(config, plugins, { db }) merge path is exposed for callers that need to merge an in-memory config map with the database, and it is covered by the new unit tests.

What I checked:

  • Full diff and the changed files (manifest.ts, api/types.ts, emdash-runtime.ts, index.ts, the admin manifest route, and the test file).
  • Call sites of generateManifest and buildManifestCollections; only the handler module, public exports, runtime, and tests reference them.
  • Field mapping parity between the old inline _buildManifest() code and the new shared dbFieldDescriptor(); behavior is identical.
  • SQL safety: all DB access goes through SchemaRegistry / Kysely; no interpolated SQL.
  • API envelope shape: the admin manifest route still returns { data: manifest }.
  • Type consistency with the admin SPA’s manifest field types.

The bug described in #1641 is fixed, the refactor consolidates the manifest-field mapping in the right place, and the added tests cover the new manual-collection path plus conflict/fallback/unknown-type edge cases. No new blocking issues were introduced.

@emdashbot emdashbot Bot removed the bot:review Trigger an emdashbot code review on this PR label Jul 21, 2026
@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-rereview Author pushed changes since the last review labels Jul 21, 2026
…lections-admin-manifest

# Conflicts:
#	packages/core/src/emdash-runtime.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Collections created via Admin UI ("manual" source) return Page Not Found in admin — dashboard shows collection but content route is inaccessible

2 participants