Skip to content

v1.2 — 21/04/2026

Thay đổiSectionẢnh hưởng
Khóa mặc định implementation cho role seed phase 1 và đồng bộ ref sang PRD v1.2Header, B4FE, QA, PO
Bổ sung tooltip cho source status, data quality, lifecycle mapping/backfill và runtime previewB8FE, QA, PO
Đồng bộ traceability, bổ sung SaaS setup flow, lifecycle UI, interaction/action feedback, responsive+a11ySCR-01, SCR-02, SCR-03, B3, B8.1FE, QA, PO
Khởi tạo UI spec cho LTV Phase 1 theo PRD đã khóaToàn fileFE, 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

SCRTênRoute / PlacementMô tả
SCR-00Hub Chu kỳ khách hàng/r/reports/customer_cycle_report_groupMàn group report hiện có, được mở rộng thêm tab LTV Phase 1
SCR-01Tab LTV Phase 1Tab panel trong SCR-00Filter + summary cards + bảng tổng hợp + bảng khách hàng + data quality
SCR-02Drawer Cấu hình mapping nguồn LTVMở từ SCR-01, chỉ Admin/ITQuản lý mapping_version, rule map raw source -> normalized source
SCR-03Dialog Chỉnh tay nguồn gốc LTVMở từ row action ở SCR-01, chỉ Admin/ITOverride 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-donePrimary CTASecondary CTAKhối nổi bật
Đi vào đúng cụm report vòng đời khách và chọn tab LTVChọn tab LTV Phase 1Chuyển sang các tab cycle khác nếu cần đối chiếuTab 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 labelKeyGhi chú
1Tổng quancustomer_cycle_overviewExisting
2Chu kỳ mua hàngcustomer_cycle_purchaseExisting
3Chu kỳ khách hàngcustomer_cycle_customerExisting
4LTV Phase 1customer_cycle_ltvNew

UI contract

  • Không tạo card group mới ngoài customer_cycle_report_group.
  • LTV Phase 1 là tab mới trong màn group hiện có để user vẫn tìm report tại nhóm Chu 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_ltv vào registry/tab keys của module report.
  • FE bắt buộc cập nhật validTabs / logic localStorage hiện có để tab mới persist đúng khi reload.
  • FE bắt buộc thêm tab mới vào tabs map và QTabPanels của CustomerCycleReport.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ướcActorHành độngKết quả mong đợi
1Business / BODMở customer_cycle_report_group, chọn tab LTV Phase 1, xem cards + aggregate + bảng khách hàngHiểu cohort nào có LTV tốt, cohort nào đang nhiều Chưa xác định
2Admin/ITTừ 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
3Admin/ITClone / tạo draft, chỉnh rule mapping, xem preview runtime, publish versionCó version mới sẵn sàng cho khách mới mà không rewrite lịch sử cũ
4Admin/ITQuyết định có chạy backfill explicit hay khôngNế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
5Business / Admin/ITQuay 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ệtReport phản ánh đúng lifecycle mới và audit trail rõ

B1.3) Screen Dependency Map

ScreenPhụ thuộc vàoKết quả phụ thuộc
SCR-00Report registry + permission group hiện cóHiện đúng tab LTV Phase 1 trong customer_cycle_report_group
SCR-01Query overview/customers/data-quality; mapping version hiện hành; backfill job mới nhấtHiển thị đúng semantics, job status và số liệu canonical
SCR-02Dữ liệu version/rules + preview impactCho phép Admin/IT chỉnh draft, publish version và hiểu ảnh hưởng runtime
SCR-03Customer row context từ SCR-01 + audit/source snapshot hiện tạiOverride có kiểm soát cho từng case đặc biệt

B1.4) Screen Linking Matrix

FromActionToReturn path
SCR-00Chọn tab LTV Phase 1SCR-01Quay lại tab trước bằng tab strip
SCR-01Click Cấu hình mappingSCR-02Đóng drawer quay về SCR-01, giữ nguyên filter hiện tại
SCR-01Click Chạy backfillConfirm modal tại SCR-01Sau confirm ở lại SCR-01, hiện badge job và toast
SCR-01Click Chỉnh tay nguồn trên 1 rowSCR-03Submit/close dialog quay lại đúng row đang xem
SCR-02Publish version thành côngSCR-02 success stateCTA phụ Quay lại report để chạy backfill deeplink về SCR-01
SCR-03Submit override thành côngSCR-01Refresh 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-donePrimary CTASecondary CTAKhố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ệtTải xuốngCấu hình mapping, Chạy backfill, Chỉnh tay nguồn theo từng rowSummary 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

#ComponentTypeDefaultBehavior
1Cohort first paidDate range30 ngày gần nhất hoặc preset gần nhấtLọc theo first_paid_at, không cắt doanh thu all-time
2Chi nhánh first paidMulti-selectTất cảFilter theo first_paid_branch_id
3Nhóm nguồn LTV chuẩnMulti-selectTất cảFilter theo normalized source group
4Kênh nguồn chi tiếtMulti-selectTất cảDrill-down trong nhóm nguồn chuẩn
5Nhóm dịch vụ khởi đầuMulti-selectTất cảFilter theo initial_service_group
6Trạng thái nguồnSingle-selectTất cảTự động, Chỉnh tay, Chưa xác định
7Tải xuốngQBtnDisabled khi loadingExport đúng dataset đang hiển thị
8Cấu hình mappingQBtn secondaryHidden nếu không phải Admin/ITMở SCR-02
9Chạy backfillQBtn secondaryHidden nếu không phải Admin/ITTrigger job backfill, có confirm modal

Interaction Behavior Contract

Hành viContract
Filter applyDate 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 stateSCR-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 updateKhi 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
ExportTải xuống dùng đúng committed filter state đang hiển thị; disabled khi đang loading hoặc đang tạo file export
BackfillClick 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ĩaFormat
Tổng khách trong cohortTổng customer match filterInteger
LTV trung bìnhavg_ltv của tập khách lọcVND
LTV trung vịMedian LTV của tập khách lọcVND
Tỷ lệ Chưa xác địnhunknown / total%
Case chỉnh taySố snapshot trạng thái manual_overrideInteger

Bảng tổng hợp quản trị

TabCột tối thiểuNotes
Theo nguồnNhóm nguồn, Số khách, LTV TB, LTV median, Tổng LTVTab mặc định
Theo kênhKênh chi tiết, Nhóm nguồn, Số khách, LTV TBChỉ drill-down
Theo chi nhánhChi nhánh first paid, Số khách, LTV TB, Tỷ lệ unknownLabel 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 medianKhông được diễn giải như phân bổ full lifecycle

Bảng khách hàng

CộtFormatNotes
Mã KHTextClickable nếu đã có pattern detail
Tên khách hàngTextHiển thị tên chuẩn hiện tại
SĐTTextMask theo pattern report hiện có nếu cần
LTV chuẩnVNDAlign right
Ngày first paidDatetimeTheo timezone Asia/Ho_Chi_Minh
Ngày last paidDatetimeTheo timezone Asia/Ho_Chi_Minh
Chi nhánh first paidTextKhông phải branch gần nhất
Nhóm nguồn LTV chuẩnBadge/textVí dụ Quảng cáo trả phí
Kênh nguồn chi tiếtTextVí dụ Facebook Ads
Trạng thái nguồnBadgeTự động, Chỉnh tay, Chưa xác định
Mapping versionTextChỉ hiện cho role có quyền hoặc trong tooltip
Hành độngIcon buttonChỉnh tay nguồn chỉ hiện với Admin/IT

States

StateHiển thị
LoadingSkeleton cho cards + bảng tổng hợp + bảng khách hàng
EmptyKhô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

ObjectStateUI hiển thịCTA cho phép
Backfill jobqueuedBadge Đang chờ xử lý ở khu data quality, chưa đổi số liệu reportKhông auto rerun; cho phép xem job mới nhất
Backfill jobrunningBadge Đ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 jobdoneCập nhật summary_payload, unknown count và log gần nhấtChạy backfill lại nếu user chủ động
Backfill jobfailedError banner + thông điệp lỗi ngắn + CTA Chạy lạiChạy lại tạo job mới

B2.1) Semantics bắt buộc hiển thị trên UI

Khu vựcWording bắt buộc
Filter thời gianCohort first paid
Bảng theo chi nhánhChi nhánh first paid
Bảng theo dịch vụNhóm dịch vụ khởi đầu
Tooltip LTVLTV 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ánh hoặc LTV 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-donePrimary CTASecondary CTAKhối nổi bật
Chuẩn bị một version mapping đủ an toàn để publish cho khách mới và future snapshotPublish versionLưu nháp, Clone từ version đang publish, ĐóngRule 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ướcNgười dùng làm gìOutput
1Chọn version đang publish để clone hoặc tạo version draft mớiCó draft để chỉnh mà không đụng version đang live
2Nhập effective_from, effective_to, notesDraft có effective window rõ ràng
3Map raw source chưa chuẩn hóa sang Nhóm nguồn LTV chuẩn + Kênh nguồn chi tiếtRule grid hoàn chỉnh
4Xem preview runtime và cảnh báo Chưa mapBiết version còn chỗ hở nào trước khi publish
5Publish versionDraft thành published, hiển thị deeplink quay lại SCR-01 để chạy backfill nếu cần

Screen Linking / Readiness

TriggerDeep link / next stepKỳ vọng
Raw source chưa map trong SCR-01Mở SCR-02 với version draft hoặc version đang publish gần nhấtUser không phải tự tìm màn cấu hình khác
Publish version thành côngCTA Quay lại report để chạy backfill về SCR-01Từ config sang runtime chỉ 1 bước
Đóng drawer khi chưa publishQuay lại SCR-01 với filter giữ nguyênBusiness tiếp tục đọc report ngay

UI contract

  • Chỉ Admin/IT nhì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 version phả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 map và 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/IT chạy backfill explicit.

Interaction Behavior Contract

Hành viContract
Save modeDrawer dùng explicit save mode: chỉ Lưu nháp hoặc Publish version; không auto-save
Dirty stateNế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?
ValidationPublish fail thì giữ drawer mở, focus vào field lỗi đầu tiên và highlight các raw source chưa map
Clone flowClone version đang publish tạo record draft mới; không sửa trực tiếp record published
Self-serve ergonomicsDay-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

FieldTypeRequiredNotes
Mapping version codeTextYesVí dụ v2026.04.20
Effective fromDateYesNgày hiệu lực
Effective toDateNoNull = còn hiệu lực
StatusSelectYesdraft, published, archived
Raw sourceRead-only source pickerYesLấy từ master data/source hiện có
Nhóm nguồn LTV chuẩnSelectYesTheo taxonomy đã khóa
Kênh nguồn chi tiếtText/selectYesTầng chi tiết
Ghi chúTextareaNoDùng cho rule đặc biệt

Runtime Preview & Publish Safety

BlockContract
Preview runtimeHiể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 safetyConfirm 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 dateLuôn hiển thị effective_from/effective_to trong preview để user thấy version sẽ áp dụng từ lúc nào
Return pathSau publish hiện CTA Quay lại report để chạy backfill thay vì tự auto tạo job

Lifecycle State-to-UI Mapping

StateEditable?CTA chínhCTA phụGhi chú
draftPublish versionLưu nháp, ĐóngDùng để soạn / sửa rule
publishedKhôngClone thành draftArchive, Quay lại report để chạy backfillRead-only, không edit inline
archivedKhôngClone thành draftĐóngChỉ để 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-donePrimary CTASecondary CTAKhối nổi bật
Sửa một case canonical source đặc biệt mà auto mapping không đủ đúngXác nhậnHủyCurrent 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/IT thấ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 viContract
Save modeSubmit theo kiểu pessimistic; dialog chỉ đóng khi API trả success
Dirty stateNếu user đã đổi source/channel/reason mà bấm đóng, hiện confirm bỏ thay đổi
ValidationNhó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 updateSau success refresh đúng row đang thao tác trong SCR-01, không reload full page

B3) Notification / Feedback

EventFeedback
Apply filterKhông toast; block đang tải show skeleton theo từng khu vực
Export thành côngBrowser download start + toast Đang chuẩn bị file tải xuống.
Export lỗiToast lỗi + giữ nguyên filter state để user thử lại
Chạy backfill thành côngToast Đã 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ỗiError 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ôngToast Đã lưu nháp version mapping.
Publish mapping version thành côngToast Đã publish version mapping mới. + success banner kèm CTA quay lại report
Publish mapping validation failInline error tại field/rule chưa map + focus vào lỗi đầu tiên
Chỉnh tay nguồn thành côngToast Đã 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ỗiInline validation + giữ dialog mở để sửa

B4) Permission Matrix

Role / capabilityXem tab LTVExportMở config mappingPublish mapping versionChạy backfillChỉ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ùng report_role chi 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

ScreenLoadingEmptyErrorPartial
SCR-01 Cards + summarySkeletonRetryNếu 1 widget fail, widget đó show error riêng
SCR-01 Customer tableTable skeletonEmpty stateError state + retryGiữ filter state
SCR-02 Mapping drawerSkeleton tableChưa có rule mapping trong version nàyError bannerCho phép reload
SCR-03 Override dialogButton loadingN/AInline validation + toastKhông đóng dialog khi fail

B6) Analytics Events

EventTriggerPayload tối thiểu
ltv_report_viewedMở tab SCR-01user, role, default filters
ltv_filter_appliedApply filterdate_range, branch_count, source_group_count
ltv_export_clickedClick exportcurrent filters
ltv_mapping_drawer_openedClick Cấu hình mappingcurrent version
ltv_mapping_version_publishedPublish versionversion_code
ltv_backfill_triggeredConfirm backfillversion_code, scope
ltv_source_override_submittedConfirm overridecustomer_id, old_group, new_group

B7) Copy Text Dictionary

KeyText (VI)Context
page_titleLTV Phase 1Tab title
filter_cohort_first_paidCohort first paidFilter label
filter_first_paid_branchChi nhánh first paidFilter label
filter_source_groupNhóm nguồn LTV chuẩnFilter label
filter_source_channelKênh nguồn chi tiếtFilter label
filter_initial_service_groupNhóm dịch vụ khởi đầuFilter label
filter_source_statusTrạng thái nguồnFilter label
btn_exportTải xuốngPrimary action
btn_mappingCấu hình mappingAdmin/IT action
btn_backfillChạy backfillAdmin/IT action
status_autoTự độngSource status
status_manualChỉnh taySource status
status_unknownChưa xác địnhSource status
empty_customer_tableKhông có khách hàng phù hợp với bộ lọc hiện tạiEmpty state
mapping_publish_confirmPublish 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

ElementTooltip textĐiều kiện hiện
LTV chuẩnTổng actual revenue hợp lệ all-time của khách sau giao dịch đảo chiềuHover 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àyHover icon cạnh card LTV trung vị
Tỷ lệ Chưa xác địnhTỷ 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ốngHover icon cạnh card Tỷ lệ Chưa xác định
Case chỉnh taySố khách trong tập lọc hiện tại đã được Admin/IT chỉnh tay canonical source và có audit logHover icon cạnh card Case chỉnh tay
Cohort first paidBộ 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-timeHover icon cạnh filter
Chi nhánh first paidChi nhánh phát sinh thanh toán hợp lệ đầu tiên của kháchHover icon cạnh bảng theo chi nhánh
Nhóm dịch vụ khởi đầuNhóm dịch vụ của giao dịch first paid, không phải mọi dịch vụ khách từng muaHover icon cạnh bảng theo dịch vụ
Trạng thái nguồn = Tự độngCanonical 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 tayCanonical source đã được người có quyền override thủ công; xem audit để biết ai sửa và lý doHover tại badge Chỉnh tay
Trạng thái nguồn = Chưa xác địnhHệ 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ệuHover tại badge Chưa xác định
Mapping versionVersion rule map raw source -> normalized source đã dùng cho snapshotHover tại cột version
Effective fromThời điểm version bắt đầu được dùng cho khách mới hoặc snapshot mới sau khi publishHover icon cạnh field Effective from
Effective toNếu để trống, version có hiệu lực cho đến khi có version khác thay thế hoặc bị archiveHover icon cạnh field Effective to
Preview runtimePreview 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 versionPublish chỉ mở hiệu lực cho version mới. Snapshot cũ chỉ thay đổi khi Admin/IT chạy backfill explicitHover icon hoặc confirm modal cạnh CTA Publish version
Chạy backfillTạ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útHover 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 đổiHover 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ểmHover tại badge Đang xử lý
Backfill job = Hoàn tấtJob đã ghi xong snapshot mới và summary_payload; report có thể đã phản ánh dữ liệu mớiHover tại badge Hoàn tất hoặc log job
Backfill job = Thất bạiJob 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ầnHover tại badge Thất bại hoặc error banner
Lý do chỉnhGhi 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 logHover icon cạnh field Lý do chỉnh trong SCR-03

B8.1) Responsive + Accessibility Rules

ScreenResponsive rulesAccessibility / 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 actionsTabs 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-02Tablet/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 gridFocus 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 ở footerFocus 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

CaseExpected UI behavior
Khách không có source đủ chắcHiển thị Chưa xác định, không tự suy diễn
Khách bị override thủ côngBadge Chỉnh tay, có tooltip lý do gần nhất
Mapping version mới đã publish nhưng snapshot cũ không đổiRow cũ vẫn giữ version cũ
User chọn kỳ không có kháchCards = 0 / , bảng empty state rõ ràng
Job backfill đang chạyHiện badge/trạng thái Đang xử lý ở khu data quality hoặc job status