feat(ADM-018): completed feature

This commit is contained in:
chattie
2026-08-17 22:23:10 +02:00
parent cf1c69fc8b
commit d595b4871f
871 changed files with 47411 additions and 281 deletions

View File

@@ -0,0 +1,31 @@
# Architect — F-025 Reviews module
## Feature
F-025 adds verified-purchase reviews with moderation and rating aggregates.
## Design
### Module boundaries
Create `project/src/modules/reviews/` with domain/application/infrastructure/api/tests. Reviews owns review persistence and aggregates. Catalog is the source of product truth.
### Data model
Add migration `019_reviews.js`:
- `reviews_reviews`: id, user_id, product_id, order_id uuid, order_item_id uuid, rating int 1..5, title, body, status text default 'pending', created_at, updated_at.
- CHECK `status IN ('pending','published','rejected')` and `rating BETWEEN 1 AND 5`.
- UNIQUE `(order_item_id)` to allow one review per order item.
- Index `(product_id, status)` for public listing.
### Use cases
- `submitReview(userId, input)` requires an order owned by the user whose items contain the target order item and whose state is DELIVERED. Otherwise 403.
- `moderateReview(reviewId, status)` admin-only, transitions pending -> published or rejected.
- `listPublishedForProduct(productId)` public, returns only published reviews plus aggregate `averageRating` and `count`.
### API
- `POST /reviews` authenticated, returns 201/403.
- `GET /reviews?productId=` returns published reviews and aggregate.
- `PATCH /reviews/:id/moderate` admin-only.
## Acceptance trace
- No delivered order item -> 403.
- Second review on same order item -> 409 (unique constraint).
- Pending reviews never appear on product listing.

View File

@@ -0,0 +1,25 @@
# Documenter — F-025 Reviews module
## Summary
Reviews module records verified-purchase reviews with moderation and aggregate ratings. Reviews are scoped to one order item per user and only published reviews appear on product listings.
## Public API notes
| Route | Access | Result |
|---|---|---|
| POST /reviews | authenticated | Creates review for an order item |
| PATCH /reviews/:id/moderate | admin | Transitions pending review to published or rejected |
| GET /reviews?productId= | public | Returns published reviews with aggregate |
## Errors
- `REVIEW_DUPLICATE` — HTTP 409
- `REVIEW_NOT_ELIGIBLE` — HTTP 403
- `REVIEW_NOT_FOUND` — HTTP 404
- `INVALID_REVIEW` — HTTP 422
## Evidence
- `work/artifacts/F-025/architect.md`
- `work/artifacts/F-025/implementer.md`
- `work/artifacts/F-025/reviewer.json`
- `work/artifacts/F-025/security.json`
- `work/artifacts/F-025/qa.json`

View File

@@ -0,0 +1,23 @@
# Implementer — F-025 Reviews module
## Summary
Implemented reviews module with verified-purchase guard (order item must be DELIVERED and owned by user), unique constraint per order item, moderation by admin, and aggregate per product.
## Files changed
- `project/migrations/019_reviews.js`
- `project/src/modules/reviews/**`
- `project/src/app/build-app.ts`
## Acceptance evidence
- AC1 ineligible user -> 403: `reviews-service.test.ts` rejects with `ReviewNotEligibleError` when verifier returns false.
- AC2 duplicate review -> 409: existing review or repository race returns `DuplicateReviewError`; UNIQUE constraint at DB level enforces.
- AC3 only published reviews appear: `listPublishedByProduct` filters by status='published'.
## 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
- No new runtime dependency.
- Aggregates are computed live from `reviews_reviews`; cached aggregates can be added later without changing the public contract.

View File

@@ -0,0 +1,15 @@
{
"feature_id": "F-025",
"agent": "leader",
"verdict": "APPROVED",
"summary": "F-025 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-025 status done and gates true",
"work/current.md updated: no active feature, next suggested F-026"
],
"timestamp": "2026-08-15T18:51:34Z"
}

View File

@@ -0,0 +1,20 @@
{
"feature_id": "F-025",
"agent": "qa",
"verdict": "APPROVED",
"summary": "QA approved. All F-025 acceptance criteria are covered by executable tests and green checks.",
"evidence": [
"reviews-service.test.ts covers ineligible, duplicate, invalid rating, moderate-missing, success and listing",
"boundary.test.ts verifies reviews module owns no other module tables",
"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 user without delivered order item When review submitted Then HTTP 403", "status": "PASS", "evidence": "reviews-service.test.ts rejects with ReviewNotEligibleError when verifier returns false; route maps to 403" },
{ "criterion": "Given second review for same order item When submitted Then HTTP 409", "status": "PASS", "evidence": "DuplicateReviewError when existing review found; UNIQUE constraint at DB level also enforces" },
{ "criterion": "Only published reviews appear on product page", "status": "PASS", "evidence": "listPublishedByProduct filters status='published'" },
{ "criterion": "verify.sh green", "status": "PASS", "evidence": "./scripts/verify.sh PASS" }
],
"timestamp": "2026-08-15T18:51:12Z"
}

View File

@@ -0,0 +1,19 @@
{
"feature_id": "F-025",
"agent": "reviewer",
"verdict": "APPROVED",
"summary": "F-025 review approved. Reviews module enforces verified-purchase guard, single review per order item via unique constraint, moderation through admin-only endpoint, and aggregate per product.",
"evidence": [
"Read work/current.md, architect.md and implementer.md",
"Inspected reviews domain/application/infrastructure/API and migration 019_reviews.js",
"Verified UNIQUE (order_item_id) constraint and CHECK rating 1..5",
"Verified PgOrderItemVerifier joins orders_orders by user and filters by state=DELIVERED",
"Verified listPublishedByProduct filters status='published'",
"Verified service unit tests cover eligibility, duplicate, invalid rating and moderate-missing",
"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:51:12Z"
}

View File

@@ -0,0 +1,13 @@
{
"feature_id": "F-025",
"agent": "security",
"verdict": "APPROVED",
"summary": "Security approved. No new dependencies. Reviews submission requires authenticated user, ownership of the order item, and delivered state; moderation requires admin role. SQL is parameterized; schema constraints enforce rating range and unique order item.",
"evidence": [
"cd project && npm audit --audit-level=high --omit=dev: found 0 vulnerabilities",
"Reviewed POST /reviews: authenticated; rating 1..5; verifier joins order_items and orders_orders",
"Reviewed PATCH /reviews/:id/moderate: admin-only",
"Reviewed SQL: parameterized queries only"
],
"timestamp": "2026-08-15T18:51:12Z"
}