API & Services Reference
WFP MVP không expose REST API public. Toàn bộ I/O đi qua Supabase client + service layer trong
src/services/. Trang này tham chiếu services chính.
Tổng quan service layer
| Service | File | Phụ trách |
|---|---|---|
adjustmentService | adjustmentService.ts | CRUD adjustment |
forecastService | forecastService.ts | Read forecast_results, trigger nightly |
reviewService | reviewService.ts | State machine NEW→SEEN→ACCEPTED/REJECTED |
reportService | reportService.ts | Aggregate cho warehouse/customer reports |
configService | configService.ts | Read/write config_values |
auditService | auditService.ts | Insert audit_log (insert-only) |
historicalImportService | historicalImportService.ts | Parse + upsert historical_orders |
customerService | customerService.ts | Customer CRUD + tier |
warehouseService | warehouseService.ts | Warehouse CRUD |
Convention chung
- Mọi service trả về typed result (Zod-validated khi cross boundary)
- Error: ném
Errorvới message tiếng Việt + code field - Audit: service tự ghi audit row khi có side-effect
- Auth:
supabase.auth.getUser()ở mọi insert/update
Hook layer (React Query)
| Hook | File | Service gọi |
|---|---|---|
useForecast | hooks/useForecast.ts | forecastService |
useAdjustments | hooks/useAdjustments.ts | adjustmentService |
useConfig | hooks/useConfig.ts | configService |
useCustomers | hooks/useCustomers.ts | customerService |
useWarehouses | hooks/useWarehouses.ts | warehouseService |
Engine functions (pure)
engine/forecast/generator.ts
ts
function generate(input: GenerateInput): GenerateOutput| Input field | Type | Note |
|---|---|---|
baseline | BaselineResolution | từ historical-aggregator |
monthly_multiplier | number ≥ 0 | từ config |
event_multiplier | number ≥ 0 | từ config |
| Output field | Type |
|---|---|
forecast_qty | number (rounded) |
raw_qty | number (pre-round) |
baseline_avg | number |
resolved_event_type | EventType |
fallback_used | boolean |
p85 | number | null |
sample_size | number |
engine/wlu/calculator.ts
| Function | Mô tả |
|---|---|
uphLookupFromMap(map, warehouseId) | Wrap UPH config thành lookup |
computeWlu(input) | WLU/đơn (phút) |
computeTotalWorkload(input) | Tổng phút nhân lực |
minutesToHeadcount(min, shift=480) | Headcount cho ca 8h |
Supabase tables (DDL summary)
Xem chi tiết trong Database. Liệt kê quick:
| Table | PK | FK chính |
|---|---|---|
warehouses | id | – |
customers | id | – |
customer_warehouse | id | customer_id, warehouse_id |
historical_orders | id | customer_warehouse_id |
forecast_adjustments | id | customer_warehouse_id |
forecast_results | id | customer_warehouse_id |
config_values | id | config_definitions.id |
audit_log | id | actor_id (auth.users) |
RPC (Postgres functions)
| RPC | Purpose |
|---|---|
rpc_run_nightly_forecast() | Trigger nightly compute (chạy bởi pg_cron) |
rpc_accept_adjustment(adjustment_id, audited_qty, reason) | State change + qty edit + 2 audit row atomically |
rpc_reject_adjustment(adjustment_id, reason) | State → REJECTED + audit |
Implementation đầy đủ: xem migration
M5_review.sqltrong supabase-schema.md.
Examples
ts
import { adjustmentService } from '@/services/adjustmentService';
await adjustmentService.submit({
customerCode: 'LOREAL_VN',
warehouseCode: 'HCM_01',
targetDate: '2026-06-15',
qty: 5500,
eventType: 'MID_MONTH',
note: 'Mid-Month sale, KOL livestream',
});
// → row state=NEW, audit_log insert SUBMIT_ADJUSTMENTts
import { reviewService } from '@/services/reviewService';
await reviewService.accept({
adjustmentId: '...',
auditedQty: 5200, // optional override
reason: 'Buffer xuống 5200, ổn hơn',
});
// → state=ACCEPTED, 2 audit rowsts
import { useForecast } from '@/hooks/useForecast';
const { data, isLoading } = useForecast({
warehouseId,
from: '2026-06-01',
to: '2026-06-14',
});