Skip to content

Design Doc: Cải thiện UX cài đặt Mã Công Việc / Tiền Tour

FieldValue
FeatureSettings UX — Subtask Config + Tour Fee
Version1.1
Date2026-03-26
StatusDraft
AudienceIT Leader, IT Staff, Admin, PO

1. Bối cảnh & Vấn đề

Hiện trạng

Hệ thống có 3 trang cài đặt riêng biệt để cấu hình công việc và tiền tour:

TrangRouteDBMục đích
Công Việc (subtask config)/s/internal-settings/subtaskecommerce.subtask275+ mã công việc (SUB280, SUB279...)
Tiền Tour (task tag)/s/internal-settings/task-tagproject.project_task_tagTag tiền tour theo cấp bậc
Nhóm Tiền Tour (group)/s/internal-settings/group-task-tagproject.project_task_group_tagNhóm chứa tags

Quan hệ dữ liệu:

project_task_group_tag (nhóm: "Tiền tour 2024")
└── project_task_tag (tag: T26 "100k", T15 "Laser CO2")
    └── tag_tour_moneys (Cấp độ 1: 100,000đ, Cấp độ 2: 100,000đ...)

subtask (mã: SUB280 "Tạo hình tai vểnh")
└── subtask_tag (junction) → project_task_tag

Pain points

#Vấn đềMức độẢnh hưởng
P1Workflow phân mảnh: Phải navigate 3 trang để cấu hình 1 luồng nghiệp vụ. Tạo group → sang trang khác tạo tag → sang trang khác gán vào subtaskNặng nhấtIT Staff
P2Form subtask vô nghĩa: Field "Danh sách tag" hiện chip tag chỉ có tên (VD: "Ok", "100k") — không biết nhóm nào, tiền tour bao nhiêuNặngIT Staff, Admin/PO
P3Ngôn từ lẫn lộn: Sidebar gọi "Công Việc" (trùng với tab Công Việc ở chi tiết khách hàng), code gọi "Task Tag" nhưng UI gọi "Tiền Tour"Trung bìnhTất cả
P4List subtask khó tìm: 275+ items, chỉ filter theo loại + trạng thái, không filter/hiện tag tiền tourTrung bìnhIT Staff
P5Tên tag = giá trị tiền: IT Staff đặt tên tag = "100k", "Ok" vì UI không cung cấp đủ context → naming convention bị pháNhẹIT Staff
P6Cột bảng subtask bị swap label: Cột 3 label "Loại công việc" nhưng hiển thị type, cột 4 label "Tên công việc" nhưng hiển thị name/descriptionNhẹIT Staff

Đối tượng sử dụng

RoleHành viTần suất
IT Leader / IT StaffCấu hình: tạo/sửa/xóa subtask config, tag, groupVài lần/tháng
Admin / POXem tham khảo: kiểm tra subtask nào dùng tag nào, tiền tour bao nhiêuThỉnh thoảng

2. Quyết định thiết kế

D1: Gộp Group + Tag thành 1 trang

  • Quyết định: Gộp 2 trang "Nhóm Tiền Tour" + "Tiền Tour" thành 1 trang "Cấu Hình Tiền Tour"
  • Lý do: Group và Tag có quan hệ cha-con chặt, cùng project DB, cùng mục đích (tiền tour). Tách riêng buộc user navigate qua lại không cần thiết.
  • Trade-off: Component phức tạp hơn (accordion + nested table) nhưng giảm 3 trang → 2 trang.

D2: Giữ trang Subtask riêng

  • Quyết định: Không gộp subtask vào trang tiền tour
  • Lý do: Subtask config thuộc ecommerce DB (khác domain), 275+ items, có fields riêng (loại, mô tả). Gộp sẽ overload trang.
  • Trade-off: Vẫn 2 trang nhưng mỗi trang có mục đích rõ ràng.

D3: Tag chip hiện số tiền thay vì tên

  • Quyết định: Trong tất cả nơi hiện tag chip/text, hiện [Mã — Range tiền] thay vì chỉ tên tag.
  • Lý do: Tên tag hiện tại vô nghĩa ("Ok", "100k"). Số tiền là thông tin mọi người thực sự cần.
  • Trade-off: Chip dài hơn nhưng có ý nghĩa.
  • Blast radius: TaskTagSelect dùng ở 2 nơi (settings SubTaskForm + projects TaskForm), TaskTagDisplay dùng ở 3 nơi (SubtaskDetail + OrderTaskLimitForm + ServiceSubtaskItem). Tất cả đều hưởng lợi từ enriched display.

D4: Không inline-create tag trong form subtask

  • Quyết định: Không cho tạo tag mới ngay trong form subtask. Chỉ cung cấp link "Xem chi tiết ↗" mở tab mới.
  • Lý do: Tạo tag cần cấu hình tiền tour theo 5 cấp bậc (form phức tạp). Tần suất tạo tag thấp (vài lần/tháng). Link mở tab mới đủ tiện.

D5: Rename sidebar + labels

  • Quyết định: "Công Việc" → "Mã Công Việc", gộp "Nhóm Tiền Tour" + "Tiền Tour" → "Cấu Hình Tiền Tour"
  • Lý do: "Công Việc" trùng với tab Công Việc ở chi tiết khách hàng. "Mã Công Việc" khớp với cột "MÃ CÔNG VIỆC" trong bảng.

D6: Giữ route name cũ hoạt động

  • Quyết định: ROUTE_SETTING_TASK_TAG_DETAIL vẫn resolve được (redirect sang trang mới). Không cần sửa 2 file ecommerce.
  • Lý do: OrderTaskLimitForm và ServiceSubtaskItem dùng route name này để mở link. Redirect ở router level là đủ, không cần sửa từng consumer.

3. Thiết kế chi tiết

3.1 Trang "Cấu Hình Tiền Tour" (gộp Group + Tag)

Route: /s/internal-settings/tour-fee-config

Thay thế 2 trang:

  • /s/internal-settings/group-task-tag (xóa)
  • /s/internal-settings/task-tag (xóa)

Layout:

┌─── CẤU HÌNH TIỀN TOUR ────────────────────────────────────────────┐
│                                                                      │
│  [🔍 Tìm theo mã, tên, số tiền...]  [Nhóm: Tất cả ▼]  [+ Nhóm]  │
│                                                                      │
│  ┌─── Tiền tour 2024 ──────────────────────── [Sửa nhóm] [▼] ──┐  │
│  │                                                                │  │
│  │  ┌────┬───────┬─────────┬───────────────────┬───────┬─────┐  │  │
│  │  │ Mã │ Tên   │ Range   │ Chi tiết          │T.thái │     │  │  │
│  │  ├────┼───────┼─────────┼───────────────────┼───────┼─────┤  │  │
│  │  │T26 │ 100k  │100,000đ │ CĐ1-5: đều 100k  │  ✅  │[Sửa]│  │  │
│  │  │T15 │LaserX │50k-120k │ CĐ1:50k CĐ5:120k │  ✅  │[Sửa]│  │  │
│  │  │T08 │ Ok    │ 80,000đ │ CĐ1-5: đều 80k   │  ❌  │[Sửa]│  │  │
│  │  └────┴───────┴─────────┴───────────────────┴───────┴─────┘  │  │
│  │                                                                │  │
│  │  [+ Thêm tag tiền tour]                                      │  │
│  │                                                                │  │
│  │  Đang dùng bởi: 45 mã công việc                   [Xem ↗]  │  │
│  └────────────────────────────────────────────────────────────────┘  │
│                                                                      │
│  ┌─── Tiền tour 2023 ──────────────────────── [Sửa nhóm] [▶] ──┐  │
│  │  12 tags · 8 đang hoạt động                                    │  │
│  └────────────────────────────────────────────────────────────────┘  │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

Hành vi:

ActionBehavior
Click ▶/▼ nhómToggle expand/collapse
SearchTìm cả tên nhóm lẫn tên/mã tag
[+ Nhóm]Dialog tạo nhóm (code + name)
[+ Thêm tag tiền tour]Side dialog tạo tag, nhóm pre-fill
[Sửa] tagSide dialog sửa tag (giữ nguyên form hiện tại)
[Sửa nhóm]Inline edit (code readonly, name editable) — group chỉ có 2 fields, không cần dialog
[Xem ↗]Expand danh sách subtask configs đang dùng tags trong nhóm

Expand "Đang dùng bởi":

  Đang dùng bởi: 45 mã công việc                       [Thu gọn ▲]
  ┌──────────┬──────────────────────────┬──────────────┐
  │ Mã       │ Tên công việc            │ Tags         │
  ├──────────┼──────────────────────────┼──────────────┤
  │ SUB280   │ Tạo hình tai vểnh        │ T08 (Ok)     │
  │ SUB156   │ Laser Q-switch           │ T26, T15     │
  │ SUB089   │ Chăm sóc cơ bản         │ T26          │
  └──────────┴──────────────────────────┴──────────────┘

Cột "Range" logic:

- Flat-rate (tất cả cấp bậc = nhau): "100,000đ"
- Multi-rate: "50k — 120k" (min — max)
- Chưa cấu hình: "—"

Cột "Chi tiết" logic:

- Flat-rate: "CĐ1-5: đều 100k"
- Multi-rate: "CĐ1:50k CĐ2:60k ... CĐ5:120k"
- Chưa cấu hình: "Chưa có tiền tour"

3.2 Cải thiện form "Chỉnh sửa Mã Công Việc" (Settings)

File: settings/components/subtask/SubTaskForm.tsx

A. Label rename:

Hiện tạiSau
Title: "CHỈNH SỬA CÔNG VIỆC""CHỈNH SỬA MÃ CÔNG VIỆC"
Field: "Danh sách tag""Tag tiền tour"

B. Tag chip enriched:

Hiện tại:   [Ok ×]  [100k ×]

Đề xuất:    [T08 — 80,000đ ×]  [T26 — 100,000đ ×]
               ↑ mã    ↑ flat       ↑ mã    ↑ flat

            [T15 — 50k~120k ×]
               ↑ mã    ↑ multi-rate range

C. Hover chip → tooltip:

┌──────────────────────────────┐
│ T26 — 100k                   │
│ Nhóm: Tiền tour 2024        │
│                               │
│ Cấp độ 1    100,000đ        │
│ Cấp độ 2    100,000đ        │
│ Cấp độ 3    100,000đ        │
│ Cấp độ 4    100,000đ        │
│ Cấp độ 5    100,000đ        │
│                               │
│ [Xem chi tiết ↗]            │
└──────────────────────────────┘
  • "Xem chi tiết ↗" → mở /internal-settings/tour-fee-config?tag={id} (trang mới) focus vào tag đó

D. Dropdown search cải thiện (TaskTagSelect):

┌───────────────────────────────────────────────┐
│ 🔍 Tìm tag tiền tour...                       │
├───────────────────────────────────────────────┤
│ T26  100k          100,000đ  (Tiền tour 2024)│
│ T15  Laser CO2     50k~120k  (Tiền tour 2024)│
│ T08  Ok             80,000đ  (Tiền tour 2024)│
│ T03  Massage        30k~60k  (CHĂM SÓC DA)  │
└───────────────────────────────────────────────┘
      ↑ mã   ↑ tên    ↑ range     ↑ nhóm

3.3 Cải thiện bảng list Mã Công Việc (Settings)

File: settings/components/subtask/SubTaskTable.tsx

Thêm cột + filter + fix label swap:

TRƯỚC (hiện tại):
┌────┬────────┬──────────┬─────────────────────┬────────┐
│ #  │ Mã CVC │ Loại CVC │ Tên công việc       │ T.thái │ ← không có cột tag
└────┴────────┴──────────┴─────────────────────┴────────┘
                ↑ label sai (hiện type nhưng ghi "Loại công việc")

SAU:
┌────┬────────┬──────────┬─────────────────────┬─────────────────────┬────────┐
│ #  │ Mã     │ Loại     │ Tên công việc       │ Tag tiền tour       │ T.thái │
├────┼────────┼──────────┼─────────────────────┼─────────────────────┼────────┤
│ 1  │ SUB280 │ Dịch vụ  │ Tạo hình tai vểnh   │ T08: 80,000đ       │  ✅    │
│ 2  │ SUB279 │ Dịch vụ  │ BS- Meso da chất... │ T26: 100k, T15: 50k~120k│ ✅ │
│ 3  │ SUB089 │ Thủ công │ Chăm sóc cơ bản    │ —                   │  ✅    │
└────┴────────┴──────────┴─────────────────────┴─────────────────────┴────────┘
                                                  ↑ CỘT MỚI

Filter bar mở rộng:

TRƯỚC: [🔍 Tìm kiếm...] [Bộ lọc 🔽] (chỉ loại + trạng thái)

SAU:   [🔍 Tìm kiếm...] [Loại ▼] [Nhóm tiền tour ▼] [Tag tiền tour ▼] [Trạng thái ▼]

3.4 Rename tổng hợp

Vị tríHiện tạiSauLý do
Sidebar menuCông ViệcMã Công ViệcPhân biệt với "Công Việc" ở tab khách hàng
Sidebar menuNhóm Tiền Tour(xóa)Gộp
Sidebar menuTiền TourCấu Hình Tiền Tour1 trang thay 2
BreadcrumbQuản Lý Công ViệcGiữ nguyênParent section vẫn đúng
Form title (settings)CHỈNH SỬA CÔNG VIỆCCHỈNH SỬA MÃ CÔNG VIỆCRõ nghĩa
Form field (settings)Danh sách tagTag tiền tourRõ nghĩa
Table header (settings)(không có cột tag)Tag tiền tourThêm mới

4. Ảnh hưởng hiển thị ngoài Settings (Blast Radius)

TaskTagSelectTaskTagDisplay được dùng ở 3 nơi ngoài settings module. Tất cả đều hiển thị tag tiền tour và đều hưởng lợi từ enriched display.

4.1 TaskForm — Tạo/sửa subtask trong Projects

File: projects/components/TaskForm/index.tsx:2108-2131Context: Form tạo/sửa subtask trong tab Công Việc ở chi tiết khách hàng. KTV chọn "Loại tiền tour" cho subtask. Component: TaskTagSelect (single select, useBox=false)

TRƯỚC:
┌─── TẠO CÔNG VIỆC CON ───────────────────────────────┐
│                                                        │
│  Loại tiền tour *                                     │
│  ┌──────────────────────────────────────────────┐     │
│  │ Ok                                        ▼  │     │
│  └──────────────────────────────────────────────┘     │
│  ↑ Chỉ hiện tên "Ok" — KTV không biết tiền bao nhiêu │
│                                                        │
└────────────────────────────────────────────────────────┘

SAU:
┌─── TẠO CÔNG VIỆC CON ───────────────────────────────┐
│                                                        │
│  Loại tiền tour *                                     │
│  ┌──────────────────────────────────────────────┐     │
│  │ T08 — Ok — 80,000đ (Tiền tour 2024)      ▼  │     │
│  └──────────────────────────────────────────────┘     │
│  ↑ Hiện mã + tên + range tiền + nhóm                 │
│                                                        │
│  Dropdown khi mở:                                     │
│  ┌──────────────────────────────────────────────┐     │
│  │ T26  100k       100,000đ  (Tiền tour 2024)  │     │
│  │ T15  Laser CO2  50k~120k  (Tiền tour 2024)  │     │
│  │ T08  Ok          80,000đ  (Tiền tour 2024)  │     │
│  └──────────────────────────────────────────────┘     │
│                                                        │
└────────────────────────────────────────────────────────┘

Lợi ích: KTV chọn đúng tag tiền tour dựa trên số tiền thực tế, không phải đoán từ tên vô nghĩa. Label: Giữ nguyên "Loại tiền tour" (đã đúng nghĩa ở context này). Thay đổi: Chỉ ở component TaskTagSelect — hiện enriched option format.

4.2 OrderTaskLimitForm — Hiển thị tag trong form đơn hàng

File: ecommerce/components/order/OrderForm/OrderTaskLimitForm.tsx:186-228Context: Hiển thị danh sách tag tiền tour của subtask trong form giới hạn công việc của đơn hàng. Component: Custom render (không dùng TaskTagSelect, render QText trực tiếp)

TRƯỚC:
┌─── Giới hạn công việc ──────────────────────────────┐
│                                                        │
│  Tag: Ok, 100k                                        │
│       ↑ text xanh (link cho IT), đen (role khác)     │
│                                                        │
└────────────────────────────────────────────────────────┘

SAU:
┌─── Giới hạn công việc ──────────────────────────────┐
│                                                        │
│  Tag: T08 (80,000đ), T26 (100,000đ)                 │
│       ↑ hiện mã + range tiền, vẫn giữ link cho IT   │
│                                                        │
└────────────────────────────────────────────────────────┘

Lợi ích: Manager/PO xem đơn hàng thấy ngay tiền tour, không cần click vào từng tag. Thay đổi: Sửa render logic — thay tag.name bằng ${tag.code} (${range}). Route link: Vẫn dùng ROUTE_SETTING_TASK_TAG_DETAIL → redirect sang /tour-fee-config?tag={id}.

4.3 ServiceSubtaskItem — Hiển thị tag trong cài đặt dịch vụ

File: ecommerce/components/service/ServiceForm/ServiceSubtaskItem.tsx:110-140Context: Hiển thị tag tiền tour gắn với subtask trong form cài đặt dịch vụ (Ecommerce module). Component: Custom render (QText trực tiếp, tương tự OrderTaskLimitForm)

TRƯỚC:
┌─── Subtask: BS - Laser sắc tố nám ─────────────────┐
│                                                        │
│  Tag: Ok                                              │
│       ↑ chỉ hiện tên, link xanh cho IT               │
│                                                        │
└────────────────────────────────────────────────────────┘

SAU:
┌─── Subtask: BS - Laser sắc tố nám ─────────────────┐
│                                                        │
│  Tag: T08 (80,000đ)                                  │
│       ↑ mã + range tiền, link xanh cho IT            │
│                                                        │
└────────────────────────────────────────────────────────┘

Lợi ích: Khi cấu hình dịch vụ, IT Staff thấy ngay subtask dùng tag tiền tour bao nhiêu. Thay đổi: Sửa render logic — thay tag.name bằng ${tag.code} (${range}). Route link: Vẫn dùng ROUTE_SETTING_TASK_TAG_DETAIL → redirect.

4.4 TaskTagDisplay — Component hiển thị tag dùng chung

File: settings/components/task-tag/TaskTagDisplay.tsxContext: Component reusable, hiện dùng ở SubtaskDetail (settings). Cũng bị ảnh hưởng gián tiếp nếu OrderTaskLimitForm và ServiceSubtaskItem chuyển sang dùng component này.

TRƯỚC:
  Ok, 100k         (hoặc "--" nếu không có tag)

SAU:
  T08 (80,000đ), T26 (100,000đ)    (hoặc "--" nếu không có tag)

Thay đổi: Sửa display format trong TaskTagDisplay — cần truyền thêm tag_tour_moneys data.

4.5 Tổng hợp tất cả nơi bị ảnh hưởng

#NơiModuleComponentLoại thay đổiRisk
1Trang Cấu Hình Tiền ToursettingsNEW TourFeeConfigTrang mớiLow — không đụng gì cũ
2Form Chỉnh sửa Mã Công ViệcsettingsSubTaskFormRename label + enriched chipLow
3Bảng list Mã Công ViệcsettingsSubTaskTableThêm cột + filter + fix labelLow
4Form Tạo/sửa subtaskprojectsTaskForm via TaskTagSelectEnriched dropdown optionMedium — KTV sẽ thấy format mới
5Form đơn hàng — giới hạn CVecommerceOrderTaskLimitFormTag text hiện mã + rangeMedium — Manager thấy format mới
6Cài đặt dịch vụ — subtaskecommerceServiceSubtaskItemTag text hiện mã + rangeMedium — IT Staff thấy format mới
7Chi tiết Mã Công ViệcsettingsSubtaskDetail via TaskTagDisplayTag text hiện mã + rangeLow
8Sidebar menusettingsmodule.tsRename + gộp menu itemsLow
9Route redirectssettingsmodule.tsRedirect routes cũ → mớiLow — transparent

5. Impact Map

Frontend — Settings module

FileThay đổiEffort
settings/module.tsThêm route /tour-fee-config, redirect routes cũ, rename sidebar0.5d
settings/types.tsThêm route constants mới0.1d
settings/pages/TourFeeConfig.tsxNEW — Trang gộp Group + Tag accordion2d
settings/components/tour-fee/TourFeeGroupAccordion.tsxNEW — Accordion nhóm chứa tags1.5d
settings/components/tour-fee/TourFeeTagTable.tsxNEW — Bảng tags trong nhóm (range, chi tiết, trạng thái)1d
settings/components/tour-fee/TourFeeUsageExpand.tsxNEW — "Đang dùng bởi N mã công việc" expandable0.5d
settings/components/task-tag/TaskTagSelect.tsxEnriched dropdown: hiện mã + range + nhóm, enriched chip1d
settings/components/task-tag/TaskTagDisplay.tsxEnriched display: code (range) thay vì name0.25d
settings/components/task-tag/TaskTagForm.tsxGiữ nguyên logic, reuse trong trang mới0.25d
settings/components/subtask/SubTaskForm.tsxRename label "Danh sách tag" → "Tag tiền tour"0.1d
settings/components/subtask/SubTaskTable.tsxThêm cột "Tag tiền tour" + filter + fix label swap1d
settings/pages/SubTask.tsxRename title0.1d

Frontend — Ngoài settings (blast radius)

FileThay đổiEffort
ecommerce/components/order/OrderForm/OrderTaskLimitForm.tsxSửa tag display format: tag.name${tag.code} (${range})0.25d
ecommerce/components/service/ServiceForm/ServiceSubtaskItem.tsxSửa tag display format: tag.name${tag.code} (${range})0.25d
projects/components/TaskForm/index.tsxKhông sửa — tự động thay đổi qua TaskTagSelect0d

GraphQL

QueryThay đổi
Fragment TaskTag (task-tag.graphql)Thêm tag_tour_moneys { seniority, tour_money }
Fragment Subtask (subtask.graphql)Thêm subtask_tags { tag { code, tag_tour_moneys { tour_money } } }
GetTaskTagGroupThêm nested project_task_tags { code, tag_tour_moneys { tour_money } }

Backend / Hasura

ZERO thay đổi — chỉ FE restructure. Tất cả data đã có sẵn qua existing relationships.


6. Data Flow

Trang Cấu Hình Tiền Tour

TourFeeConfig page
├── GetTaskTagGroup (list nhóm + nested tags + tour_moneys)
├── Accordion render
│   ├── TourFeeGroupAccordion (per group)
│   │   ├── TourFeeTagTable (tags trong nhóm)
│   │   │   ├── Range column: computed từ tag_tour_moneys (min/max hoặc flat)
│   │   │   └── Chi tiết column: formatted tour_moneys by seniority
│   │   └── TourFeeUsageExpand
│   │       └── GetSubtaskConfig WHERE subtask_tags.tag_id IN group's tag IDs
│   └── [Sửa tag] → TaskTagForm (reuse component hiện tại)
└── Search: filter cả group name + tag name/code

Form Subtask (Settings) — Tag Chip Enriched

SubTaskForm
├── TaskTagSelect (sửa)
│   ├── Query GetTaskTag + tag_tour_moneys (MỚI)
│   ├── Dropdown item: render [Mã] [Tên] [Range] [Nhóm]
│   └── Selected chip: render [Mã — Range ×]
├── Tooltip on chip hover
│   ├── Show: tên, nhóm, bảng tiền tour 5 cấp
│   └── Link "Xem chi tiết ↗" → /tour-fee-config?tag={tagId}
└── Label: "Tag tiền tour"

TaskForm (Projects) — Tự động thay đổi

TaskForm (projects module)
├── TaskTagSelect (CÙNG component — tự động enriched)
│   ├── Dropdown: [Mã] [Tên] [Range] [Nhóm]
│   └── Selected: hiện enriched format
└── Label: "Loại tiền tour" (GIỮU NGUYÊN)

OrderTaskLimitForm + ServiceSubtaskItem — Display enriched

OrderTaskLimitForm / ServiceSubtaskItem
├── Tag data: tag.code + tag.tag_tour_moneys (CẦN thêm vào data source)
├── Display: "${tag.code} (${computeRange(tag.tag_tour_moneys)})"
└── Link: ROUTE_SETTING_TASK_TAG_DETAIL → redirect → /tour-fee-config?tag={id}

7. Migration Plan (URL redirects)

Để không break bookmarks, links, và external references:

Route path redirects

Route cũRedirect đến
/s/internal-settings/group-task-tag/s/internal-settings/tour-fee-config
/s/internal-settings/group-task-tag/:id/s/internal-settings/tour-fee-config?group={id}
/s/internal-settings/task-tag/s/internal-settings/tour-fee-config
/s/internal-settings/task-tag/:id/s/internal-settings/tour-fee-config?tag={id}
/s/internal-settings/task-tag/:id/edit/s/internal-settings/tour-fee-config?tag={id}&edit=true

Route name mapping (QUAN TRỌNG)

Route name cũBehavior
ROUTE_SETTING_TASK_TAG_DETAILRedirect sang /tour-fee-config?tag={id}PHẢI giữ vì OrderTaskLimitForm + ServiceSubtaskItem dùng
ROUTE_SETTING_TASK_TAGRedirect sang /tour-fee-config
ROUTE_SETTING_TASK_TAG_GROUPRedirect sang /tour-fee-config

8. Effort Estimate

NhómTasksEstimate
Trang Cấu Hình Tiền Tour (gộp)Page + Accordion + TagTable + UsageExpand5d
TaskTagSelect enrichedDropdown + chip + tooltip + GraphQL1.5d
TaskTagDisplay enrichedDisplay format + data0.25d
Cải thiện form Subtask (settings)Rename label0.1d
Cải thiện bảng Subtask (settings)Cột tag + filters + fix label swap1d
Blast radius — ecommerceOrderTaskLimitForm + ServiceSubtaskItem display format0.5d
Rename + redirectSidebar + titles + route redirects + route name mapping0.5d
GraphQL adjustmentsFragment mở rộng + codegen0.5d
Testing + polishCross-module test, responsive, edge cases1.5d
Tổng~10.85d

9. Risks

#RiskImpactMitigation
R1Accordion performance nếu nhiều groups × nhiều tagsMediumLazy load tags khi expand group, không load all upfront
R2"Đang dùng bởi" query chậm (cross-DB)MediumQuery chỉ khi user click "Xem ↗", không auto-load
R3Tooltip hiện bảng tiền tour cần thêm queryLowPrefetch tag_tour_moneys trong fragment GetTaskTag
R4Route redirects bị miss — 2 file ecommerce dùng route NAMEHighGiữ ROUTE_SETTING_TASK_TAG_DETAIL name mapping trong router (D6)
R5SubTaskTable 275+ rows thêm nested tag_tour_moneys → payload lớnMediumChỉ query tag.code + tag_tour_moneys { tour_money } (không cần seniority/name cho list). Hoặc compute range server-side
R6TaskTagSelect enriched chip quá dài khi subtask có 3+ tagsLowMax-width chip + ellipsis, hover để xem full. Test responsive
R7TaskForm (projects) tự động đổi format — KTV chưa quenLowFormat mới rõ nghĩa hơn — chỉ cần thông báo thay đổi

10. Phạm vi KHÔNG thay đổi

  • Form tạo/sửa tag tiền tour (TaskTagForm): giữ nguyên — chỉ đổi nơi render
  • Form tạo/sửa nhóm (TaskTagGroupForm): giữ nguyên
  • Database schema: ZERO thay đổi
  • Hasura metadata / permissions: ZERO thay đổi
  • Backend Go services: ZERO thay đổi
  • Event triggers (assignee insert/update, task_log): ZERO thay đổi
  • Logic tính tiền tour: ZERO coupling — snapshot tại event trigger, không đọc từ UI
  • Logic tính lương: ZERO coupling — dùng ecommerce_task_log.tour_fee đã snapshot
  • Trang cài đặt khác: ZERO ảnh hưởng

11. Verification — Tiền tour runtime KHÔNG bị ảnh hưởng

[Settings UI — CÁI CHÚNG TA SỬA]
    project_task_tag + tag_tour_money → chỉ thay đổi cách HIỂN THỊ

                    (data DB giữ nguyên)

[Event Trigger — KHÔNG SỬA]
    project_task_assignee_insert.go:176-200
    → Query tag_tour_moneys BY seniority → SET tour_money (1 lần)

[Salary — KHÔNG SỬA]
    project_task_assignee_update.go:260-447
    → ecommerce_task_log.tour_fee (snapshot)
    → INCREMENT user_salary.tour_money

3 lớp bảo vệ:

  1. Snapshot: tour_money SET 1 lần khi assign, salary dùng giá trị đã lưu
  2. Server-side: Event triggers chạy trong Go, không qua UI
  3. FE-only changes: Design chỉ sửa Vue components + GraphQL SELECT fields