KB-2549 rev 2

Assembly Module — SSOT

5 min read Revision 2

Assembly Module — SSOT

v1.0 | 2026-03-05 S104 Tài liệu NỀN TẢNG cho MỌI quyết định UI/component/module. search_knowledge("assembly module SSOT") ĐỌC TRƯỚC: Operating Rules §0 + §II


I. TRIẾT LÝ

Hệ thống là ASSEMBLY ENGINE, không phải web app.

Schema (Directus) → Config (module) → Render (Nuxt UI) → UI xuất hiện

UI mới = khai báo schema + config. KHÔNG CODE.


II. KIẾN TRÚC 3 TẦNG

Tầng 1: Nuxt UI v2.22.3 (KHÔNG SỬA)
  UTable, UTimeline, UStepper, UModal, UCheckbox, UTabs, UBadge,
  UTooltip, UPopover, USkeleton, UPagination, UAccordion, UInput,
  UTextarea, USelect, UForm, USlideover, UDropdown, UAvatar,
  UBreadcrumb, UProgress, UNavigationMenu...

Tầng 2: Wrappers (viết 1 lần, dùng mãi mãi)
  DirectusTable    = UTable + Directus SDK + insert marks + proposals
  DirectusTimeline = UTimeline + workflow_steps data + checkboxes
  DirectusForm     = UForm + Directus schema auto-fields (tương lai)

Tầng 3: Page config (DUY NHẤT viết khi cần UI mới)
  <DirectusTable collection="workflows" :fields="[...]" />
  Tối đa 20 dòng. Không code.

Scale: Thay đổi Tầng 2 → tất cả trang đổi theo. Tầng 3 không sửa.


III. NUXT UI INVENTORY (S104 — từ Assembly Step 1)

Đang dùng: 23 components (UButton 48x, UTable 8x, UBadge 7x...) Chưa dùng nhưng CÓ SẴN: UTimeline, UStepper, UPopover, UTabs, UBreadcrumb, USkeleton, UCheckbox, UProgress, UDivider, URadio, UToggle, UChip, UMeter, URange

Gap = USAGE, không phải availability. Không cần cài thêm gì.

Two-world problem: Portal layer dùng Nuxt UI. Knowledge/Workflow modules dùng custom HTML. Assembly = thống nhất tất cả sang Nuxt UI.


IV. WRAPPERS REGISTRY

Wrapper Wrap Trạng thái SSOT
DirectusTable UTable + Directus SDK 🔄 ĐANG XÂY (Step 3) search_knowledge("table module SSOT")
DirectusTimeline UTimeline/UStepper + workflow data 📋 SAU Step 3
DirectusForm UForm + Directus schema 📋 Tương lai

V. ASSEMBLY GATE — 5 CÂU HỎI BẮT BUỘC

Mọi agent PHẢI trả lời TRƯỚC KHI code:

1. Nuxt UI đã có component? (UTable? UTimeline? UModal?...)
2. Codebase đã có wrapper/component tương tự? (grep)
3. CÓ → dùng NGUYÊN hoặc WRAP. KHÔNG viết lại.
4. KHÔNG CÓ → ghi rõ đã tìm ở đâu, tại sao không có.
5. Code mới đăng ký custom-code-registry.md chưa?

Vi phạm = reject PR.


VI. CUSTOM CODE ĐANG TỒN TẠI (cần migrate)

P1 — Tables (~939 dòng custom):

File Dòng Thay bằng Trạng thái
DirectusDataTable.vue 639 DirectusTable (UTable wrapper) 🔄 Step 3 đang làm
ProcessRegistryView.vue 389 DirectusTable 📋 Step 4
current-tasks/index.vue 217 DirectusTable 📋 Step 4
approval-desk/index.vue 333 DirectusTable 📋 Step 4

P2 — Popups (~400 dòng):

File Thay bằng Trạng thái
ProposalPopup.vue UPopover/UModal 📋 Step 4
InlineWcrPopup.vue UPopover 📋 Step 4
Column desc popover UTooltip 📋 Step 4

P3 — Timeline (317 dòng):

File Thay bằng Trạng thái
StepsTimeline.vue DirectusTimeline (UTimeline wrapper) 📋 Sau Step 4

P4 — Form elements (~15 files):

Raw <input>, <select>, <textarea>, <input type="checkbox"> → UInput, USelect, UTextarea, UCheckbox


VII. LỘ TRÌNH

Bước Mục tiêu Trạng thái
1 Điều tra inventory ✅ DONE
2 Cài thêm (nếu cần) ✅ SKIP
3 DirectusTable wrap UTable 🔄 ĐANG LÀM
4 Migrate TẤT CẢ custom tables + popups 📋 SAU Step 3
5 DirectusTimeline wrap UTimeline 📋 SAU Step 4
6 Migrate forms → Nuxt UI 📋 SAU Step 5
7 CI Guards enforce (TD-069) 📋 SAU Step 6

Chi tiết: search_knowledge("assembly roadmap")


VIII. BÀI HỌC ĐAU THƯƠNG

S104: 4 vòng fix custom table thất bại (PR #437→#440). Nguyên nhân: viết 639 dòng custom <table> thay vì dùng UTable đã có (8 lần trong portal). Lãng phí 5+ phiên, hàng ngàn dòng code vứt đi.

Quy tắc rút ra: KHÔNG BAO GIỜ code component mà Nuxt UI đã có. Kiểm tra Nuxt UI TRƯỚC. Wrap nếu cần thêm tính năng. KHÔNG viết lại.


v1.0 | S104 | Assembly = Scale. Config = Code. Nuxt UI = Foundation.