feat(ADM-018): completed feature
This commit is contained in:
31
work/artifacts/F-025/architect.md
Normal file
31
work/artifacts/F-025/architect.md
Normal 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.
|
||||
25
work/artifacts/F-025/documenter.md
Normal file
25
work/artifacts/F-025/documenter.md
Normal 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`
|
||||
23
work/artifacts/F-025/implementer.md
Normal file
23
work/artifacts/F-025/implementer.md
Normal 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.
|
||||
15
work/artifacts/F-025/leader-close.json
Normal file
15
work/artifacts/F-025/leader-close.json
Normal 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"
|
||||
}
|
||||
20
work/artifacts/F-025/qa.json
Normal file
20
work/artifacts/F-025/qa.json
Normal 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"
|
||||
}
|
||||
19
work/artifacts/F-025/reviewer.json
Normal file
19
work/artifacts/F-025/reviewer.json
Normal 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"
|
||||
}
|
||||
13
work/artifacts/F-025/security.json
Normal file
13
work/artifacts/F-025/security.json
Normal 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"
|
||||
}
|
||||
Reference in New Issue
Block a user