KB-469D rev 2

D28 — Nuxt/UI/Template Consolidation Design Plan (DRAFT)

8 min read Revision 2
dieu28designnuxttableidmaproute-resolutionsmokelegacy-cleanup2026-05-08

D28 — Nuxt/UI/Template Consolidation Design Plan

DRAFT v0.2 | 2026-05-08 | Updated with Agent evidence + GPT route-resolution correction Phụ thuộc: Phụ lục Điều 28 approved + VPS reverify trước implementation Scope: Thiết kế, KHÔNG implementation.


0. Ngữ cảnh

Notification Phase 1 (P3D) đạt 90% nhưng blocked bởi Nuxt hardcoded maps. User/GPT quyết định dừng, viết luật (Điều 28 phụ lục), rồi sửa mechanism chung.

Agent live inventory (2026-05-08) cung cấp evidence cụ thể. Design plan v0.2 cập nhật dựa trên data thực.


1. Thay thế hardcoded maps bằng registry-driven resolution

1.1 Vấn đề — 3 điểm hardcoded (CONFIRMED_ISSUE)

File Map Entries Source
pages/knowledge/registries/[entityType]/index.vue:39-58 tableIdMap 18 LOCAL_FACT
config/detail-sections.ts:227 collectionMap ? LOCAL_FACT
server/api/discovery/relations.get.ts:19 collectionMap mirror ? LOCAL_FACT

Tất cả 3 map phải migrate cùng lúc (hoặc ít nhất cùng design).

1.2 Evidence từ Agent — route convention analysis

total_live_rows=21
collection_equals_entityType=1/21 (chỉ event_outbox)
page_url_convention_match=13/21
exception_rows=8/21 (workflow tabs, modules, tasks, proposals, registries index)

Kết luận: entityType ↔ collection KHÔNG consistent vì collection plural, entityType singular. Bất kỳ runtime lookup nào dựa trên collection = entityType sẽ fail 18/21 rows.

1.3 Options — updated assessment

Option B — Runtime query by collectionREJECTED as primary

collection_match_rate=1/21 (4.8%)

Fail cho 20/21 rows. Không khả thi kể cả với convention mapping (plural↔singular).

Option A — Runtime query by page_url → PARTIAL candidate

page_url_convention_match=13/21 (62%)
exception_rate=8/21 (38%)

13/21 rows match /knowledge/registries/{entityType}. 8 rows có non-standard page_url (workflow tabs ?tab=, /admin/, /knowledge/modules, /knowledge/current-tasks, /knowledge/registries index). Cần fallback cho 38% exceptions.

Ưu: Không cần convention mapping. URL = source of truth. Nhược: 38% exception rate cao. Extra runtime API call. page_url substring matching fragile.

Option C — Build-time generated map → PRIMARY CANDIDATE

Ý tưởng: DOT/script query table_registry → generate static map file → Nuxt import
Khi nào generate: build time (nuxt build) hoặc deploy hook
BUILD STEP:
  curl GET /items/table_registry?fields=id,table_id,collection,page_url,status
  → transform to: { entityType: table_id } map
  → write to web/generated/tableIdMap.ts (auto-generated, NOT manual)
  
NUXT:
  import { tableIdMap } from '~/generated/tableIdMap'
  // Replaces hardcoded map — same usage, different source

Ưu:

  • Zero runtime cost (static import)
  • Deterministic — map = exact registry state at build time
  • Auto-generated = NOT hardcode (§0-AU compliant)
  • Convention mapping handled by generation script (entityType ↔ table_id ↔ collection)
  • 100% coverage — every table_registry row gets an entry

Nhược:

  • Cần rebuild/redeploy khi thêm table mới → acceptable (thêm table = cần deploy anyway)
  • Generation script cần maintain → simple script, low burden

Quan trọng: Manual edit of generated file = vi phạm. File PHẢI có header:

// AUTO-GENERATED from table_registry — DO NOT EDIT MANUALLY
// Generated by: scripts/generate-table-maps.ts
// Source: GET /items/table_registry
// Date: ${ISO_DATE}

Option D — Hybrid (build-time + runtime fallback) → FALLBACK CANDIDATE

Build step: generate static map (same as C)
Runtime: if entityType not in static map → query table_registry live → cache

Ưu: Handles new tables added between deploys. Nhược: Complexity. Cần runtime Directus read permission cho table_registry on Public Access role.

1.4 Recommendation v0.2

PRIMARY:   Option C (build-time generated map)
FALLBACK:  Option D (hybrid) — chỉ nếu C không đáp ứng
REJECTED:  Option B (collection lookup)
PARTIAL:   Option A (page_url) — có thể dùng trong generation script

Yêu cầu bắt buộc:

  1. Generated map PHẢI sinh từ table_registry bằng DOT/API/script
  2. KHÔNG edit tay file generated
  3. Generation script = registered tool, có DOT cặp (Cấp B generate + Cấp A verify)
  4. Trước implementation PHẢI VPS reverify (Nuxt findings hiện = LOCAL_FACT)

1.5 Generation script scope (sơ bộ — detail khi implement)

Script cần generate 3 maps từ table_registry:

Map Thay thế Dùng ở đâu
tableIdMap [entityType]/index.vue:39 Registry route resolution
collectionMap detail-sections.ts:227 Entity→collection mapping
reverseCollectionMap detail-sections.ts:252 Collection→entity reverse

Có thể 1 script sinh 1 file chứa cả 3 maps. hoặc 3 files riêng. Design khi implement.

1.6 collectionMap mirror (relations.get.ts)

Server API server/api/discovery/relations.get.ts:19 mirror collectionMap. Phải consume from same generated source. KHÔNG maintain 2 copies.


2. Automated route smoke design — unchanged from v0.1

(Phase 1 bash curl, Phase 2 Playwright, Phase 3 CI. Detail giữ nguyên.)


3. Template registry reconciliation — unchanged from v0.1


4. Legacy cleanup phases — updated

Phase L0 — VPS reverify (NEW — required before L1)

Agent chạy grep trên VPS /opt/incomex cho Bước 2-4 của inventory prompt. Confirm/update LOCAL_FACT findings.

Phase L1 — Generate maps (Option C implementation)

  • Write generation script
  • Generate 3 maps from table_registry
  • Replace hardcoded maps with generated imports
  • Verify all registry routes resolve correctly
  • Route smoke

Phase L2 — Resume P3D

  • Generated map includes event_outbox → tbl_event_outbox
  • Route smoke: /knowledge/registries/event_outbox → SharedDirectusTable mounts
  • Field leak smoke: unsafe fields 403
  • Publish tbl_event_outbox: draft → published
  • P3D Phase 1 = COMPLETE

Phase L3 — Migrate UTable direct usages (11 knowledge/admin)

Per Agent 4B findings.

Phase L4 — Migrate business calcs (6 pages)

Per Agent 4F findings. Move to PG views → Directus → render.

Phase L5 — Cleanup remaining

HTML table MatrixView, portal UTable review, stale docs.


5. Cách resume P3D tbl_event_outbox — updated

Preconditions (updated)

  1. ✅ Phụ lục Điều 28 approved (or enacted)
  2. ✅ Design plan v0.2+ approved
  3. ✅ VPS reverify complete (Phase L0)
  4. ✅ Generation script built + maps generated (Phase L1)
  5. ✅ Route smoke pass for event_outbox

Steps — same as v0.1 (R1-R5)

Nhưng R1 bây giờ = "generated map deployed" thay vì "dynamic lookup deployed".


6. Open decisions (updated)

# Decision Status Notes
1 Route resolution mechanism Option C primary GPT approved direction. Final confirm after VPS reverify
2 Template registry location Deferred KB docs sufficient for now
3 Smoke Phase 1 tool bash + curl
4 Legacy cleanup priority L0→L1→L2→L3→L4→L5
5 Table Module SSOT update After implementation
6 Generation script design Deferred to implementation 1 script, 3 maps, DOT cặp
7 collectionMap server mirror Consume from generated source

D28 Design Plan | v0.2 | Option C primary, Option B rejected | Agent evidence merged | 2026-05-08

Back to Knowledge Hub knowledge/dev/laws/dieu28-trien-khai/design/d28-nuxt-ui-template-consolidation-design-plan.md