Skip to content

Test Checklist · BQ-Calibrated

~35 test case chia 7 nhóm (A → G). Mỗi TC có expected_value lấy trực tiếp từ data/calibration/2026Q1.json, reference_query để verify lại nếu cần, và automation (auto qua vitest / manual qua UI).

Pre-condition: npm run seed chạy thành công. Snapshot có:

  • 6 warehouses, 12 customers, 589 calendar days
  • ~16,779 historical orders (rng_seed=20260523 → deterministic)
  • 162 config values

Nhóm A · Cấu hình tham số (5 TC)

IDTestExpectedReferenceAutomation
A01Monthly factor 12 tháng đúng calibrationT1=0.95, T2=0.83, T11=1.55, T12=1.45calibration.monthly_factors_workload_adjustedauto: forecast.bq-calibrated.test.ts
A02Event multiplier 6 loại đúngNORMAL=1.0, MEGA=3.8, DOUBLE=2.0calibration.event_multipliersauto: same
A03Sửa monthly:11 từ 1.55 → 1.60Tạo ConfigValue version=2, version=1 is_current=false, audit rowSupabase MCP configService.test.tsmanual UI
A04Effective_from < hôm nayReject với error "effective_from must be future"configService validationmanual UI
A05Concurrent edit cùng keyOptimistic lock fail → toast "config đã thay đổi"Supabase RLSmanual (2 tab)

Nhóm B · Cấu hình định mức (4 TC)

IDTestExpectedReferenceAutomation
B01Đủ tổ hợp UPH (DEFAULT + KEY override)≥ 130 row UPH_NORMexpected-config-snapshot.json#counts.uph_norms_minauto: same
B02Lookup ưu tiên customer-specific → DEFAULTC-Store COSMETIC UPH ≠ DEFAULTwlu.bq-calibrated.test.tsauto
B03Thay UPH 1 ô + re-forecastwlu_per_order_minutes đổi inversecomputeWlu()manual UI
B04Missing combo (PG=ELECTRONICS, no override)Fallback DEFAULT_UPH=60, used_fallback=truecalculator.tsauto

Nhóm C · Forecast engine (6 TC)

IDTestExpectedReferenceAutomation
C01Forecast NORMAL wh_vn_hcm_01 × c_cstore_vn ngày thườngqty ∈ [2500, 5500], confidence highforecast-targets.json#T01auto
C02Forecast MEGA 11.11 wh_vn_hcm_03 × c_unicornqty ∈ [8k, 150k], low_confidence=true (sample=4)targets#T03auto
C03Forecast Tết wh_vn_hn_01 × c_cstore_vn 2026-02-17qty ∈ [0, 800]targets#T05auto
C04Forecast MID_MONTH wh_vn_hcm_01 × c_skinetiqqty ∈ [800, 2500]targets#T08auto
C05Customer thiếu history (TH × c_judydoll VN-only)low_confidence=true, fallbacktargets#T06auto
C06Fallback chain MEGA → DOUBLE_DAY → NORMALresolved_type updates correctlyaggregator.test.tsauto (đã có)

Nhóm D · Planner (6 TC)

IDTestExpectedReferenceAutomation
D01Planner load wh_vn_hcm_01 ngày NORMAL3 shift (45/42/13%), total = Σ shiftsplanner-scenarios.json#P01manual UI
D02Planner 11.11 MEGASpillover >30% sang ca sau + ngày sauP07manual UI
D03Override headcountratio recomputescreens-hiring-override.jsxmanual UI
D04Switch warehousestate reset, data load lạiroutermanual UI
D05Date range picker 14 ngàygrid 14 cột × 3 caUImanual UI
D06Hiring gap (workload/8h − current_headcount)Hiển thị đỏ nếu gap > 0hiring-overridemanual UI

Nhóm E · KAM submit + Review pipeline (5 TC)

IDTestExpectedReferenceAutomation
E01KAM submit override 11.11 c_cstore_vnstatus NEW, audit INSERTadjustmentService.test.tsauto + manual
E02Ops mở review → SEENstatus SEEN, seen_at setreviewService.test.tsauto
E03Accept overridestatus ACCEPTED, forecast cập nhật theo submitted_qtyreviewServiceauto
E04Reject overridestatus REJECTED, forecast giữ engine outputreviewServiceauto
E05Audit row INSERT-onlyUPDATE / DELETE bị Supabase rejectRLS policymanual via Supabase MCP

Nhóm F · Báo cáo & Hiring override (6 TC)

IDTestExpectedReferenceAutomation
F01Báo cáo kho Q1 2026 wh_vn_hcm_01~1.18M đơn ±5%BQ Q1b row 3manual UI
F02Top customer leaderboardC-Store #1, Skinetiq #2, Judydoll #3customer_mapping[].net_sale_q1manual UI
F03MoM/YoY tính từ historyYoY % hiển thị (KEY customers)data-forecast.js#CUSTOMERS_EXTmanual UI
F04Hiring override theo khothêm/bớt số nhân sự theo khoUImanual UI
F05Export CSV báo cáoheader đầy đủ, ngày dạng ISOxlsx libmanual UI
F06Filter báo cáo theo channelSHOPEE / LAZADA / TIKTOK / WEBSITE / B2BCustomer.channelsmanual UI

Nhóm G · History import & data intake (3 TC)

IDTestExpectedReferenceAutomation
G01Import XLSX 1 ngàyupsert vào historical_orders, source='IMPORT_XLSX'historicalImportService.test.tsauto
G02Import API push (mock)source='IMPORT_API', audit có request_idhistoricalImportServiceauto
G03Manual entry single rowsource='MANUAL_ENTRY', audit before/afterservice + auditmanual UI

Nhóm tổng — Smoke tests (4 TC)

IDTestExpectedReferenceAutomation
Z01npm run seed không lỗiexit 0, snapshot có 6 wh + 12 cust + 162 configseed/index.tsauto: shell
Z02npm run typecheck0 errorstsconfig.app.jsonauto: shell
Z03npm run test (toàn bộ)138+ tests passvitestauto: shell
Z04npm run builddist/ tạo OK, no errorsviteauto: shell

Cách diễn giải expected_value

Tất cả expected_value đều derive từ data/calibration/2026Q1.json. Quy ước:

  • qty ±15% = qty trong khoảng [0.85·expected, 1.15·expected]
  • low_confidence = sample_size < 5 || fallback_used
  • Khi BQ data có thêm tháng / năm mới, chỉ cần re-run query + cập nhật 2026Q1.jsonnpm run seed. Test sẽ tự match khoảng mới (range trong fixture).

Khi test fail

  1. So sánh forecast_qty thực tế với expected range trong forecast-targets.json — confirm có thực sự fail không (ranges generous ±15%).
  2. Check rng_seed=20260523 không đổi (deterministic).
  3. Chạy git diff public/seed-snapshot.json — config_values count > 145?
  4. Nếu sửa calibration, update expected-config-snapshot.json để match.