Appearance
Delivery Index — Kho vật tư
| Field | Value |
|---|---|
| Feature | Kho vật tư — Quản lý định lượng & giá vật tư dịch vụ (material-warehouse) |
| Version | 3.0 |
| Date | 2026-03-27 |
| Profile | L (Large) |
| Quality Bar | Pending |
Files
| # | File | Path | Audience |
|---|---|---|---|
| 1 | PRD | docs/features/material-warehouse/prd.md | PO, Tech Lead, all |
| 2 | UI Spec | docs/features/material-warehouse/ui-spec.md | UI/UX Designer, Frontend Dev |
| 3 | Dev Spec | docs/features/material-warehouse/dev-spec.md | Frontend Dev, Backend Dev |
| 4 | QA Test Plan | docs/features/material-warehouse/qa-test-plan.md | QA |
| 5 | Go-Live Checklist | docs/features/material-warehouse/go-live-checklist.md | Ops, Tech Lead, DevOps |
| 6 | Design Doc (reference) | docs/superpowers/specs/2026-03-26-material-warehouse-design.md | Tech Lead (deep context) |
| 7 | Handoff (this file) | docs/features/material-warehouse/handoff.md | All |
RACI
| Deliverable | PO/BA | FE Dev | BE Dev | QA | UI/UX | DevOps |
|---|---|---|---|---|---|---|
| DB Migration (6 bảng + 1 ALTER) | I | — | R/A | I | — | C |
| Hasura Metadata (8 files) | I | — | R/A | I | — | C |
| Event Trigger handlers (autoDeduct + autoReverse) | I | — | R/A | C | — | — |
| Low Stock Notification logic | I | — | R/A | C | — | — |
| SCR-01 Danh sách kho vật tư | I | R/A | — | C | C | — |
| SCR-02 Form cấu hình vật tư | I | R/A | — | C | C | — |
| SCR-03 Chi tiết + lịch sử | I | R/A | — | C | — | — |
| SCR-04 MaterialForm nâng cấp (ĐVT/giá) | I | R/A | — | C | C | — |
| SCR-05 Aggregate view nâng cấp | I | R/A | — | C | — | — |
| SCR-06 Nhập kho manual + Excel | I | R/A | C | C | — | — |
| SCR-07 Kiểm kê + điều chỉnh | I | R/A | — | C | C | — |
| Sidebar tài chính — nguồn mới | I | R/A | — | C | — | — |
| Cảnh báo tồn kho trên subtask form | I | R/A | — | C | — | — |
| Batch table + FIFO logic + Cron HSD | I | — | R/A | C | — | — |
| Batch UI (nhập kho mở rộng + danh sách lô) | I | R/A | — | C | C | — |
| SCR-08 Form chuyển kho (branch → material warehouse) | I | R/A | C | C | C | — |
| Update SCR-01: nút [★ Chuyển kho] + [Nhập tay] | I | R/A | — | C | — | — |
| Transfer action + event trigger (BE) | I | — | R/A | C | — | — |
| QA Testing (85 TCs) | C | C | C | R/A | — | — |
| Deploy staging | I | C | C | A | — | R |
| Deploy production | A | I | I | C | — | R |
Timeline
| Milestone | Target | Owner | Dependency | Output |
|---|---|---|---|---|
| M1: DB Migration + Hasura metadata (test env) | T+4d | BE Dev | — | 6 bảng, 1 ALTER, 8 Hasura files, event trigger + cron registered |
| M2: Event triggers (autoDeduct FIFO + autoReverse + notification) | T+8d | BE Dev | M1 | Go handlers: FIFO deduct logic, batch split, cron expiry check tested on staging |
| M3: SCR-01 + SCR-02 + SCR-03 (Kho vật tư CRUD) | T+11d | FE Dev | M1 | Danh sách, form cấu hình, chi tiết + lịch sử |
| M4: SCR-06 + SCR-07 (Nhập kho batch + Kiểm kê) | T+14d | FE Dev | M1, M3 | Nhập tay (tạo lô), import Excel, kiểm kê điều chỉnh, danh sách lô |
| M5: SCR-04 + SCR-05 nâng cấp (ĐVT, giá, aggregate) | T+17d | FE Dev | M1, M2 | MaterialForm + aggregate view + sidebar tài chính |
| M5b: Transfer BE (action + event trigger) | T+12d | BE Dev | M1, T6 | transferToMaterialWarehouse action, inventory_document_material_warehouse event trigger |
| M6: SCR-08 Transfer + SCR-01 buttons | T+19d | FE Dev | M1, M5b | SCR-08 form chuyển kho, SCR-01 nút [★ Chuyển kho] + [Nhập tay] |
| M7: QA Testing | T+25d | QA | M2, M3, M4, M5, M5b, M6 | 85 TCs executed, bugs fixed |
| M8: Deploy production | T+29d | DevOps | M7 pass + Sign-off | Production live |
Critical path: M1 → M2 → M5 → M7 → M8
Parallel work:
- M3 và M4 có thể làm song song (cùng depend M1, không depend nhau)
- M5 cần M2 (event triggers) cho test auto-deduct trên FE
- M5b (transfer BE) có thể song song với M3/M4/M5, chỉ depend M1 + T6
- M6 (transfer FE) depend M5b, có thể song song với M5
Task Breakdown
Backend Tasks (T1-T11: ~11d)
| Task | Mô tả | Owner | Estimate | Dependency | Status |
|---|---|---|---|---|---|
| T1 | Migration create_material_warehouse — DDL + UNIQUE(branch_id) | BE Dev | 0.25d | — | [ ] Todo |
| T2 | Migration create_material_price_config — DDL + CHECK constraints + unique indexes | BE Dev | 0.5d | — | [ ] Todo |
| T3 | Migration create_material_usage_unit — DDL + UNIQUE(config_id, usage_unit_name) | BE Dev | 0.5d | T2 | [ ] Todo |
| T4 | Migration create_material_stock_movement — DDL + indexes + VIEW material_stock_balance | BE Dev | 0.5d | T1 | [ ] Todo |
| T5 | Migration ALTER project_task_material — thêm 10 cột (usage_unit, unit_price, amount, ...) | BE Dev | 0.25d | — | [ ] Todo |
| T6 | Hasura metadata — 7 files (4 bảng mới + view + update ptm + tables.yaml) + permissions | BE Dev | 1d | T1-T5 | [ ] Todo |
| T7 | Event trigger handlers — materialAutoDeduct (FIFO batch split) + materialAutoReverse + low stock notification | BE Dev | 4d | T6 | [ ] Todo |
| T7b | Migration create_material_batch — DDL + indexes (warehouse_id, product_id, status, expiry_date) + CHECK constraint | BE Dev | 0.5d | T1 | [ ] Todo |
| T7c | FIFO deduct logic — batch selection (oldest active first), split across batches, block if insufficient | BE Dev | 2d | T7, T7b | [ ] Todo |
| T7d | Cron material_batch_expiry_check — auto-lock expired batches + 90-day warning notification | BE Dev | 1d | T7b, T6 | [ ] Todo |
| T7e | Hasura metadata material_batch.yaml — permissions Admin/Manager | BE Dev | 0.5d | T7b | [ ] Todo |
Frontend Tasks (T8-T19b: ~15d)
| Task | Mô tả | Owner | Estimate | Dependency | Status |
|---|---|---|---|---|---|
| T8 | GraphQL fragments + mutations + queries cho 5 bảng mới → pnpm codegen | FE Dev | 0.5d | T6 | [ ] Todo |
| T9 | SCR-01: Trang danh sách Kho vật tư (route + page + table + search + branch dropdown) | FE Dev | 2d | T8 | [ ] Todo |
| T10 | SCR-02: Form cấu hình vật tư (giá, hao hụt, ĐVT, auto-calc giá) | FE Dev | 2d | T8 | [ ] Todo |
| T11 | SCR-03: Chi tiết vật tư + lịch sử giá + lịch sử movement (pagination) | FE Dev | 1.5d | T8 | [ ] Todo |
| T12 | SCR-06: Nhập kho manual (multi-row form + validation) | FE Dev | 1.5d | T8 | [ ] Todo |
| T12b | SCR-06: Nhập kho mở rộng — thêm fields lô: batch_code, purchase_price, expiry_date | FE Dev | 1d | T12 | [ ] Todo |
| T12c | Danh sách lô per sản phẩm — bảng lô với status badge, HSD, remaining_qty | FE Dev | 1d | T8, T7e | [ ] Todo |
| T13 | SCR-06b: Import Excel nhập kho (upload + preview + confirm) | FE Dev | 0.5d | T12 | [ ] Todo |
| T14 | SCR-07: Kiểm kê (bảng so sánh hệ thống vs thực tế + adjustment) | FE Dev | 1.5d | T8 | [ ] Todo |
| T15 | SCR-04: Nâng cấp MaterialForm — dropdown ĐVT, cột giá/thành tiền, snapshot logic | FE Dev | 2d | T8, T7 | [ ] Todo |
| T16 | SCR-05: Nâng cấp Aggregate view — cột giá + FORMULA-005 | FE Dev | 0.5d | T15 | [ ] Todo |
| T17 | Sidebar tài chính — thêm nguồn chi phí vật tư (FORMULA-005 + backward compat) | FE Dev | 1d | T15 | [ ] Todo |
| T18 | Cảnh báo tồn kho trên form subtask (badge đỏ + tooltip) | FE Dev | 0.5d | T8 | [ ] Todo |
| T19 | Permission integration — ẩn menu/cột theo role + branch scoping | FE Dev | 0.5d | T9-T18 | [ ] Todo |
Transfer Tasks — v3.0 (T21-T26: ~8.25d)
| Task | Mô tả | Owner | Estimate | Dependency | Status |
|---|---|---|---|---|---|
| T21 | BE: transferToMaterialWarehouse action handler — validate branch warehouse stock, unit conversion, lot selection FIFO, create movement pair (out branch + in material) | BE Dev | 2d | T6 | [ ] Todo |
| T22 | BE: inventory_document_material_warehouse event trigger — listen inventory_document insert (type=transfer_to_material), auto-create stock movement in material warehouse | BE Dev | 1.5d | T21 | [ ] Todo |
| T23 | BE: Add master_data entries — transfer behavior configs (DEC-D29, DEC-D30, DEC-D32) | BE Dev | 0.25d | T6 | [ ] Todo |
| T24 | FE: SCR-08 Transfer form page — branch selector, product search (reuse ProductLotNumberSelect), lot selection table, dual-input (qty + ĐVT quy đổi), submit + confirm dialog | FE Dev | 2.5d | T8, T21 | [ ] Todo |
| T25 | FE: Update SCR-01 — thêm nút [★ Chuyển kho] + [Nhập tay] trên toolbar, routing to SCR-08 / SCR-06 | FE Dev | 0.5d | T9, T24 | [ ] Todo |
| T26 | QA: Transfer test cases (TC-TRF-001→017, 17 TCs) — happy path, insufficient stock, unit conversion, lot FIFO, concurrent transfer, permission | QA | 1.5d | T22, T25 | [ ] Todo |
QA Tasks (T20: ~3d)
| Task | Mô tả | Owner | Estimate | Dependency | Status |
|---|---|---|---|---|---|
| T20 | Execute 64 test cases (16 nhóm gốc + pricing + config) + regression + bug verification | QA | 3d | T7e, T19 | [ ] Todo |
Tổng: ~33d
Notes
BE Dev Notes
- Concurrency: Event trigger
materialAutoDeductPHẢI dùngpg_advisory_xact_lock(hashtext(warehouse_id || product_id))— serialize per (warehouse, product) để tránh race condition running_balance - Immutable log:
material_stock_movementKHÔNG có update/delete permission trong Hasura. Sai → tạo movement mới điều chỉnh (BR-13) - Price precision:
NUMERIC(15,4)cho đơn giá nội bộ,BIGINTcho amount cuối (DEC-D01). Round 1 lần duy nhất ở amount - Reverse logic: Khi undo subtask done HOẶC cancel sau done → tạo movement
auto_reverse(KHÔNG dùngauto_deductcho reverse, DEC-D18) - Branch fallback: Query giá:
WHERE (branch_id = $bid OR branch_id IS NULL) AND effective_to IS NULL ORDER BY branch_id NULLS LAST LIMIT 1(BR-12) - Transfer action:
transferToMaterialWarehousePHẢI tạo movement pair đối xứng: 1 movementtransfer_outở branch warehouse + 1 movementtransfer_inở material warehouse trong cùng transaction (DEC-D29) - No approval flow: Transfer không cần duyệt (DEC-D31) — action thực hiện ngay khi submit
- Unit conversion: Khi transfer, quy đổi theo
material_price_config.source_quantity(đơn vị mua → stock unit), KHÔNG dùngto_stock_factor(usage unit → stock unit) - Lot selection: Transfer để user chọn lot thủ công theo PRD (DEC-D36), KHÔNG tự động chọn FIFO rồi mới override
FE Dev Notes
- Snapshot giá: Khi thêm vật tư vào subtask → copy unit_price, to_stock_factor, config_version_id tại thời điểm thêm. KHÔNG query lại giá khi mở form sửa (DEC-D05)
- Staff view: Ẩn cột Đơn giá + Thành tiền cho role Staff (KTV). Check
hasRole('staff')→ hide columns (DEC-D10) - Discrete validation: Nếu
is_discrete = true→ input SL chỉ chấp nhận số nguyên (BR-04) - Product disabled: Filter search + badge "Ngưng KD" — pattern tham khảo từ ServiceFormMaterial.tsx
- Auto-calc: Khi Admin sửa source_price / wastage_rate trên form cấu hình → usage_unit_price recalc realtime (BR-07). Dùng
computedhoặcwatchtrong Vue - Backward compat: Sidebar tài chính phải check cả
project_task_material.amount(mới) VÀinventory_document.capture(cũ) — FORMULA-005 - SCR-08 Transfer form: Reuse
ProductLotNumberSelectcomponent cho lot selection. Dual-input: hiển thị cả qty ĐVT gốc + qty ĐVT quy đổi, auto-calc khi nhập 1 bên (DEC-D33) - SCR-01 buttons: Thêm [★ Chuyển kho] (primary, icon star) + [Nhập tay] (secondary) trên toolbar. Ẩn [★ Chuyển kho] nếu chưa có branch warehouse nào (DEC-D30)
QA Notes
- Seed data: Chạy DS-001 → DS-006 trên test env trước khi bắt đầu test. Hoặc tạo bằng UI (option B)
- Formula verification: Nhóm TC-FML là critical — verify số liệu exact match (4 decimal)
- Race condition test (TC-EC-002): Cần 2 browser sessions đồng thời chuyển subtask done. Dùng 2 tab hoặc 2 người test
- Backward compat (TC-FI-002): Cần data cũ (inventory_document) trên test env. Hỏi DevOps nếu cần import
- Transfer test (TC-TRF-*): Cần branch warehouse có stock để test chuyển kho. Setup: tạo inventory_document nhập kho ≥ 3 sản phẩm, mỗi SP ≥ 2 lô
- Concurrent transfer (TC-TRF-012): 2 user cùng chuyển 1 SP, tổng vượt stock → 1 phải fail. Test bằng 2 browser sessions
Open Items
| ID | Item | Owner | Deadline | Status |
|---|---|---|---|---|
| OI-01 | UI Designer review wireframes (SCR-01 → SCR-07) | UI/UX Designer | T+3d | Open |
| OI-02 | QA review test plan + confirm seed data approach | QA Lead | T+3d | Open |
| OI-03 | DevOps verify migration strategy trên staging | DevOps | T+2d | Open |
| OI-04 | Confirm Excel import template format (column headers, sample file) | PO/BA + FE Dev | T+5d | Open |
| OI-05 | Confirm notification channel (chỉ in-app hay cả SMS/Zalo?) | PO/BA | T+3d | Open |
| OI-06 | PO quyết định Phase 1 hay 1.5 cho nút "Thay thế vật tư" | PO/BA | T+5d | Open |
| OI-07 | Data cleanup kho chính (DEC-D35) — song song, không block go-live | DevOps + BE Dev | T+10d | Open |
| OI-08 | UI Designer review wireframe SCR-08 Transfer form | UI/UX Designer | T+5d | Open |
Sign-off Status
| Domain | Reviewer | Role | Status | Date |
|---|---|---|---|---|
| PRD & Business Rules | PO/BA | Product Owner | [ ] Pending | — |
| Design Doc | Tech Lead | Tech Lead | [ ] Pending | — |
| Frontend (SCR-01 → SCR-08) | FE Lead | Frontend Dev | [ ] Pending | — |
| Backend (DB + Hasura + Triggers) | BE Lead | Backend Dev | [ ] Pending | — |
| QA Test Plan (81 TCs) | QA Lead | QA | [ ] Pending | — |
| QA Execution (Exit Criteria met) | QA Lead | QA | [ ] Pending | — |
| Go-Live Checklist | DevOps | DevOps | [ ] Pending | — |
| Final Go-Live Approval | PO/BA + Tech Lead | Final | [ ] Pending | — |
Acceptance Criteria (Final sign-off)
| # | Criteria | Verify by |
|---|---|---|
| 1 | Tạo kho vật tư per branch → UNIQUE constraint hoạt động | QA (TC-MW-001, TC-MW-002) |
| 2 | Cấu hình giá + hao hụt → FORMULA-001 tính đúng | QA (TC-PC-001, TC-PC-005) |
| 3 | Price versioning → giá cũ archive, snapshot subtask không thay đổi | QA (TC-PC-003, TC-PC-004) |
| 4 | Usage unit quy đổi + auto-calc giá → FORMULA-002 đúng | QA (TC-UU-001, TC-UU-003) |
| 5 | Nhập kho tay + Excel → tồn kho cập nhật đúng | QA (TC-SI-001, TC-SI-003) |
| 6 | Subtask material: snapshot giá, ĐVT, thành tiền → FORMULA-003/004 đúng | QA (TC-SM-001, TC-SM-003) |
| 7 | Auto-deduct khi done → running_balance đúng | QA (TC-AD-001) |
| 8 | Undo done / cancel sau done → reverse movement đúng | QA (TC-AD-003, TC-AD-005) |
| 9 | Kiểm kê → adjustment movement đúng | QA (TC-SK-002) |
| 10 | Cảnh báo tồn kho ≤ min_stock → notification + dedupe | QA (TC-AL-001, TC-AL-002) |
| 11 | Sidebar tài chính → FORMULA-005 đúng (mới + backward compat) | QA (TC-FI-001, TC-FI-002) |
| 12 | RBAC: Staff ẩn menu/giá, Manager branch-scoped, Admin full | QA (TC-PM-001 ~ TC-PM-003) |
| 13 | Race condition: pg_advisory_xact_lock → no data corruption | QA (TC-EC-002) |
| 14 | Tiền tour / Commission / Lương KHÔNG bị ảnh hưởng | QA (manual verify) |
| 15 | Performance: auto-deduct < 5s, list page < 500ms | QA (staging test) |
| 16 | Chuyển kho branch → material warehouse: tồn kho 2 bên cập nhật đúng, movement pair đối xứng | QA (TC-TRF-001, TC-TRF-002) |
| 17 | Unit conversion khi chuyển kho: quy đổi ĐVT đúng theo to_stock_factor | QA (TC-TRF-005) |
| 18 | Lot selection FIFO khi chuyển kho: chọn lô cũ nhất trước | QA (TC-TRF-007) |
| 19 | SCR-08: form chuyển kho hoạt động đúng (select branch, product, lot, qty) | QA (TC-TRF-001) |
| 20 | SCR-01: nút [★ Chuyển kho] + [Nhập tay] hiển thị đúng role | QA (TC-TRF-015, TC-PM-001~003) |
Không ảnh hưởng (reassurance cho team)
- Tiền tour / Commission / Lương: ZERO coupling — material_cost là field mới, không thay đổi logic tính tour_money
- Kho chính (kho chi nhánh): Kho vật tư kết nối với kho chi nhánh qua transfer (DEC-D29) — chỉ READ dữ liệu kho chi nhánh, KHÔNG sửa bảng/logic kho chi nhánh
- Order / Ecommerce: Không sửa order flow — sidebar tài chính chỉ THÊM 1 dòng mới
- Report modules: Không thay đổi — reports hiện tại không query material tables
- Flow giao việc hàng loạt: Không thay đổi
- Backend services khác: Chỉ sửa 1 service (crm-api hoặc project handler)
Changelog
| Version | Ngày | Thay đổi | Tác giả |
|---|---|---|---|
| 1.0 | 2026-03-26 | Khởi tạo Handoff: RACI, timeline 7 milestones, task breakdown T1-T20 (~23d), open items OI-01~05, sign-off, acceptance criteria | PO/BA + AI |
| 1.1 | 2026-03-27 | Sửa "9 cột" → "10 cột" (T5, HAS-06). Update TC count 46→49 (T20, RACI, Sign-off). +OI-06: PO quyết định Phase 1 hay 1.5 cho "Thay thế vật tư". Verify T1-T20 numbering OK. | PO/BA + AI |
| 2.0 | 2026-03-27 | Design v2 — Batch-based FIFO. RACI: +batch table/FIFO logic, +batch UI rows. DB migration 5→6 bảng. Hasura 7→8 files. Timeline: 20d→25d. BE tasks: +T7b (batch table), +T7c (FIFO logic, 2d), +T7d (cron HSD, 1d), +T7e (batch Hasura). FE tasks: +T12b (nhập kho mở rộng), +T12c (danh sách lô). QA: 49→60 TCs. Tổng effort: 23d→29d. Sign-off: update TC count. | PO/BA + AI |
| 2.1 | 2026-03-27 | QA TCs: 60→66. +TC-PRICE-001~004 (Two-Phase Pricing), +TC-CFG-001~002 (FR-017 import config). Sửa TC-SI-001~003 (stock-in → batch contract). FR traceability aligned 100% với PRD FR-001~021. | PO/BA |
| 3.0 | 2026-03-27 | Design v3 — Transfer from branch warehouse. DEC-D12 (kho độc lập) superseded → DEC-D29 (kết nối kho chi nhánh). +FR-022 (transfer branch→material). +SCR-08 (transfer form). +DEC-D29→D36 (8 decisions: transfer, dual-input, no approval, unit conversion, lot selection, data cleanup). BE tasks: +T21 (transferToMaterialWarehouse action, 2d), +T22 (event trigger, 1.5d), +T23 (master_data, 0.25d). FE tasks: +T24 (SCR-08, 2.5d), +T25 (SCR-01 buttons, 0.5d). QA: +T26 (TC-TRF-001→017, 17 TCs, 1.5d). Tổng QA: 64→81 TCs. Tổng effort: 29d→33d. Timeline: +M5b (transfer BE), +M6 (transfer FE), milestones renumbered M7/M8. RACI: +3 rows transfer. Acceptance criteria: +5 items (#16-20). Open items: +OI-07 (data cleanup), +OI-08 (SCR-08 wireframe review). | PO/BA + AI |