Skip to content

feat(web): consolidate canonical URN model — component entity + componentUrn - #10

Merged
odenirdev merged 1 commit into
mainfrom
feat/canonical-consolidation
Jul 5, 2026
Merged

feat(web): consolidate canonical URN model — component entity + componentUrn#10
odenirdev merged 1 commit into
mainfrom
feat/canonical-consolidation

Conversation

@odenirdev

Copy link
Copy Markdown
Contributor

What

Closes the BASE / CANONICAL MODEL DATA PATTERN MVP task — consolidates the
web-side canonical identity (URN) model. The closed Entity union now covers all
four engine entities, and the model exposes both stored and type-level
identity factories. Interface + factory, no classes — a urn stays a plain string
across the RSC boundary.

DONE criteria

CriterionStatus
Entity = page | site-setting | plugin | componenturn.ts
buildUrn / componentUrn with testsurn.test.ts (6 tests)
No call site widened to plain stringblockKey now returns Urn<string>
Wire/CMS contract untouched (urn never sent/stored by press-cms)✅ zero packages/cms change

Changes

  • Entity gains component (additive — the ThemeName "additive, not breaking"
    precedent) → urn:component:{uid}.
  • New pure componentUrn(uid) factory (exported from the package root) + tests.
  • blockKey return type tightened stringUrn<string>: the COMPUTED
    per-instance key keeps its urn brand while staying a valid React key. This
    closes the one remaining "widened to string" call site and aligns code with the
    docs.
  • BlockRenderer's unknown-component dev warning now cites the canonical
    urn:component:… form (+ regression test).
  • Removed the now-redundant docs/superpowers/plans/2026-07-04-canonical-urn.md
    CLAUDE.md ("Canonical identity (URNs)") is the living reference.

Three identity classes (each wired to a real consumer)

  • STORED (Canonical<E>): Page (urn:page:{documentId}),
    ResolvedPressConfig (urn:site-setting:default), PressPlugin
    (urn:plugin:{id}).
  • TYPE-level (componentUrn): BlockRenderer unknown-component warning.
  • COMPUTED (blockKey): dynamic-zone React keys — urn:{__component}:{id},
    never stored.

Not in this PR (deliberately separate)

The working branch also carries two unrelated frontiers kept out of this commit to
keep concerns separate: the engine plugin content-type and the cookie-consent
findings. Those ship on their own.

Verification

  • pnpm --filter @ogs-tech/press-web test213/213
  • pnpm --filter @ogs-tech/press-web typecheck → clean ✅

🤖 Generated with Claude Code

…ponentUrn
Close the BASE/CANONICAL identity task. The closed `Entity` union now covers
all four engine entities and the model exposes both stored and type-level
identity factories.
- `Entity` gains `component` (additive, ThemeName precedent) → `urn:component:{uid}`
- add pure `componentUrn(uid)` factory + tests (`buildUrn` already covered)
- `blockKey` now returns `Urn<string>` (was plain `string`): the COMPUTED
identity keeps its brand while staying a valid React key — no call site
widened to plain string
- BlockRenderer's unknown-component dev warning cites the canonical
`urn:component:…` form (+ test)
- drop the now-redundant canonical-urn plan doc (CLAUDE.md is the living ref)
- wire/CMS contract untouched: a urn is never sent or stored by press-cms
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@odenirdev
odenirdev merged commit 260d8ea into mainJul 5, 2026
1 check passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@odenirdev