Skip to content

Quyết định thiết kế (ADR)

TÓM TẮT

Tài liệu ghi lại các quyết định kiến trúc quan trọng, bối cảnh tại thời điểm quyết định, và trade-offs được chấp nhận.

ADR-001: Frontend đọc trực tiếp từ Supabase

Ngày: 2025-Q4
Trạng thái: Đang dùng

Bối cảnh: Cần giải quyết real-time data display cho dashboard mà không cần pass qua backend Python.

Quyết định: Frontend React kết nối trực tiếp Supabase JS SDK để đọc transactions và forecast results. Backend Python chỉ ghi ML results.

Hệ quả:

  • ✅ Tốc độ đọc nhanh, real-time subscriptions
  • ✅ Giảm tải backend — Python chỉ lo ML
  • ❌ Logic query nằm phân tán ở cả frontend lẫn backend
  • ❌ RLS policy phải cấu hình cẩn thận

ADR-002: LightGBM Two-Stage Segmented Model

Ngày: 2026-01
Trạng thái: Đang dùng (thay thế cho Prophet + XGBoost ensemble cũ)

Bối cảnh: E-commerce fulfillment có intermittent demand — nhiều ngày volume = 0, sau đó spike đột ngột. Mô hình single-stage không xử lý tốt.

Quyết định: Two-stage approach:

  1. Stage 1 — Day Classifier: LightGBM phân loại ngày thành 5 segments (zero/low/mid/high/extreme)
  2. Stage 2 — Segment Regressors: Mỗi segment có regressor riêng

Hệ quả:

  • ✅ Xử lý intermittent demand tốt (classifier lọc ngày zero)
  • ✅ Mỗi regressor tối ưu cho regime cụ thể
  • ❌ Pipeline phức tạp hơn (train 1 classifier + N regressors)
  • ❌ Threshold tuning giữa segments cần calibrate

ADR-003: Hybrid Forecast Engine (Frontend + Backend)

Ngày: 2026-01
Trạng thái: Đang dùng

Bối cảnh: ML model chỉ retrain weekly. Giữa các lần retrain, cần forecast có tính "real-time" hơn.

Quyết định: Frontend có forecast engine riêng (forecastEngine.ts) sử dụng Holt-Winters + event calendar weights. ML results từ backend là overlay/supplement.

Hệ quả:

  • ✅ Forecast luôn available (không phụ thuộc backend uptime)
  • ✅ Real-time adjustment theo event calendar
  • Logic trùng lặp — cả frontend và backend đều có forecast logic
  • ❌ Kết quả có thể khác nhau giữa 2 engines

CẢI TIẾN ĐỀ XUẤT

Khi ML model đạt wMAPE < 15%, nên chuyển sang ML-primary với BAU fallback. Xem IMP-08.


ADR-004: Warehouse Config Hardcoded trong TypeScript

Ngày: 2025-Q4
Trạng thái: Đang dùng — cần cải tiến

Bối cảnh: 4 warehouses với configs phức tạp (UPH, headcount, tables, channel distributions). Ban đầu hardcode cho nhanh.

Quyết định: Hardcode warehouse configs trong workforcePlanningEngine.ts (lines 186-282) dưới dạng TypeScript constants.

Hệ quả:

  • ✅ Nhanh chóng triển khai
  • ❌ Thay đổi config = phải deploy lại frontend
  • ❌ DB config loaded nhưng thường bị override bởi hardcoded values

CẢI TIẾN ĐỀ XUẤT

Chuyển sang warehouse_configs table trong Supabase với versioning. Xem IMP-02.


ADR-005: Config Registry (Module-level Config Management)

Ngày: 2026-02
Trạng thái: Đang dùng

Bối cảnh: 21 loại config khác nhau (seasonal, dow, event weights...) nằm rải rác trong nhiều modules. Cần centralize.

Quyết định: Tạo configRegistry.ts làm single source of truth cho tất cả configs. Hỗ trợ:

  • In-memory defaults
  • Database override (per-warehouse)
  • Caching

Hệ quả:

  • ✅ Single source of truth
  • ✅ Dễ thay đổi config mà không sửa code
  • ✅ 82 tests đảm bảo backward compatibility
  • ❌ Thêm 1 abstraction layer

ADR-006: HashRouter thay vì BrowserRouter

Ngày: 2025-Q4
Trạng thái: Đang dùng

Bối cảnh: Cloudflare Pages hosting — SPA cần fallback routing.

Quyết định: Dùng HashRouter (/#/path) thay vì BrowserRouter (/path).

Hệ quả:

  • ✅ Không cần cấu hình server-side rewrites
  • ✅ Compatible với mọi static hosting
  • ❌ URL "xấu" hơn (có #)
  • ❌ SEO kém hơn (hash fragments không index)

ADR-007: GitHub Actions thay Railway cho Backend Cron

Ngày: 2026-02
Trạng thái: Đang dùng

Bối cảnh: Backend Python (forecast training) chỉ cần chạy weekly. Railway tốn $5/mo cho idle server.

Quyết định: Chuyển weekly training từ Railway Docker cron sang GitHub Actions workflow.

Hệ quả:

  • ✅ Chi phí $0 (2000 min/mo free)
  • ✅ Không cần maintain Docker + Server
  • ❌ Cold start mỗi lần chạy (install deps)
  • ❌ 6 giờ timeout limit

Tài liệu liên quan

BoxMe Forecast — Tài liệu kỹ thuật nội bộ