Skip to content

Database Schema

10 bảng chính, mọi bảng có RLS, audit log insert-only. Source: openspec/changes/wfp-mvp/supabase-schema.md.

1. ERD tổng quan

mermaid
erDiagram
    warehouses ||--o{ customer_warehouse : "operates at"
    customers  ||--o{ customer_warehouse : "delivered to"
    customer_warehouse ||--o{ historical_orders : "history"
    customer_warehouse ||--o{ forecast_adjustments : "request"
    customer_warehouse ||--o{ forecast_results : "computed"
    forecast_adjustments ||--o{ audit_log : "logs"
    forecast_results     ||--o{ audit_log : "logs"
    config_definitions ||--o{ config_values : "values"
    customers ||--o{ product_mix : "mix"
    product_groups ||--o{ product_mix : "in"
    warehouses ||--o{ uph_config : "per wh"
    product_groups ||--o{ uph_config : "per group"

Text mô tả: Trục chính là customer_warehouse (cặp KH × Kho) — mọi historical_orders, forecast_adjustments, forecast_results đều thuộc 1 cặp này. Config tham số tách bảng config_definitions + config_values. WLU phụ thuộc uph_config × product_mix.

2. Bảng chính (10)

#BảngMô tảInsert-only?
1warehousesDanh mục kho
2customersDanh mục khách
3customer_warehouseCặp KH × Kho (tier, active)
4product_groupsNhóm sản phẩm (NORMAL/HEAVY/...)
5product_mixMix theo khách × group × pk_type (%)
6uph_configUPH theo (warehouse, group, pk_type)
7historical_ordersĐơn lịch sử 90 ngày (raw)
8forecast_adjustmentsYêu cầu KAM (state machine)
9forecast_resultsOutput nightly job + audited_qty
10audit_logTrail mọi action✅ Yes
+config_definitions / config_valuesTham số mùa, event multipliers

3. Conventions

  • Mọi bảng có: id uuid pk default uuid_generate_v4(), created_at, updated_at, created_by uuid references auth.users
  • snake_case cho table + column
  • Index chuẩn trên (warehouse_id, customer_id, date) ở mọi bảng có 3 cột này
  • Migration: M{phase}_{purpose}.sql (e.g. M1_core.sql)

4. RLS pattern

sql
-- ví dụ cho forecast_adjustments
alter table forecast_adjustments enable row level security;

create policy "planner reads all"
on forecast_adjustments for select
using ( is_planner() );

create policy "kam reads own"
on forecast_adjustments for select
using ( created_by = auth.uid() );

create policy "kam inserts own"
on forecast_adjustments for insert
with check ( created_by = auth.uid() );

create policy "planner updates state"
on forecast_adjustments for update
using ( is_planner() );

5. Audit log — insert only

sql
alter table audit_log enable row level security;

revoke update, delete on audit_log from anon, authenticated;

create policy "all authenticated can read audit"
on audit_log for select using ( auth.role() = 'authenticated' );

create policy "all authenticated can insert audit"
on audit_log for insert with check ( actor_id = auth.uid() );

audit_log schema (rút gọn):

CộtKiểuGhi chú
iduuidPK
entity_typetextadjustment, forecast_result, config, import
entity_iduuid
actiontextSTATE_CHANGE, QTY_EDIT, CONFIG_CHANGE, IMPORT
before / afterjsonbsnapshot
reasontextbắt buộc khi Δ > 30% (UI enforce)
actor_iduuid= auth.uid()
created_attimestamptz

6. State machine ràng buộc

Adjustment state machine enforce cả ở DB (CHECK constraint) lẫn ở engine:

sql
alter table forecast_adjustments
add constraint chk_state
check (state in ('NEW','SEEN','ACCEPTED','REJECTED'));

Transitions hợp lệ:

TừTới
NEWSEEN, ACCEPTED, REJECTED
SEENACCEPTED, REJECTED
ACCEPTED, REJECTEDterminal (KHÔNG sửa)

7. Index chính

sql
create index idx_hist_wh_cust_date
  on historical_orders (warehouse_id, customer_id, date desc);

create index idx_fc_wh_cust_date
  on forecast_results (warehouse_id, customer_id, date);

create index idx_adj_state_date
  on forecast_adjustments (state, target_date);

8. Seed data (demo)

Run npm run seed → load dist/seed-snapshot.json. Reset demo: npm run demo:reset.

Schema đầy đủ + tất cả migration: openspec/changes/wfp-mvp/supabase-schema.md

Tiếp: Data Flow · Deployment