fix(core): resolve entry slug to canonical id when reading content terms#1163
fix(core): resolve entry slug to canonical id when reading content terms#1163officialasishkumar wants to merge 2 commits into
Conversation
GET /_emdash/api/content/{collection}/{id}/terms/{taxonomy} passed the raw
URL `id` straight to the taxonomy repository, but content_taxonomies rows
are keyed by the canonical content ULID. The POST handler already resolves a
slug to that ULID via handleContentGet before writing, so a slug-addressed
read matched no rows and returned an empty list even when terms were
assigned — only requests using the ULID returned the assignments.
Resolve the slug the same way in the GET handler before querying, falling
back to the raw id when the entry can't be resolved so the existing
'no such entry -> empty list' behaviour is preserved.
Closes emdash-cms#1045
🦋 Changeset detectedLatest commit: a1cde57 The changes in this PR will be included in the next version bump. This PR includes changesets to release 14 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 |
|
All contributors have signed the CLA ✍️ ✅ |
There was a problem hiding this comment.
Pull request overview
Fixes a read/write asymmetry in the content-terms API so that GET /_emdash/api/content/{collection}/{id}/terms/{taxonomy} resolves a slug {id} to the entry’s canonical ULID before querying term assignments (matching the existing POST behavior), and adds a regression test + changeset.
Changes:
- Update the terms GET route to resolve
{id}viahandleContentGet()and query by the canonical entry ID. - Add an integration test covering GET-by-slug vs GET-by-ULID behavior.
- Add a patch changeset for the
emdashpackage.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
packages/core/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts |
Resolve slug → canonical ULID in GET before querying content_taxonomies. |
packages/core/tests/integration/astro/content-terms-slug-resolution.test.ts |
Regression test ensuring GET returns assigned terms when addressed by slug. |
.changeset/fix-terms-get-slug-resolution.md |
Patch release note for the bugfix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // The URL `id` may be a slug. Term rows are keyed by the canonical | ||
| // content ULID — the POST handler resolves the slug and stores under | ||
| // that ULID, so the read must resolve it too. Without this, a request | ||
| // addressed by slug looks up assignments under the slug, finds none, | ||
| // and returns an empty list even though the term is assigned (#1045). | ||
| const existing = await emdash.handleContentGet(collection, id); | ||
| const canonicalId = existing.success ? (existing.data?.item.id ?? id) : id; | ||
| const terms = await repo.getTermsForEntry(collection, canonicalId, taxonomy); |
|
I have read the CLA Document and I hereby sign the CLA |
What does this PR do?
Fixes
GET /_emdash/api/content/{collection}/{id}/terms/{taxonomy}returning an empty term list when the content entry is addressed by its slug instead of its ULID.Term assignments (
content_taxonomiesrows) are keyed by the canonical content ULID. ThePOSThandler on this route already resolves the URLidsegment (which may be a slug) to that ULID viahandleContentGetbefore writing. TheGEThandler did not — it looked up assignments under the raw slug, found none, and returned{ "terms": [] }, even though the terms were assigned and a request by ULID returned them correctly.Closes #1045
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.AI-generated code disclosure
Root cause
In
packages/core/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts:idstraight through:getTermsForEntryjoinscontent_taxonomiesonentry_id, which stores the canonical ULID. A slug never matches, so a slug-addressed read returns an empty list. It is a read/write asymmetry: POST stores under the ULID, GET read under whatever was in the URL.Fix
Resolve the slug to the canonical id in the GET handler before querying, mirroring POST. When the entry can't be resolved (for example, it doesn't exist), the handler falls back to the raw
id, preserving the previous "no such entry → empty list" behaviour instead of introducing a new 404 on a read.How to test
Added
packages/core/tests/integration/astro/content-terms-slug-resolution.test.ts, which:tagterm and apostwith slugesim-pakistan,POST .../terms/tagaddressed by slug (POST already resolves it),GET .../terms/tagreturns the term both when addressed by ULID (control) and by slug (the regression).The test reproduces the bug — on
mainthe slug-addressed GET returns[]; with this change it returns the assigned term.Manual check against a running instance: