37 lines
4.0 KiB
Markdown
37 lines
4.0 KiB
Markdown
# EDU-030 — Activate native Trade after-sale
|
||
|
||
- **Status:** done — tenant-owned after-sale persistence, native state machine, Pay Refund bridge, RBAC, corrected Vben UI, and PostgreSQL evidence delivered
|
||
- **Type:** native module takeover / refund lifecycle / tenant isolation
|
||
- **Phase:** 5 / commercialization foundation
|
||
- **Blockers:** EDU-022, EDU-025, EDU-027, EDU-029, PostgreSQL Flyway
|
||
|
||
## Problem
|
||
|
||
The source backend stores order-level UUID rows in `public.commerce_refund_requests` and append-only `public.commerce_refund_events`, with statuses `requested`, `approved`, `processing`, `succeeded`, `failed`, `rejected`, and `cancelled`. RuoYi already owns a richer line-item after-sale state machine: Member application, administrator agree/disagree, return logistics, receipt/refusal, Pay Refund creation/callback, order-item state updates, immutable operation logs, exact RBAC, and an existing Vben list/detail page. Reimplementing that lifecycle in Education would create a second refund ledger and bypass native Trade/Pay coordination.
|
||
|
||
## Delivered contract
|
||
|
||
- `AfterSaleDO` and `AfterSaleLogDO` extend `TenantBaseDO`; existing app/admin controllers, `AfterSaleServiceImpl`, `AfterSaleLogServiceImpl`, order updates, and `PayRefundApi` remain authoritative.
|
||
- V4420 creates `trade_after_sale` and `trade_after_sale_log` with explicit sequences and `(tenant_id,id)` ownership. Order, order item, SPU, SKU, Pay Refund, delivery express, log, and order-item back-reference constraints are tenant-qualified.
|
||
- Database checks enforce native status/type/way values, non-negative amounts, required audit/return/refund facts, JSON arrays, valid log actor/operation/status values, unique tenant numbers, and at most one active after-sale per order item.
|
||
- Menu IDs 7010–7015 reuse `mall/trade/afterSale/index` with exactly `trade:after-sale:query`, `agree`, `disagree`, `receive`, and `refund` permissions.
|
||
- The Vben page sends the backend's `auditReason` field, requires `refuseMemo` in a locked/validated refusal modal, displays the actual application `createTime`, and guards every action with its exact permission. Backend request validation now rejects blank refusal notes and the detail response exposes `createTime`.
|
||
|
||
## Legacy data decision
|
||
|
||
V4420 starts the native after-sale ledger empty. A source request identifies an aggregate UUID order but does not identify a verified native Member, `trade_order_item`, SPU/SKU allocation, return quantity, delivery company, or Pay Refund row. Its status history also does not prove the native line-item and return-logistics transitions. Automatic import would invent ownership and lifecycle facts, so explicit legacy refund import is deferred until legacy Product, Order, Order Item, and Member mappings are reviewed.
|
||
|
||
## Verification
|
||
|
||
- The after-sale tenant contract proves both native records participate in framework tenant isolation.
|
||
- The focused V4420 Flyway scenario proves cross-tenant identifier reuse, tenant-qualified ownership/back-references, two explicit sequences, audit/log rejection, exact route/permissions, and fail-closed adoption of a pre-existing global table.
|
||
- A Spring/MyBatis PostgreSQL integration test imports the real services and production tenant SQL interceptor, creates same-ID Product/Order/Order Item fixtures in tenants 10 and 20, and proves isolated create, page, detail, and log reads plus order-item update calls.
|
||
- The full PostgreSQL Flyway suite passes 49 scenarios through V4420. The server reactor compiles, and the corrected Vben page passes typecheck plus scoped oxlint/oxfmt checks.
|
||
|
||
## Explicitly open
|
||
|
||
- Trade brokerage and special-order Promotion families remain separate native activation slices.
|
||
- Legacy Product/coupon/order/refund import requires explicit UUID-to-native mappings and reconciliation artifacts; V4420 does not reinterpret source refunds.
|
||
- Configured target Pay App/Channel data and a deployed order/payment/refund smoke are still required for end-to-end production evidence.
|
||
- Purchase-driven Education entitlement fulfillment and refund-driven entitlement revocation remain separate orchestration work.
|