00 — RP Production API Operator Fix / UI Truth / Smoke — Readme First
— RP PRODUCTION API OPERATOR FIX / UI TRUTH / POST-FIX SMOKE — 2026-06-06
Status: PARTIAL. Execution mode: EXECUTION (delegated). Live mutation: YES on DB (10 additive birth-neutral views), NO on production handlers/containers (no restart, no rebuild, no source edit). Host: vps.incomexsaigoncorp.vn. DB: directus.
Objective met to the safe boundary: the only RED control-plane lane (RP production API/UI) is now fully root-caused with live evidence, all fixes are engineered and proven, a real smoke harness exists, the UI cannot falsely report ready, and the router reflects truth. The remaining step — restart/rebuild of the production Nuxt container — is an all-users action left to the operator with a staged, auto-rollback packet.
Headline facts (live, 2026-06-06 ~04:47 UTC):
- Endpoint truth: 12 HEALTHY (200) / 4 PARAM_REQUIRED (400, by design) / 2 SERVER_ERROR (500) / 1 ROUTE_MISSING (404). One extra route /api/registry/refresh-counts returns 404 to GET because it is a POST-only mutating route (not a break).
- 3 real breaks: /api/registry/matrix (500), /api/registry/pivot-query (500), /api/registries/index (404).
- PIVOT_MISSING = 14: explained 14/14 (9 by-design cross/drill nodes, 3 empty composition levels, 2 retire-phantoms). Not a production break.
Root causes (concrete):
- pivot-query 500: handler filters jsonb column group_spec with Directus
_neqagainst a JSON string literal — Directus 11.5 emits invalid SQL -> 400 -> rethrown 500. Fix proven live: drop the jsonb filter, filter cross in JS -> 200 with 12 cross of 37 active pivots. - matrix 500: handler pulls /items/entity_labels?limit=-1 = 897,347 rows over Directus REST in a 512 MB container with a 15s per-fetch timeout -> times out -> generic 500 at ~28s. Fix: aggregate via pg view v_rp_entity_label_facet_counts (226,052 rows) using the existing rpQuery helper, mirroring the sibling registries-pivot endpoints.
- registries/index 404: the /knowledge/registries page calls GET /api/registries/index but no server route is mounted in build s174 (string present only in the client chunk) = client/server drift. Fix: add the handler (needs rebuild to register) or repoint the page.
Read order: 01 baseline, 02 route/handler mapping, 03 404 fix, 04 500 fix, 05 pivot-missing, 06 UI current integration, 07 smoke harness, 08 operator packet, 09 router update, 10 safety audit, 11 final summary, 12 checkpoint.
Staged artifacts on VPS: /opt/incomex/docs/mcp-writes/rp-production-api-fix-2026-06-06/ — 01_apply.sql, 99_rollback.sql, rp-production-smoke.sh, rp-apply-hotfix.sh, patches/pivot-query.get.mjs, patches/matrix.get.mjs, patches/registries-index.get.ts. Local copies: /Users/nmhuyen/rp-production-smoke.sh and rp-apply-hotfix.sh.
Forbidden lines respected: no fake API PASS, no UI ready while any API 404/500, no unsafe deploy over divergent git, no source IU edit, no REAL_RUN, no event activation, no fake owner/vote, no broad auth mutation, PIVOT_MISSING not hidden.