Appearance
PRD: Cải thiện UX cài đặt Mã Công Việc / Tiền Tour
Feature slug: settings-ux-subtask-tagVersion: 1.0 Ngày: 2026-03-26 Profile: M (Medium)
Executive Summary
Gộp 2 trang "Nhóm Tiền Tour" + "Tiền Tour" thành 1 trang "Cấu Hình Tiền Tour" (accordion layout). Cải thiện hiển thị tag tiền tour ở tất cả nơi sử dụng — hiện mã + range tiền thay vì tên vô nghĩa. Rename sidebar + labels cho rõ nghĩa. Zero DB/backend changes — chỉ FE restructure.
Milestones
| # | Milestone | Target | Owner | Dependency |
|---|---|---|---|---|
| M1 | GraphQL fragment mở rộng + codegen | T+1d | FE Dev | — |
| M2 | TaskTagSelect enriched (chip + dropdown + tooltip) | T+3d | FE Dev | M1 |
| M3 | Trang Cấu Hình Tiền Tour (accordion + CRUD) | T+7d | FE Dev | M1 |
| M4 | SubTaskTable cải thiện (cột tag + filter + fix label) | T+8d | FE Dev | M1 |
| M5 | Blast radius: ecommerce display format | T+9d | FE Dev | M2 |
| M6 | Rename + route redirects | T+9d | FE Dev | M3 |
| M7 | QA testing | T+11d | QA | M2-M6 |
Critical path: M1 → M2 → M3 → M6 → M7 Parallel: M4, M5 song song với M3
Sign-off
| Role | Người | Điều kiện |
|---|---|---|
| PO | PO/BA | Tất cả FR pass, UX trực quan |
| Tech Lead | Tech Lead | Zero runtime impact, route redirects hoạt động |
| QA | QA Lead | All TC pass, no P1/P2 bugs |
Pending Decisions
Không có — tất cả đã resolved trong design doc (D1-D6).
RACI
| Deliverable | PO/BA | FE Dev | QA | UI/UX |
|---|---|---|---|---|
| Trang Cấu Hình Tiền Tour | I | R/A | C | C |
| TaskTagSelect enriched | I | R/A | C | C |
| Blast radius ecommerce | I | R/A | C | — |
| Rename + redirects | I | R/A | C | — |
| QA testing | C | C | R/A | — |
Backlog Phase 2
| # | Item | Lý do defer |
|---|---|---|
| 1 | Inline-create tag trong form subtask | Tần suất thấp, form phức tạp (D4) |
| 2 | Drag-drop reorder tags trong group | Nice-to-have, không ảnh hưởng workflow |
| 3 | Bulk assign tags cho nhiều subtask | Cần UX research thêm |
Z) Decision Log
Z1 — Business Decisions
| ID | Quyết định | Lý do | Alternatives considered |
|---|---|---|---|
| DEC-B01 | Gộp Group + Tag → 1 trang "Cấu Hình Tiền Tour" | Quan hệ cha-con chặt, cùng DB, cùng domain tiền tour. Tách riêng buộc navigate không cần thiết | (a) Giữ 3 trang + thêm link, (b) Gộp cả 3 trang thành 1 |
| DEC-B02 | Giữ trang Subtask riêng | Khác domain (ecommerce DB), 275+ items, fields riêng biệt. Gộp sẽ overload | Gộp cả subtask vào trang tiền tour |
| DEC-B03 | Không inline-create tag trong form subtask | Tạo tag cần 5 cấp bậc tiền tour (form phức tạp), tần suất vài lần/tháng | Inline dialog tạo tag nhanh |
| DEC-B04 | Rename "Công Việc" → "Mã Công Việc" | Trùng tên với tab Công Việc ở chi tiết khách hàng. "Mã Công Việc" khớp cột MÃ CÔNG VIỆC | Giữ nguyên |
Z2 — UX Decisions
| ID | Quyết định | Lý do | Alternatives considered |
|---|---|---|---|
| DEC-U01 | Tag chip hiện [Mã — Range tiền] thay vì tên | Tên tag vô nghĩa ("Ok", "100k"). Mã + tiền là thông tin thực sự cần | (a) Hiện tên + nhóm, (b) Hiện tên + tooltip |
| DEC-U02 | Hover chip → tooltip bảng tiền tour 5 cấp | Quick preview không cần mở form sửa. "Xem chi tiết ↗" mở tab mới | Click chip mở form inline |
| DEC-U03 | Dropdown search hiện 4 thông tin: mã + tên + range + nhóm | IT Staff chọn tag dựa trên số tiền, không phải tên | Hiện chỉ tên + nhóm |
| DEC-U04 | Accordion per group, expand/collapse | Hierarchy rõ ràng, lazy load khi expand | Tab per group, tree view |
| DEC-U05 | "Đang dùng bởi N mã công việc" ở footer group | Traceability ngược — biết sửa tag ảnh hưởng gì. Lazy load khi click | Luôn hiện inline |
Z3 — Technical Decisions
| ID | Quyết định | Lý do | Alternatives considered |
|---|---|---|---|
| DEC-T01 | Zero DB/Hasura changes — FE only | Tất cả relationships đã có sẵn. Chỉ cần mở rộng GraphQL fragments | Thêm computed field/view |
| DEC-T02 | Giữ route name ROUTE_SETTING_TASK_TAG_DETAIL hoạt động | OrderTaskLimitForm + ServiceSubtaskItem dùng route name để mở link. Redirect ở router level | Sửa từng consumer file |
| DEC-T03 | Enriched display áp dụng toàn bộ nơi dùng TaskTagSelect/TaskTagDisplay | Blast radius 5 nơi — tất cả đều hưởng lợi từ enriched format | Chỉ sửa trong settings |
| DEC-T04 | SubTaskTable chỉ query tag.code + tag_tour_moneys { tour_money } | 275+ rows — payload tối thiểu. Không cần seniority name cho list view | Query full tag_tour_moneys |
Z4 — QA Decisions
| ID | Quyết định | Lý do | Alternatives considered |
|---|---|---|---|
| DEC-Q01 | Test cả 5 nơi bị ảnh hưởng (settings + projects + ecommerce) | Blast radius rộng — sửa TaskTagSelect ảnh hưởng 3 module | Chỉ test settings |
| DEC-Q02 | Verify route redirects cho tất cả route cũ | 2 file ecommerce dùng route name để mở link | Chỉ test path redirect |
A1) Blueprint
| Field | Value |
|---|---|
| Feature | Cải thiện UX cài đặt Mã Công Việc / Tiền Tour |
| Type | Enhancement |
| Complexity | M (Medium) |
| Effort | ~10.85 dev-days |
| Impact | Settings (primary), Projects + Ecommerce (blast radius) |
| DB Changes | ZERO |
| Backend Changes | ZERO |
| Frontend Changes | 12 files sửa + 4 files mới |
A2) Context — Tổng quan dễ hiểu
Vấn đề là gì?
IT Staff cấu hình công việc spa phải đi 3 trang khác nhau:
- Nhóm Tiền Tour — tạo nhóm (VD: "Tiền tour 2024")
- Tiền Tour — tạo tag tiền tour trong nhóm (VD: T26 "100k", với bảng tiền theo 5 cấp bậc)
- Mã Công Việc — gán tag vào subtask config (VD: SUB280 "Tạo hình tai vểnh" dùng tag T08)
Khi ở form Mã Công Việc, field "Danh sách tag" hiện chip [Ok] — IT Staff không biết tag "Ok" thuộc nhóm nào, tiền tour bao nhiêu. Phải mở tab khác kiểm tra.
Giải pháp
Gộp 2 trang (Nhóm + Tag) thành 1 trang "Cấu Hình Tiền Tour" — accordion layout, mỗi nhóm chứa tags bên trong. CRUD tại chỗ.
Enriched display — ở TẤT CẢ nơi hiện tag (settings, TaskForm tạo subtask, form đơn hàng, cài đặt dịch vụ), hiện [T08 — 80,000đ] thay vì [Ok].
Rename — "Công Việc" → "Mã Công Việc", gộp sidebar menu items.
Ai bị ảnh hưởng?
| Role | Thay đổi họ thấy |
|---|---|
| IT Staff | 1 trang thay 2 cho tiền tour, tag chip có nghĩa, sidebar rename |
| KTV (projects) | Dropdown "Loại tiền tour" hiện mã + range tiền thay vì tên |
| Manager/PO | Xem đơn hàng thấy tag hiện mã + tiền thay vì tên vô nghĩa |
Cái gì KHÔNG đổi?
- Database: zero changes
- Backend/Go code: zero changes
- Cách tính tiền tour/lương: zero coupling (snapshot tại event trigger)
- Trang cài đặt khác: zero ảnh hưởng
A3) Goals & Success Metrics
Goals
| # | Goal | Metric | Target |
|---|---|---|---|
| G1 | Giảm navigation khi cấu hình tiền tour | Số trang cần mở | 3 → 1 |
| G2 | IT Staff chọn đúng tag nhanh hơn | Context visible khi chọn tag | Hiện mã + range + nhóm |
| G3 | Onboarding IT Staff mới dễ hơn | Ngôn từ nhất quán | Rename sidebar + labels |
Non-goals
- Thay đổi logic tính tiền tour
- Thay đổi database schema
- Thêm tính năng mới cho tiền tour (VD: auto-calculate)
A4) Personas
| Persona | Role | Context | Tần suất |
|---|---|---|---|
| IT Admin (Thọ) | IT Leader | Cấu hình subtask + tag cho chi nhánh mới, vài lần/tháng | Primary |
| IT Staff (Hương) | IT Staff | Sửa tiền tour khi có chính sách mới, 1-2 lần/tháng | Primary |
| PO (Linh) | Admin/PO | Xem tham khảo subtask nào dùng tag nào | Secondary |
| KTV (Mai) | Staff | Chọn "Loại tiền tour" khi tạo subtask trong tab Công Việc | Affected |
| Manager (Tuấn) | Manager | Xem đơn hàng, thấy tag tiền tour | Affected |
A5) Functional Requirements
FR-001: Trang Cấu Hình Tiền Tour — Accordion Layout (Ref: DEC-B01, DEC-U04)
Mô tả: Gộp 2 trang "Nhóm Tiền Tour" + "Tiền Tour" thành 1 trang tại route /s/internal-settings/tour-fee-config. Layout accordion: mỗi nhóm là 1 section collapsible, expand ra bảng tags bên trong.
Acceptance Criteria:
- AC-1: Trang hiện tất cả nhóm tiền tour, mỗi nhóm là 1 accordion section
- AC-2: Click ▶/▼ toggle expand/collapse nhóm
- AC-3: Nhóm collapsed hiện summary: "{N} tags · {M} đang hoạt động"
- AC-4: Nhóm expanded hiện bảng tags với cột: Mã, Tên, Range, Chi tiết, Trạng thái, Action
- AC-5: [+ Nhóm] mở dialog tạo nhóm (code + name)
- AC-6: [Sửa nhóm] inline edit (code readonly, name editable)
- AC-7: [+ Thêm tag tiền tour] mở side dialog với nhóm pre-fill
- AC-8: [Sửa] tag mở side dialog (reuse TaskTagForm hiện tại)
FR-002: Cột Range + Chi tiết tiền tour (Ref: DEC-U03)
Mô tả: Bảng tags trong accordion hiện 2 cột mới tính từ tag_tour_moneys.
Acceptance Criteria:
- AC-1: Cột "Range" hiện flat-rate ("100,000đ") hoặc min-max ("50k — 120k") hoặc "—" nếu chưa cấu hình
- AC-2: Cột "Chi tiết" hiện tóm tắt: "CĐ1-5: đều 100k" (flat) hoặc "CĐ1:50k CĐ2:60k ... CĐ5:120k" (multi)
- AC-3: Tag chưa có tiền tour hiện "Chưa có tiền tour" ở cột Chi tiết
FR-003: Traceability — "Đang dùng bởi N mã công việc" (Ref: DEC-U05)
Mô tả: Footer mỗi nhóm hiện số subtask configs đang dùng tags trong nhóm. Click expand ra danh sách.
Acceptance Criteria:
- AC-1: Footer hiện "Đang dùng bởi: {N} mã công việc" với count chính xác
- AC-2: Click [Xem ↗] expand danh sách: Mã, Tên công việc, Tags
- AC-3: Nếu N = 0 hiện "Chưa có mã công việc nào sử dụng"
- AC-4: Lazy load — chỉ query khi user click, không auto-load
FR-004: Tag chip enriched — Mã + Range tiền (Ref: DEC-U01, DEC-T03)
Mô tả: Ở TẤT CẢ nơi hiện tag tiền tour (5 nơi), tag chip/text hiện [Mã — Range] thay vì tên.
Acceptance Criteria:
- AC-1: SubTaskForm (settings): chip
[T08 — 80,000đ ×]thay vì[Ok ×] - AC-2: TaskForm (projects): dropdown option hiện
T08 — Ok — 80,000đ (Tiền tour 2024) - AC-3: OrderTaskLimitForm (ecommerce): text
T08 (80,000đ)thay vìOk - AC-4: ServiceSubtaskItem (ecommerce): text
T08 (80,000đ)thay vìOk - AC-5: SubtaskDetail (settings): text
T08 (80,000đ)thay vìOk - AC-6: Flat-rate hiện 1 số ("80,000đ"), multi-rate hiện range ("50k~120k")
FR-005: Tooltip chi tiết tiền tour (Ref: DEC-U02)
Mô tả: Hover tag chip trong form subtask → hiện tooltip bảng tiền tour 5 cấp.
Acceptance Criteria:
- AC-1: Hover chip → tooltip hiện: tên tag, nhóm, bảng 5 cấp bậc + tiền tour
- AC-2: Tooltip có link "Xem chi tiết ↗" → mở
/tour-fee-config?tag={id}tab mới - AC-3: Tooltip áp dụng cho SubTaskForm (settings) — nơi dùng chip
useBox=true - AC-4: Không áp dụng tooltip cho TaskForm (projects) — nơi dùng dropdown
useBox=false
FR-006: Dropdown search enriched (Ref: DEC-U03)
Mô tả: Dropdown TaskTagSelect hiện 4 thông tin: mã, tên, range tiền, nhóm.
Acceptance Criteria:
- AC-1: Mỗi option hiện:
[Mã] [Tên] [Range] ([Nhóm]) - AC-2: Search vẫn tìm theo name + keywords (giữ nguyên logic)
- AC-3: Áp dụng cho cả SubTaskForm (settings, multiple select) và TaskForm (projects, single select)
FR-007: Cải thiện bảng Mã Công Việc (Ref: DEC-B02)
Mô tả: Thêm cột "Tag tiền tour" vào bảng list subtask + thêm filter nhóm/tag + fix label swap.
Acceptance Criteria:
- AC-1: Cột mới "Tag tiền tour" hiện
T08: 80,000đhoặcT26: 100k, T15: 50k~120khoặc "—" - AC-2: Filter bar thêm: [Nhóm tiền tour ▼] [Tag tiền tour ▼]
- AC-3: Fix cột 3 label "Loại công việc" → hiện đúng type
- AC-4: Fix cột 4 label "Tên công việc" → hiện đúng name
FR-008: Rename + Route redirects (Ref: DEC-B04, DEC-T02)
Mô tả: Rename sidebar menu, form titles, labels. Route cũ redirect sang route mới.
Acceptance Criteria:
- AC-1: Sidebar: "Công Việc" → "Mã Công Việc"
- AC-2: Sidebar: gộp "Nhóm Tiền Tour" + "Tiền Tour" → "Cấu Hình Tiền Tour"
- AC-3: Form title: "CHỈNH SỬA CÔNG VIỆC" → "CHỈNH SỬA MÃ CÔNG VIỆC"
- AC-4: Form field: "Danh sách tag" → "Tag tiền tour"
- AC-5: Route
/s/internal-settings/task-tagredirect →/tour-fee-config - AC-6: Route
/s/internal-settings/group-task-tagredirect →/tour-fee-config - AC-7: Route name
ROUTE_SETTING_TASK_TAG_DETAILvẫn resolve (redirect sang/tour-fee-config?tag={id}) - AC-8: OrderTaskLimitForm + ServiceSubtaskItem link vẫn hoạt động sau redirect
A6) Assumptions
| # | Assumption | Impact nếu sai |
|---|---|---|
| 1 | Tất cả tag_tour_moneys có 5 cấp bậc (CĐ1-CĐ5) | Tooltip/chi tiết cần handle dynamic levels |
| 2 | Số nhóm tiền tour < 20 | Accordion performance không cần virtual scroll |
| 3 | Mỗi nhóm có < 50 tags | Lazy load per group đủ nhanh |
| 4 | IT Staff không cần bulk operations trên tags | Defer bulk assign/move sang Phase 2 |
| 5 | Route name redirect trong Vue Router hoạt động | Cần test cụ thể |
A7) Risks
| # | Risk | Probability | Impact | Mitigation |
|---|---|---|---|---|
| R1 | Accordion performance nhiều groups × tags | Low | Medium | Lazy load khi expand, không load all |
| R2 | "Đang dùng bởi" query chậm (cross-DB) | Medium | Medium | Lazy load khi click, không auto-load |
| R3 | SubTaskTable 275+ rows + nested tag data → payload lớn | Medium | Medium | Chỉ query tag.code + tour_money (DEC-T04) |
| R4 | Route name redirect bị miss → link break ở ecommerce | Medium | High | Test cụ thể 2 file ecommerce (DEC-Q02) |
| R5 | Tag chip dài khi subtask có 3+ tags | Low | Low | Max-width + ellipsis + hover full |
| R6 | KTV chưa quen format mới trong TaskForm | Low | Low | Format rõ nghĩa hơn — chỉ cần thông báo |
| R7 | GraphQL fragment mở rộng → codegen conflict | Low | Medium | Run codegen ngay sau sửa fragment, resolve types |
A8) Metrics
| # | Metric | Baseline | Target | Cách đo |
|---|---|---|---|---|
| 1 | Số trang navigate để cấu hình tiền tour | 3 trang | 1 trang | Count pages |
| 2 | Thông tin visible khi chọn tag | Chỉ tên | Mã + tên + range + nhóm | UI audit |
| 3 | Thời gian IT Staff gán đúng tag cho subtask | N/A (chưa đo) | Giảm 50% nhờ context visible | User feedback |
A9) Glossary
| Thuật ngữ (VI) | Thuật ngữ (EN) | Định nghĩa | Phân biệt với |
|---|---|---|---|
| Mã Công Việc | Subtask Config | Cấu hình template cho subtask (VD: SUB280 "Tạo hình tai vểnh"). Bảng subtask trong ecommerce DB | ≠ Công việc thực tế (project_task) |
| Tag Tiền Tour | Task Tag / Tour Fee Tag | Cấu hình tiền tour theo cấp bậc nhân viên (VD: T26 "100k"). Bảng project_task_tag trong project DB | ≠ Tag thông thường |
| Nhóm Tiền Tour | Tour Fee Group | Nhóm chứa nhiều tag tiền tour (VD: "Tiền tour 2024"). Bảng project_task_group_tag | ≠ Nhóm dịch vụ |
| Cấp bậc | Seniority Level | Cấp bậc KTV từ default_master_data (CĐ1-CĐ5). Mỗi tag có tiền tour riêng per cấp bậc | ≠ Chức vụ |
| Range tiền | Tour Fee Range | Min-max tiền tour qua các cấp bậc. Flat-rate = 1 số, multi-rate = "min~max" | ≠ Tiền tour cụ thể |
| Accordion | Accordion | UI pattern: section collapsible, click header toggle nội dung | ≠ Tab, ≠ Tree |
| Enriched display | Enriched display | Hiện thêm context (mã, range tiền, nhóm) thay vì chỉ tên | ≠ Raw display |
| Blast radius | Blast radius | Các nơi ngoài scope chính bị ảnh hưởng bởi thay đổi component dùng chung | ≠ Direct scope |
Changelog
| Version | Ngày | Thay đổi | Author |
|---|---|---|---|
| 1.0 | 2026-03-26 | Initial release — full PRD (M profile) | AI + PO |
Hướng dẫn đọc
| Bạn là... | Đọc |
|---|---|
| PO / tất cả | PRD (file này): A2 Context → A5 FR → Z Decision Log |
| UI/UX Designer | UI Spec: B1-B9 + wireframes |
| FE Dev | Dev Spec: C1-C12 + Impact Map |
| QA | QA Test Plan: D1-D5 |
| PM / TL | Handoff: timeline + RACI |