Files
nick-doc/04 - Flows/Rating Flow.md
Siavash Sameni 7a616744f4 docs: complete code-reality alignment for remaining docs + reconcile issue set
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>
2026-05-29 15:15:02 +04:00

6.4 KiB
Raw Blame History

title, tags, related_models, related_apis
title tags related_models related_apis
Rating Flow
flow
rating
review
moderation
Review
ShopSettings
PurchaseRequest
POST /api/marketplace/reviews
GET /api/marketplace/reviews/:subjectType/:subjectId

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/marketplaceController before 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.
  • Backendbackend/src/services/marketplace/reviewRoutes.ts.
  • MongoDBreviews collection (backend/src/models/Review.ts).

Preconditions

  • The associated PurchaseRequest is completed (or finalized).
  • The reviewer is the buyer of that request (for isVerifiedBuyer to be true).
  • The subject's ShopSettings.allowSellerReviews / allowTemplateReviews is not false (reviewRoutes.ts:15-31).

Step-by-step narrative

  1. From the request detail or seller profile, the buyer clicks "Leave review". The form captures rating (15) and comment (≤ 1000 chars).
  2. Frontend POSTs POST /api/marketplace/reviews with { subjectType: 'seller' | 'template', subjectId, rating, comment, purchaseRequestId? }.
  3. Backend route handler:
    • Validates payload.
    • Calls isReviewsAllowed(subjectType, subjectId) — checks the seller's ShopSettings (for sellers, look up the seller directly; for templates, look up the template's owning seller).
    • Sets isVerifiedBuyer = true if the user owns a completed purchase request from that seller.
    • Defaults status: 'published' (no moderation queue today).
  4. Inserts a Review document. Unique index { subjectType, subjectId, reviewerId } prevents a user from reviewing the same subject twice (Review.ts:34).
  5. Aggregated stats are recomputed on read via computeStats (reviewRoutes.ts:33-62) — count, average, per-star histogram. No denormalised counter on User today; everything is computed at read-time.

Visibility

  • Public — anyone hitting GET /api/marketplace/reviews/seller/:sellerId sees status: 'published' reviews paginated by 10.
  • If ShopSettings.allowSellerReviews === false (or allowTemplateReviews === false), reads return 403 Reviews are disabled by seller.
  • The seller can flag a review for moderation (planned — current statuses include pending and rejected, 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 controls allowSellerReviews / allowTemplateReviews in their shop settings.

Socket events emitted

  • None today. A new-review event broadcast to user-{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 stats per subject when the review count grows.
  • Order rating field also stamps metadata.rating on the purchase request when the marketplace endpoint accepts ratings inline (see routes.ts references in backend/src/services/marketplace/routes.ts).

Error / edge cases

  • Duplicate review → MongoDB E11000 from the unique index; surface as 409 Already reviewed.
  • Subject disabled reviews403.
  • Reviewer not a verified buyer → review is still allowed but isVerifiedBuyer = false. Display this in the UI.
  • Rating out of 15 → Mongoose schema validator rejects.
  • Comment > 1000 chars → schema-level rejection.
  • Seller toggles allowSellerReviews=false after 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 status to rejected to hide.

[!tip] Verified-buyer badge The isVerifiedBuyer flag is the most credible signal for prospective buyers. Always render a "Verified buyer" pill next to reviews where this is true.

Linked flows

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