KB-6A6D

IU Core 1500x — Directus read-only registration package

5 min read Revision 1
iu-core1500xdirectusregistrationthree-axisui-assembly

03 — Directus read-only registration package

1. Boundary held

The PG -> Directus -> Nuxt assembly contract requires every Nuxt screen to read IU Core data via Directus, never directly from PG. This macro builds the read-only registration package for that Directus collection — not the Nuxt code, not the Directus runtime call.

The package is data-only: a JSON-serialisable artifact a Directus admin (or the next deploy-gated slice) can apply via the standard Directus REST/SDK paths. No Nuxt logic, no Directus client in this module, no permission bypass.

2. v_ui_iu_directus_registration_envelope — the discovery view (durable)

Migration 021 added a read-only view that introspects information_schema.columns for v_ui_iu_three_axis_envelope and returns the deterministic field list:

field source purpose
field_name c.column_name Directus field id
pg_type c.data_type discriminator for Directus type map
pg_udt c.udt_name discriminator for array / udt
is_nullable c.is_nullable Directus required flag
ordinal_position c.ordinal_position sort + tab ordering
axis_group CASE on column_name primary / axis_a / axis_b / axis_c / meta

Live evidence — 16 fields, every axis group populated (unit_id, canonical_address, unit_kind, section_type, lifecycle_status, axis_a_doc_code, axis_a_sort_order, axis_a_section_code, axis_b_tags, axis_b_tags_by_source, axis_c_parent_id, axis_c_depth, axis_c_ancestors, axis_c_ancestor_addresses, created_at, updated_at).

The view is the SSOT — the field list is never hand-typed in Python, SQL or Nuxt. Adding a field to v_ui_iu_three_axis_envelope automatically propagates to the registration package.

3. directus_registration.py — the package builder

build_registration_package(executor, collection_name=DIRECTUS_THREE_AXIS_COLLECTION) reads the envelope view and returns a frozen DirectusRegistrationPackage. Three payload methods produce the bodies for the Directus REST/SDK calls — the operator (not this module) issues them:

  • directus_collections_payload() -> body for POST /collections. Marks the collection read-only by convention (sort on axis_a_sort_order, accountability=all, icon=schema).
  • directus_fields_payload() -> bodies for POST /fields/<collection>, one per field. Each carries readonly=true, sort=ordinal_position, required=NOT is_nullable, axis-group note. The unit_id field is flagged primary.
  • directus_permissions_payload() -> READ-only permission objects, one per role in DIRECTUS_ROLE_HINTS = (administrator, viewer, editor). The operator chooses which roles to grant.

A deterministic JSON serialiser (as_json()) makes the package diffable in git. The Directus type map is derived from the pg_type/udt (uuid -> uuid, jsonb -> json, ARRAY/_text/_uuid -> json, timestamp* -> dateTime, integer kinds -> integer, else string).

4. Disable / rollback path

build_disable_package(collection_name) returns DELETE /collections/<name>. The Directus REST DELETE cascades the fields + permissions metadata. The underlying PG view is never touched.

5. CLI surface

DIRECTUS_REGISTRATION_COMMANDS registers two one-commands (no IO):

  • dot_iu_directus_three_axis_register_plan — prints the registration package JSON for operator review.
  • dot_iu_directus_three_axis_disable_plan — prints the disable package JSON.

6. What is NOT in this macro

  • The Directus REST calls themselves (deploy-gated; operator action).
  • The Directus admin permissions grant (operator chooses roles).
  • Any Nuxt screen — doc 04 handles the assembly contract.

7. Sandbox/200 — registry + envelope probe (10/10 PASS)

S1 register new collection (planned) - PASS S2 re-register flips status (idempotent) - PASS S3 refuse re-dimension (immutable identity) - PASS S4 refuse empty actor - PASS S5 refuse invalid distance metric (Hamming) - PASS S6 reversible retire - PASS S7 re-register resurrects retired row - PASS S8 envelope view returns >=12 fields - PASS S9 every axis group covered - PASS S10 refuse retire on unknown collection - PASS

All 10 inside one BEGIN...ROLLBACK on production. Zero durable rows written by sandbox/200.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-1500x-qdrant-directus-nuxt-external-closeout-open-goal/03-directus-registration-package.md