KB-72AF

Branch H — Claude Code Handoff (engineering brief)

9 min read Revision 1
mowui-handoffclaude-codeengineering-briefdata-contractviewsdotpermissionacceptance2026-05-29

Branch H — Claude Code Handoff (engineering brief)

Audience: Claude Code only. Data contracts, backend views/functions, DOT action map, permission model, state/loading/error handling, test cases, acceptance. No visual design guessing — for look/tokens/components see doc 07. You wire a render shell to backend contracts; you invent no business logic and no visual decisions.


1. Architecture rules (Điều 28)

  • Nuxt = render shell, zero business logic. No rules/calculations/workflow semantics in the front end.
  • No direct PG from the UI. All reads go through Directus views/permissions or named DOTs. The UI never opens a PG connection.
  • No hardcoded workflow/task/tier data. Everything comes from registry config + view rows.
  • No raw writes to design columns. Every mutation is a DOT call (doc 05) enforcing gate/owner/approval.
  • No realtime vector / no Qdrant write (vector_sync_enabled=false, never_flip).
  • No PG tables not in the registry; no schema creation from the UI layer.

2. Data contracts (consume, don't redefine)

  • CanvasNode (22 fields + instance_data) and CanvasContext — doc 03 §1–2.
  • The UI is shape-driven: it renders whatever CanvasNode[] the DOT returns and shows the action chips named in permission_actions. It must not assume fields beyond the contract.

3. Backend views / functions (the read substrate)

Object Type Backs Notes
v_mow_design_workflow view Surface 1/3 header scale fix required: replace the two correlated subqueries (step_count, bound_step_count) with a pre-aggregated LEFT JOIN (SELECT workflow_id, count(*) step_count, count(*) FILTER (WHERE step_iu_ref IS NOT NULL) bound_step_count FROM workflow_steps GROUP BY workflow_id) before exposing at thousands of rows
v_mow_design_step view Surface 3 steps is_iu_bound = (step_iu_ref IS NOT NULL)
v_mow_governance_cockpit view (doc 07 P1) Surface 4 over approval_requests/apr_approvals/workflow_change_requests/governance_registry
fn_mow_design_health fn health rollup owner_set, version_set, bound_pct, dangling refs
fn_mow_design_validate fn validation findings doc-06 checks
fn_mow_design_render_tree fn DAG steps+relations+condition refs
fn_mow_design_audit fn change history workflow_change_requests + approval_requests
fn_workflow_rollup_compute fn nav traffic_light R1–R6 rollup → gray|green|yellow|red
fn_iu_gate_verify_closed fn cockpit gate light all_safe / never_flip / governed_closed

EXTEND columns this UI depends on (additive, pending Điều-32 commit — doc 02 Phase 1): workflows +8 (owner_gov_code, design_iu_ref, active_design_version, freeze_active, freeze_reason, freeze_at, freeze_by, design_health), workflow_steps +7 (step_iu_ref, guide_iu_ref, dot_ref, output_table_ref, event_domain_ref, event_type_ref, step_version), workflow_step_relations +1 (condition_iu_ref). 8 FKs land NOT VALID then VALIDATE off-peak.

Tier-table reality: tbl_linh_vuc/tbl_cong_ty/tbl_phong_ban/tbl_chuyen_mon/tbl_nhiem_vu_type/tbl_task_type are not yet born in live PG. Build T6–T4 against a mock/config source behind the same DOT interface; switch to tbl_* when ratified. T2/T1 run on workflows/workflow_steps/tasks today. First engineering task: a live-PG reuse-first survey confirming which of the 31 logical registries are REUSE/EXTEND/NEW/DEFER (the v1 pack's one blocking item P2).

4. DOT action map (consume doc 05)

  • Read DOTs registerable post-EXTEND: dot_mow_design_list/get/health/validate/render_tree/audit.
  • New canvas read DOTs to implement (DOT_SPEC_ONLY): dot_mow_canvas_get_nodes/get_context/drill_down, dot_mot_get_task_card. Each must be added to dot_iu_command_catalog with a target function and a passing Điều-35 paired test before the UI calls it.
  • Mutating DOTs (deferred, need fn + approval): binds, freeze/unfreeze, propose_change, activate, rollback. The UI calls these only through the capability list; it must gracefully hide/disable any DOT the row's permission_actions omits.
  • Verify every DOT exists in dot_iu_command_catalog before wiring it; treat absence as "render disabled + explain", never a crash.

5. Permission model (backend-enforced, Điều 37)

  • Every list = DB view + Directus permission policy + per-tier Điều-37 predicate; super-admin is subject to the same predicate.
  • The UI renders action chips only from each row's server-provided permission_actions (view / propose / admin). No client-side permission logic.
  • Approve/Reject is NOT an agent-callable DOT — it writes apr_approvals and requires ≥2 human cross-signs; the backend automated-agent CHECK rejects any agent decision row (Điều 32). The agent UI shows governance read-only.
  • Activation/rollback owned by GOV-COUNCIL; bind/freeze by MOW owner; propose by any author (queued).

6. State / loading / error handling

  • Loading: skeleton rows/cards; never blank.
  • Error: banner + retry; never a partial silent list; never hide a 🔴 governance item.
  • Empty: contract-specified strings per surface (doc 02 §5, doc 04).
  • Stale-data: every payload carries as_of + per-row last_updated_at; re-fetch on action completion; optimistic updates forbidden for governance.
  • Large-result guard: keyset pagination, hard page cap (~100), "refine filters" guard; never OFFSET at 10k+.

7. Test cases (acceptance-level)

  1. Contract conformance: dot_mow_canvas_get_nodes(tier=T3, parent=X) returns CanvasNode[] with all 22 fields, child_preview ≤ 3, rollup traffic_light computed in SQL.
  2. Permission slice: a read-only role sees permission_actions:[view] only; no mutate chip rendered; a forged mutate DOT call is rejected backend-side.
  3. Agent self-approval blocked: an agent-authored apr_approvals insert is rejected (automated-agent CHECK).
  4. Scale: v_mow_design_workflow returns page 1 of 10k rows under target latency using the pre-agg join (no correlated-subquery regression).
  5. Stale-data: after dot_mow_design_propose_change, the card re-fetches and proposal_count increments; no optimistic stale render persists.
  6. Traffic-light correctness: a workflow with a dangling dot_ref renders 🔴 at step and rolls up to 🔴 at the workflow card.
  7. Empty/error/loading: each surface renders the contract strings; an injected view error shows banner+retry, not a partial list.
  8. WF-001 pilot (doc 09): the 10-step pilot renders 🟢 with all is_iu_bound=true after binding; drill-down to IU works.
  9. DOT existence guard: an unregistered DOT renders the action disabled+explained, never a crash.
  10. Tier-table absence: with tbl_* absent, T6–T4 render from the mock/config source through the same DOT interface without UI changes.

8. Acceptance criteria

  • UI is a pure render shell: removing all backend views/DOTs leaves zero business logic stranded in Nuxt.
  • Every surface is server-paginated, server-sorted, server-filtered; no client full scan.
  • Every action goes through a named DOT; no raw SQL/Directus item write to design columns.
  • Permission chips come 100% from permission_actions; no hardcoded role logic.
  • All 10 test cases pass against live (read) PG; mutating paths only after EXTEND commit + DOT registration + approval.
  • No Qdrant write, no runtime instance creation, no event emission from the UI.

9. Code handoff verdict

READY (separated, engineering-only). Data contracts, backend views/functions, EXTEND-column dependency, DOT map with registration gaps, backend-enforced permission model, state/loading/error rules, 10 test cases, and acceptance criteria are specified with no visual guessing. The one prerequisite engineering task (live-PG reuse-first survey + read-model contract validation) is named as the first step.

Back to Knowledge Hub knowledge/dev/reports/architecture/mow-unified-canvas-master-ui-handoff-pack-2026-05-29/08-claude-code-handoff.md