Appearance
v1.2 — 21/04/2026
| Thay đổi | Section | Ảnh hưởng |
|---|---|---|
| Khóa mặc định implementation cho role seed phase 1 và đồng bộ ref sang PRD v1.2 | Header, B4 | FE, QA, PO |
| Bổ sung tooltip cho source status, data quality, lifecycle mapping/backfill và runtime preview | B8 | FE, QA, PO |
| Đồng bộ traceability, bổ sung SaaS setup flow, lifecycle UI, interaction/action feedback, responsive+a11y | SCR-01, SCR-02, SCR-03, B3, B8.1 | FE, QA, PO |
| Khởi tạo UI spec cho LTV Phase 1 theo PRD đã khóa | Toàn file | FE, PO, QA |
UI Spec — LTV Phase 1
Ref: PRD v1.2 | Date: 21/04/2026
UI spec này mô tả cách người dùng thật sự đi qua report LTV, từ đọc số liệu đến cấu hình mapping và xử lý case chỉnh tay.
Phần nên đọc trước là End-to-End User Journey, SCR-01, SCR-02, sau đó mới xuống các bảng copy/state/tooltip để FE và QA có chung contract.
B1) Screen Map
| SCR | Tên | Route / Placement | Mô tả |
|---|---|---|---|
| SCR-00 | Hub Chu kỳ khách hàng | /r/reports/customer_cycle_report_group | Màn group report hiện có, được mở rộng thêm tab LTV Phase 1 |
| SCR-01 | Tab LTV Phase 1 | Tab panel trong SCR-00 | Filter + summary cards + bảng tổng hợp + bảng khách hàng + data quality |
| SCR-02 | Drawer Cấu hình mapping nguồn LTV | Mở từ SCR-01, chỉ Admin/IT | Quản lý mapping_version, rule map raw source -> normalized source |
| SCR-03 | Dialog Chỉnh tay nguồn gốc LTV | Mở từ row action ở SCR-01, chỉ Admin/IT | Override Nguồn gốc LTV chuẩn / Kênh nguồn chi tiết cho 1 khách |
B1.1) SCR-00: Hub Chu kỳ khách hàng
Mục tiêu & CTA
| Job-to-be-done | Primary CTA | Secondary CTA | Khối nổi bật |
|---|---|---|---|
| Đi vào đúng cụm report vòng đời khách và chọn tab LTV | Chọn tab LTV Phase 1 | Chuyển sang các tab cycle khác nếu cần đối chiếu | Tab strip trong customer_cycle_report_group |
Layout
text
┌─ Chu kỳ khách hàng ─────────────────────────────────────────────────────────┐
│ [ Tổng quan ] [ Chu kỳ mua hàng ] [ Chu kỳ khách hàng ] [ LTV Phase 1 ✓ ] │
├─────────────────────────────────────────────────────────────────────────────┤
│ Nội dung tab active │
└─────────────────────────────────────────────────────────────────────────────┘Tabs
| # | Tab label | Key | Ghi chú |
|---|---|---|---|
| 1 | Tổng quan | customer_cycle_overview | Existing |
| 2 | Chu kỳ mua hàng | customer_cycle_purchase | Existing |
| 3 | Chu kỳ khách hàng | customer_cycle_customer | Existing |
| 4 | LTV Phase 1 | customer_cycle_ltv | New |
UI contract
- Không tạo card group mới ngoài
customer_cycle_report_group. LTV Phase 1là tab mới trong màn group hiện có để user vẫn tìm report tại nhómChu kỳ khách hàng.- Label tab hiển thị tiếng Việt:
LTV Phase 1. - FE bắt buộc thêm constant tab mới
customer_cycle_ltvvào registry/tab keys của module report. - FE bắt buộc cập nhật
validTabs/ logiclocalStoragehiện có để tab mới persist đúng khi reload. - FE bắt buộc thêm tab mới vào
tabsmap vàQTabPanelscủaCustomerCycleReport.tsx. - FE bắt buộc cập nhật report registry / permission handling để user có quyền nhìn thấy đúng entry trong
customer_cycle_report_group.
B1.2) End-to-End User Journey
| Bước | Actor | Hành động | Kết quả mong đợi |
|---|---|---|---|
| 1 | Business / BOD | Mở customer_cycle_report_group, chọn tab LTV Phase 1, xem cards + aggregate + bảng khách hàng | Hiểu cohort nào có LTV tốt, cohort nào đang nhiều Chưa xác định |
| 2 | Admin/IT | Từ SCR-01 mở Cấu hình mapping khi thấy raw source chưa map hoặc taxonomy cần đổi | Đi vào đúng màn config mà không phải tự nhớ route khác |
| 3 | Admin/IT | Clone / tạo draft, chỉnh rule mapping, xem preview runtime, publish version | Có version mới sẵn sàng cho khách mới mà không rewrite lịch sử cũ |
| 4 | Admin/IT | Quyết định có chạy backfill explicit hay không | Nếu chạy, tạo job có trạng thái rõ ràng; nếu không chạy, snapshot cũ vẫn giữ nguyên |
| 5 | Business / Admin/IT | Quay lại SCR-01, theo dõi badge job và đọc số liệu mới, export hoặc chỉnh tay case đặc biệt | Report phản ánh đúng lifecycle mới và audit trail rõ |
B1.3) Screen Dependency Map
| Screen | Phụ thuộc vào | Kết quả phụ thuộc |
|---|---|---|
| SCR-00 | Report registry + permission group hiện có | Hiện đúng tab LTV Phase 1 trong customer_cycle_report_group |
| SCR-01 | Query overview/customers/data-quality; mapping version hiện hành; backfill job mới nhất | Hiển thị đúng semantics, job status và số liệu canonical |
| SCR-02 | Dữ liệu version/rules + preview impact | Cho phép Admin/IT chỉnh draft, publish version và hiểu ảnh hưởng runtime |
| SCR-03 | Customer row context từ SCR-01 + audit/source snapshot hiện tại | Override có kiểm soát cho từng case đặc biệt |
B1.4) Screen Linking Matrix
| From | Action | To | Return path |
|---|---|---|---|
| SCR-00 | Chọn tab LTV Phase 1 | SCR-01 | Quay lại tab trước bằng tab strip |
| SCR-01 | Click Cấu hình mapping | SCR-02 | Đóng drawer quay về SCR-01, giữ nguyên filter hiện tại |
| SCR-01 | Click Chạy backfill | Confirm modal tại SCR-01 | Sau confirm ở lại SCR-01, hiện badge job và toast |
| SCR-01 | Click Chỉnh tay nguồn trên 1 row | SCR-03 | Submit/close dialog quay lại đúng row đang xem |
| SCR-02 | Publish version thành công | SCR-02 success state | CTA phụ Quay lại report để chạy backfill deeplink về SCR-01 |
| SCR-03 | Submit override thành công | SCR-01 | Refresh row vừa chỉnh, highlight badge Chỉnh tay |
B2) SCR-01: Tab LTV Phase 1
Mục tiêu & CTA
| Job-to-be-done | Primary CTA | Secondary CTA | Khối nổi bật |
|---|---|---|---|
| Đọc chất lượng cohort LTV và xác định cần export, remap hay chỉnh tay case đặc biệt | Tải xuống | Cấu hình mapping, Chạy backfill, Chỉnh tay nguồn theo từng row | Summary cards + aggregate tabs + customer table |
Layout
text
┌─ LTV Phase 1 ──────────────────────────────────────────────────────────────────────┐
│ Cohort first paid [Từ ngày - Đến ngày] [Chi nhánh first paid ▼] [Nhóm nguồn ▼] │
│ [Kênh chi tiết ▼] [Nhóm DV khởi đầu ▼] [Trạng thái nguồn ▼] [Tải xuống] │
│ [Cấu hình mapping] [Chạy backfill] │
├────────────────────────────────────────────────────────────────────────────────────┤
│ [Tổng khách] [LTV TB] [LTV median] [Tỷ lệ Chưa xác định] [Case chỉnh tay] │
├────────────────────────────────────────────────────────────────────────────────────┤
│ Tabs tổng hợp: [Theo nguồn ✓] [Theo kênh] [Theo chi nhánh] [Theo nhóm DV] │
│ ┌────────────────────────────────────────────────────────────────────────────────┐ │
│ │ Bảng tổng hợp quản trị │ │
│ └────────────────────────────────────────────────────────────────────────────────┘ │
├────────────────────────────────────────────────────────────────────────────────────┤
│ Bảng khách hàng LTV │
│ ┌────┬────────┬────────────┬─────────────┬──────────────┬────────────┬─────────┐ │
│ │ KH │ LTV │ First paid │ Last paid │ Nguồn chuẩn │ Kênh chi tiết│Status │ │
│ └────┴────────┴────────────┴─────────────┴──────────────┴────────────┴─────────┘ │
├────────────────────────────────────────────────────────────────────────────────────┤
│ Data quality │
│ ┌────────────────────────────────────────────────────────────────────────────────┐ │
│ │ Top raw source chưa map / số case Chưa xác định / log backfill gần nhất │ │
│ └────────────────────────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────────────┘Filter Bar
| # | Component | Type | Default | Behavior |
|---|---|---|---|---|
| 1 | Cohort first paid | Date range | 30 ngày gần nhất hoặc preset gần nhất | Lọc theo first_paid_at, không cắt doanh thu all-time |
| 2 | Chi nhánh first paid | Multi-select | Tất cả | Filter theo first_paid_branch_id |
| 3 | Nhóm nguồn LTV chuẩn | Multi-select | Tất cả | Filter theo normalized source group |
| 4 | Kênh nguồn chi tiết | Multi-select | Tất cả | Drill-down trong nhóm nguồn chuẩn |
| 5 | Nhóm dịch vụ khởi đầu | Multi-select | Tất cả | Filter theo initial_service_group |
| 6 | Trạng thái nguồn | Single-select | Tất cả | Tự động, Chỉnh tay, Chưa xác định |
| 7 | Tải xuống | QBtn | Disabled khi loading | Export đúng dataset đang hiển thị |
| 8 | Cấu hình mapping | QBtn secondary | Hidden nếu không phải Admin/IT | Mở SCR-02 |
| 9 | Chạy backfill | QBtn secondary | Hidden nếu không phải Admin/IT | Trigger job backfill, có confirm modal |
Interaction Behavior Contract
| Hành vi | Contract |
|---|---|
| Filter apply | Date range và select filter apply ngay sau khi user chốt giá trị; toàn bộ cards, aggregate tabs, customer table và data quality refetch theo cùng một committed filter state |
| Dirty state | SCR-01 là màn read-only nên không có dirty state; thay đổi filter không yêu cầu Lưu |
| Async update | Khi filter đổi, request cũ bị bỏ qua nếu response về muộn; mỗi block show skeleton/error riêng nhưng giữ filter state |
| Export | Tải xuống dùng đúng committed filter state đang hiển thị; disabled khi đang loading hoặc đang tạo file export |
| Backfill | Click Chạy backfill phải mở confirm modal; sau confirm chỉ tạo job async, không optimistic update số liệu trước khi job hoàn tất |
Summary Cards
| Card | Ý nghĩa | Format |
|---|---|---|
| Tổng khách trong cohort | Tổng customer match filter | Integer |
| LTV trung bình | avg_ltv của tập khách lọc | VND |
| LTV trung vị | Median LTV của tập khách lọc | VND |
Tỷ lệ Chưa xác định | unknown / total | % |
| Case chỉnh tay | Số snapshot trạng thái manual_override | Integer |
Bảng tổng hợp quản trị
| Tab | Cột tối thiểu | Notes |
|---|---|---|
| Theo nguồn | Nhóm nguồn, Số khách, LTV TB, LTV median, Tổng LTV | Tab mặc định |
| Theo kênh | Kênh chi tiết, Nhóm nguồn, Số khách, LTV TB | Chỉ drill-down |
| Theo chi nhánh | Chi nhánh first paid, Số khách, LTV TB, Tỷ lệ unknown | Label phải ghi rõ first paid |
| Theo nhóm dịch vụ | Nhóm dịch vụ khởi đầu, Số khách, LTV TB, LTV median | Không được diễn giải như phân bổ full lifecycle |
Bảng khách hàng
| Cột | Format | Notes |
|---|---|---|
| Mã KH | Text | Clickable nếu đã có pattern detail |
| Tên khách hàng | Text | Hiển thị tên chuẩn hiện tại |
| SĐT | Text | Mask theo pattern report hiện có nếu cần |
| LTV chuẩn | VND | Align right |
| Ngày first paid | Datetime | Theo timezone Asia/Ho_Chi_Minh |
| Ngày last paid | Datetime | Theo timezone Asia/Ho_Chi_Minh |
| Chi nhánh first paid | Text | Không phải branch gần nhất |
| Nhóm nguồn LTV chuẩn | Badge/text | Ví dụ Quảng cáo trả phí |
| Kênh nguồn chi tiết | Text | Ví dụ Facebook Ads |
| Trạng thái nguồn | Badge | Tự động, Chỉnh tay, Chưa xác định |
| Mapping version | Text | Chỉ hiện cho role có quyền hoặc trong tooltip |
| Hành động | Icon button | Chỉnh tay nguồn chỉ hiện với Admin/IT |
States
| State | Hiển thị |
|---|---|
| Loading | Skeleton cho cards + bảng tổng hợp + bảng khách hàng |
| Empty | Không có khách hàng phù hợp với bộ lọc hiện tại |
| Error | Đã xảy ra lỗi. Vui lòng thử lại. + nút Thử lại |
| No permission | Ẩn tab hoặc route guard theo pattern report hiện có |
Lifecycle UI Mapping
| Object | State | UI hiển thị | CTA cho phép |
|---|---|---|---|
| Backfill job | queued | Badge Đang chờ xử lý ở khu data quality, chưa đổi số liệu report | Không auto rerun; cho phép xem job mới nhất |
| Backfill job | running | Badge Đang xử lý, disable Chạy backfill để tránh duplicate job cùng scope ngay thời điểm đó | Không có optimistic data rewrite |
| Backfill job | done | Cập nhật summary_payload, unknown count và log gần nhất | Chạy backfill lại nếu user chủ động |
| Backfill job | failed | Error banner + thông điệp lỗi ngắn + CTA Chạy lại | Chạy lại tạo job mới |
B2.1) Semantics bắt buộc hiển thị trên UI
| Khu vực | Wording bắt buộc |
|---|---|
| Filter thời gian | Cohort first paid |
| Bảng theo chi nhánh | Chi nhánh first paid |
| Bảng theo dịch vụ | Nhóm dịch vụ khởi đầu |
| Tooltip LTV | LTV chuẩn là tổng actual revenue hợp lệ all-time của khách, sau giao dịch đảo chiều |
Không được dùng wording mơ hồ như
LTV theo chi nhánhhoặcLTV trong kỳnếu không có prefix semantics đi kèm.
B2.2) SCR-02: Drawer Cấu hình mapping nguồn LTV
Mục tiêu & CTA
| Job-to-be-done | Primary CTA | Secondary CTA | Khối nổi bật |
|---|---|---|---|
| Chuẩn bị một version mapping đủ an toàn để publish cho khách mới và future snapshot | Publish version | Lưu nháp, Clone từ version đang publish, Đóng | Rule grid + preview runtime + publish safety |
Layout
text
┌─ Cấu hình mapping nguồn LTV ───────────────────────────────────────────────────────┐
│ Version [v2026.04.21-draft ▼] [Clone version đang publish] [Tạo version mới] │
│ Effective from [dd/mm/yyyy] [Effective to] [Status: draft] │
├────────────────────────────────────────────────────────────────────────────────────┤
│ Raw source │ Nhóm nguồn chuẩn │ Kênh chi tiết │ Trạng thái │
│ Facebook │ Quảng cáo trả phí │ Facebook Ads │ Đã map │
│ Google Maps │ Kênh tự nhiên / Kênh số │ Google Maps │ Đã map │
│ Raw source mới │ [Chọn ▼] │ [Nhập/chọn] │ Chưa map │
├────────────────────────────────────────────────────────────────────────────────────┤
│ Preview runtime: đã map 92/100 raw source | chưa map 8 | sample label sau publish │
│ [Xem only raw source chưa map] [Đi tới report để chạy backfill sau khi publish] │
├────────────────────────────────────────────────────────────────────────────────────┤
│ [Đóng] [Lưu nháp] [Publish version] │
└────────────────────────────────────────────────────────────────────────────────────┘Setup Navigator
| Bước | Người dùng làm gì | Output |
|---|---|---|
| 1 | Chọn version đang publish để clone hoặc tạo version draft mới | Có draft để chỉnh mà không đụng version đang live |
| 2 | Nhập effective_from, effective_to, notes | Draft có effective window rõ ràng |
| 3 | Map raw source chưa chuẩn hóa sang Nhóm nguồn LTV chuẩn + Kênh nguồn chi tiết | Rule grid hoàn chỉnh |
| 4 | Xem preview runtime và cảnh báo Chưa map | Biết version còn chỗ hở nào trước khi publish |
| 5 | Publish version | Draft thành published, hiển thị deeplink quay lại SCR-01 để chạy backfill nếu cần |
Screen Linking / Readiness
| Trigger | Deep link / next step | Kỳ vọng |
|---|---|---|
| Raw source chưa map trong SCR-01 | Mở SCR-02 với version draft hoặc version đang publish gần nhất | User không phải tự tìm màn cấu hình khác |
| Publish version thành công | CTA Quay lại report để chạy backfill về SCR-01 | Từ config sang runtime chỉ 1 bước |
| Đóng drawer khi chưa publish | Quay lại SCR-01 với filter giữ nguyên | Business tiếp tục đọc report ngay |
UI contract
- Chỉ
Admin/ITnhìn thấy CTA mở drawer. - Không cho sửa trực tiếp version đang
published; khi thay đổi phải tạo version mới hoặc clone version cũ. Publish versionphải có confirm text vì ảnh hưởng khách mới / rerun an toàn sau này.- Drawer phải hiển thị rõ version nào đang
published, version nào làdraft. - Drawer phải hiển thị số raw source
Chưa mapvà cảnh báo nếu draft chưa đủ điều kiện publish. - Sau publish phải nhắc rõ: version mới áp dụng cho khách mới / snapshot mới; snapshot cũ chỉ đổi khi
Admin/ITchạy backfill explicit.
Interaction Behavior Contract
| Hành vi | Contract |
|---|---|
| Save mode | Drawer dùng explicit save mode: chỉ Lưu nháp hoặc Publish version; không auto-save |
| Dirty state | Nếu user sửa draft rồi đóng drawer, hệ thống hỏi confirm Bạn có muốn bỏ thay đổi chưa lưu? |
| Validation | Publish fail thì giữ drawer mở, focus vào field lỗi đầu tiên và highlight các raw source chưa map |
| Clone flow | Clone version đang publish tạo record draft mới; không sửa trực tiếp record published |
| Self-serve ergonomics | Day-1 phải hỗ trợ clone toàn bộ version đang publish và filter only raw source chưa map để tenant nhiều dữ liệu không phải sửa từ đầu |
Fields
| Field | Type | Required | Notes |
|---|---|---|---|
| Mapping version code | Text | Yes | Ví dụ v2026.04.20 |
| Effective from | Date | Yes | Ngày hiệu lực |
| Effective to | Date | No | Null = còn hiệu lực |
| Status | Select | Yes | draft, published, archived |
| Raw source | Read-only source picker | Yes | Lấy từ master data/source hiện có |
| Nhóm nguồn LTV chuẩn | Select | Yes | Theo taxonomy đã khóa |
| Kênh nguồn chi tiết | Text/select | Yes | Tầng chi tiết |
| Ghi chú | Textarea | No | Dùng cho rule đặc biệt |
Runtime Preview & Publish Safety
| Block | Contract |
|---|---|
| Preview runtime | Hiển thị mapped_count, unmapped_count, 5 dòng sample output raw source -> nhóm nguồn -> kênh chi tiết của draft đang mở |
| Publish safety | Confirm modal bắt buộc nhắc rõ version mới không auto remap snapshot cũ, và muốn đổi lịch sử thì phải chạy backfill explicit |
| Effective date | Luôn hiển thị effective_from/effective_to trong preview để user thấy version sẽ áp dụng từ lúc nào |
| Return path | Sau publish hiện CTA Quay lại report để chạy backfill thay vì tự auto tạo job |
Lifecycle State-to-UI Mapping
| State | Editable? | CTA chính | CTA phụ | Ghi chú |
|---|---|---|---|---|
draft | Có | Publish version | Lưu nháp, Đóng | Dùng để soạn / sửa rule |
published | Không | Clone thành draft | Archive, Quay lại report để chạy backfill | Read-only, không edit inline |
archived | Không | Clone thành draft | Đóng | Chỉ để tra cứu / audit |
B2.3) SCR-03: Dialog Chỉnh tay nguồn gốc LTV
Mục tiêu & CTA
| Job-to-be-done | Primary CTA | Secondary CTA | Khối nổi bật |
|---|---|---|---|
| Sửa một case canonical source đặc biệt mà auto mapping không đủ đúng | Xác nhận | Hủy | Current source context + reason bắt buộc |
Layout
text
┌─ Chỉnh tay nguồn gốc LTV ─────────────────────────────────────┐
│ Khách hàng: Nguyễn Thị A │
│ LTV hiện tại: 18.000.000 │
│ Nguồn chuẩn hiện tại: Quảng cáo trả phí │
│ Kênh chi tiết hiện tại: Facebook Ads │
│ │
│ Nhóm nguồn mới [▼] │
│ Kênh chi tiết mới [▼] │
│ Lý do chỉnh [..............................................] │
│ │
│ [Hủy] [Xác nhận] │
└───────────────────────────────────────────────────────────────┘UI contract
- Chỉ
Admin/ITthấy action mở dialog. - Bắt buộc nhập
Lý do chỉnh. - Sau khi confirm, row phải hiển thị badge
Chỉnh tay. - Có link/tooltip xem
lịch sử chỉnh tay.
Interaction Behavior Contract
| Hành vi | Contract |
|---|---|
| Save mode | Submit theo kiểu pessimistic; dialog chỉ đóng khi API trả success |
| Dirty state | Nếu user đã đổi source/channel/reason mà bấm đóng, hiện confirm bỏ thay đổi |
| Validation | Nhóm nguồn mới, Kênh chi tiết mới, Lý do chỉnh là bắt buộc; lỗi hiển thị inline |
| Async update | Sau success refresh đúng row đang thao tác trong SCR-01, không reload full page |
B3) Notification / Feedback
| Event | Feedback |
|---|---|
| Apply filter | Không toast; block đang tải show skeleton theo từng khu vực |
| Export thành công | Browser download start + toast Đang chuẩn bị file tải xuống. |
| Export lỗi | Toast lỗi + giữ nguyên filter state để user thử lại |
| Chạy backfill thành công | Toast Đã tạo job backfill. Kết quả sẽ cập nhật sau khi xử lý xong. + badge job ở data quality |
| Chạy backfill lỗi | Error toast, không đổi số liệu hiện tại, giữ CTA Chạy lại |
| Lưu nháp mapping thành công | Toast Đã lưu nháp version mapping. |
| Publish mapping version thành công | Toast Đã publish version mapping mới. + success banner kèm CTA quay lại report |
| Publish mapping validation fail | Inline error tại field/rule chưa map + focus vào lỗi đầu tiên |
| Chỉnh tay nguồn thành công | Toast Đã cập nhật nguồn gốc LTV chuẩn cho khách hàng. + row badge Chỉnh tay |
| Chỉnh tay nguồn lỗi | Inline validation + giữ dialog mở để sửa |
B4) Permission Matrix
| Role / capability | Xem tab LTV | Export | Mở config mapping | Publish mapping version | Chạy backfill | Chỉnh tay nguồn |
|---|---|---|---|---|---|---|
bod, hr_leader, it_leader / role được cấp report | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
Admin/IT | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Role khác không có report role | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
Phase 1 seed mặc định cho quyền xem tab/report là
bod,hr_leader,it_leader. Nếu hệ thống đang dùngreport_rolechi tiết hơn, FE bám theo quyền backend trả về. UI không disable nút; không có quyền thì ẩn.
B5) State Matrix
| Screen | Loading | Empty | Error | Partial |
|---|---|---|---|---|
| SCR-01 Cards + summary | Skeleton | — | Retry | Nếu 1 widget fail, widget đó show error riêng |
| SCR-01 Customer table | Table skeleton | Empty state | Error state + retry | Giữ filter state |
| SCR-02 Mapping drawer | Skeleton table | Chưa có rule mapping trong version này | Error banner | Cho phép reload |
| SCR-03 Override dialog | Button loading | N/A | Inline validation + toast | Không đóng dialog khi fail |
B6) Analytics Events
| Event | Trigger | Payload tối thiểu |
|---|---|---|
ltv_report_viewed | Mở tab SCR-01 | user, role, default filters |
ltv_filter_applied | Apply filter | date_range, branch_count, source_group_count |
ltv_export_clicked | Click export | current filters |
ltv_mapping_drawer_opened | Click Cấu hình mapping | current version |
ltv_mapping_version_published | Publish version | version_code |
ltv_backfill_triggered | Confirm backfill | version_code, scope |
ltv_source_override_submitted | Confirm override | customer_id, old_group, new_group |
B7) Copy Text Dictionary
| Key | Text (VI) | Context |
|---|---|---|
page_title | LTV Phase 1 | Tab title |
filter_cohort_first_paid | Cohort first paid | Filter label |
filter_first_paid_branch | Chi nhánh first paid | Filter label |
filter_source_group | Nhóm nguồn LTV chuẩn | Filter label |
filter_source_channel | Kênh nguồn chi tiết | Filter label |
filter_initial_service_group | Nhóm dịch vụ khởi đầu | Filter label |
filter_source_status | Trạng thái nguồn | Filter label |
btn_export | Tải xuống | Primary action |
btn_mapping | Cấu hình mapping | Admin/IT action |
btn_backfill | Chạy backfill | Admin/IT action |
status_auto | Tự động | Source status |
status_manual | Chỉnh tay | Source status |
status_unknown | Chưa xác định | Source status |
empty_customer_table | Không có khách hàng phù hợp với bộ lọc hiện tại | Empty state |
mapping_publish_confirm | Publish version mapping mới sẽ áp dụng cho khách mới và các lần backfill hợp lệ sau này. Bạn có chắc chắn muốn tiếp tục? | Confirm modal |
B8) Tooltip Dictionary
| Element | Tooltip text | Điều kiện hiện |
|---|---|---|
| LTV chuẩn | Tổng actual revenue hợp lệ all-time của khách sau giao dịch đảo chiều | Hover icon cạnh metric |
| LTV trung vị | 50% khách trong tập hiện tại có LTV thấp hơn hoặc bằng giá trị này, 50% còn lại cao hơn hoặc bằng giá trị này | Hover icon cạnh card LTV trung vị |
Tỷ lệ Chưa xác định | Tỷ lệ khách trong tập lọc hiện tại chưa có đủ bằng chứng để chốt Nguồn gốc LTV chuẩn; đây là output hợp lệ, không tự động xem là lỗi hệ thống | Hover icon cạnh card Tỷ lệ Chưa xác định |
| Case chỉnh tay | Số khách trong tập lọc hiện tại đã được Admin/IT chỉnh tay canonical source và có audit log | Hover icon cạnh card Case chỉnh tay |
| Cohort first paid | Bộ lọc này chọn khách theo ngày thanh toán hợp lệ đầu tiên, không cắt phần LTV all-time | Hover icon cạnh filter |
| Chi nhánh first paid | Chi nhánh phát sinh thanh toán hợp lệ đầu tiên của khách | Hover icon cạnh bảng theo chi nhánh |
| Nhóm dịch vụ khởi đầu | Nhóm dịch vụ của giao dịch first paid, không phải mọi dịch vụ khách từng mua | Hover icon cạnh bảng theo dịch vụ |
Trạng thái nguồn = Tự động | Canonical source được hệ thống chốt từ evidence hiện có theo mapping version, không có thao tác chỉnh tay sau đó | Hover tại badge Tự động |
Trạng thái nguồn = Chỉnh tay | Canonical source đã được người có quyền override thủ công; xem audit để biết ai sửa và lý do | Hover tại badge Chỉnh tay |
Trạng thái nguồn = Chưa xác định | Hệ thống chưa có đủ bằng chứng an toàn để gán source chuẩn; khách vẫn được giữ trong report để business nhìn đúng chất lượng dữ liệu | Hover tại badge Chưa xác định |
| Mapping version | Version rule map raw source -> normalized source đã dùng cho snapshot | Hover tại cột version |
| Effective from | Thời điểm version bắt đầu được dùng cho khách mới hoặc snapshot mới sau khi publish | Hover icon cạnh field Effective from |
| Effective to | Nếu để trống, version có hiệu lực cho đến khi có version khác thay thế hoặc bị archive | Hover icon cạnh field Effective to |
| Preview runtime | Preview này chỉ cho thấy số raw source đã map/chưa map và sample output của draft hiện tại; không tự rewrite snapshot lịch sử | Hover icon cạnh block preview ở SCR-02 |
| Publish version | Publish chỉ mở hiệu lực cho version mới. Snapshot cũ chỉ thay đổi khi Admin/IT chạy backfill explicit | Hover icon hoặc confirm modal cạnh CTA Publish version |
| Chạy backfill | Tạo một job explicit để tính lại snapshot theo scope đã chọn; không cập nhật optimistic ngay lúc bấm nút | Hover icon cạnh CTA Chạy backfill |
Backfill job = Đang chờ xử lý | Job đã được tạo nhưng worker chưa nhận xử lý; số liệu report hiện tại chưa đổi | Hover tại badge Đang chờ xử lý |
Backfill job = Đang xử lý | Job đang tính snapshot và data quality; tránh chạy thêm job trùng scope ở cùng thời điểm | Hover tại badge Đang xử lý |
Backfill job = Hoàn tất | Job đã ghi xong snapshot mới và summary_payload; report có thể đã phản ánh dữ liệu mới | Hover tại badge Hoàn tất hoặc log job |
Backfill job = Thất bại | Job lỗi và chưa tạo được kết quả cuối; cần xem log lỗi rồi Chạy lại nếu cần | Hover tại badge Thất bại hoặc error banner |
| Lý do chỉnh | Ghi ngắn gọn bằng chứng hoặc bối cảnh business khiến case này phải override; nội dung này được lưu vào audit log | Hover icon cạnh field Lý do chỉnh trong SCR-03 |
B8.1) Responsive + Accessibility Rules
| Screen | Responsive rules | Accessibility / keyboard |
|---|---|---|
| SCR-01 | <= 1280px: summary cards wrap 2 hàng; aggregate tabs cho phép horizontal scroll. <= 768px: filter bar stack theo cột, customer table dùng horizontal scroll/sticky first actions | Tabs phải đi được bằng keyboard, icon tooltip có label đọc được, nút Chỉnh tay nguồn phải có accessible name theo customer row |
| SCR-02 | Tablet/mobile mở drawer full-height, footer sticky để luôn thấy Lưu nháp / Publish version, preview chuyển xuống dưới rule grid | Focus trap trong drawer, Esc chỉ đóng khi không có dirty state, field lỗi đầu tiên được focus sau validate fail |
| SCR-03 | <= 768px dialog thành full-screen sheet, CTA cố định ở footer | Focus trap, Enter không submit khi reason còn trống, confirm button phải có label rõ Xác nhận chỉnh tay nguồn gốc LTV |
B9) Edge Cases
| Case | Expected UI behavior |
|---|---|
| Khách không có source đủ chắc | Hiển thị Chưa xác định, không tự suy diễn |
| Khách bị override thủ công | Badge Chỉnh tay, có tooltip lý do gần nhất |
| Mapping version mới đã publish nhưng snapshot cũ không đổi | Row cũ vẫn giữ version cũ |
| User chọn kỳ không có khách | Cards = 0 / —, bảng empty state rõ ràng |
| Job backfill đang chạy | Hiện badge/trạng thái Đang xử lý ở khu data quality hoặc job status |