medOS ultra

Unified Procedure-Room Setup

One admin page to configure procedure rooms, presets, and per-procedure features.

4 min read diagramsUpdated 2026-05-30docs/architecture/procedure-room-setup-unified.md

Status: Phase 1 (sandbox prototype) in progress 2026-05-29. Goal: one admin page where you add a procedure → assign it to a department’s procedure room → configure that room’s phases, columns, actions/gates, and category — and the procedure then routes to that room’s procedure_day_queue. Unifies config that’s currently split across three stores + a hardcoded TS file.

The mental model

A procedure room = a subDept UUID (department_id). Everything hangs off it:

Procedure Room (subDept UUID)
├─ Metadata        category / title / color / workspace_style   → specialty_clinic_modules   [EXISTS]
├─ Procedures      catalog assigned to this room                → NEW (today: hardcoded dayProcedures)
├─ Phases/times    sign_in(time-in) / time_out / sign_out(time-out) / intra_op(clock-in/out) /
│                  recovery / par_score / surgical_team / surgical_type   → procedure_workflow_config [EXISTS]
├─ Actions & gates allowed row actions + required-before-complete → procedure_workflow_config.gate + policy_gates [EXISTS]
└─ Queue columns   which columns show / order / labels           → NEW

Why “assign to room” just works for routing: the room’s subDept UUID is the procedure_day_queue.department_id. Orders carry category:'procedure' + the room’s location; the encounter-orchestrator routes category:'procedure' → the procedure queue for that room (resolveDepartmentKeyFromOrderItem). So assigning a procedure to a room + ordering it lands it in that room’s queue with no extra plumbing.

What already exists (reuse — do NOT rebuild)

Concern Store Where
Phases / timestamps / gates procedure_workflow_config (Supabase, mig 075) 4-tier resolver procedureWorkflowConfig.service.ts (resolveConfig/saveConfig), admin page pages/admin/procedure-workflow-config.tsx, catalog ALL_PROCEDURE_FEATURES
Clinic metadata + category specialty_clinic_modules (Supabase, mig 20260517c) useSpecialtyClinicModules.ts; columns incl. category (clinic/specialized_unit/other_service), title_*, color, icon, sub_dept_id, workspace_style, status, display_order
Procedure catalog (backend) procedureItems (Mongo REST v2/medication/procedureItems) services/ever-medication/procedureItem.service.tslist/create/update, fields name/product/unit/category/snomed/active
Department picker source SEEDED_DEPARTMENTS (code) + custom UUID procedureWorkflowConfig.defaults.ts, screeningModalConfig.defaults.ts
Routing category + location → department_queues.dept_type encounter-orchestrator/index.ts resolveDepartmentKeyFromOrderItem (case 'procedure')
Related admin pages department-config-hub.tsx, subclinic-management.tsx, administration-setup.tsx, clinic-management.tsx, fee-schedule-management.tsx

The genuinely-new pieces

  1. Procedure → room assignment — today dayProcedures is hardcoded in clinic-configs.ts. Need a per-room, runtime-editable list. Phase 2 table: procedure_room_procedures(department_id, code, name_th, name_en, est_minutes, icd_code, addons jsonb, display_order, active).
  2. Queue column config — per-room which columns show, order, labels. Phase 2: a column_config JSONB on the room (or a small table). Column ids: hn, patient, procedure, priority, status, time_in, time_out, clock_in, clock_out, room, actions.
  3. The unified page — one editor tying all axes together (below).

The page — ProcedureRoomSetup (5 tabs)

Pick a room (dropdown from specialty_clinic_modules + SEEDED_DEPARTMENTS + paste-UUID), then:

  1. Room & Category — category, title, color, workspace_style, subDept id (+ placeholder warning).
  2. Procedures — list the room’s procedures; add new (code, nameTh, nameEn, est minutes, ICD); remove; reorder. This is “add a procedure, assign it to this room.”
  3. Phases & TimestampsALL_PROCEDURE_FEATURES rows with enabled/required toggles + presets (full-or / minor-ops / safety-only / basic-opd). Reuses the real procedure_workflow_config service.
  4. Columns — enable/disable + reorder + relabel queue columns; live preview of the resulting queue header.
  5. Actions & Gates — allowed row actions (accept/start/complete/cancel/hold) + which phases are required-before-complete (drives blocked_actions). Reuses procedure_workflow_config.gate.

Rollout

Phase 1 — sandbox prototype (this work)

  • [ ] docs/architecture/procedure-room-setup-unified.md (this file)
  • [x] room-registry.ts + AddRoomDialog.tsx — runtime-added rooms persist to localStorage procedure_rooms.v1; getAllRooms() merges built-in (SPECIALTY_CLINIC_CONFIGS) + custom. A custom room is a full SpecialtyClinicConfig (placeholder subDept until a real UUID is pasted).
  • [x] ProcedureRoomDirectory.tsx (“stores” page) — searchable card grid of all rooms; Add clinic; per-card code ID + category + proc count + built-in/custom badge; cards deep-link to ?target=ProcedureRoomSetup&room=<key> and ?target=ClinicOrderSystem&clinic=<key>; Remove (custom only).
  • [x] ProcedureRoomSetup picker surfaces the code ID per item + a code <key> chip, an inline New button (AddRoomDialog), and ?room=<key> deep-link preselect.
  • [ ] ProcedureRoomSetup.tsx — 5-tab editor, localStorage-backed (procedure_room_setup.v1) so it’s try-able offline; Phases tab uses the real resolveConfig/saveConfig. Plain MUI (sandbox-safe).
  • [ ] ProcedureRoomSetupTarget.tsx + register (?target=ProcedureRoomSetup) + targetMeta (category ‘config’)
  • [ ] Verify in sandbox: pick room → add procedure → toggle phases → add/reorder columns → gates → preview

Phase 2 — real persistence + wiring (next)

  • [ ] Migration: procedure_room_procedures + per-room column_config (Supabase) with RLS like 075/076
  • [ ] Procedures tab → real procedureItems REST create + room assignment write
  • [ ] Room & Category tab → real specialty_clinic_modules upsert
  • [ ] Mount as a real admin route (design-kit components per style guide) — likely a tab in department-config-hub.tsx
  • [ ] Wire ClinicOrderSystem to READ the room config: procedures from procedure_room_procedures, columns from column_config, phase columns/actions from procedure_workflow_config
  • [ ] Confirm end-to-end: add procedure in setup → appears in that room’s Order System → orders route to its procedure_day_queue

Invariants

  • Room identity = subDept UUID = procedure_day_queue.department_id. Never invent a second id.
  • Reuse procedure_workflow_config for phases/gates; never fork it.
  • Frontend writes config to config stores only — never to read models (procedure_day_queue, department_queues).
  • A procedure with no real subDept assignment can’t route (surface a placeholder warning).
Ask Anything