Skip to content

Handoff — Tab Chu kỳ khách ghé không mua

Version: 2.8
Date: 11/05/2026
Canonical Inputs: SOURCE_OF_TRUTH.md, EVIDENCE_PACK.md, prd.md.

v2.8 — 11/05/2026

Thay đổiSectionẢnh hưởng
Thêm 8 implementation step (10-17) cho clarity tweak3) Implementation orderAll
Thêm timeline row +1-2 days dev + 1 day QA4) TimelinePM, TL
Thêm 5 blocker mới (sub-text fit, column rename scope, tooltip coverage)5) BlockersAll
Thêm 8 DoD v2.8 (DEC-027..030, TC-020..024, mobile, no regression)6) Definition of doneAll

File này là index giao team: ai làm gì, thứ tự nào, blocker nào. Scope/timeline trong file này thắng các timeline tóm tắt rải rác nếu có.

1) Delivery package

FileOwner đọc chínhStatus
decision-brief.mdPO/TL/SếpReady
EVIDENCE_PACK.mdPO/BA/TLReady
SOURCE_OF_TRUTH.mdAllReady
prd.mdPO/BA/TLReady
ui-spec.mdUI/FE/QAReady
dev-spec.mdBE/FE/TLReady
qa-test-plan.mdQAReady
_consistency-matrix.mdPO/BA/TLReady

2) RACI

WorkstreamResponsibleAccountableConsulted
Business sign-offPO/BAProduct LeadMarketing, CSKH
BE actions/metadataBE DevTech LeadQA
FE tab/matrix/popupFE DevTech LeadUI/UX, QA
QA seed/regressionQAQA LeadBE, FE
UATPO/BAProduct LeadMarketing, CSKH

3) Implementation order

StepTaskOwnerExit condition
0Implement resolveBranchScope helper (DEC-016 — review C-01: KHÔNG dùng IsAdmin())BEUnit test pass cả 6 case verification matrix; explicit test case Manager Q1 với Hasura role user không bypass
1Add Hasura action types/metadataBEMetadata validates
2Implement reportVisitCycleNoPurchase (call resolveBranchScope first; CTE exclude converted)BEAggregate seed test pass + TC-010/TC-012
3Implement reportVisitCycleNoPurchaseDetail (resolveBranchScope + branch_ids input DEC-026 + customer_ids intersect + visit_source normalize)BEDetail seed test pass + TC-013 + TC-019 cross-branch consistency
4Add FE GraphQL queries/codegenFEGenerated types compile
5Add tab key/panel + fix DEC-015 tab persistenceFETab visible and survives refresh; tab Chu kỳ khách hàng cũng survive (regression)
6Build overview/matrixFEData renders with empty/loading/error
7Build popup + utility formatVisitSource (DEC-017)FESearch/open customer works; multi-source render đúng
8QA P0 (TC-001..006, 008, 010, 012, 013, TC-019 cross-branch popup drift) + regression purchase tab + tab persistence regressionQAAll P0 pass
8bQA P1 (TC-007 by_month bucket DEC-018, TC-009 error state, TC-011 same-day order, TC-014 copy/core tooltip, TC-015 click guard, TC-016 performance benchmark, TC-017 responsive tab label, TC-018 filter validation)QA + BETC-016 pass mới được merge GA. Fail TC-016 → BE switch SQL fallback và re-test. Tooltip ngoài core là backlog, không block GA.
9UAT with Marketing/CSKHPO/BASign-off
10Build component VisitNoPurchaseInfoStrip.tsx (FR-007, DEC-028) + integrate vào tab panelFEStrip visible permanent above filter bar, không có dismiss; TC-020 pass
11Build component reusable LabelWithSubText.tsx (DEC-029)FEComponent compile + render với label + subtext + tooltip props
12Integrate <LabelWithSubText> vào 3 cards overview + matrix headers + 2 matrix rows (DEC-029)FESub-text visible đúng copy theo B6; TC-021 pass
13Add q-icon info + tooltip cho 6 popup column headers (DEC-029, DEC-030)FE6 ℹ️ icon visible inline, hover hiện tooltip; TC-023 pass
14Rename matrix column cuối Tỷ lệ% trên tổng (DEC-029 rename T6); regression tab purchaseFECột mới hiển thị % trên tổng ở tab mới; tab Chu kỳ mua hàng KHÔNG đổi; TC-022 pass
15Add 9 i18n keys mới (xem UI B6)FEi18n keys available và hiển thị đúng tiếng Việt
16QA v2.8: TC-020 → TC-024 + regression TC-001 → TC-019QA5 TC mới pass + 19 TC cũ regression pass; 19 tooltip 100% coverage
17UAT v2.8 với PO/Marketing/CSKHPO/BASign-off; verify "mờ hồ" feedback resolved

4) Timeline estimate

PhaseDurationNotes
BE contract + implementation3-4 daysAggregate/detail action + resolveBranchScope + buildBuckets riêng
FE implementation2-3 daysReuse shell but new copy/data + core tooltip set + click guard
QA + regression + benchmark2-3 daysNeeds seed 100k + 500k cho TC-016
Performance fallback (nếu fail TC-016)+2 daysBE rewrite sang PostgreSQL function/CTE; QA re-test
UAT + fixes1 dayFocus copy/semantics + core tooltip readability
Clarity tweak v2.8 (info strip + sub-text + popup tooltip + column rename)+1-2 ngày dev + 1 ngày QAMostly static components + i18n keys, low risk; designer pair review wireframe trước khi commit

5) Blockers / watch items

ItemSeverityAction
Branch scope enforcement in BE action (DEC-016 — review C-01 footgun)CaoImplement helper resolveBranchScope(ctx, requested) BE-000. TUYỆT ĐỐI KHÔNG dùng Actor.IsAdmin() vì returns true cho cả RoleUser → bypass toàn bộ Manager/Staff. Dùng pattern empty user.branches = no restriction. Verify với TC-012 expanded.
Detail action branch_ids (DEC-026 — review C-03)CaoDetail input phải có branch_ids; BE re-apply resolveBranchScope; QA TC-019 cross-branch drift.
Order canonical enum (review C-02)CaoMọi SQL/code dùng 'order_canceled'/'prepaid_canceled' (KHÔNG dùng 'canceled') — pkg/store/order.go:174,191. Sweep rg "canceled" trước commit.
Formula 002+ filter target_customers (review M-01)Trung bìnhPRD/Dev đã update; aggregate Go phải filter customer_id IN target_customers cho mọi formula sau FORMULA-001. Verify TC-010 expected count khớp.
Empty payload vs errorCaoAdd unit/integration test
Exclude converted customers (DEC-014) phải đúng từ aggregate, không re-compute ở detailCaoAggregate trả customer_ids đã exclude → detail nhận và query trực tiếp; verify matrix tổng = popup tổng cho mỗi bucket
CustomerCycleReport.tsx tab persistence inconsistency (DEC-015)CaoFix to: CUSTOMER_CYCLE_CUSTOMER + whitelist 4 key đang render trong cùng PR; QA TC-001 regression tab Chu kỳ khách hàng
visit_source ordering (DEC-017)Trung bìnhBE normalize trước return; FE utility formatVisitSource defense in depth; QA TC-013
Performance NFR (DEC-020)CaoBlock GA nếu benchmark fail target P95 < 3s @ 100k AND < 5s @ 500k. Fail → switch sang SQL aggregation (xem dev-spec C9 fallback). QA TC-016.
Bucket label divergence với purchase tab (DEC-018)ThấpTab mới dùng ≤ 3 tháng / 4-6 / 7-9 / > 9 (mới); tab cũ giữ quirk hiện tại. PR mô tả rõ. QA TC-007 verify.
Cell click guard (DEC-019)ThấpComponent matrix conditional click handler theo cell value; QA TC-015.
Tab label responsive (DEC-022)ThấpQuasar $q.screen.lt.md chọn i18n key; QA TC-017.
Date range max + clamp (DEC-023)ThấpFE validate onChange + toast; BE defense in depth; QA TC-018.
Bước chu kỳ validation (DEC-024)ThấpFE inline error theo type_cycle; BE validate; QA TC-018.
Popup title format (DEC-021)ThấpComponent popup nhận rowLabel + columnLabel riêng để dễ test.
Export request from stakeholder during buildTrung bìnhTreat as phase 2 decision, not quick add
Info strip placement không break responsive (DEC-028)ThấpQA TC-020 mobile verify; designer pair review
Sub-text dưới donut chart fit (Chart.js doughnut + label plugin — DEC-029)Trung bìnhDesigner pair review wireframe trước implementation; FE có thể trim sub-text donut nếu thấy clutter với chart label
Column rename T6 phải scope nghiêm tab mới — không break tab Chu kỳ mua hàng (DEC-029)Trung bìnhTC-022 explicit regression; review code change phải chỉ touch component tab mới
19 tooltip required coverage có thể miss item nếu B9 rewrite không cẩn thận (DEC-030)Trung bìnhTC-024 enumerate đủ 19 vị trí; QA checklist explicit
Sub-text "Trên tổng {total} KH" có thể trùng giá trị Card 1 → user thấy duplicateThấpDesign review: nếu redundant, có thể trim donut subtext xuống chỉ ghi Trên tổng

6) Definition of done

  • Tab mới visible to authorized report users.
  • Qualified visit rule matches is_zero_order=true and source consultant/do_service.
  • DEC-014 exclude converted: khách có order hợp lệ tạo sau last_qualified_visit_date không xuất hiện ở matrix lẫn popup.
  • DEC-015 tab persistence: 4 tab đang render đều persist đúng sau refresh; to mapping đúng.
  • DEC-016 branch scope: Manager attempt qua DevTools với branch ngoài scope → empty payload, không leak data.
  • DEC-017 Loại ghé format: multi-source luôn Tư vấn + Làm dịch vụ thứ tự cố định.
  • DEC-018 bucket by_month: tab mới render ≤ 3 tháng, 4 - 6 tháng, 7 - 9 tháng, > N tháng; tab cũ unchanged.
  • DEC-019: matrix cell value 0 không có cursor pointer + không mở popup.
  • DEC-020: benchmark report đính kèm PR; P95 đạt target hoặc đã switch SQL fallback và re-pass.
  • DEC-021: popup title format {Row} • {Column} (không phải (Chu kỳ: ...)).
  • DEC-022: tab label responsive — đã verify cả desktop ≥768px và mobile <768px.
  • DEC-023: date range max 365 ngày — clamp + toast warning hoạt động đúng.
  • DEC-024: bước chu kỳ validation — FE inline error + BE reject invalid_duration đều test pass.
  • Matrix total equals popup detail source counts for clicked bucket.
  • Popup has no export and no purchase-oriented columns.
  • Purchase tab regression pass.
  • DEC-026: detail action có branch_ids input + popup count khớp matrix bucket cho mọi filter scope.
  • Order canonical enum: SQL/code dùng 'order_canceled'/'prepaid_canceled' (verify qua sweep + TC-010 CUST-I không bị wrongly excluded).
  • QA P0 pass (TC-001 → TC-006, TC-008, TC-010, TC-012, TC-013, TC-019) + P1 pass (TC-007, TC-009, TC-011, TC-014 core-only, TC-015, TC-016, TC-017, TC-018) và PO/CSKH UAT sign-off. Tooltip mở rộng ngoài UI B9 core không thuộc DoD phase 1.
  • V2.8 (clarity tweak) DoD:
  • DEC-027: v2.8 clarity umbrella shipped — 3 layer (strip + sub-text + tooltip) tất cả visible.
  • DEC-028: Info strip permanent visible mọi data state, không có dismiss, không có localStorage.
  • DEC-029: 8 sub-text + 6 popup column tooltip + column rename T6 đúng copy theo B6.
  • DEC-030: 19 tooltip required 100% coverage, không còn classification "Optional"/"Backlog".
  • TC-020 (P0), TC-022 (P0), TC-021/023/024 (P1) all pass.
  • Mobile responsive: info strip wrap + sub-text wrap + tooltip not cut tất cả verified.
  • Tab Chu kỳ mua hàng KHÔNG có regression copy (cột cuối vẫn Tỷ lệ).
  • UAT PO/Marketing/CSKH confirm "mờ hồ" feedback (11/05/2026) resolved.