Appearance
Chỉ mục bàn giao (Delivery Index) — Ví KM 2 (Promotion Wallet 2)
File này dùng để làm gì: cho team biết phải đọc file nào trước, file nào là canonical, và còn blocker gì sau đợt review/regenerate này. Nên đọc trước:
Danh sách file->Điểm còn mở / blocker->Gate kỹ thuật trước merge / bàn giao QA->Kế hoạch triển khai.
| Trường | Giá trị |
|---|---|
| Feature | Ví Khuyến Mãi 2 (Promotion Wallet 2) |
| Phiên bản | 1.6 |
| Ngày | 28/04/2026 |
| Độ phức tạp | L |
Đầu vào chuẩn (Canonical Inputs)
| File | Vai trò | Nếu xung đột |
|---|---|---|
| SOURCE_OF_TRUTH.md | Nguồn sự thật chuẩn + khóa giải pháp | Ưu tiên cao nhất |
| decision-brief.md | Cửa vào package, tóm tắt phạm vi/ảnh hưởng/rủi ro | Chỉ định hướng, không thay file chịu trách nhiệm |
| go-live-checklist.md | Readiness, deploy order, rollback, monitoring | File owner của release gates |
Danh sách file
| # | File | Người đọc | Ghi chú |
|---|---|---|---|
| 1 | Tóm tắt quyết định | PO, TL, Delivery, Tất cả | Đọc đầu tiên: tóm tắt 5 phút, phạm vi, rủi ro, file cần đọc tiếp |
| 2 | Gói bằng chứng | PO, TL, QA, Tất cả | Bằng chứng code/screen/config thật; đọc trước khi tin vào tài liệu dẫn xuất |
| 3 | Nguồn sự thật chuẩn | PO, TL, FE, BE, QA | Nguồn sự thật chuẩn + khóa giải pháp của bản regen |
| 4 | PRD | PO, Tech Lead, Tất cả | View business/decision/formula đã được đặt dưới canonical layer |
| 5 | Đặc tả UI | UI/UX, FE Dev | UI delta và flows; nếu khác SoT thì SoT thắng |
| 6 | Đặc tả kỹ thuật | BE Dev, FE Dev, Tech Lead | Ảnh hưởng kỹ thuật, data model, FIFO Go action, report/fund/print impact |
| 7 | Kế hoạch kiểm thử | QA | Coverage/test data/traceability; dùng cùng SoT làm nền |
| 8 | Checklist phát hành | Ops, TL, QA | Release gates, rollback, monitoring cho wallet/payment rủi ro |
| 9 | Design doc | Tất cả | Design intent ban đầu; không còn là nguồn truth cao nhất |
Ai đọc gì
| Vai trò | Đọc | Trọng tâm |
|---|---|---|
| PO/BA | Tóm tắt quyết định → PRD: A0 → Z → A5 → A10 | Duyệt requirements, formulas, kế toán |
| UI/UX | PRD: A0 + A5 FR-012. Đặc tả UI: B0-B9 + B-FR012 | Thiết kế màn mới + rà delta 8 màn cũ |
| Tech Lead | PRD: A0 → Z. Đặc tả kỹ thuật: C1-C4/C8/C11. Handoff: TG-001..TG-007 | Duyệt architecture, FIFO Go action, cross-DB snapshot, Dynamic Permission v2, gate trước merge |
| FE Dev | Đặc tả UI: B2.1-B9 + B-FR012. Đặc tả kỹ thuật: C5-C6 | Triển khai 8 màn mới + delta 8 màn cũ |
| BE Dev | Đặc tả kỹ thuật: C1-C12. PRD: A10 (4 formulas) | FIFO action, event handler, scheduler, 30+ files sửa |
| QA | PRD: A5. Kế hoạch kiểm thử: D1-D5 | 80 TCs, focus race condition + multi-payment + Dynamic Permission v2 + FR-012 + impact boundary regression |
| Ops/TL | Checklist phát hành: E1-E6 | Deploy gates, rollback, monitoring |
RACI
| Hạng mục bàn giao | PO | TL | UI/UX | FE Dev | BE Dev | QA |
|---|---|---|---|---|---|---|
| PRD | A | C | I | I | I | I |
| Đặc tả UI — màn mới (B2.1-B9) | C | I | R | C | I | I |
| Đặc tả UI — delta FR-012 (B-FR012) | C | I | R | C | I | I |
| Đặc tả kỹ thuật | I | A | I | C | R | I |
| Kế hoạch kiểm thử | C | I | I | I | I | R |
| Checklist phát hành | I | A | I | I | C | C |
| Migration + Hasura | I | A | — | — | R | I |
| FE Components | I | I | C | R | — | I |
Kế hoạch triển khai
| Mốc | Mục tiêu | Phụ trách | Phụ thuộc |
|---|---|---|---|
1. BE Phase 1a — DB migrations + wallet constants + Go action deduct_km2_payment | T+7 ngày | BE Dev | — |
| 2. BE Phase 1b — Payment flow (payment_order, order_confirm) + scheduler + event handlers | T+12 ngày | BE Dev | Sau #1 |
| 3. FE Phase 1 — Config + PrepaidCard form + Payment method + FR-012 Phase 1 (mỹ phẩm, sản phẩm, invoice, fund) | T+14 ngày | FE Dev | Sau #1 deploy |
| 4. QA Phase 1 — Test bán Gói Ví KM2 + thanh toán + multi-payment + FR-012 | T+17 ngày | QA | Sau #2 + #3 |
5. BE Phase 2 — Refund flow + refund_km2_wallet trong Yêu cầu hoàn tiền + withdraw | T+22 ngày | BE Dev | Sau Phase 1 pass |
| 6. FE Phase 2 — Tab Ví KM 2 profile + Form Hoàn ví KM2 + FR-012 Phase 2 (report DV/NV, CRM) | T+24 ngày | FE Dev | Sau #5 |
| 7. QA Phase 2 — Test refund + Hoàn ví KM2 + permission v2 + profile + report | T+27 ngày | QA | Sau #5 + #6 |
| 8. Phase 3 — Report dashboard KM2 + Dashboard PTTT update | T+37 ngày | Tất cả | Sau Phase 2 pass + PO chốt PD-001 |
| 9. Go-Live | Theo lịch release | TL + Ops + QA | E1-E6 pass trong go-live-checklist.md |
Điểm còn mở / blocker
| ID | Hạng mục | Phụ trách | Hạn chót | Trạng thái | Có block không? |
|---|---|---|---|---|---|
| PD-001 | Vị trí Report dashboard trong menu | PO | Trước Phase 3 | Mở | Không block Phase 1/2 |
| TL-001 | Review final C3/C5 về idempotency + expiry guard cho deduct_km2_payment | TL + BE | Trước payment implementation | Sẵn sàng kickoff | Không — acceptance checkpoint trong P1 |
| BE-001 | Grep full hardcode wallet / wallet_promotion / VND_PROMOTION để lập implementation checklist | BE Dev | Đầu P1 | Sẵn sàng kickoff | Không — task bắt buộc trong P1 |
| OPS-001 | ZNS template đăng ký với Zalo provider | Ops | Trước khi bật FR-011 | Mở | Không block core nếu FR-011 chưa bật |
| BE-002 | Fix Invoice struct thiếu WalletPromotionAmount (bug hiện tại) | BE Dev | Phase 1 | Mở | Không — fix trong P1 |
Sprint 0 — Checklist 1 tuần kickoff (BẮT BUỘC trước Phase 1)
Mục tiêu: giảm rủi ro tech debt + design ambiguity trước khi BE bắt đầu code Phase 1. Sprint 0 không phải Phase 1; là pre-work. Hoàn tất 7 task dưới đây thì Phase 1 mới được kickoff.
Thời lượng: 5 ngày làm việc. Daily standup 9:00 sáng review tiến độ.
Pass criteria: mỗi task có cột
Bằng chứng passđược TL ký xác nhận. Sprint 0 close khi 7 task đều có ✅.
| ID | Task | Owner | Effort | Bằng chứng pass | Block Phase 1 nếu thiếu? |
|---|---|---|---|---|---|
| S0-01 | BE-001 Grep hardcode — chạy grep toàn repo diva-backend/ cho 3 keyword wallet_promotion, VND_PROMOTION, wallet_type_id; phân loại mỗi occurrence thành sửa cho KM2 / giữ nguyên có lý do / không liên quan; output sang Google Sheet hoặc BE_HARDCODE_AUDIT.md trong repo | BE Dev | 1 ngày | Sheet/file có 100% occurrence được phân loại; TL review + sign | CÓ — nếu thiếu thì task P1-04..P1-07 không biết scope |
| S0-02 | TL-001 Idempotency design review — TL đọc dev-spec C5.4.1 mới, viết docs/features/vi-km-2/design-notes/idempotency-review.md trả lời: (a) có đồng ý dedup window 7 ngày? (b) có đồng ý lock TTL 90s? (c) có đồng ý attempt_id gen ở client thay vì server? (d) edge case nào còn miss? | TL | 0.5 ngày | File design-notes commit; 7 test case TC-IDEMPOTENT-01..07 được TL approve | CÓ — không có thì BE code có rủi ro phải refactor |
| S0-03 | Cross-DB snapshot POC — viết script test: tạo prepaid_card ở ecommerce DB → tạo wallet_km2_lot ở wallet DB với snapshot fields; verify Hasura có thể query lot + JOIN logic FE-side với prepaid_card (vì cross-DB join không hỗ trợ); test scenario Admin sửa giá Gói sau bán → lot cũ giữ nguyên giá snapshot | BE Dev | 1 ngày | POC script + screenshot Hasura query + test pass cho 3 case (snapshot OK, sửa giá không ảnh hưởng lot, FE-side join hoạt động) | CÓ — pattern này dùng xuyên suốt; sai sẽ cần redesign C4 |
| S0-04 | TG-001 Refund handler subtask — TL + BE chia subtask cho refund_km2_wallet behavior: 1 subtask FE (option dialog SCR-07), 1 subtask BE handler, 1 subtask QA test cases; verify backend refund hiện tại không hard-code wallet_type_id='VND_PROMOTION' ở các path ngoài transaction_request (nếu có thì list ra) | TL + BE + FE | 0.5 ngày | 3 ticket Linear/Jira tạo với scope rõ; danh sách hard-code path khác (nếu có) đính kèm | KHÔNG Phase 1 — nhưng block Phase 2 nếu thiếu |
| S0-05 | BE-002 Fix Invoice struct bug — fix bug hiện tại: pkg/store/invoice.go thiếu field WalletPromotionAmount cho KM1; merge fix này trước khi vào KM2 work để FR-012 hoá đơn in render đúng KM1 trước, KM2 sau | BE Dev | 0.5 ngày | PR merged; smoke test render hoá đơn có KM1 hiển thị đúng | CÓ — fix lẫn lộn KM1/KM2 nếu để sau |
| S0-06 | Capacity model verify — TL review dev-spec C9 mới (capacity ước lượng + index strategy); verify ước lượng row count với 1 spa thật đang dùng KM1 (lấy COUNT từ wallet_promotion history); confirm partial index strategy + threshold partition | TL | 0.5 ngày | Comment trong dev-spec C9 ghi "đã verify với data spa X" + giá trị thật | KHÔNG — chỉ block Phase 2 |
| S0-07 | Monitoring instrumentation kickoff — BE list 23 metric trong dev-spec C10 mới, tạo template Prometheus client code (Go); Ops tạo Grafana dashboard skeleton; QA viết runbook stub RUNBOOK-KM2-01..05 (chỉ cần action steps, không cần đầy đủ) | BE + Ops + QA | 1 ngày | Code template commit + dashboard URL + 5 file runbook stub | KHÔNG Phase 1 code — nhưng block Day-0 |
Gate Sprint 0 close (TL ký)
- [ ] 7 task có bằng chứng pass
- [ ] TL review tổng + commit
SPRINT_0_REPORT.mdtóm tắt findings (đặc biệt nếu S0-01 phát hiện thêm impact ngoài scope hiện tại) - [ ] PO + TL agree go/no-go Phase 1
- [ ] Nếu Sprint 0 phát hiện scope tăng > 30% → quay lại update
SOURCE_OF_TRUTH.md+ dev-spec; KHÔNG kickoff Phase 1 với scope cũ
Gate kỹ thuật trước merge / bàn giao QA
Các gate dưới đây là checklist bắt buộc để giảm rủi ro kỹ thuật khi team bắt đầu implement. Phase 1/2 được kickoff ngay, nhưng code liên quan không được merge lên staging/UAT nếu gate tương ứng chưa có bằng chứng pass.
| Gate | Phạm vi kiểm soát | Owner | Bằng chứng cần có | Điều kiện pass |
|---|---|---|---|---|
| TG-001 | Luồng Hoàn ví KM2 trong Yêu cầu hoàn tiền | TL + FE + BE + QA | Subtask riêng cho refund_km2_wallet; diff FE/BE; test tạo/duyệt/thực hiện hoàn | UI có option "Hoàn ví KM2"; request dùng behavior refund_km2_wallet; không hard-code wallet_type_id='VND_PROMOTION'; hoàn đúng lot KM2, ghi deduction/audit, không rơi nhầm luồng KM1 |
| TG-002 | Hard-code KM1 / wallet promotion | TL + BE + FE | Kết quả grep "wallet_promotion", "VND_PROMOTION", "wallet_type_id" và phân loại sửa / giữ nguyên có lý do / không liên quan | Không còn occurrence chưa phân loại trong payment, invoice, fund, print, report, notification, customer profile; KM1 và KM2 có field/label/semantics tách riêng |
| TG-003 | FIFO deduction, idempotency, expiry guard | TL + BE | Review note thiết kế transaction; test race condition/retry; log idempotency | deduct_km2_payment dùng transaction lock theo lot, chống double submit bằng idempotency key, luôn check expired_at > NOW() trước khi trừ tiền, rollback đúng khi payment fail |
| TG-004 | DB / Hasura / codegen contract | BE + FE | Migration applied trên staging clone; metadata reload; GraphQL codegen output | wallet_km2_lot, wallet_km2_lot_deduction, wallet_km2_config, action get_customer_km2_lots, deduct_km2_payment, refund_km2_wallet và các field KM2 xuất hiện đúng contract dev-spec |
| TG-005 | Dynamic Permission v2 runtime mapping | TL + BE + FE + QA | Seed module_permission_action; role_module.actions; ModuleOperationMapping; test grant/revoke/API no-leak | KM2 không hard-code theo role name; FE ẩn/hiện theo quyền; backend chặn API trực tiếp khi thiếu quyền, sai portal hoặc ngoài branch scope |
| TG-006 | Scheduler, rollback, monitoring | TL + Ops + BE | Cron dry-run; metric/log dashboard; rollback rehearsal | Scheduler không trừ nhầm lot đang hợp lệ; disable config/cron rollback được; có metric/log cho deduction error, scheduler error, expired balance và duplicate deduction |
| TG-007 | Impact boundary regression | QA + TL | Chạy đủ TC-IMPACT-*; danh sách affected/unaffected đã tick kết quả | Flow bị ảnh hưởng được thêm KM2 đúng chỗ; flow không ảnh hưởng không bị đổi dữ liệu, route, quyền hoặc báo cáo ngoài phạm vi |
Luồng Hoàn ví KM2 cần chốt khi giao task
| Điểm kiểm soát | Yêu cầu khi implement |
|---|---|
| Entry point | Dùng màn Yêu cầu hoàn tiền hiện có, thêm option nghiệp vụ "Hoàn ví KM2"; không tạo module duyệt mới. |
| Behavior | Dùng refund_km2_wallet; không dùng lại behavior KM1 nếu behavior đó đang gắn mặc định VND_PROMOTION. |
| Dữ liệu bắt buộc | Customer, Gói Ví KM2/lot KM2, số tiền hoàn, phí hoàn nếu có, phương thức nhận hoàn, chứng từ, lý do, reviewer step. |
| Wallet/lot update | Hoàn phải cập nhật đúng wallet_km2_lot / wallet_km2_lot_deduction, không chỉ ghi wallet_balance tổng. |
| Permission | Dùng refund_request_management_submenu:access/create/update/approve/payment + reviewer config + branch scope. |
| QA oracle | Tạo request, sửa request, duyệt, từ chối, thực hiện hoàn, hoàn partial/full, lot hết hạn, thiếu quyền, khác branch. |
Lưu ý quan trọng cho team
Logic kế toán (xem PRD FR-003 + FR-004)
MUA GÓI VÍ KM2:
Khách trả 500k → Thực thu = 500k (giá mua gói)
→ Ví KM 2 = +5,000,000đ (toàn bộ vào KM2)
→ Ví VND = 0, Ví KM 1 = 0
→ Commission tính trên giá mua gói (500k)
Khác KM1: KM1 chia base→VND + bonus→KM1. KM2: toàn bộ vào KM2.
THANH TOÁN BẰNG KM2:
Đơn 1tr → KM2 trả 140k + tiền mặt 860k
→ Thực thu = 860k (chỉ tiền mặt)
→ KM2 không tính thực thu, không tính customer points
→ Không ảnh hưởng hạng thành viên (hạng dựa trên thực thu)
THANH TOÁN NHIỀU LẦN (mua Gói Ví KM2):
Ví nhận theo tỉ lệ đã trả. Lot tạo từ lần trả đầu tiên.
VD: trả 60% → ví nhận 60% giá trị. Trả nốt 40% → ví nhận 40%.Kiến trúc đặc biệt
- FIFO deduction: Go action handler
deduct_km2_paymentdùng direct PostgreSQL tx (DEC-018) — KHÔNG qua Hasura GraphQL vì cầnSELECT FOR UPDATE - Cross-DB:
wallet_km2_lotsnapshot giá mua gói (DEC-016) — KHÔNG join cross-DB sang ecommerce - Dynamic Permission v2: Không hard-code role name; quyền thực tế =
role_module.actions+portal+branch_mode+ backend enforcement. Customer profile dùng actionget_customer_km2_lots; Hoàn ví KM2 dùngrefund_request_management_submenu:access/create/update/approve/payment+ reviewer config (DEC-025/026) - Default enablement: migration seed config KM2 ở trạng thái
disabled=true; chỉ bật trong go-live sau khi readiness pass (DEC-023) - Trả góp: KHÔNG cho mua Gói Ví KM2 bằng trả góp (DEC-017)
Ảnh hưởng màn hình cũ (FR-012)
Phase 1 PHẢI sửa (sẽ break nếu không):
- Đơn mỹ phẩm:
CosmeticOrderFormPayment+ table + multi-payment - Đơn sản phẩm:
ProductOrderItems(allow_promo_wallet_2) - Hoá đơn in:
print_invoice_popup.go,InvoiceTemplatePopupPrint.tsx - Fund/Quỹ:
FundTable,FundInvoicePopup
Phase 2 nên sửa (data sẽ thiếu):
- Withdraw detail, Report DV/NV, CRM Customer
KHÔNG cần sửa:
- OrderCard, CustomerOrderHistory (card không breakdown)
- Dashboard (Phase 3)
- Rank/Loyalty (KM2 không tính thực thu → không ảnh hưởng hạng)
Checklist trước khi dev bắt đầu
- [ ] PO ký duyệt Tóm tắt quyết định + PRD — đặc biệt: bảng kế toán FR-003/004, hoàn ví KM2 FR-009, multi-payment DEC-019, report PD-001
- [ ] Tech Lead rà soát Đặc tả kỹ thuật — trọng tâm: DEC-018 FIFO Go action, DEC-022 idempotency/expiry guard, DEC-016 cross-DB snapshot, DEC-024/025 Dynamic Permission v2, C2 Ảnh hưởng 30+ files
- [ ] Tech Lead tạo checklist/subtask theo TG-001..TG-007 — mỗi gate có owner, bằng chứng pass và trạng thái trước khi merge staging/UAT
- [ ] UI/UX rà soát Đặc tả UI — trọng tâm: B-FR012 delta 8 màn cũ, SCR-03 đối chiếu UI thực tế, SCR-07 form Hoàn ví KM2 mới
- [ ] QA rà soát Kế hoạch kiểm thử — 80 TCs, focus TC-004-09/11/12, TC-006-06, TC-009-05/06/07/08, TC-PERM-*, TC-012 và TC-IMPACT regression
- [ ] Ops/TL rà soát Checklist phát hành — E1-E6 tiêu chí pass, rollback, monitoring
- [ ] Ops đăng ký ZNS template với Zalo nếu PO bật FR-011 cho rollout
- [ ] BE Dev grep
"wallet_promotion"toàn bộ codebase → liệt kê full list files cần sửa (RSK-002) - [ ] FE Dev đối chiếu Đặc tả UI SCR-03 với màn hình "Tạo Mới Nạp Tiền" thực tế