OR System Component Map
Complete inventory of the Operating Room subsystem: every routable surface, kit component, miniapp, and service.
Scope: Complete inventory of the Operating Room subsystem across the medOS-ultra monorepo — every routable surface, every kit component, every miniapp, every service. Written so a designer or frontend engineer can decide where to plug in a new UI layer without spelunking the codebase first.
Last verified live: 2026-05-13 on localhost:5192 with my recent route wiring + MUI v7 grid + STUB-encounter fixes.
1. Executive Summary
The OR system spans three tiers of “View” that all hit the same operating_room_requests data model:
- Standalone page routes at
/operating-room/*and/periops/operating-room*— full-page clinic surfaces (dashboard, worklists, settings, reports). Mounted via React Router. - Miniapp surfaces rendered by
DynamicContentRenderer— embedded inside the patient profile dynamic-tab system, keyed byDynamicCoreAppenum values. The OR-related ones arePERFORM_SURGERY,RECOVERY_ROOM_REQUEST,PREOPERATIVE_CHECKLIST, and ~14 anesthesia miniapps. - Dialogs spawned from worklist rows — modal-style flows for status transitions, team assignment, dates, marking site, eform attachment, pre-op assessment.
Three things matter when redesigning:
- The
operating_room_requestsentity is the spine. ~10 page-level surfaces and ~20 dialogs/forms all CRUD this one entity (with different filter slices + status state-machine transitions). - The data layer is dual-backend — MongoDB (write source-of-truth, REST API via
@services/ever-medication/operatingRoomRequest.service) AND Supabase (read-model cache + the perform-surgery write path). When redesigning forms, check which backend the form targets (*.supabase.service.tsvs the REST service). - Kit components live in
web/packages/periops-kit/src/operating-room/components/*. They are framework-agnostic UI shells — fetch data themselves via hooks, render their own MUI tables/forms. The container files underweb/src/containers/operating-room/*are 5-line wrappers that just re-export the kit component.
A new UX/UI can replace any layer independently:
- Replace container wrappers to swap in a new kit
- Replace kit components to keep routing + services but get a new look
- Replace miniapps (in
web/packages/miniapps/perform-labourroom-supabase/) to redesign the in-patient-profile surface independently of the standalone pages
2. MVC Mapping for This Repo
The codebase doesn’t use a textbook MVC framework, but the layers are clearly separable:
| Classic MVC | medOS layer | Where it lives |
|---|---|---|
| Model | Backend entity + Supabase tables + service-client typings | services/ever-medication/operatingRoomRequest.service.ts (REST/MongoDB), infrastructure/medbase/migrations/* (Supabase tables), perform-labourroom-supabase/services/*.supabase.service.ts (Supabase client) |
| View | Kit components + miniapp render files | web/packages/periops-kit/src/operating-room/components/*, web/packages/miniapps/perform-labourroom-supabase/Render*.tsx |
| Controller | React Router routes + lazy container wrappers + DynamicContentRenderer switch | web/src/routes.tsx, web/src/routes/OperatingRoomRoutes.tsx, web/src/containers/operating-room/*/index.tsx, web/src/common/components/shared-engine/dynamic-core/engine/DynamicContentRenderer.tsx |
When the prompt says “build new UX/UI on the View layer,” it means: edit the kit components and miniapp render files. Routing + services stay untouched.
3. System Topology
┌─────────────────────────────────────────────────────────────────────┐
│ USER ENTRY POINTS │
├──────────────────────────────────┬──────────────────────────────────┤
│ Standalone routes │ Embedded miniapps │
│ (full-page surfaces) │ (DynamicContentRenderer) │
│ │ │
│ /operating-room/dashboard │ ?module=modules.PerformSurgery │
│ /operating-room/list-or-patient│ ?module=modules.RecoveryRoom… │
│ /operating-room/list-or-wait-… │ ?module=modules.Preop… │
│ /operating-room/list-or-recov… │ ?module=modules.Anesthesia* │
│ /operating-room/setting/surg… │ │
│ /operating-room/list-or-stat… │ │
│ /anaesthetist/operating-room… │ │
│ /periops/operating-room │ │
│ /periops/operating-room-calend.│ │
│ /periops/screening-surgery │ │
│ /periops/surgery │ │
└──────────────┬───────────────────┴──────────────┬───────────────────┘
│ │
▼ ▼
┌──────────────────────────┐ ┌────────────────────────────────┐
│ Container wrappers │ │ DynamicContentRenderer.tsx │
│ (5-line re-exports) │ │ switch (tabName) { │
│ /containers/operating-… │ │ case 'PerformSurgery': … │
│ │ │ case 'RecoveryRoomRequest':…│
└──────────────┬───────────┘ └──────────────┬─────────────────┘
│ │
└────────────────┬───────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ KIT COMPONENTS (the actual View) │
│ periops-kit/src/operating-room/components/ │
│ miniapps/perform-labourroom-supabase/ │
└─────────────────────────────────┬───────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ HOOKS LAYER │
│ useOperatingRoomData, useDashBoard, │
│ useDepartmentQueueSubscription, useQuery (react-query) │
└─────────────────────────────────┬───────────────────────────────────┘
▼
┌──────────────────────────┬──────────────────────────────────────────┐
│ REST API (MongoDB) │ Supabase client (read-model + writes) │
│ ever-medication/ │ operatingRoomRequest.supabase.service. │
│ operatingRoomRequest. │ ts (perform-labourroom-supabase) │
│ service.ts │ │
└──────────────────────────┴──────────────────────────────────────────┘
│
▼
┌──────────────────────┐
│ operating_room_ │
│ requests table │
│ (MongoDB + Supabase) │
└──────────────────────┘
4. Layer-by-Layer
4.1 Routing Layer
Active routes (post my wiring work):
| URL | Element | Container/Page | Source |
|---|---|---|---|
/operating-room/dashboard |
`` | containers/operating-room/dashboard/index.tsx → kit OperatingRoomSetupModule |
routes/OperatingRoomRoutes.tsx |
/operating-room/list-or-patient |
same | containers/operating-room/list-or-patient/index.tsx → kit ListOperatingRoomPatient |
same |
/operating-room/list-or-wait-requested |
same | containers/.../list-or-wait-requested/index.tsx → kit ListOperatingRoomWaitRequestModule |
same |
/operating-room/list-or-recovery |
same | containers/.../list-or-recovery/index.tsx → kit RecoveryRoomRequest |
same |
/operating-room/setting/surgery-type |
same | containers/operating-room/setting/surgery-type/index.tsx → kit OperatingRoomSetting |
same |
/operating-room/list-or-statist-report |
same | containers/.../list-or-statist-report/index.tsx → kit MainTab |
same |
/anaesthetist/operating-room-worklist |
direct route | containers/anaesthetist/operating-room-worklist/page.tsx |
routes.tsx:276 |
/periops/operating-room |
`` | containers/operating-room/page.tsx (demo OR dashboard with hardcoded rooms) |
routes/PeriopsRoutes.tsx |
/periops/operating-room-calendar |
same | containers/operating-room-calendar/page.tsx |
same |
/periops/screening-surgery |
same | containers/screening-surgery/page.tsx |
same |
/periops/surgery |
same | containers/surgery/page.tsx |
same |
Legacy redirects (routes/LegacyRedirects.tsx:92-93):
/operating-room→/periops/operating-room/operating-room-calendar→/periops/operating-room-calendar
Bare /operating-room still redirects to the demo dashboard; the sub-paths I added (/operating-room/dashboard, etc.) are matched first by React Router because they’re more specific.
4.2 Container Layer
Purpose: act as the controller’s lazy boundary. Each container is a ~6 line file:
import { OperatingRoomSetupModule } from '@periops-kit/operating-room/components/dashboard';
export default function Page() { return <OperatingRoomSetupModule />; }
Why: keeps the route file lean, provides a stable import target if the kit’s named export changes, and lets us inject app-level providers/wrappers later without touching the kit.
Files in web/src/containers/operating-room/:
dashboard/index.tsxlist-or-patient/index.tsxlist-or-wait-requested/index.tsxlist-or-recovery/index.tsxsetting/surgery-type/index.tsxlist-or-statist-report/index.tsxpage.tsx— the legacy demo dashboard (independent — uses local DEMO_ROOMS array, not the kit)
4.3 Kit Components — periops-kit/src/operating-room/components/*
This is the primary View layer. Six sub-modules, each handles one OR business surface.
4.3.1 dashboard/ — OR Resource Schedule
Entry: OperatingRoomSetupModule.tsx → wraps MainDashboard.tsx in a padding: 1rem div.
Props: { isOpenInDialog?: boolean } (was required before my fix; now optional with default false).
Renders: dual-pane resource calendar.
- LEFT (2fr): `` — filters (calendar month picker + wound-class checkboxes + specialty/building/room/floor autocompletes)
- RIGHT (8fr): `` — schedule grid with weekday columns (Sun-Sat) showing OR occupancy
Top row: Station/Location selector (Major Surgery, Minor Surgery, Endoscopy, Cath Lab).
Hooks: useDepartmentQueueSubscription('PROCEDURE', activeLocation, [['get-list-operating-room'], ['list-surgery-schedule'], ['orRoomStatus']]) — subscribes to Supabase realtime channel for department_queues (deptType=PROCEDURE).
Sub-files:
OperatingRoomFilter.tsx— the left sidebarOpeatingRoomCalendar.tsx— typo in filename, calendar gridCustomOperatingCalendar.tsx— calendar componentTopFilter.tsx— date/location top barmockUpOption.ts—roomarray fallback (mock data)style.tsx— emotion styled wrappers (DashboardContainer)
Known issues: filename typo Opeating (missing ‘r’). Mock data hardcoded. Only MAJOR_SURGERY location wired to real data.
Recent fix: kit’s MainDashboard.tsx had css={{}} (3 places) instead of style={{}} — silently dropped in MUI v7. Fixed by me.
4.3.2 list-or-patient/ — OR Patients (scheduled + in-progress)
Entry: OperatingRoomListPatient.tsx → wraps ``.
Props: none (entry).
Renders: filterable patient table showing OR requests with 9 statuses:
- REQUESTED, ACCEPTED, CANCELLED, OPERATING, COMPLETED, POSTPONE, WAITING, RECOVERED, SENT_BACK_TO_WARD, SENT_TO_ICU, DEAD_ON_TABLE
Filters: date range, building → room (dependent), search box, status tabs.
Data: listOperatingRoomRequestApi() with populate=patientRef,encounterRef,surgeonRef,assistantDoctorRef,specialtyRef,createdBy,acknowledgeBy.
Sub-files:
MainTab.tsx— filter UI + tab containertable-data/ListOrPatientTable2.tsx— table rendertable-data/RowListOrPatientData.tsx— column config
Dialogs spawned from rows: none directly in MainTab — dialogs are in list-or-wait-requested/dialog/ and reused.
4.3.3 list-or-wait-requested/ — Master Pending OR Queue
Most complex subsystem. This is the queue surgeons act on to schedule cases.
Entry: OperatingRoom.tsx exports ListOperatingRoomWaitRequestModule (default).
Renders: 2-tab worklist (PENDING / REQUESTED) with rich filter bar:
- date picker, building, room
- specialty multi-select
- surgical type (EMERGENCY, URGENCY, TRAUMA, ELECTIVE, ELECTIVE_ODS, ELECTIVE_PREMIUM, ELECTIVE_MIS)
- patient type (EMERGENCY, APPOINTMENT, CANCEL)
Data hook: hooks/useOperatingRoomData.ts wraps listOperatingRoomRequestApi(). Default status filter: ['PENDING'], activity: ['normal'].
Table:
NotNotifiedTable.tsx— main table with row action menutable/TableRowNotified.tsx— row config + column definitions
Dialogs (10) in dialog/:
| File | Purpose |
|---|---|
DialogAssignTeam.tsx |
Assign surgeon + anesthesiologist + assistants to case |
DialogNotified.tsx |
Mark case as notified (acked); shows vitals + dates + detail header |
OperatingDetail.tsx |
Edit case details (diagnosis, procedures) |
OperatingDate.tsx |
Reschedule OR date/time (slot picker) |
OperatingEform.tsx |
Attach electronic form (pre-op checklist) |
OperatingForm.tsx |
Generic create/edit form container |
OperatingMarkSite.tsx |
Mark surgical site (Left/Right/Both/N/A) |
OperatingPreOp.tsx |
Pre-op assessment checklist (NPO, consent, labs, etc.) |
OperatingStatus.tsx |
Status state machine transitions |
DetailHeader.tsx |
Patient header banner used inside all the dialogs |
Supporting: mockUpData.ts, timeFormatFunction.ts, type.ts.
Sister folder (top-level, outside components/):
web/packages/periops-kit/src/operating-room/list-or-wait-requested/dialog/ contains DialogAssignTeam.tsx + DialogNotified.tsx only. Duplicate/legacy — same names but in a different location. Almost certainly pre-refactor cruft. Recommendation: confirm via git log and delete if unused.
4.3.4 list-or-recovery/ — PACU Recovery Room Dashboard
Entry: RecoveryRoomRequest.tsx (re-exported via index.ts).
Renders: 2-tab dashboard:
?mainTab=rr-list— Recovery Room patient roster?mainTab=patient-transfer— patients awaiting bed transfer
Data: countAllEncounterStatus() Supabase query for TRANSFEROUT / TRANSFERIN encounter status.
Sub-files:
RecoveryRoomRequestDetail.tsx— RR list tableDialogRecoveryRoomRequest.tsx— detail modalCoditionDetail.tsx,VitalSignDetail.tsx,ParScoreDetail.tsx— vital sign panels inside the dialogPatientSurgeryFormDetail.tsx— surgery form snapshotEventOrItems.tsx— event timelineOperatingQueueDetail.tsx— queue summary
Known issues:
- Room filter commented out (lines 96–102 of
RecoveryRoomRequest.tsx) — unclear if intentional UX or unfinished - Hardcoded sub-clinic UUIDs
affeecb9-…,02c98eb4-…in the query
4.3.5 setting/ — Master Data Configuration
Entry: OpeartingRoomSetting.tsx (typo: Opearting).
Renders: 2-tab MenuTab container:
- ประเภทการผ่าตัด (Surgery Type) — manages elective/urgency/emergency/trauma/elective ODS/elective premium/elective MIS catalog
- การทำความสะอาดห้องผ่าตัด (OR Cleanliness) — manages Clean / Clean-Contaminated / Contaminated / Dirty + cleaning protocols
Routes its child via router.push(code) based on selected menu option.
Sub-folders:
type/— surgery type CRUD:DialogSurgicalManagement.tsx,TableOperatingRoomRequestType.tsxoperating-room-cleanliness/— cleanliness states CRUDutils/— shared helpers
Services: operatingRoomRequestType.service.ts, operatingRoomRequestCleanliness.service.ts from @services/ever-medication/.
4.3.6 list-or-statist-report/ — Surgery Statistics Report
Entry: MainTab.tsx exports MainTab (named).
Renders: filterable report with date range + filters:
- surgical type, specialty, sub-clinic, doctor, wound class
- default status filter:
COMPLETED
Data: listOperatingRoomRequestApi() with populate=...subClinicRef.
Sub-files:
FilterReport.tsx— filter barListOrStatisticReport.tsx— table wrapperTableRowStatisticReport.tsx— column config (returned as a function — possible bug)
Known issues:
TableRowStatisticReport()invoked as function (should be const) — suggests per-row customization not happening- Line ~68:
convertToDateshadowsconvertFromDate— date-range query may break for non-same-day ranges
4.4 Anaesthetist Worklist — Different Data Model
web/packages/periops-kit/src/anaesthetist/components/operating-room-work-list/
This is separate from the OR list-or-patient. The anaesthetist worklist hits a different API and tracks a different state machine:
| OR Patient List | Anaesthetist OR Worklist | |
|---|---|---|
| API | listOperatingRoomRequestApi |
listAnesthesiaSystemsRequestApi |
| Workflow | OR request 9-state machine | Anesthesia 3-stage (PRE → INTRA_POST → COMPLETED) |
| Render | @ui-kit/Table |
DynamicTable + DynamicNavigationTab |
| Visible role | Surgeon | Anesthesiologist (assignable) |
| Row actions | Edit / Status / Date | 11-item more-menu: ซักประวัติ / พิมพ์ / สแกนเอกสาร / นัดหมาย / ออเดอร์ / ผลแล็บ / Referral / assign team / E-Form / เคลื่อนย้าย / confirm status |
Container: web/src/containers/anaesthetist/operating-room-worklist/page.tsx. Mounted at both /labour-room/anaesthetist-or-worklist (via LabourRoomRoutes.tsx:38) and my new /anaesthetist/operating-room-worklist (top-level route).
Known issue: pre-existing crash in RosterRegistry.registerRoster (web/src/common/components/shared-engine/roster-registry/registry.ts:14) when packages/patient-roster/src/anaesthetist-worklist/register.tsx:13 passes undefined config. Fires on both URLs.
5. Miniapp Layer — DynamicContentRenderer
When the patient profile page mounts an “OR-related” tab, it routes through DynamicContentRenderer.tsx. Cases relevant to OR:
Enum (in setup/dynamic/DynamicCoreApp.ts) |
Value (URL ?module=) |
Rendered by |
|---|---|---|
OPERATING_ROOM |
modules.OperatingRoom |
commented out in renderer (line 1437); renders nothing |
OPERATING_ROOM_MEASUREMENTS |
modules.OperatingRoomMeasurements |
(separate miniapp) |
ADVANCED_OPERATING_ROOM_MEASUREMENTS |
modules.AdvancedOperatingRoomMeasurements |
(separate miniapp) |
PERFORM_SURGERY |
modules.PerformSurgery |
PerformSurgeryTab from @miniapps/perform-labourroom-supabase (line 1443) |
PERFORM_LABOURROOM |
modules.PerformSurgery (same value!) |
PerformLabourRoomTab (line 1457) |
RECOVERY_ROOM_REQUEST |
modules.RecoveryRoomRequest |
(search renderer for case) |
PACU_REQUEST |
modules.PACURequest |
(search renderer) |
PREOPERATIVE_CHECKLIST |
modules.PreoperativeChecklist |
(search renderer) |
ANESTHESIA_* (10 variants) |
modules.Anesthesia* |
separate anesthesia miniapps |
Gotcha: OPERATING_ROOM and PERFORM_LABOURROOM enum values both equal modules.PerformSurgery strings — the enum names diverge but the runtime string is the same. Renderer cases use string match, so behavior depends on which case appears first.
5.1 perform-labourroom-supabase/ — The Surgery Performance Miniapp
The biggest OR-related miniapp. ~30 files.
Entry: PerformSurgeryTab.tsx — mounted at ?module=modules.PerformSurgery.
Props:
{
encounterData?: any | null;
onCloseDialog?: () => void;
}
Renders: tabs containing the full intraoperative form. Uses patientRef from ContextPatientProfile (falls back to encounterData prop). Fetches clinicList, healthTimelineItemList, patientData, operatingRoomRequestCount.
Component tree:
PerformSurgeryTab
├─ RenderPerformSurgeryUi (main form layout)
│ ├─ RenderIcdTab (Pre-Op Diagnosis + Operation sections)
│ │ ├─ DiagnosisICD10ClinicalRecord (ICD10 entries — from @medical-kit)
│ │ ├─ OperationICD9 (ICD9 procedure rows: OPERATION/SITE/SIDE/MINS/แพทย์)
│ │ └─ DiagnosisICD9CMDescription (ICD9CM description table)
│ ├─ TablePatientSurgicalSequence (patient's surgical history)
│ ├─ OperatingEform (E-Form selector)
│ ├─ EquipmentAndOthersNew (จัดการอุปกรณ์ Draft List)
│ └─ DialogEditOperatingTableData (row-edit modal)
├─ RenderSurgicalHistoryUi (read-only history view)
├─ DialogOperatingRoom (OR booking)
├─ DialogOperativeNotes (operative notes editor)
├─ DialogReDiagnosis (re-diagnosis flow)
└─ ListAllDetails / ListDetailsOperativeNote (all-details rendering)
Services (Supabase, not REST):
services/operatingRoomRequest.supabase.service.ts— main CRUD, validates UUIDs, includesOperatingRoomRequesttype matching the Supabase row shapeservices/operatingRoomRequest.supabase.service.ENHANCED.ts— enhanced variantservices/anesthesiaWorklist.supabase.service.ts— anesthesia side
Hooks: useDashBoard (clinic list lookup, line ~127 of PerformSurgeryTab).
Recent fixes by me:
RenderPerformSurgeryUi.tsx:73—encounter?.episodeOfCareRef?._idnull-guard for STUB sandbox encounterRenderIcdTab.tsx:538-590— wrapped the empty `` (containing commented-outClinicalDiagnosisCilinicalRecord) in a JSX comment, madeDiagnosisICD10ClinicalRecordspansize={12}so it fills the rowOperationIcd9Data.tsx:117-144— removed the conditionalposition:absolutesx hack on the Autocomplete that was overflowing the OPERATION cell by ~210px
5.2 Dead/Unwired Miniapps
| Directory | Status |
|---|---|
web/packages/miniapps/perform-surgery/ |
dead — name suggests OR but DynamicContentRenderer imports from perform-labourroom-supabase, not here. Contains parallel implementations of PerformSurgeryTab, RenderPerformSurgeryUi, etc. Suspect: pre-Supabase legacy. |
web/packages/miniapps/room-appointments/ |
orphaned — contains the RoomAppointments shell (surgery + labour + EMS tabs with DialogCreateSurgeryAppointment + DialogUpdateSurgeryRequest) but is not registered in DynamicCoreApp or imported by DynamicContentRenderer. Could be the next wiring opportunity. |
6. Service Layer
| Service file | Entity | Backend |
|---|---|---|
services/ever-medication/operatingRoomRequest.service.ts |
OperatingRoomRequest |
REST → MongoDB (gateway) |
services/ever-medication/operatingRoomRequestType.service.ts |
Surgery types catalog | REST → MongoDB |
services/ever-medication/operatingRoomRequestCleanliness.service.ts |
Cleanliness states | REST → MongoDB |
services/ever-medication/operatingRoomRequestDetailAlert.service.ts |
Alerts on OR detail | REST → MongoDB |
services/ever-medication/labourRoomRequest.service.ts |
Labour-room twin entity | REST → MongoDB |
services/ever-medication/emsRequest.service.ts |
EMS twin entity | REST → MongoDB |
miniapps/perform-labourroom-supabase/services/operatingRoomRequest.supabase.service.ts |
Same entity, Supabase shape | Supabase JS client |
6.1 Endpoint Inventory (REST)
operatingRoomRequest.service.ts exposes:
listOperatingRoomRequestApi(params)— paginated list, used by every worklistcreateOperatingRoomRequestApi(payload)updateOperatingRoomRequestApi(id, payload)getOperatingRoomRequestApi(id)deleteOperatingRoomRequestApi(id)
Filter params accepted by list:
page,pageSize,sortfromDate,toDatebuildingRef,room,status[],activity[]specialtyRef[],surgicalType[],patientType[]encounterRef,populate(comma-separated relations)
6.2 OR Request Status State-Machine
11 statuses (declared in OperationIcd9Data.tsx + service typings):
REQUESTED → ACCEPTED → OPERATING → RECOVERED → SENT_BACK_TO_WARD / SENT_TO_ICU → COMPLETED
↘ DEAD_ON_TABLE
↘ CANCELLED
↘ POSTPONE
↘ WAITING
Transitions are gated by user role + the OperatingStatus.tsx dialog.
7. Hooks Layer
| Hook | Location | Purpose |
|---|---|---|
useOperatingRoomData |
kit/operating-room/components/list-or-wait-requested/hooks/ |
Paginated OR-request fetch + filter binding (default status ['PENDING']) |
useDashBoard |
miniapps/perform-labourroom-supabase/useDashBoard.ts |
Clinic list lookup for the surgery form |
useDepartmentQueueSubscription |
web/src/hooks/useDepartmentQueueSubscription.ts |
Supabase realtime channel for department_queues |
useQuery |
@hooks/useQueryAdapter |
Wrapper around react-query 5 with the project’s standard config |
useMutation |
same | Standard react-query mutation |
8. Data Layer
8.1 MongoDB (write source-of-truth)
Collection: operatingRoomRequests — schema in packages/platform-api-schema/src/medication/operatingRoomRequest/. Mirror collections: operatingRoomRequestTypes, operatingRoomRequestCleanliness, operatingRoomRequestDetailAlert.
8.2 Supabase (read-model + perform-surgery writes)
Tables (search infrastructure/medbase/migrations/ for operating_room):
operating_room_requests— the perform-surgery miniapp writes here via the Supabase serviceor_preop_prep_items— pre-op checklist items (consent, NPO, site mark, IV line, labs, cardiac, blood reserve, premeds, allergy band) — see migrations/038_or_preop_prep_items.sqlor_preop_prep_item_types— catalog of item types- View
or_preop_transport_readiness— gates transport when blocking pre-op items unsatisfied
8.3 Encounter Cache
encounter_journey_cache.financial_summary carries OR-billing info; downstream consumed by trg_sync_billing_queue Postgres trigger.
9. Component Reference (alphabetical)
Quick lookup for “what does X do”:
| Component | Type | Location | Purpose |
|---|---|---|---|
AnaesthetistOperatingRoomWorkList |
page | kit/anaesthetist/components/operating-room-work-list/ |
Anesthesia 3-stage worklist |
ClinicalDiagnosisCilinicalRecord |
form | miniapps/perform-labourroom-supabase/ |
Clinical diagnosis editor (currently commented out of RenderIcdTab) |
DiagnosisICD10ClinicalRecord |
form | @medical-kit/encounter-tools/.../clinical-boxs |
ICD10 diagnosis row editor |
DiagnosisICD9CMDescription |
form | miniapps/perform-labourroom-supabase/ |
ICD9-CM description right column |
DialogAssignTeam |
modal | kit/.../list-or-wait-requested/dialog/ |
Surgeon + assistant + anesthesiologist assignment |
DialogCreateSurgeryAppointment |
modal | miniapps/room-appointments/ |
Create OR appointment (unwired) |
DialogEditOperatingTableData |
modal | miniapps/perform-labourroom-supabase/ |
Row-level edit of surgery table data |
DialogNotified |
modal | kit/.../list-or-wait-requested/dialog/ |
Mark case as notified to OR |
DialogOperatingRoom |
modal | miniapps/perform-labourroom-supabase/ |
Book/select OR room |
DialogOperativeNotes |
modal | miniapps/perform-labourroom-supabase/ |
Operative notes editor |
DialogReDiagnosis |
modal | miniapps/perform-labourroom-supabase/ |
Re-diagnosis trigger |
DialogRecoveryRoomRequest |
modal | kit/operating-room/components/list-or-recovery/ |
PACU patient detail |
DialogSurgicalManagement |
modal | kit/.../setting/type/ |
Surgery type create/edit |
EquipmentAndOthers / EquipmentAndOthersNew |
form | miniapps/perform-labourroom-supabase/ |
Equipment Draft List manager |
ListOperatingRoomPatient |
page | kit/operating-room/components/list-or-patient/ |
OR patient table |
ListOperatingRoomWaitRequestModule |
page | kit/.../list-or-wait-requested/OperatingRoom.tsx |
Master pending OR queue |
MainDashboard (OR) |
layout | kit/operating-room/components/dashboard/ |
Filter + calendar dual-pane |
MainTab (OR worklist) |
page | several locations | Filter + table shell per subsystem |
NotNotifiedTable |
table | kit/.../list-or-wait-requested/table/ |
Pending-queue table |
OperatingDate |
modal | kit/.../list-or-wait-requested/dialog/ |
OR date/time scheduling |
OperatingDetail |
modal | same | Case detail edit |
OperatingEform |
modal | same | E-Form attach to OR request |
OperatingMarkSite |
modal | same | Surgical site marker |
OperatingPreOp |
modal | same | Pre-op checklist |
OperatingRoomFilter |
sidebar | kit/.../dashboard/ |
Calendar + wound class + specialty filters |
OperatingRoomSetting |
page | kit/.../setting/OpeartingRoomSetting.tsx |
Settings menu (surgery type + cleanliness) |
OperatingRoomSetupModule |
page | kit/.../dashboard/ |
Top-level dashboard wrapper |
OperatingStatus |
modal | kit/.../list-or-wait-requested/dialog/ |
Status transitions |
OpeatingRoomCalendar |
calendar | kit/.../dashboard/ |
Schedule grid (filename typo) |
OperationICD9 |
table | miniapps/perform-labourroom-supabase/ |
ICD9 procedure editor (the OPERATION/SITE/SIDE/MINS table) |
PerformSurgeryTab |
miniapp | miniapps/perform-labourroom-supabase/ |
Top-level surgery miniapp |
RecoveryRoomRequest |
page | kit/operating-room/components/list-or-recovery/ |
PACU dashboard |
RenderIcdTab |
layout | miniapps/perform-labourroom-supabase/ |
Pre-Op Diagnosis + Operation grid layout |
RenderPerformSurgeryUi |
layout | miniapps/perform-labourroom-supabase/ |
Surgery miniapp main render |
RenderSurgicalHistoryUi |
view | miniapps/perform-labourroom-supabase/ |
Read-only surgery history |
RoomAppointments |
shell | miniapps/room-appointments/ |
Surgery + labour + EMS appointment tabs (unwired) |
TableInDialog |
shared | @ui-kit/components/table/ |
Table primitive used by OperationICD9 |
TablePatientSurgicalSequence |
table | miniapps/perform-labourroom-supabase/ |
Patient’s surgery history table |
10. Known Issues / Tech Debt
Discovered during the recent loop work:
- Filename typo —
OpeatingRoomCalendar.tsx(missing ‘r’) andOpeartingRoomSetting.tsx(transposed). Rename is safe; just touch their importers. OPERATING_ROOMcase commented out in DynamicContentRenderer.tsx:1437. Probably should be uncommented and pointed at the kit’sOperatingRoomSetupModulefor in-profile dashboards.RoomAppointmentsminiapp orphaned — needs aDynamicCoreAppenum + renderer case if we want appointment management inside the patient profile.- Duplicate
list-or-wait-requested/dialog/folder outsidecomponents/— 2 dialogs shadow the canonical ones. Investigate viagit logand delete the duplicate. AnaesthetistORWorklistPageregistry crash —RosterRegistry.registerRosterreadsconfig.enabledfrom undefined. Pre-existing bug; fires on both/labour-room/anaesthetist-or-worklistand/anaesthetist/operating-room-worklist.list-or-statist-reportdate-range bug —convertToDateshadowsconvertFromDateat ~line 68 ofMainTab.tsx. Non-same-day ranges return empty.list-or-recoveryhardcoded sub-clinic IDs —affeecb9-…,02c98eb4-…baked into the query. Should be config-driven.list-or-recoveryroom filter commented out — line 96-102. Either complete or remove.- Dead miniapp —
web/packages/miniapps/perform-surgery/not imported anywhere. Safe to delete after confirming withgit log. - MUI v7 migration leftovers — `` syntax (
itemprop is removed in Grid v2 but tolerated). Cosmetic; no runtime effect.
11. UX/UI Rebuild Strategy
If you want to ship a new design without touching routing or services:
Option A — Replace kit components
Edit files under web/packages/periops-kit/src/operating-room/components/*. The container wrappers and routes won’t notice. Every page-level surface picks up the new look. Lowest risk, highest reach.
Option B — Replace miniapps
Edit web/packages/miniapps/perform-labourroom-supabase/Render*.tsx. Only affects the in-patient-profile surgery form (where surgeons actually fill out cases). The standalone worklists stay on the old design until you do A.
Option C — Build a parallel kit and switch at the container
Create web/packages/periops-kit-v2/src/operating-room/. Each container wrapper has ONE import to swap:
- import { OperatingRoomSetupModule } from '@periops-kit/operating-room/components/dashboard';
+ import { OperatingRoomSetupModule } from '@periops-kit-v2/operating-room/components/dashboard';
Lets you ship the new design behind a feature flag (env var → which import) without forking the existing UI.
Option D — New miniapp via DynamicCoreApp
Add a new enum value to DynamicCoreApp.ts, register the case in DynamicContentRenderer.tsx, point it at a new miniapp folder. Use this to introduce a new in-profile experience without disturbing PerformSurgery.
12. Appendix — Where to Look First
| Goal | First file |
|---|---|
| “Where does the OR worklist fetch from?” | useOperatingRoomData.ts |
| “What statuses exist?” | operatingRoomRequest.service.ts (REST typings) + operatingRoomRequest.supabase.service.ts (Supabase typings — slightly out of sync) |
| “Which dialog handles status changes?” | OperatingStatus.tsx in list-or-wait-requested/dialog/ |
| “How does the surgery form save?” | PerformSurgeryTab.tsx → RenderPerformSurgeryUi → formik.submitForm → services/operatingRoomRequest.supabase.service.ts::create/updateOperatingRoomRequestSupabase |
| “How does the dashboard get realtime updates?” | useDepartmentQueueSubscription('PROCEDURE', ...) — Supabase channel for department_queues |
| “What URL does menu item X point to?” | setup/system/navigation/listMenuNavigation.tsx + setup/system/menus/{th,en,ja}.json |
| “Add a new module to the dynamic renderer?” | (1) Append enum to setup/dynamic/DynamicCoreApp.ts, (2) Add case to DynamicContentRenderer.tsx, (3) Create miniapp under web/packages/miniapps/<slug>/, (4) Register in web/sandbox/registry.ts for fast iteration |
Maintained by: this analysis is a living doc. When the dialog inventory, status state machine, or filter set changes, update the relevant section. Don’t rebuild the doc from scratch — append.