Skip to content

Sales-CSKH Debt Follow-up & Handover — QA Test Plan

Canonical Source of Truth: SOURCE_OF_TRUTH.md — DEC-001: codebase Diva là ground truth, đây là hardening pass (không greenfield). Slug: sales-cskh-debt-handover · Version: v1.0 hardening · Updated: 2026-05-14 Spec Index: prd.md · ui-spec.md · dev-spec.md · go-live-checklist.md · handoff.md

FR/AC: prd.md A5 + A12 · Wireframes + codebase mapping: ui-spec.md §0 · Code paths: dev-spec.md C11


ⓘ Hardening QA approach

Đây là test plan cho hardening pass trên feature đã build sẵn ~85% trong codebase. Định hướng:

  1. Regression-first — verify component đã có (🟢 Reuse) vẫn hoạt động đúng spec
  2. Delta-focused — test deep cho component cần extend (🟡 Extend): KPI mới, scope chip, leaderboard, drawer NV
  3. Critical path E2E — luồng nghiệp vụ end-to-end: filter → KPI → drill-down → alert → handover → rollback
  4. Permission hardening — least-data per DEC-012 cho 5 bảng debt_*; test field-level masking
  5. Capacity gate — benchmark SCR-01-TAB-ANALYTICS @ 1.5M order rows trước go-live (DEC-013 gate cho materialized snapshot)

Tham chiếu test code paths:

  • FE Web: diva-admin/src/modules/debt-manager/ + customer-handover/
  • FE Mobile: diva-flutter/staff/lib/presentation/modules/debt_management/
  • BE: diva-backend/services/ecommerce-api/action/ + scheduler/daily_debt_alert.go
  • DB: function customer_debt_dashboard_order_scope() (migration 1776054869987_*)

D) QA Test Plan


D1. Scope & Coverage

Feature: sales-cskh-debt-handover v4.11 MVP-Lite + Mobile + Quản lý lịch nhắc + Navigation & Tooltip + Review Fix + UX Usability P0+P1+P2 + Debt UI Sync + Analytics Tab Sync. Coverage: 100% FR (20/20) + 100% NFR (10/10) + Mobile screens (5/5) + Drawer web (2/2) + UX P0 (4 TC) + UX P1 (6 TC) + UX P2 (4 TC) + Analytics (7 TC).


D2. Requirements Test Matrix

ReqLayerScenario chínhTiêu chí passStatus
FR-001E2EFilter cascade + preset< 2s p95 (30 ngày); cascade đúngPlanned
FR-002Int+E2EDS tư vấn theo hoa hồngĐúng quyền, role, %Planned
FR-003Int1 khách nhiều sự kiện tư vấncùng ngày/cùng CN: visit=1, unique=1; thêm 4 ngày khác: visit=5, unique=1Planned
FR-004IntClosed + conversionMua+thu>0; N/A khi 0Planned
FR-005IntKPI nợ distinct+equivalentSai số ≤1%; N/A rulePlanned
FR-006IntWeighted + settlementĐúng TZ VNPlanned
FR-007Unit+IntAging boundary 29/30/59/60/89/90Không overlapPlanned
FR-008IntThreshold overridebranch ?? global; validate min=1 max=365Planned
FR-009Int+E2EJob cảnh báo hằng ngày≥95% gửi; không trùng; push mobilePlanned
FR-010E2EHandover wizard 3 bướcPreview + confirm đúng; rollback toàn bộPlanned
FR-011IntAudit log100% có log immutable (incl. rollback)Planned
FR-012E2EExport XLSX theo filterChunking 200k; đúng quyền; 13/18 cột đúngPlanned
MOB-01E2E MobileKPI cá nhân hiển thị đúngData khớp web; filter thời gianPlanned
MOB-02E2E MobileDanh sách nợ + CTAScope chip vai trò đúng; gọi, LH, lịch hoạt độngPlanned
MOB-05E2E MobilePush notification deeplinkTap → đúng màn hìnhPlanned
FR-013E2EQuản lý lịch nhắc follow-upTạo→xem→đánh dấu xong; noti in-app khi đến giờ; timeline đúngPlanned
FR-014E2ERole-gated tab Thống kêChỉ Manager/Admin thấy tab; Staff không thấyPlanned
FR-015Int+E2E6 KPI cố định tab Thống kêValue/sub-label/trend/progress đúng theo bộ lọcPlanned
FR-016E2ESo sánh nợ theo Chi nhánh/Nhân viênĐổi mode + sort (Đã thu/Còn nợ) recalc đúng, giữ filter globalPlanned
FR-017E2EXu hướng nợ 3 lineMặc định bật 3 line, toggle legend đúng, tooltip số liệu đúngPlanned
FR-018Int+E2ELeaderboard thu nợSort/pagination/tie-break đúng; top 3 highlight đúngPlanned
FR-019E2EDrawer chi tiết nhân viênMở từ leaderboard; KPI + aging + top5 đúng; CTA Xem chi tiết quay về tab Công nợ với filter nhân sựPlanned
FR-020E2EExport XLSX tab Thống kêXuất đúng theo filter hiện tại; đủ 2 sheet (summary + leaderboard detail)Planned
— (CTA)IntmarkCustomerContacted + debt_contact_logĐánh dấu/hủy đúng; log append-only; trạng thái cuối đúngPlanned
FR-008-APIIntupsertDebtAlertConfig validation edge casesmin/max/notify_time/branch scope/unique constraint passPlanned
UX-P0-01E2EAction Card hiện/ẩn + CTA navigateHiện khi nợ ≥30d; ẩn khi không có; CTA → tab Công nợ + pre-filter Nhóm nợ đúng; dismiss persist localStoragePlanned
UX-P0-02E2EDefault sort SCR-03 + MOB-02Load trang → sort overdue_days DESC, outstanding_amount DESC; click header → overridePlanned
UX-P0-03E2ECTA overflow menu SCR-03Chỉ [📞 Gọi] hiện trực tiếp; [⋯] chứa 3 items; nợ ≥90d → nút Gọi đỏ #B71C1CPlanned
UX-P0-04E2EDebt scope chip roleSCR-01 tab Công nợ + MOB-02 hiển thị scope chip Sale/Telesale/CSKH; tooltip match; dữ liệu recalc đúngPlanned
UX-P1-01E2ESub-label KPI cardsMỗi card có sub-label đúng (VD: "45 khách mua / 67 khách"); N/A → "Chưa đủ dữ liệu"; font 12px #757575Planned
UX-P1-02E2E MobileMOB-03 collapsible sections3 sections collapse/expand; badge count đúng; "Dịch vụ nợ" collapse khi >2 đơnPlanned
UX-P1-03E2ESCR-03-DRAWER overlay modeOverlay (không push); backdrop dim; click ngoài đóng; bảng SCR-03 không coPlanned
UX-P1-04E2E MobileMOB-02 card CTA + overflowCard hiển thị đúng metadata; CTA [Gọi ngay] [Tạo lịch] [⋯] hoạt động; tap card → MOB-03Planned
UX-P1-05E2ESCR-01 Dashboard 2 tabsTab "Hiệu suất" = Block A + bảng; tab "Công nợ" = Block B + Aging + bảng nợ; filter giữ nguyên khi chuyển tabPlanned
UX-P1-06E2E MobileMOB-03 sticky summary cardSticky khi scroll xuống; 48px; name + tổng nợ + badge + [📞]; ẩn khi scroll lênPlanned
UX-P2-01E2EKPI full-set nhất quánBlock B luôn hiện full bộ KPI nợ trên web/mobile; không còn control toggle; metric/value khớp theo filterPlanned
UX-P2-02E2EQuick Handover modeScope "Toàn bộ" → wizard 2 bước; bảng chi tiết khách ẩn; scope "Lọc" → wizard 3 bước bình thườngPlanned
UX-P2-03E2EDaily Focus Top 55 khách ưu tiên; sort: nhắc quá hạn > nợ ≥90d chưa LH > overdue DESC; [📞] hoạt động; hide/show persistPlanned
UX-P2-04E2EOnboarding Tour 3 bướcLần đầu SCR-01 → tour hiện; 3 steps đúng target; "Bỏ qua" set flag; hoàn thành set flag; lần sau không hiện; "Xem lại" từ menu ⓘPlanned

D3. Seed Data

DatasetNội dung bắt buộc
Seed-KPI-011 khách nhiều sự kiện tư vấn (cùng ngày + khác ngày + khác chi nhánh) — kiểm soát visit vs unique
Seed-COMMISSION-011 đơn nhiều DV, nhiều role, nhiều %; có case 2 Sale 50/50
Seed-COMMISSION-021 đơn 3 DV mixed: DV1 = 1 Sale 100% (auto primary), DV2 = 2 Sale 50/50 (cần chọn radio), DV3 = chỉ CSKH 100% (không áp dụng primary Sale)
Seed-COMMISSION-031 đơn 1 DV, 3 Sale (40/30/30) — test radio 3 options + validation chưa chọn
Seed-KPI-02Khách mua chưa thu + khách có thu
Seed-DEBT-01Nợ outstanding > 0 và = 0
Seed-DEBT-02Nợ payments nhiều kỳ (weighted + settlement)
Seed-DEBT-03Nợ ở boundary aging: 29, 30, 59, 60, 89, 90 ngày
Seed-CONFIG-01Branch có override + không có
Seed-ALERT-01Owner chain đủ 3 cấp fallback
Seed-HANDOVER-01KH để test wizard 3 bước + rollback 24h
Seed-EXPORT-01Dữ liệu > 200k rows
Seed-MANAGER-01Manager quản lý 3 branch; test RBAC scope
Seed-MOBILE-01User mobile với KPI + nợ để test MOB-01…03
Seed-FOLLOWUP-01Lịch nhắc: 2 pending (1 quá hạn, 1 chưa đến), 2 done, 1 cancelled. Cùng 1 khách + khách khác
Seed-ACTION-CARD-01Data có nợ ≥30d (trigger Action Card) + data không có nợ ≥30d (ẩn Action Card)
Seed-DAILY-FOCUS-017+ khách với mixed priorities: 2 có lịch nhắc quá hạn, 2 nợ ≥90d chưa LH, 3 nợ 30-89d — verify top-5 ranking
Seed-ONBOARDING-01User mới chưa có localStorage flag debt_onboarding_completed
Seed-QUICK-HANDOVER-01Nhân viên có 45 khách, test cả scope "Toàn bộ" (2-step) và scope "Lọc" (3-step)

D4. Critical Path Test Scenarios

TC-CPMô tảFR Covered
TC-CP-01Filter cascade → KPI → drill-down → xuất XLSX đúng quyềnFR-001…004, 012
TC-CP-02Job gửi noti (in-app + push) → mở danh sách → xử lý → CRMFR-005, 007, 009
TC-CP-03Handover SCR-05→06→07→08 → audit → rollback 24h toàn bộFR-010, 011
TC-CP-04Owner rule + threshold: test đủ 3 cấp fallbackFR-008, 009
TC-CP-05Manager scope: chỉ thấy branch đang quản lýDEC-013
TC-CP-06Mobile: push → tap → MOB-02 → gọi → đánh dấu LHMOB-02, 05
TC-CP-07Perf query + freshness + monitor alertsNFR-001, 002, 006, 009
TC-CP-0850/50 commission (new flow): 1 DV, 2 Sale cùng % → user chọn "Phụ trách chính" trong popup hoa hồng, owner đúng người chọn. KPI mỗi người 50%, không chồng chéoDEC-QA-006, FR-009
TC-CP-08b50/50 commission (legacy): 1 DV, 2 Sale cùng %, cùng created_at, không có cờ is_primary_owner → tie-break user_id ASC chọn đúng 1 ownerDEC-QA-006, FR-009
TC-CP-08c1 Sale duy nhất (auto primary): 1 DV, 1 Sale 100% → auto set is_primary_owner = true, KHÔNG hiện radio. Owner = Sale đó. Label hiện "✅ Phụ trách chính" readonlyDEC-003, FR-002
TC-CP-08d3+ Sale (multi-select): 1 DV, 3 Sale (40/30/30) → hiện radio 3 options, user chọn Sale 2 → is_primary_owner = Sale 2. KPI: mỗi người nhận đúng % riêng, owner = Sale 2DEC-003, FR-002
TC-CP-08eValidation chưa chọn: 2+ Sale trên DV, user chưa chọn radio "Phụ trách chính" → nút "Xác nhận" disabled + warning "Vui lòng chọn người phụ trách chính cho Sale trên dịch vụ [tên DV]"FR-002
TC-CP-08fMulti-DV mixed: Đơn 3 DV — DV1 có 1 Sale (auto primary), DV2 có 2 Sale (cần chọn), DV3 chỉ CSKH (không áp dụng) → chỉ DV2 hiện radio, submit chỉ enabled khi DV2 đã chọnFR-002, DEC-003
TC-CP-09Handover limit: thử bàn giao 201 khách → block + error "Tối đa 200 khách/lần"DEC-017, DEC-TECH-009
TC-CP-10Tạo lịch nhắc → xem lại trong drawer (web) → đánh dấu Đã xong → status chuyển doneFR-013
TC-CP-11Lịch nhắc quá hạn (remind_at < now, pending) → hiện badge 🔴 Quá hạn trong drawer + counter trên nút toolbarFR-013, DEC-UX-009
TC-CP-12Đến giờ nhắc → hệ thống gửi in-app noti (NTF-FOLLOWUP-REMIND) → user click → mở SCR-03 drawerFR-013, DEC-020
TC-CP-13Xem timeline lịch nhắc cho 1 khách: hiện đúng thứ tự + trạng thái từng lần nhắcFR-013
TC-CP-14markCustomerContacted: đánh dấu → hủy đánh dấu → đánh dấu lại → debt_contact_log có 3 bản ghi, trạng thái cuối = trueFR-005, CTA
TC-CP-15upsertDebtAlertConfig: validate min=1 max=365, notify_time 06:00–10:00, branch scope consistency, unique constraintFR-008, DEC-TECH-002
TC-CP-16P0 Action Card + Sort: Mở SCR-01 có nợ ≥30d → Action Card hiện đúng badge count + CTA "Xử lý ngay" → click → tab Công nợ, apply filter nhóm nợ cao nhất → bảng sort overdue_days DESC → Quay lại dismiss "Ẩn hôm nay" → refresh → vẫn ẩn (localStorage) → đổi ngày → hiện lạiUX-P0-01, UX-P0-02
TC-CP-17P0 CTA Overflow + Scope Chip: SCR-03 load → dòng chỉ có [📞 Gọi] + [⋯] → click ⋯ → dropdown 3 items → "Đánh dấu Đã LH" → icon ✅ → mở lại ⋯ → thành "Hủy đánh dấu" → đổi scope chip Sale/Telesale/CSKH → data recalc đúng scope → cột "% tham gia" hiệnUX-P0-03, UX-P0-04
TC-CP-18P1 Dashboard Tabs + Sub-labels: SCR-01 mở → tab "Hiệu suất" default → KPI cards có sub-label (VD: "45 khách mua / 67 khách") → đổi tab "Công nợ" → Block B + Aging hiện → filter giữ nguyên → KPI "Tỷ lệ chuyển đổi" N/A → sub-label = "Chưa đủ dữ liệu"UX-P1-01, UX-P1-05
TC-CP-19P1 Overlay Drawer: SCR-03 click [📅 Lịch nhắc (2)] → drawer overlay hiện bên phải → backdrop dim → bảng SCR-03 KHÔNG bị co → click backdrop → drawer đóng → click lại → scroll lịch nhắc → tạo mới → toast thành côngUX-P1-03
TC-CP-20P1 Mobile Card CTA + Collapsible + Sticky: MOB-02 → card hiển thị đúng Tham gia / Phụ trách chính / Đã gọi ... → tap [Gọi ngay] → gọi → quay lại → hỏi "Đã LH?" → tap [Tạo lịch] → mở MOB-04 → tap card → MOB-03 → scroll xuống → sticky summary hiện (48px) → section "Lịch sử LH" collapsed → tap expand → badge count đúngUX-P1-02, UX-P1-04, UX-P1-06
TC-CP-21P2 KPI Full-set + Daily Focus: SCR-01 tab Công nợ → Block B hiển thị full bộ KPI nợ mặc định (không toggle) → đổi filter → giá trị recalc đúng → Qua SCR-03 → Daily Focus top 5 hiện → verify thứ tự: nhắc quá hạn trước → nợ ≥90d → overdue DESC → click [📞] → gọi → click "Ẩn" → reload → vẫn ẩnUX-P2-01, UX-P2-03
TC-CP-22P2 Quick Handover: SCR-05 chọn nguồn + scope "Toàn bộ" (45 khách) → stepper hiện 2 bước → click "Tiếp theo" → Step 2 gộp: chọn đích + Preview + Tóm tắt + 2 checkbox → tick đủ → "Xác nhận bàn giao" enabled → confirm → SCR-08 → Quay lại SCR-05 → chọn scope "Theo bộ lọc" → stepper hiện 3 bước bình thường → Step 2 có bảng chi tiết kháchUX-P2-02
TC-CP-23P2 Onboarding Tour: Clear localStorage → mở SCR-01 lần đầu → tour Step 1/3 hiện (spotlight KPI Nợ) → "Tiếp theo" → Step 2/3 (Aging Chart) → "Tiếp theo" → Step 3/3 (Lịch nhắc) → "Hoàn thành" → toast → reload → tour KHÔNG hiện → menu ⓘ → "Xem lại hướng dẫn" → tour hiện lại → "Bỏ qua" → confirm → tour đóngUX-P2-04
TC-CP-24Analytics End-to-End: Manager mở tab Thống kê → verify 6 KPI cố định (Tổng tiền nợ, Đã thu trong kỳ, Tỷ lệ thu nợ, Khách còn nợ, Đã tất toán, Tỷ lệ nợ/doanh thu) → đổi chart mode Chi nhánh/Nhân viên + đổi sort Đã thu/Còn nợ → mở leaderboard và sort → click 1 nhân sự mở drawer chi tiết → bấm Xem chi tiết quay về tab Công nợ và auto-set filter nhân sự + scroll tới bảng phù hợp → quay lại tab Thống kê và bấm Xuất XLSX để xác nhận export theo bộ lọc hiện tạiFR-014…020

D5. Entry / Exit Criteria

Entry: PRD + UI/UX (Web + Mobile) + Dev Spec review xong. Seed data sẵn sàng. PD-007/008/009 đã confirm hoặc feature flag tắt cho phần chưa confirm.

Exit: 100% TC FR pass. 100% NFR đạt ngưỡng. Không còn S1/S2. UAT sign-off (Web + Mobile).