Skip to content

feat(core): content-references HTTP API (relation defs + entry edges)#1535

Open
MA2153 wants to merge 2 commits into
emdash-cms:mainfrom
MA2153:content-references-api
Open

feat(core): content-references HTTP API (relation defs + entry edges)#1535
MA2153 wants to merge 2 commits into
emdash-cms:mainfrom
MA2153:content-references-api

Conversation

@MA2153

@MA2153 MA2153 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds the HTTP API layer over the content-references repository — the third bottom-up slice after the schema (migration 043) and RelationRepository. Two surfaces:

  • Relation-definition CRUD under /_emdash/api/relations — manage relationship types (editor-readable via schema:read, admin-writable via schema:manage), treated as schema-like structural config.
  • Content-entry reference edges under /_emdash/api/content/:collection/:id/references/:relation/{children,parents} — attach/read directed references on a specific entry, ownership-aware like the taxonomy edge endpoint.

This is the trust boundary: Zod at the route, and the write-path invariants (relation-exists, collection-agreement, directed storage) the repository deliberately skipped. References are stored only in _emdash_content_references, keyed by translation_group — no ec_* column.

The final commit hardens the slice against a code review:

  • Create-path failures map precisely instead of flattening to 500 — bad translationOfNOT_FOUND, name/locale collisions → CONFLICT, missing collections → COLLECTION_NOT_FOUND.
  • Edge reads resolve entries in one batched IN query (chunked) instead of N+1 per edge.
  • Edge reads are cursor-paginated (?cursor/?limit, default 50, max 100) returning nextCursor; the backlink (parents) side is genuinely unbounded, so this matters. Bad cursors → INVALID_CURSOR.
  • Each resolved entry ref carries the locale of the variant returned, so the variant fallback is explicit rather than a silent wrong-locale substitution.
  • content:edit_own is gated before the existence lookup on POST children to close an existence-oracle.
  • Empty PATCH relation bodies are rejected with VALIDATION_ERROR.

Closes #

Type of change

Approved feature Discussion: #386

Part of the planned content-references effort tracked under the schema (#1367) and repository (#1444) slices.

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes — repo-wide typecheck has 5 pre-existing failures in packages/plugin-cli / src/plugins/* from an unbuilt @emdash-cms/plugin-types (build-order, unrelated to this PR); 0 new errors introduced by these changes.
  • pnpm lint passes — pnpm lint:json is clean for all files in this PR; the only remaining diagnostics are pre-existing in unrelated demo/template astro.config.mjs files.
  • pnpm test passes (targeted): relation/reference handler, route, and repository suites — 60 tests green.
  • pnpm format has been run
  • I have added/updated tests for my changes
  • User-visible strings in the admin UI are wrapped for translation — n/a, no admin UI in this slice; server error messages are English-only and mapped to localized strings client-side by code.
  • I have added a changeset (emdash, minor)
  • New features link to an approved Discussion: Complete the reference field: collection picker in schema editor + content picker in content editor #386

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Claude Opus 4.8 (Claude Code)

Screenshots / test output

Test Files  4 passed (4)
     Tests  60 passed (60)

@changeset-bot

changeset-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ee22100

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

This PR includes changesets to release 16 packages
Name Type
emdash Minor
@emdash-cms/cloudflare Minor
@emdash-cms/sandbox-workerd 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 Minor
@emdash-cms/auth Minor
@emdash-cms/blocks Minor
@emdash-cms/gutenberg-to-portable-text Minor
@emdash-cms/x402 Minor
create-emdash Minor
@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 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@github-actions

Copy link
Copy Markdown
Contributor

Scope check

This PR changes 1,516 lines across 13 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.

@github-actions github-actions Bot added the review/needs-review No maintainer or bot review yet label Jun 18, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 18, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

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

@emdash-cms/auth

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

@emdash-cms/auth-atproto

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

@emdash-cms/blocks

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

@emdash-cms/cloudflare

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

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

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

emdash

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

create-emdash

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

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

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

@emdash-cms/plugin-cli

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

@emdash-cms/plugin-types

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

@emdash-cms/registry-client

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

@emdash-cms/registry-lexicons

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

@emdash-cms/sandbox-workerd

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

@emdash-cms/x402

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

@emdash-cms/plugin-ai-moderation

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

@emdash-cms/plugin-atproto

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

@emdash-cms/plugin-audit-log

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

@emdash-cms/plugin-color

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

@emdash-cms/plugin-embeds

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

@emdash-cms/plugin-field-kit

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

@emdash-cms/plugin-forms

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

@emdash-cms/plugin-webhook-notifier

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

commit: ee22100

Adds relation-definition routes and handlers (list/create/get/update/delete/translations)
and content-entry reference edge routes for children and parents, with edge-read
hardening and error handling.
@MA2153 MA2153 force-pushed the content-references-api branch from 96936ca to b17ee59 Compare June 18, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant