/speckit-plan output for 004-product-knowledge: technical context and constitution gate check (all PASS), Phase 0 research (6 decisions: new-row-per-version instead of in-place overwrite to satisfy history retention, conditional-update-then-insert concurrency reusing 003-ticketing's optimistic-locking pattern, structured (non-semantic) filtered retrieval per doc 11 gap B1, known-issue lookup by error code, creating the ai-support module group for the first time with only its knowledge submodule populated, and admin auth consistent with prior features), Phase 1 data model (KnowledgeEntry/ErrorCode/ KnownIssue/Runbook, refining doc 06's conceptual schema with an explicit version-history mechanism), the admin CRUD + retrieval contract, and a 6-scenario quickstart. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2.9 KiB
2.9 KiB
Contract: Knowledge Admin CRUD & Retrieval
All admin routes gated by fastify.authenticate (research.md — known limitation inherited from
002/003).
Knowledge Entries
POST /admin/products/:externalProductId/knowledge— creates a new entry,version: 1,isCurrentVersion: true,status: draft.PATCH /admin/knowledge/:code/publish— body{ effectiveDate? }— setsstatus: published.PATCH /admin/knowledge/:code/unpublish— setsstatus: unpublished.PATCH /admin/knowledge/:code/validate— body{ validationStatus }— sets validation status on the current version.PUT /admin/knowledge/:code— body is the new content +expectedVersion. Creates a new version per research.md's conditional-update-then-insert;409 CONFLICTon a staleexpectedVersion.GET /admin/knowledge/:code/versions— lists every version of this entry, newest first, including non-current ones (admin-only history view).
Runbooks
Same shape as Knowledge Entries, keyed by (key, productId) instead of code:
POST /admin/products/:externalProductId/runbooksPUT /admin/products/:externalProductId/runbooks/:key(versioned edit, sameexpectedVersion/409rule)PATCH /admin/products/:externalProductId/runbooks/:key/deactivateGET /admin/products/:externalProductId/runbooks/:key— current version only (execution-ready lookup, not the admin history view)
Error Codes & Known Issues
POST /admin/products/:externalProductId/error-codesPOST /admin/products/:externalProductId/known-issues— body includeserrorCodeId(optional)GET /admin/products/:externalProductId/known-issues/by-error-code/:code— FR-007's direct lookup
Retrieval
GET /knowledge/retrieve?productId=&feature=&category=— the filtered, ranked query (research.md). Returns onlypublished, currently-effective, current-version entries scoped to the given product, validated entries ranked first. Empty array on no matches, never an error.
Guarantees (callable contract)
- A draft entry is never returned by
/knowledge/retrieve, regardless of any other filter (SC-001). - Retrieval never crosses product scope — a query for product A never returns product B's
entries, even if B has a matching
code/feature(SC-002). - Publishing takes effect within the same request cycle — no cache/propagation delay before a newly-published entry appears in retrieval (SC-003).
- Editing never destroys a prior version —
GET .../versionsafter an edit still includes the pre-edit content (SC-004). - A stale-version edit is rejected with
409, never silently applied on top of a change it didn't observe — same guarantee class as 003-ticketing's ticket-status concurrency. - A validated entry outranks an equally-matching unvalidated one in every retrieval result that includes both (SC-005).