Remaining docs updated to match code (the docs that the first pass had not covered):
- Flows: Chat, Referral, Rating, Registration, Google OAuth, Negotiation, Payout,
Trezor Safekeeping — corrected endpoints, socket events, status enums, auth gaps
- API Reference: User API, Trezor API — admin route prefix/verb/status corrections,
added undocumented endpoints (ton-proof challenge, profile email verify,
GET /trezor/account, POST /trezor/verify-operation)
- Data Models: Chat, Notification, Payment, PointTransaction, User — corrected
enums (PaymentProvider, escrowState, PointTransaction.type, User.status),
90-day notification TTL, soft-delete semantics, wallet fields
Trezor "zero frontend" finding (audit C31/C32) corrected as STALE:
- Verified current code HAS a full frontend Trezor implementation (admin/trezor
page, TrezorSettingsView, trezorConnector via @trezor/connect-web,
TrezorSignDialog, actions/trezor.ts building the {message,signature} object)
- Fixed Trezor Safekeeping Flow doc (removed false "no frontend" warnings)
- Reclassified ISSUE-012 as invalid/superseded with explanation
Issue set reconciled to a single canonical numbering (ISSUE-001..054):
- Adopted the comprehensive 51-issue set (long-slug, fully indexed)
- Removed 35 superseded short-slug duplicates from the first pass
- Removed a duplicate ISSUE-046 file
- Added 3 issues the 51-set lacked: ISSUE-052 (completed-not-counted-in-stats),
ISSUE-053 (axios 401-only interceptor), ISSUE-054 (rate limiter counts all attempts)
- Regenerated Issues Index: 53 open (14 critical, 39 major) + 1 invalid
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.4 KiB
6.4 KiB
title, tags, related_models, related_apis
| title | tags | related_models | related_apis | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Rating Flow |
|
|
|
Rating Flow
Last updated: 2026-05-29 — aligned with code (see Doc vs Code Audit Report)
[!caution] Not deeply audited This flow was not deeply covered by the 2026-05-29 audit; endpoints should be verified against
reviewRoutes/marketplaceControllerbefore relying on them for UAT.
After an order is completed, the buyer rates the seller and (optionally) leaves a review; the seller can rate the buyer in the reciprocal flow. Reviews are scoped by subjectType (seller | template) and constrained by the seller's ShopSettings.
Actors
- Buyer (typical reviewer).
- Seller (subject; can also be a reviewer in the reciprocal direction).
- System — enforces uniqueness and moderation rules.
- Backend —
backend/src/services/marketplace/reviewRoutes.ts. - MongoDB —
reviewscollection (backend/src/models/Review.ts).
Preconditions
- The associated
PurchaseRequestiscompleted(orfinalized). - The reviewer is the buyer of that request (for
isVerifiedBuyerto betrue). - The subject's
ShopSettings.allowSellerReviews/allowTemplateReviewsis notfalse(reviewRoutes.ts:15-31).
Step-by-step narrative
- From the request detail or seller profile, the buyer clicks "Leave review". The form captures
rating(1–5) andcomment(≤ 1000 chars). - Frontend POSTs
POST /api/marketplace/reviewswith{ subjectType: 'seller' | 'template', subjectId, rating, comment, purchaseRequestId? }. - Backend route handler:
- Validates payload.
- Calls
isReviewsAllowed(subjectType, subjectId)— checks the seller'sShopSettings(for sellers, look up the seller directly; for templates, look up the template's owning seller). - Sets
isVerifiedBuyer = trueif the user owns acompletedpurchase request from that seller. - Defaults
status: 'published'(no moderation queue today).
- Inserts a
Reviewdocument. Unique index{ subjectType, subjectId, reviewerId }prevents a user from reviewing the same subject twice (Review.ts:34). - Aggregated stats are recomputed on read via
computeStats(reviewRoutes.ts:33-62) — count, average, per-star histogram. No denormalised counter onUsertoday; everything is computed at read-time.
Visibility
- Public — anyone hitting
GET /api/marketplace/reviews/seller/:sellerIdseesstatus: 'published'reviews paginated by 10. - If
ShopSettings.allowSellerReviews === false(orallowTemplateReviews === false), reads return403 Reviews are disabled by seller. - The seller can flag a review for moderation (planned — current statuses include
pendingandrejected, but no UI to flip them today; admin can update via direct DB).
Sequence diagram
sequenceDiagram
autonumber
actor B as Buyer
participant FE as Frontend
participant BE as Backend
participant DB as MongoDB
B->>FE: Open seller profile / request detail
B->>FE: Click "Leave review", choose stars + comment
FE->>BE: POST /api/marketplace/reviews
BE->>DB: ShopSettings.findOne({sellerId}) → allowSellerReviews?
alt allowed
BE->>DB: PurchaseRequest.exists({buyer, seller, status:"completed"})?
BE->>DB: Review.create({status:"published", isVerifiedBuyer})
BE-->>FE: 201 { review }
else disabled
BE-->>FE: 403 Reviews disabled
end
Note over FE: Public visitor:
FE->>BE: GET /api/marketplace/reviews/seller/{id}
BE->>DB: Review.find / computeStats aggregate
BE-->>FE: { items, pagination, stats:{count, avg, histogram} }
API calls
| Method | Endpoint | Purpose |
|---|---|---|
POST |
/api/marketplace/reviews |
Submit review |
GET |
/api/marketplace/reviews/:subjectType/:subjectId |
List reviews + stats |
PATCH |
/api/marketplace/reviews/:id |
Edit own review (within edit window) |
DELETE |
/api/marketplace/reviews/:id |
Delete own review |
Database writes
reviews— insert on submission; one document per(subjectType, subjectId, reviewerId).shopsettings— read-only here; the seller controlsallowSellerReviews/allowTemplateReviewsin their shop settings.
Socket events emitted
- None today. A
new-reviewevent broadcast touser-{sellerId}would be a useful enhancement so sellers see reviews appear live.
Side effects
- Recompute aggregate on every list call — fine for small volumes; consider caching
statsper subject when the review count grows. - Order rating field also stamps
metadata.ratingon the purchase request when the marketplace endpoint accepts ratings inline (seeroutes.tsreferences inbackend/src/services/marketplace/routes.ts).
Error / edge cases
- Duplicate review → MongoDB
E11000from the unique index; surface as409 Already reviewed. - Subject disabled reviews →
403. - Reviewer not a verified buyer → review is still allowed but
isVerifiedBuyer = false. Display this in the UI. - Rating out of 1–5 → Mongoose schema validator rejects.
- Comment > 1000 chars → schema-level rejection.
- Seller toggles
allowSellerReviews=falseafter reviews exist → existing reviews remain stored but become unreadable via the public GET (reviewRoutes.ts:81-83). - Spam / abuse → no automatic moderation; admin can flip
statustorejectedto hide.
[!tip] Verified-buyer badge The
isVerifiedBuyerflag is the most credible signal for prospective buyers. Always render a "Verified buyer" pill next to reviews where this istrue.
Linked flows
- Purchase Request Flow — precursor that makes the buyer "verified".
- Seller Offer Flow — display average rating on offer cards.
- Dispute Flow — a resolved dispute could trigger a review prompt; today they are independent.
Source files
- Backend:
backend/src/services/marketplace/reviewRoutes.ts - Backend:
backend/src/models/Review.ts - Backend:
backend/src/services/marketplace/shopSettingsController.ts(allow flags) - Backend:
backend/src/services/marketplace/routes.ts(inline rating on order completion) - Frontend: review components under
frontend/src/sections/account/and seller profile views