Appearance
PRD: Quản lý vật tư theo Subtask (Công việc con)
Feature slug: subtask-materialVersion: 1.0 Ngày: 2026-03-26 Profile: M (Medium) Tác giả: PO/BA Design doc: docs/superpowers/specs/2026-03-26-subtask-material-management-design.md
Executive Summary (TL;DR)
Chuyển quản lý vật tư từ task cha xuống subtask (công việc con) trong tab "Công Việc" của chi tiết khách hàng. Gồm 3 nhóm tính năng:
- MaterialForm trong subtask — Mỗi subtask có bảng vật tư riêng: auto-fill từ service config + tìm kiếm thêm + sửa/xóa. (FR-001 → FR-004, FR-008)
- Aggregate ở task cha — Bảng tổng hợp vật tư dự kiến từ tất cả subtask con, dùng flat query + denormalized data. (FR-005, FR-006)
- Fix UX — Sửa button label "Thêm vật tư" → "Thêm công việc" + delete confirm mention materials. (FR-007)
Tiền tour: KHÔNG bị ảnh hưởng (ZERO coupling confirmed). Kho: Chưa làm xuất kho (phase 2).
Milestones
| Milestone | Target Date | Owner | Status |
|---|---|---|---|
| M1: Migration + Hasura metadata deploy (test env) | T+2d | Backend Dev | Pending |
| M2: MaterialForm component + auto-fill | T+5d | Frontend Dev | Pending |
| M3: Tích hợp vào TaskForm + save flow | T+7d | Frontend Dev | Pending |
| M4: Aggregate view + backward compat | T+9d | Frontend Dev | Pending |
| M5: Fix button + delete confirm + readonly + disabled | T+10d | Frontend Dev | Pending |
| M6: QA testing | T+11d | QA | Pending |
| M7: Deploy production | T+12d | DevOps | Pending |
Trạng thái Sign-off
| Domain | Người review | Status | Ngày |
|---|---|---|---|
| Business (PO) | PO/BA | ✅ Approved | 2026-03-26 |
| UX/UI | — | Pending (cần UI Designer review wireframes) | — |
| Technical (Tech Lead) | Senior Tech Lead | ✅ Approved (với điều chỉnh R1-R5) | 2026-03-26 |
| QA | — | Pending (cần QA review test plan) | — |
| Ops | N/A (không có scheduler/infra changes) | N/A | — |
Action Items — Unblock Readiness
| ID | Item | Owner | Deadline | Status |
|---|---|---|---|---|
| AI-01 | UI Designer review wireframes (MaterialForm layout, badge "Ngưng KD") | UI/UX Designer | T+3d | Open |
| AI-02 | QA review test plan + confirm seed data approach | QA Lead | T+3d | Open |
| AI-03 | DevOps verify migration strategy trên staging | DevOps | T+2d | Open |
Pending Decisions
| ID | Quyết định | Recommendation | Owner | Deadline | Status |
|---|---|---|---|---|---|
| — | Tất cả PDs đã resolved thành DEC-B01→B05, DEC-U01→U04, DEC-T01→T05, DEC-Q01→Q02 | — | — | — | ✅ All Resolved |
RACI
| Deliverable | PO/BA | Frontend Dev | Backend Dev | QA | UI/UX | DevOps |
|---|---|---|---|---|---|---|
| prd.md | R/A | C | C | I | C | — |
| ui-spec.md | R | C | — | I | A | — |
| dev-spec.md | C | R | A | I | — | C |
| qa-test-plan.md | C | I | I | R/A | — | — |
| Migration | I | — | R/A | I | — | C |
| MaterialForm component | I | R/A | — | C | C | — |
| Aggregate view | I | R/A | — | C | — | — |
| Deploy staging | I | C | C | A | — | R |
| Deploy production | A | I | I | C | — | R |
R = Responsible, A = Accountable, C = Consulted, I = Informed
Backlog Phase 2
| ID | Item | Priority | Dependency |
|---|---|---|---|
| PH2-01 | Xuất kho thực tế: button "Xác nhận xuất kho" → requestMaterial action | High | Hệ thống kho ổn định |
| PH2-02 | SL thực tế: hiển thị từ order_materials sau xuất kho | High | PH2-01 |
| PH2-03 | So sánh SL dự kiến vs SL thực tế (chênh lệch) | Medium | PH2-02 |
| PH2-04 | Notification khi vật tư thay đổi trên subtask | Low | — |
| PH2-05 | Audit log cho material changes | Low | — |
| PH2-06 | Export báo cáo vật tư (Excel) | Low | — |
| PH2-07 | Partition bảng project_task_material nếu > 20M records | Medium | Monitor 6 tháng |
| PH2-08 | Optimistic locking cho concurrent editing | Low | Nếu phát sinh conflict |
Z) Decision Log
Decision Log LUÔN ĐẶT ĐẦU TIÊN. Mọi section downstream tham chiếu DEC-ID.
Z1 — Business Decisions
| ID | Quyết định | Lý do | Ngày | Status |
|---|---|---|---|---|
| DEC-B01 | Vật tư gắn ở cấp subtask, không phải task cha | Mỗi công việc con (subtask) trong spa sử dụng vật tư riêng biệt. VD: "Laser sắc tố" dùng serum, "Chăm sóc da" dùng mask. Gắn ở task cha không phản ánh thực tế. | 2026-03-26 | Locked |
| DEC-B02 | Auto-fill vật tư từ service config + cho phép tìm kiếm thêm mới | KTV tiết kiệm thời gian nhờ vật tư mẫu đã cấu hình sẵn, nhưng vẫn linh hoạt thêm vật tư ngoài danh sách. | 2026-03-26 | Locked |
| DEC-B03 | Task cha hiển thị aggregate vật tư từ tất cả subtask con | Manager cần nhìn tổng vật tư mà không phải click vào từng subtask. | 2026-03-26 | Locked |
| DEC-B04 | Chưa làm xuất kho (phase 2) | Hệ thống kho chưa hoạt động đúng. Ưu tiên ghi nhận vật tư dự kiến trên subtask trước. | 2026-03-26 | Locked |
| DEC-B05 | Vật tư nằm trong form subtask, không có button riêng ở bảng ngoài | Tránh confusion "thêm vật tư cho subtask nào?". Vật tư là thuộc tính của subtask. | 2026-03-26 | Locked |
Z2 — UX Decisions
| ID | Quyết định | Lý do | Ngày | Status |
|---|---|---|---|---|
| DEC-U01 | Fix button "Thêm vật tư" → luôn hiển thị "Thêm công việc" | Button cũ gây nhầm lẫn: label nói "Thêm vật tư" nhưng mở form tạo subtask. Ref: SubtaskTable.tsx:402. | 2026-03-26 | Locked |
| DEC-U02 | Delete confirm dialog mention số vật tư bị xóa | User cần biết xóa subtask sẽ CASCADE xóa vật tư đi kèm để tránh mất dữ liệu. | 2026-03-26 | Locked |
| DEC-U03 | MaterialForm readonly khi subtask done/canceled | Không cho sửa vật tư trên công việc đã hoàn thành hoặc đã hủy. | 2026-03-26 | Locked |
| DEC-U04 | Product bị disable → badge "Ngưng KD" | Vật tư đã lưu trước đó mà product sau này bị disable → vẫn hiển thị nhưng đánh dấu rõ ràng. | 2026-03-26 | Locked |
Z3 — Technical Decisions
| ID | Quyết định | Lý do | Ngày | Status |
|---|---|---|---|---|
| DEC-T01 | Tạo bảng project_task_material (project DB) thay vì dùng bảng order | Tách "dự kiến" vs "đã xuất kho". Không mix data vào order khi kho chưa đúng. | 2026-03-26 | Locked |
| DEC-T02 | Denormalize product_name/sku/unit vào project_task_material | Giảm remote join cross-DB khi aggregate ở task cha. 5 subtask × 3 vật tư = 15 remote queries → 0. | 2026-03-26 | Locked |
| DEC-T03 | Flat query cho aggregate thay vì nested qua subtask | Tránh N+1 khi task cha có nhiều subtask con. 1 query trực tiếp vào project_task_material. | 2026-03-26 | Locked |
| DEC-T04 | Không thêm event trigger lên project_task | Bảng đã có 4 triggers + 25 relationships. Materials xử lý ở application layer. | 2026-03-26 | Locked |
| DEC-T05 | ON DELETE CASCADE trên FK task_id | Xóa subtask tự xóa materials. Không cần application-level cleanup. | 2026-03-26 | Locked |
Z4 — QA Decisions
| ID | Quyết định | Lý do | Ngày | Status |
|---|---|---|---|---|
| DEC-Q01 | Test backward compat: task cha có order_materials cũ vẫn hiển thị | Data cũ không được mất sau deploy. Cần verify cả 2 data source. | 2026-03-26 | Locked |
| DEC-Q02 | Test scale: insert 1000 materials trong 1 batch | Ước tính 15K-90K records/ngày. Verify performance không degrade. | 2026-03-26 | Locked |
A1) Blueprint
| Field | Value |
|---|---|
| Feature Name | Quản lý vật tư theo Subtask |
| Feature Slug | subtask-material |
| Type | Enhancement |
| Profile | M (Medium) |
| Platform | Web (diva-admin) |
| Module chính | Projects → TaskForm, TaskDetail |
| DB Domain | project |
| Related Services | Hasura Controller (metadata only) |
| Branch Scope | Via project → department → branch (existing) |
A2) Context — Tổng quan dễ hiểu
Vấn đề hiện tại
Trong tab "Công Việc" của chi tiết khách hàng, mỗi công việc cha (task) có nhiều công việc con (subtask). Mỗi subtask đại diện cho một bước điều trị cụ thể (VD: "Laser sắc tố", "Chăm sóc da cơ bản"). Tuy nhiên:
- Button sai chức năng: Nút "Thêm vật tư" thực chất mở form tạo subtask mới — gây nhầm lẫn cho nhân viên.
- Vật tư gắn sai cấp: Vật tư hiện gắn ở task cha, không phải subtask. Kỹ thuật viên không biết subtask nào dùng vật tư gì.
- Không có form nhập vật tư: Backend có sẵn action
requestMaterialnhưng không có UI gọi.
Hệ quả: KTV không ghi nhận được vật tư theo từng bước công việc. Manager không biết tổng vật tư cần dùng. Kho không kiểm soát được vật tư theo công việc.
Giải pháp
Chuyển vật tư xuống cấp subtask — mỗi subtask có danh sách vật tư riêng, auto-fill từ cấu hình dịch vụ, cho phép thêm mới. Task cha hiển thị bảng tổng hợp.
Từ không có cách ghi nhận vật tư theo subtask → mỗi subtask có bảng vật tư riêng, auto-fill + search, aggregate ở task cha.
Giao diện mô phỏng
Form tạo/sửa subtask (có thêm section vật tư):
| Field | Value |
|---|---|
| Tên công việc | BS - Laser sắc tố nám, đồi mồi |
| Người thực hiện | K, +1 |
| Ngày hết hạn | 26/03/2026 |
| Tiền tour | 500,000đ |
| # | Vật tư | Mã | ĐVT | SL | |
|---|---|---|---|---|---|
| 1 | Serum Laser X | SP001 | ml | 2 | [xóa] |
| 2 | Gel làm mát | SP042 | tube | 1 | [xóa] |
| [Tìm kiếm thêm vật tư...] |
Bảng tổng hợp ở task cha:
| # | Vật tư | Mã | ĐVT | SL dự kiến |
|---|---|---|---|---|
| 1 | Serum Laser X | SP001 | ml | 4 |
| 2 | Gel làm mát | SP042 | tube | 1 |
| 3 | Mask dưỡng da | SP018 | miếng | 2 |
Cách hoạt động — Tổng quan
Luồng:
Chọn subtask definition → Auto-fill vật tư mẫu → Sửa SL / Thêm mới → Lưu subtask + materials
↓
Task cha aggregate hiển thị tổng| Bước | Ai làm | Điều gì xảy ra | Dữ liệu |
|---|---|---|---|
| 1 | KTV | Mở form tạo/sửa subtask | — |
| 2 | Hệ thống | Auto-fill vật tư mẫu từ product_relation theo subtask definition | product_relation WHERE subtask_id = X |
| 3 | KTV | Chỉnh SL, xóa bớt, hoặc search thêm vật tư mới | MaterialForm state |
| 4 | KTV | Bấm Lưu | Insert project_task + Insert project_task_material[] |
| 5 | Hệ thống | Cập nhật bảng tổng hợp ở task cha | Flat query aggregate project_task_material |
Quy tắc cốt lõi:
| # | Quy tắc | Ví dụ |
|---|---|---|
| 1 | Mỗi subtask có 0-N vật tư, unique theo (task_id, product_id) | Subtask "Laser" có 3 vật tư, không có 2 dòng cùng product |
| 2 | Auto-fill chỉ lấy product chưa bị disable | Product "Serum cũ" bị disable → không xuất hiện trong auto-fill |
| 3 | Subtask done/canceled → readonly materials | Subtask "Hoàn thành" → không cho sửa/xóa/thêm vật tư |
| 4 | Xóa subtask → CASCADE xóa materials | Xóa subtask "Laser" → 3 materials tự xóa theo |
| 5 | Aggregate cộng dồn theo product_id | 2 subtask cùng dùng "Serum X" (2ml + 2ml) → tổng 4ml |
Ví dụ thực tế
Case 1 — Happy path: KTV tạo subtask với vật tư
| Khoản mục | Giá trị | Giải thích |
|---|---|---|
| Task cha | "Laser Q-switch tàn nhang" | Công việc chính cho khách Đỗ Thị Thu Trang |
| Subtask | "BS - Laser sắc tố nám" | Bước điều trị laser |
| Subtask definition | Đã cấu hình 2 vật tư mẫu | Từ service "Laser Q-switch" |
| Auto-fill | Serum Laser X (2ml), Gel làm mát (1 tube) | Tự điền khi chọn subtask definition |
| KTV thêm | Mask dưỡng da (1 miếng) | Search thêm từ danh sách sản phẩm |
| Kết quả lưu | 3 records trong project_task_material | task_id = subtask ID |
| Task cha aggregate | Serum 2ml, Gel 1 tube, Mask 1 miếng | Bảng tổng hợp cập nhật |
Case 2 — Edge case: Subtask đã hoàn thành, product bị disable
| Khoản mục | Giá trị | Ghi chú |
|---|---|---|
| Subtask status | done_branch | Đã hoàn thành |
| MaterialForm | Readonly mode | Không cho sửa SL, xóa, thêm mới |
| "Serum Laser X" | Bị disable sau khi lưu | Badge "Ngưng KD" hiển thị cạnh tên |
| Aggregate task cha | Vẫn tính "Serum Laser X" | Denormalized data vẫn giữ tên cũ |
Case 3 — Edge case: Subtask definition không có vật tư mẫu
| Khoản mục | Giá trị | Ghi chú |
|---|---|---|
| Subtask definition | "Chăm sóc da cơ bản" | Chưa cấu hình product_relation |
| Auto-fill | Trống (0 results) | Bảng vật tư empty |
| KTV | Search thêm "Mask dưỡng" (1 miếng) | Tự tìm kiếm thêm |
| Kết quả | 1 record trong project_task_material | Manual input |
Ai thấy gì
| Role | Thấy được | Không thấy | Lý do |
|---|---|---|---|
| Staff (KTV) | Vật tư trên subtask mình được assign/tạo + aggregate task cha | Vật tư subtask người khác (nếu không assign) | KTV chỉ cần biết công việc mình |
| Manager | Tất cả vật tư subtask trong project mình quản lý + aggregate | — | Manager cần nhìn tổng để review |
| Admin (IT Leader) | Tất cả | — | Full access |
| Call Center | Không thấy/sửa materials | MaterialForm ẩn | Call Center không liên quan vật tư |
Công thức tính (tóm tắt)
| Chỉ số | Công thức | Ghi chú |
|---|---|---|
| SL dự kiến (aggregate) | SUM(project_task_material.quantity) GROUP BY product_id WHERE task.parent_id = X | Cộng dồn từ tất cả subtask con |
| SL thực tế | Phase 2 — từ order_materials.product_supplyings khi xuất kho | Chưa implement |
Chi tiết kỹ thuật: xem FORMULA-001 trong dev-spec.md
Các tình huống đặc biệt
| Tình huống | Hệ thống xử lý |
|---|---|
| Product bị disable sau khi đã thêm vào materials | Vẫn hiển thị với badge "Ngưng KD". Denormalized data giữ tên/SKU cũ. |
| Product bị hard-delete (hiếm) | product_id orphaned nhưng denormalized fields vẫn hiển thị tên/SKU/unit. Không crash. |
| Xóa subtask cuối cùng → parent auto-done | CASCADE xóa materials → aggregate trống → bảng vật tư task cha empty. |
| 2 users sửa materials cùng lúc | Last-write-wins. Chấp nhận risk — tương đồng behavior hiện tại toàn hệ thống. |
| Task cha có cả order_materials cũ (trước deploy) và project_task_material mới | Hiển thị 2 bảng riêng: "VẬT TƯ DỰ KIẾN" (mới) + "VẬT TƯ (ĐÃ XUẤT KHO)" (cũ). |
| Subtask tạo từ manual board (automate=false) | MaterialForm vẫn hiển thị. Auto-fill không chạy (không có subtask definition). KTV tự search. |
Lộ trình triển khai
| Phase | Nội dung | Trạng thái |
|---|---|---|
| Phase 1 (hiện tại) | Bảng project_task_material, MaterialForm, auto-fill, aggregate, fix button, backward compat | In scope |
| Phase 2 (sau) | Xuất kho thực tế: button "Xác nhận xuất kho" → requestMaterial action → SL thực tế | Backlog |
| Phase 3 (sau) | Notification khi vật tư thay đổi, audit log, export báo cáo vật tư | Backlog |
Tại sao chia phase? Hệ thống kho chưa hoạt động đúng. Phase 1 giải quyết vấn đề cấp bách nhất (ghi nhận vật tư đúng subtask). Phase 2 chờ kho ổn định.
Giá trị mang lại
- KTV: Ghi nhận vật tư đúng cho từng bước công việc, auto-fill tiết kiệm thời gian, tìm kiếm thêm linh hoạt.
- Manager: Nhìn tổng vật tư dự kiến ở task cha mà không cần click từng subtask. Review nhanh hơn.
- Kho/Admin: Chuẩn bị cho phase 2 xuất kho chính xác theo subtask.
- Không ảnh hưởng: Tiền tour (ZERO coupling), commission, lương, report hiện tại, flow giao việc hàng loạt.
A3) Goals & Metrics
| Goal | Metric | Target |
|---|---|---|
| KTV ghi nhận vật tư đúng subtask | % subtask có materials (sau deploy) | > 50% subtask automatic board |
| Giảm nhầm lẫn UX | Số ticket/complaint liên quan "Thêm vật tư" | → 0 |
| Aggregate hiển thị đúng | SL dự kiến task cha = SUM subtask con | 100% chính xác |
A4) Personas
| Persona | Vai trò | Tần suất sử dụng | Nhu cầu chính |
|---|---|---|---|
| KTV (Kỹ thuật viên) | Thực hiện subtask, nhập vật tư | 5K-30K subtask/ngày (hệ thống) | Form nhanh, auto-fill, search dễ |
| Manager chi nhánh | Review công việc + vật tư | Hàng ngày | Aggregate view, không cần drill-down |
| Admin / IT Leader | Cấu hình, full access | Khi cần | Full visibility |
A5) Functional Requirements
FR-001: Thêm vật tư vào subtask (Ref: DEC-B01, DEC-B02, DEC-B05)
Mô tả: KTV có thể thêm vật tư vào subtask thông qua form tạo/sửa subtask.
AC:
- [ ] Khi mở form subtask (
isChild=true), hiển thị section "VẬT TƯ" với bảng editable - [ ] Bảng có cột: #, Vật tư (tên), Mã (SKU), ĐVT, SL (input number), Xóa (icon)
- [ ] Có thanh tìm kiếm "Tìm kiếm thêm vật tư..." để search product theo tên/SKU
- [ ] Khi lưu subtask → insert records vào
project_task_materialvớitask_id= subtask ID - [ ] Mỗi record lưu denormalized:
product_name,product_sku,product_unit - [ ]
UNIQUE(task_id, product_id)— không cho thêm cùng product 2 lần, nếu trùng thì upsert quantity
FR-002: Auto-fill vật tư từ service config (Ref: DEC-B02)
AC:
- [ ] Khi chọn subtask definition → query
product_relation WHERE subtask_id = selected_id AND related_product.disabled IS NOT TRUE - [ ] Map kết quả → fill vào bảng vật tư:
product_id,product_name,product_sku,product_unit,quantity - [ ] Nếu subtask definition không có
product_relation→ bảng trống, KTV tự search - [ ] Auto-fill chỉ chạy 1 lần khi chọn subtask definition, không chạy lại khi sửa form
FR-003: Sửa vật tư trên subtask (Ref: DEC-B01)
AC:
- [ ] Khi mở form sửa subtask → load
task_materialshiện có từ DB → hiển thị trong MaterialForm - [ ] KTV có thể: sửa SL (inline number input), xóa dòng (icon 🗑), thêm mới (search)
- [ ] Khi lưu → delete all
project_task_material WHERE task_id = subtask_id→ re-insert tất cả (simpler than upsert) - [ ] Hoặc: upsert (on_conflict update quantity/note) + delete removed items
FR-004: Readonly khi subtask done/canceled (Ref: DEC-U03)
AC:
- [ ] Khi subtask
status_idchứadone_hoặccanceled_→ MaterialForm ở chế độ readonly - [ ] Readonly: ẩn icon xóa, disable input SL, ẩn thanh search
- [ ] Vẫn hiển thị bảng vật tư để xem (không ẩn hoàn toàn)
FR-005: Aggregate vật tư ở task cha (Ref: DEC-B03, DEC-T03)
AC:
- [ ] Task cha hiển thị section "VẬT TƯ DỰ KIẾN" với bảng tổng hợp từ tất cả subtask con
- [ ] Dùng flat query:
project_task_material WHERE task.parent_id = parent_task_id - [ ] Cùng
product_id→ cộng dồnquantity - [ ] Cột: #, Vật tư, Mã, ĐVT, SL dự kiến
- [ ] Dùng denormalized fields (
product_name,product_sku,product_unit) — zero remote join
FR-006: Backward compatibility — data cũ (Ref: DEC-Q01)
AC:
- [ ] Task cha có
order_materials(data cũ, từ trước deploy) → vẫn hiển thị bảng "VẬT TƯ (ĐÃ XUẤT KHO)" với cột SL mẫu / SL thực tế - [ ] Task cha có cả data mới (project_task_material) + data cũ (order_materials) → hiển thị 2 sections riêng
- [ ] Data cũ dùng
MaterialTablecomponent hiện tại (không sửa logic cũ)
FR-007: Fix button label + delete confirm (Ref: DEC-U01, DEC-U02)
AC:
- [ ] Button ở
SubtaskTable.tsx:402→ label luôn là "Thêm công việc" (bỏ conditionisAutomaticBoard) - [ ] Delete confirm dialog: nếu subtask có
task_materials.length > 0→ hiển thị "(Sẽ xóa N vật tư đi kèm)"
FR-008: Product disabled handling (Ref: DEC-U04)
AC:
- [ ] Auto-fill: filter
related_product.disabled IS NOT TRUE— không kéo product ngưng KD - [ ] Search: filter
product.disabled IS NOT TRUE— không hiện product ngưng KD trong kết quả tìm kiếm - [ ] Materials đã lưu mà product sau đó bị disable → hiển thị badge "Ngưng KD" cạnh tên sản phẩm
- [ ] Denormalized data (
product_name/sku/unit) vẫn giữ giá trị cũ, không mất
A6) Assumptions
| ID | Assumption | Owner xác nhận |
|---|---|---|
| ASM-01 | Trung bình 3 vật tư/subtask (ước tính cho scale) | PO |
| ASM-02 | Product hiếm khi đổi tên/SKU → denormalize chấp nhận được | PO + Tech Lead |
| ASM-03 | Concurrent editing (last-write-wins) chấp nhận được cho phase 1 | PO |
| ASM-04 | Không cần notification khi vật tư thay đổi (phase 1) | PO |
| ASM-05 | Không cần audit log cho material changes (phase 1) | PO |
A7) Risks
| ID | Risk | Impact | Mitigation |
|---|---|---|---|
| RSK-01 | Bảng project_task_material grow nhanh (5.4M-32.8M records/năm) | Query chậm | Indexes đã plan + partition roadmap (phase 2+) |
| RSK-02 | Denormalized product info bị stale nếu product đổi tên | Hiển thị tên cũ | Accept — hiếm khi xảy ra, chỉ ảnh hưởng display |
| RSK-03 | Concurrent editing → last-write-wins | Data loss tiềm ẩn | Accept cho phase 1, monitor usage |
| RSK-04 | Backward compat: 2 bảng cùng hiển thị gây confused | UX confused | Label rõ: "VẬT TƯ DỰ KIẾN" vs "VẬT TƯ (ĐÃ XUẤT KHO)" |
A8) Success Metrics
| Metric | Baseline (hiện tại) | Target (sau 1 tháng) | Cách đo |
|---|---|---|---|
| % subtask có materials | 0% | > 50% (automatic board) | COUNT(DISTINCT task_id) / COUNT(subtask) |
| Ticket "Thêm vật tư" confusion | Có | 0 | Jira/feedback |
| Aggregate accuracy | N/A | 100% | SUM check automated test |
A9) Glossary — Thuật ngữ
| Thuật ngữ (VI) | Thuật ngữ (EN) | Định nghĩa | Phân biệt với |
|---|---|---|---|
| Công việc cha | Parent Task | Công việc chính (parent_id = null), chứa nhiều subtask | ≠ Subtask |
| Công việc con | Subtask | Bước công việc cụ thể (parent_id = task_cha.id), VD: "Laser sắc tố" | ≠ Task cha |
| Vật tư | Material | Sản phẩm/hóa chất sử dụng trong subtask (VD: serum, gel, mask) | ≠ Sản phẩm bán (product) |
| Vật tư mẫu | Default Material | Vật tư được cấu hình sẵn theo subtask definition (từ product_relation) | ≠ Vật tư thêm tay |
| SL dự kiến | Planned Quantity | Số lượng vật tư dự kiến, ghi nhận trên project_task_material | ≠ SL thực tế (xuất kho) |
| SL thực tế | Actual Quantity | Số lượng thực tế đã xuất kho — phase 2, từ order_materials | ≠ SL dự kiến |
| Subtask definition | Subtask Template | Cấu hình subtask trong service (bảng subtask + service_subtask) | ≠ Subtask instance (project_task) |
| Tiền tour | Tour Money | Tiền trả cho KTV khi thực hiện subtask, theo cấp bậc (seniority) | ≠ Vật tư (hoàn toàn độc lập) |
| Automatic board | Auto Project | Project có automate = true, subtask gắn với service definition | ≠ Manual board |
| Denormalize | Denormalize | Copy product_name/sku/unit vào bảng materials để giảm join | ≠ Normalize (reference bảng gốc) |
Non-goals (Explicit)
- Xuất kho thực tế (phase 2)
- Notification khi vật tư thay đổi
- Audit log cho material changes
- Clone/copy subtask với materials
- Export báo cáo vật tư
- Mobile support
- Optimistic locking cho concurrent editing
Changelog
| Version | Ngày | Thay đổi | Tác giả |
|---|---|---|---|
| 1.0 | 2026-03-26 | Initial PRD — Phase 0-4 complete. 14 DECs, 8 FRs, 2 NFRs. | PO/BA + AI |
| 1.0.1 | 2026-03-26 | Thêm Master-spec blocks (Executive Summary, Milestones, Sign-off, PD, RACI, Phase-2 backlog) + Changelog. Fix Quality Bar items #14, #16. | AI |
Hướng dẫn đọc (RACI-based)
| Bạn là... | Đọc gì | Bỏ qua |
|---|---|---|
| PO / Manager | Executive Summary → A2 Context → A5 FRs → Milestones → Backlog Phase 2 | dev-spec.md (C sections), qa-test-plan.md |
| Frontend Dev | A2 Context → A5 FRs → ui-spec.md (B sections) → dev-spec.md (C4, C5, C11) | qa-test-plan.md |
| Backend Dev | dev-spec.md (C4 Data Model, C5 API, C7 Migration) | ui-spec.md (B sections) |
| QA | A5 FRs → qa-test-plan.md → A2 Ví dụ thực tế (dùng làm test scenario) | dev-spec.md (C4-C7) |
| UI/UX Designer | ui-spec.md (B1-B9, wireframes) → prd.md A2 Giao diện mô phỏng | dev-spec.md, qa-test-plan.md |
| Sếp / Stakeholder | Executive Summary only (đủ hiểu feature) | Tất cả sections khác |