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

46 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`.