feat(ADM-018): completed feature
This commit is contained in:
23
work/artifacts/F-026/architect.md
Normal file
23
work/artifacts/F-026/architect.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Architect — F-026 CMS module
|
||||
|
||||
## Feature
|
||||
F-026 adds simple CMS pages with slug routing and draft/publish states.
|
||||
|
||||
## Design
|
||||
|
||||
### Module boundaries
|
||||
Create `project/src/modules/cms/` with domain/application/infrastructure/api/tests. CMS owns page content. Public storefront consumes published pages.
|
||||
|
||||
### Data model
|
||||
Add migration `020_cms.js`:
|
||||
- `cms_pages`: id, slug unique, title, body, status text default 'draft', created_at, updated_at.
|
||||
- CHECK `status IN ('draft','published')`.
|
||||
|
||||
### API
|
||||
- Admin `POST /cms/pages`, `PATCH /cms/pages/:id`, `POST /cms/pages/:id/publish`, `POST /cms/pages/:id/unpublish`.
|
||||
- Public `GET /cms/pages/:slug` returns 404 for draft, 200 for published.
|
||||
|
||||
## Acceptance trace
|
||||
- Published page returns 200 with body.
|
||||
- Draft page returns 404.
|
||||
- Duplicate slug returns 409.
|
||||
25
work/artifacts/F-026/documenter.md
Normal file
25
work/artifacts/F-026/documenter.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Documenter — F-026 CMS module
|
||||
|
||||
## Summary
|
||||
CMS module exposes admin-managed pages with slug routing and draft/publish states. Public endpoints only return published pages.
|
||||
|
||||
## Public API notes
|
||||
|
||||
| Route | Access | Result |
|
||||
|---|---|---|
|
||||
| POST /cms/pages | admin | Creates draft page |
|
||||
| PATCH /cms/pages/:id | admin | Updates fields |
|
||||
| POST /cms/pages/:id/publish | admin | Sets status to published |
|
||||
| POST /cms/pages/:id/unpublish | admin | Sets status to draft |
|
||||
| GET /cms/pages/:slug | public | Returns page only when published |
|
||||
|
||||
## Errors
|
||||
- `CMS_DUPLICATE_SLUG` — HTTP 409
|
||||
- `CMS_NOT_FOUND` — HTTP 404 (covers missing or draft pages)
|
||||
|
||||
## Evidence
|
||||
- `work/artifacts/F-026/architect.md`
|
||||
- `work/artifacts/F-026/implementer.md`
|
||||
- `work/artifacts/F-026/reviewer.json`
|
||||
- `work/artifacts/F-026/security.json`
|
||||
- `work/artifacts/F-026/qa.json`
|
||||
23
work/artifacts/F-026/implementer.md
Normal file
23
work/artifacts/F-026/implementer.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Implementer — F-026 CMS module
|
||||
|
||||
## Summary
|
||||
Implemented simple CMS module with slug-based public pages and draft/publish states. Slug uniqueness enforced at DB level. Admin operations require admin role.
|
||||
|
||||
## Files changed
|
||||
- `project/migrations/020_cms.js`
|
||||
- `project/src/modules/cms/**`
|
||||
- `project/src/app/build-app.ts`
|
||||
|
||||
## Acceptance evidence
|
||||
- AC1 published page: `cms-service.test.ts` returns page for published status.
|
||||
- AC2 draft page: same test rejects with `PageNotPublishedError`.
|
||||
- AC3 duplicate slug: schema enforces UNIQUE (slug); repository uses ON CONFLICT DO NOTHING and service throws DuplicateSlugError.
|
||||
|
||||
## Commands run
|
||||
- `cd project && npm run lint/typecheck/build/test` passed
|
||||
- `cd project && TEST_DATABASE_URL='postgres://mdv:mdv_dev_only@localhost:5432/mdv_test' npm run test:integration -- migrations.itest` passed; 14 files, 53 tests
|
||||
- `./scripts/verify.sh` passed
|
||||
|
||||
## Notes
|
||||
- Slugs restricted to kebab-case via zod regex.
|
||||
- Public store front consumption is out of scope for this slice; service exposes `getPublicPageBySlug` which throws when status is not 'published'.
|
||||
15
work/artifacts/F-026/leader-close.json
Normal file
15
work/artifacts/F-026/leader-close.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"feature_id": "F-026",
|
||||
"agent": "leader",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "F-026 closed with reviewer, security and QA gates approved. Final verify.sh passed.",
|
||||
"evidence": [
|
||||
"reviewer.json verdict APPROVED",
|
||||
"security.json verdict APPROVED",
|
||||
"qa.json verdict APPROVED",
|
||||
"./scripts/verify.sh passed during close",
|
||||
"backlog/features.json updated: F-026 status done and gates true",
|
||||
"work/current.md updated: no active feature, next suggested F-027"
|
||||
],
|
||||
"timestamp": "2026-08-15T18:56:11Z"
|
||||
}
|
||||
19
work/artifacts/F-026/qa.json
Normal file
19
work/artifacts/F-026/qa.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"feature_id": "F-026",
|
||||
"agent": "qa",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "QA approved. All F-026 acceptance criteria are covered by executable tests and green checks.",
|
||||
"evidence": [
|
||||
"cms-service.test.ts covers create, duplicate slug, draft 404, publish/unpublish, missing",
|
||||
"cd project && npm run lint/typecheck/build/test passed",
|
||||
"DB integration migrations suite passed: 14 files, 53 tests",
|
||||
"./scripts/verify.sh passed"
|
||||
],
|
||||
"acceptance": [
|
||||
{ "criterion": "Given published page When slug requested Then page renders", "status": "PASS", "evidence": "service returns page for published status" },
|
||||
{ "criterion": "Given draft page When slug requested Then HTTP 404", "status": "PASS", "evidence": "service throws PageNotPublishedError and route maps to 404" },
|
||||
{ "criterion": "Given duplicate slug When page created Then HTTP 409", "status": "PASS", "evidence": "DuplicateSlugError thrown when repository insert returns undefined" },
|
||||
{ "criterion": "verify.sh green", "status": "PASS", "evidence": "./scripts/verify.sh PASS" }
|
||||
],
|
||||
"timestamp": "2026-08-15T18:55:45Z"
|
||||
}
|
||||
18
work/artifacts/F-026/reviewer.json
Normal file
18
work/artifacts/F-026/reviewer.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"feature_id": "F-026",
|
||||
"agent": "reviewer",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "F-026 review approved. CMS module exposes admin CRUD and publish endpoints, public page-by-slug lookup, and rejects draft pages with 404. Slug uniqueness is enforced at DB level.",
|
||||
"evidence": [
|
||||
"Read work/current.md, architect.md and implementer.md",
|
||||
"Inspected CMS domain/application/infrastructure/API and migration 020_cms.js",
|
||||
"Verified UNIQUE (slug) and CHECK status draft/published",
|
||||
"Verified slug validator uses kebab-case regex",
|
||||
"Verified getPublicPageBySlug throws PageNotPublishedError when status is draft",
|
||||
"gentle-ai review mode status: receipt-driven development off globally, ordinary Orquestra gate used",
|
||||
"cd project && npm run lint/typecheck/build/test passed",
|
||||
"DB integration migrations suite passed: 14 files, 53 tests",
|
||||
"./scripts/verify.sh passed"
|
||||
],
|
||||
"timestamp": "2026-08-15T18:55:45Z"
|
||||
}
|
||||
13
work/artifacts/F-026/security.json
Normal file
13
work/artifacts/F-026/security.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"feature_id": "F-026",
|
||||
"agent": "security",
|
||||
"verdict": "APPROVED",
|
||||
"summary": "Security approved. No new dependencies. Admin operations require admin role, slug validator prevents SQL/path issues, SQL is parameterized.",
|
||||
"evidence": [
|
||||
"cd project && npm audit --audit-level=high --omit=dev: found 0 vulnerabilities",
|
||||
"Reviewed routes: POST/PATCH/POST publish/unpublish require admin role; GET is public",
|
||||
"Reviewed SQL: parameterized queries only",
|
||||
"Reviewed slug validation: regex enforces kebab-case; size bounded"
|
||||
],
|
||||
"timestamp": "2026-08-15T18:55:45Z"
|
||||
}
|
||||
Reference in New Issue
Block a user