KB-6AFA
D28 — Generated Table Map Design Review Report
7 min read Revision 1
dieu28reportdesign-reviewgenerated-map2026-05-09
D28 — Generated Table Map Design Review Report
Date: 2026-05-09 Agent: claude-opus-4-7 (1M ctx) Mode: READ + DESIGN + RECOMMEND (no implementation) Linked design:
knowledge/dev/laws/dieu28-trien-khai/design/d28-generated-table-map-design.md
VPS reverify
nuxt_repo_path=/opt/incomex/docker/nuxt-repo/web # corrected — prompt path /opt/incomex/web/ inexistent
tableIdMap_vps_entries=18
tableIdMap_vps_matches_local=YES (verbatim — 18 entries: catalog, table, module, workflow, workflow_step, wcr, dot_tool, page, collection, task, agent, checkpoint_type, checkpoint_set, entity_dependency, table_proposal, checkpoint_instance, changelog, system_issue)
collectionMap_vps_content=20 entries (tableIdMap 18 + trigger, comment, taxonomy); reverseCollectionMap derived via Object.fromEntries
relations_mirror_vps_content=14 entries (subset of collectionMap; missing: changelog, system_issue, trigger, comment, taxonomy, table_proposal) — drift confirmed
build_command=nuxt build (web/package.json scripts.build)
pre_build_hooks=postinstall=nuxt prepare; NO prebuild script currently
deploy_flow=GitHub Actions (deploy-vps.yml + deploy.yml + dieu31-vps-setup.yml + nuxt-ci.yml + post-deploy-e2e.yml + ops-smoke.yml)
generated_dir_exists=NO (web/generated/ absent)
import_alias_pattern=Nuxt default (~ → web/, ~~ → repo root); no custom alias overrides in nuxt.config.ts head 100 lines
existing_auto_files=web/utils/auto-link.ts only (unrelated)
Table registry schema
table_registry_columns=[id, table_id, name, collection, fields(json), default_sort, default_filter(json), page_url, enable_insert_marks, enable_proposals, enable_search, enable_pagination, rows_per_page, status, module, description, _dot_origin]
entity_type_column_exists=NO
relevant_columns_for_design=[id, table_id, collection, page_url, status]
Row classification (21 rows)
(full table → see design §5)
registry_entity_route_count=13 (id 9–21)
non_registry_page_count=3 (id 1, 5, 6)
workflow_tab_count=3 (id 2, 3, 4)
admin_page_count=1 (id 7)
index_page_count=1 (id 8)
unknown_count=0
total=21 ✓
Notable findings:
- id 21
tbl_event_outboxstatus=draft, NOT in tableIdMap — chicken-egg target. - id 3
tbl_workflow_timelineshares collectionworkflow_stepswith id 2 — script will skip (no unique entityType). - id 5
tbl_modules_list.collection='tasks'— likely data error (should bemodules); flagged for separate data-fix pack. - id 7
table_proposalmissing fromcollectionMap— drift; generated map auto-fixes. - relations.get.ts
COLLECTION_ENTITY_MAPlags collectionMap by 6 entries — drift.
Design recommendations
entity_type_strategy_recommended=E4 (Phase 1) → E3 (Phase 2 separate pack)
entity_type_strategy_rationale=Convention rules + explicit overrides avoid schema migration; deterministic, fail-fast on unknown rows. Migration to E3 (add entity_type column) trivial after E4 lands because override dict serves as backfill source.
script_location_recommended=web/scripts/generate-table-maps.ts
script_language_recommended=TS (run via tsx) — output is .ts; preserves type safety; matches existing web/scripts/ conventions
output_path_recommended=web/generated/table-maps.generated.ts
output_format_recommended=SINGLE_FILE (3 named exports + __META__ header with rowCount, contentHash sha256, generatedAt, statusFilter)
client_server_import_safe=YES — pure static module (no env refs, no runtime fetch); imported from page.vue (client+SSR), config/detail-sections.ts (universal), and server/api/discovery/relations.get.ts (Nitro)
credential_strategy_recommended=BUILD_TOKEN (NUXT_DIRECTUS_SERVICE_TOKEN already configured in runtimeConfig; reuse for build script; NEVER bundle into output)
build_timing_recommended=PREBUILD + COMMIT_GENERATED (npm prebuild hook regenerates; CI runs --check; PR diff visible)
draft_handling_strategy_recommended=Default exclude draft; --include-draft flag for dev preview; force_include[] in script config as last-resort backup
draft_chicken_egg_solution=Sequence: (1) dev regen with --include-draft; (2) smoke route on dev preview; (3) publish row in Directus (status='published'); (4) production prebuild picks up automatically with default flag
drift_verification_design=tsx scripts/generate-table-maps.ts --check exits 1 on mismatch; integrated into nuxt-ci.yml and deploy-vps.yml; content_hash header in artifact detects manual edits
rollback_design=git revert generation commit (artifact committed → git history is backup); script supports force_include[] as hotfix
static_extras_handling=trigger/comment/taxonomy added via static_extras dict in script config (no table_registry rows); conflict detection if key collides with derived map
Blockers
phase_status=PASS
vps_reverify_status=PASS (path corrected: /opt/incomex/docker/nuxt-repo/web/)
table_registry_schema_status=PASS (no entity_type column confirmed; design accommodates)
route_row_classification_complete=PASS (21/21 classified)
generated_module_import_safe=PASS (verified pure-static design feasible from inspecting 3 consumer files)
secret_leakage=PASS (no secrets printed; build token strategy keeps token in env, not artifact)
blockers=[]
Data-quality flags (out-of-scope, deserve separate pack):
- id 5 collection mismatch (
tasksvsmodules). - relations.get.ts pre-existing drift (will be auto-fixed once consumers swap to generated import).
- 14 rows with
module=null(cosmetic).
Next
recommended_next_pack=D28_GENERATED_MAP_IMPLEMENTATION_PROMPT
follow_up_packs=
- D28_TABLE_REGISTRY_DATA_FIX_PROMPT (id 5 collection field; id 3 disambiguation policy)
- D28_TABLE_REGISTRY_SCHEMA_EXTENSION_PROMPT (Phase 2: add entity_type column + backfill)
Hard boundary final check
no_nuxt_edit=true ✓
no_file_creation_on_vps=true ✓
no_directus_mutation=true ✓
no_pg_mutation=true ✓
no_publish=true ✓
no_deploy=true ✓
no_implementation=true ✓
no_secret_in_report=true ✓
design_and_read_only=true ✓
D28 Generated Table Map Design Review Report | 2026-05-09 | claude-opus-4-7