KB-55E0
23-P3D4C2U — Table Module Read-Only Exposure Report
6 min read Revision 1
p3d4c2ureporttable-moduledirectusreadonlydesign-reviewpass
23-P3D4C2U — Table Module Read-Only Exposure Report
Date: 2026-05-08 Status: PASS — design review complete, no implementation performed. Companion design note:
knowledge/dev/laws/dieu44-trien-khai/design/23-p3d4c2u-table-module-readonly-exposure-design.md
§1. Mandatory documents reviewed
| # | Document | Read |
|---|---|---|
| 1 | knowledge/dev/ssot/assembly-module/index.md |
PASS |
| 2 | knowledge/dev/ssot/table-module/index.md (v4.1) |
PASS |
| 3 | knowledge/dev/planning/table-module/_PLAN.md |
PASS |
| 4 | knowledge/dev/laws/law-07-assembly-first.md (Điều 7) |
PASS |
| 5 | knowledge/dev/architecture/standard-template-law.md (Điều 28) |
PASS |
| 6 | knowledge/dev/laws/dieu44-trien-khai/design/23-p3d-ui-boundary-directus-nuxt-assembly-note.md |
PASS |
| 7 | knowledge/dev/laws/dieu44-trien-khai/reports/23-p3d4c1u-universal-core-implementation-report.md |
PASS |
| 8 | GPT review 23-p3d4c1u execution pass | PASS |
| 9 | GPT alignment Opus P3D4C2U template approach | PASS |
| 10 | knowledge/dev/laws/dieu43-system-context-law.md |
PASS |
§2. Live state probes (read-only)
| Probe | Result |
|---|---|
GET /items/table_registry |
20 rows; ids 1..20; mix of active/published |
tbl_system_issues row |
✅ id=20, collection=system_issues, page_url=/knowledge/registries/system_issue, status=published, default_sort=-detected_at, rows_per_page=50, enable_search=true |
| Generic route convention | /knowledge/registries/{singular} confirmed across 13/20 registry rows |
directus_list_collections |
event_outbox, event_pending, event_read, event_subscription, event_type_registry all present (auto-introspected) |
GET /items/event_outbox |
HTTP 403 — collections introspected but no read permission seeded yet (gap to be closed by DOT in next pack) |
KB search v_event_outbox* |
No live view; only design sketches (P3D4B v_iu_notification_board, P3D4C0X 5-layer note) |
§3. Required report fields
phase_status=PASS
assembly_module_read=PASS
table_module_read=PASS
dieu7_read=PASS
dieu28_read=PASS
dieu43_reviewed=PASS
dieu43_graphic_relevance=USED_AS_CONTEXT
table_registry_entries_count=20
system_issues_registry_found=PASS
directus_table_available=PASS
generic_table_route_available=PASS
event_schema_inventory=PASS
event_subject_ref_type=text
read_status_source_values=explicit,implicit_self
display_source=PG_VIEW_PROJECTION
pg_projection_needed=YES
pg_projection_name=v_event_outbox_table
unsafe_fields_hidden=PASS
table_registry_declaration_drafted=PASS
directus_dot_plan_drafted=PASS
readonly_only=true
mark_read_ui=DEFERRED
nuxt_path=NO_NUXT_CODE
bespoke_notification_ui=false
nuxt_business_logic=false
nuxt_direct_pg=false
body_payload_vector_secret_exposed=false
worker_cron_added=false
iu_runtime_changed=false
recommendation=PROCEED_TO_DOT_TABLE_REGISTRATION_PROMPT
next_required_pack=P3D4C2U_DOT_TABLE_REGISTRATION_IMPLEMENTATION_PROMPT_REVIEW
§4. Display source rationale (summary)
PG_VIEW_PROJECTION chosen over RAW_EVENT_OUTBOX:
- Schema-level masking is more durable than Directus field allowlisting (new columns auto-leak otherwise).
- Future read-state join (
LEFT JOIN event_read) lives in the view — DirectusTable config stays trivial. - Aligns with Điều 43 "consolidated read-only VIEW, 0 duplicate, 0 drift" pattern.
- Function-backed (
fn_event_unread/fn_event_board) not feasible: DirectusTable consumes a collection, not a function. Defer.
§5. Drafted artifacts (in design note)
- §3.1 design —
v_event_outbox_tableview sketch (12 metadata-only columns, deviations preserved:event_subject_ref text,read_status_source IN ('explicit','implicit_self')) - §4 design —
tbl_event_outboxrow fortable_registry(modeled ontbl_system_issues, 12 fields, status=draft) - §5 design — 8-step DOT-driven Directus exposure plan (PG view → GRANT → collection meta → field meta → permission → registry row → smoke → rollback) + verify pair convention
- §6 design —
NO_NUXT_CODEjustification + smoke-check caveat against TT-020/021/022 status
§6. Hard boundaries upheld
- ✅ No implementation performed
- ✅ No PG mutation
- ✅ No Directus mutation
- ✅ No Directus click-config
- ✅ No Nuxt code
- ✅ No bespoke notification UI / page / component
- ✅ No Nuxt business logic / direct PG
- ✅ No Directus write/mark-read in this pack
- ✅ No body / raw payload / vector / secret in proposed projection
- ✅ No IU runtime change
- ✅ No worker / pg_cron added
- ✅ No Điều 43 machinery duplication or modification
§7. Caveats / inventory uncertainty
- TT-020/021/022 status mismatch. Table Module SSOT v4.1 still lists DirectusTable wiring to
table_registryas 🔴 ("đang xây"), yet 13/20 registry rows arepublished. Implementation prompt MUST first smoke/knowledge/registries/system_issueactually renders via<DirectusTable tableId="tbl_system_issues">before flippingtbl_event_outboxtopublished. If the generic route is not wired, recommendation downgrades toNEEDS_GENERIC_TEMPLATE_EXTENSION. - Directus 403 on event_ collections.* Confirms permission seed is needed; not a blocker.
- PG view ownership/role. Implementation prompt must confirm which PG role Directus uses to read system_issues-style collections and grant SELECT on
v_event_outbox_tableaccordingly.
§8. Recommendation
PROCEED_TO_DOT_TABLE_REGISTRATION_PROMPT
next_required_pack = P3D4C2U_DOT_TABLE_REGISTRATION_IMPLEMENTATION_PROMPT_REVIEW
Single sentence: universal events can be exposed by adding one PG view + one table_registry row + a DOT-driven Directus permission seed — one more book on the existing shelf, zero new shelves, zero Nuxt code.