58 lines
2.9 KiB
Markdown
58 lines
2.9 KiB
Markdown
# 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? }` — sets `status: published`.
|
||
|
|
- `PATCH /admin/knowledge/:code/unpublish` — sets `status: 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 CONFLICT` on a stale
|
||
|
|
`expectedVersion`.
|
||
|
|
- `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/runbooks`
|
||
|
|
- `PUT /admin/products/:externalProductId/runbooks/:key` (versioned edit, same
|
||
|
|
`expectedVersion`/`409` rule)
|
||
|
|
- `PATCH /admin/products/:externalProductId/runbooks/:key/deactivate`
|
||
|
|
- `GET /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-codes`
|
||
|
|
- `POST /admin/products/:externalProductId/known-issues` — body includes `errorCodeId` (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 only `published`, 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)
|
||
|
|
|
||
|
|
1. **A draft entry is never returned by `/knowledge/retrieve`**, regardless of any other filter
|
||
|
|
(SC-001).
|
||
|
|
2. **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).
|
||
|
|
3. **Publishing takes effect within the same request cycle** — no cache/propagation delay before
|
||
|
|
a newly-published entry appears in retrieval (SC-003).
|
||
|
|
4. **Editing never destroys a prior version** — `GET .../versions` after an edit still includes
|
||
|
|
the pre-edit content (SC-004).
|
||
|
|
5. **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.
|
||
|
|
6. **A validated entry outranks an equally-matching unvalidated one** in every retrieval result
|
||
|
|
that includes both (SC-005).
|