Files
vmall/docs/domains/aftersales-reviews.md
T

2.0 KiB
Raw Blame History

Domain: After-sales and Reviews (post-order lifecycle)

Aftersales (modules/aftersale/)

Per-order-item refund applications; the order's refund_total_minor is the authoritative sum of completed refunds.

refund_only:   pending ──approve──► approved ──refund──► refunded
return_refund: pending ──approve──► approved ──buyer tracking──► buyer_shipping
                    ──confirm receipt──► merchant_confirmed ──refund──► refunded

pending ──reject──► rejected ──reopen (once)──► pending
any non-terminal ──buyer cancel──► cancelled
platform arbitration: pending ──► refunded | rejected (terminal)

Invariants:

  • One active (non-terminal) aftersale per order item — partial unique index.
  • Amount ≤ line paid − already refunded, checked at apply time.
  • Refund completion is one transaction: guarded status flip + guarded order refund_total_minor increment (≤ total_minor) + one ledger credit to the customer's available balance in the order currency (the account row is created lazily when missing). Retries hit the status guard — no double credit. The refund_completed hook point is a tracing call today; notifications attach there later.
  • Eligibility: order paid/fulfilling/shipped/completed and updated within AFTERSALE_WINDOW_DAYS (15).
  • Messages are an append-only bilateral log (buyer/merchant/platform); readers are the customer, the owning shop, and platform admins.

Reviews (modules/review/)

One review per completed order line (unique index on order_item_id), rating 1–5 + bilingual content (at least one locale; display falls back) + image URLs; immutable after creation. Merchant replies once (guarded WHERE reply IS NULL). Platform moderation: visible → hidden (guarded) or delete. Public listing and the SQL rating summary (count/avg/star distribution) only see visible rows. GET /me/reviewable lists the customer's completed lines without reviews.

Key files

See docs/code_index/post-order.md.