Build a CMS-backed knowledge site for article 447. Revision 8 is public; revision 9 is an editor draft. Public routes, cards, and search must admit only approved revision 8. Editor 47 may preview revision 9 through a private response, while editor 81 may not. Media ID 83 has versioned article and card variants; draft media ID 91 is inaccessible to public readers. Publishing revision 9 creates one durable publication identity that each route, card, search document, and feed projection can reconcile. The work is complete only when a repeated or lost event cannot leave an older version as the final state.
Project: CMS Publication Reconciliation
Build contract
- Construct a public response from explicit approved fields and fail duplicate canonical routes.
- Keep preview authorization, revision fetch, and no-store behavior outside public cache keys.
- Bind article revisions to exact media versions and validate variant dimensions and alternatives.
- Record publication versions, repair missed notifications, and reject stale projection updates.
- Reconcile unpublish, path rename, and rollback across routes and discovery surfaces.
Implementation checkpoint
function shouldApply(currentVersion, incomingVersion, appliedVersion) {
return incomingVersion === currentVersion && incomingVersion > appliedVersion;
}
console.log(shouldApply(9, 8, 7));
console.log(shouldApply(9, 9, 7));Cost and boundaries
A route map over N public records takes O(N) expected build time and memory. A published route lookup is expected O(1) after materialization, while a live CMS call adds network time and a failure mode. Media variants cost storage and encoding work proportional to their actual bytes; a reference ledger is needed before retiring shared assets. One publication update fans out to D dependent surfaces. A targeted dependency index bounds that work by D but must itself be kept current. A preview may spend an extra permission and revision read because its low-volume editor path should never borrow a shared public cache. Define lag budgets for card and search updates rather than assuming all surfaces change atomically.
Failure drill
Save revision 9 without publishing and probe public route, cards, search, feeds, and cache. Try preview as both editors and anonymously. Make a proxy ignore query strings and verify the draft cannot poison the public key. Replace shared media 83 while one published article still references its older version. Publish 9, deliver event 8 after 9, duplicate 9, and lose the webhook for revision 10; a reconciliation scan must recover. Unpublish, rename the canonical path, and republish earlier approved text as a new rollback version. Inspect stale duration and repair state for each projection. A CMS timeout must not become a false 404.
Acceptance checks
- Anonymous readers never receive a draft or private media object.
- Preview permission and cache isolation hold after access is revoked.
- Older events and duplicate deliveries cannot lower a projection's applied version.
- A missed notification can be repaired from current published state.
Common Mistakes
- Testing draft privacy only in the article route, not in cards and search.
- Using noindex as the only preview control.
- Retiring a media object while another revision still references it.
- Treating one webhook as a complete publication transaction.
Related lessons
CMS Content, Publication, and Preview Boundaries; CMS Public Projections and Route Identity; CMS Draft Preview Authorization and Cache Isolation; CMS Media Variants, Alt Text, and Asset Ownership; CMS Publish Events, Cache, Search, and Rollback.
