Guides
Operations
OR / surgical ward board — the fourth and last specialty kiosk.
Two parts:
- Part A — Business level. What OR / surgical ward staff are responsible for, what the screen looks like when they sign in, and how the day flows.
- Part B — Technical level. What the routes, components, RBAC, and APIs do under the hood.
Companion docs: docs/ICU_GUIDE.md, docs/MATERNITY_GUIDE.md, docs/EMERGENCY_GUIDE.md, docs/WORKFLOWS.md, docs/ADMISSIONS_OFFICER_GUIDE.md.
Part A — Business level
A.1 What an Operations doctor / nurse owns
| Responsibility | Detail |
|---|---|
| Operations board | The single screen they sign in to. One row per surgical case, segmented by status (Pre-Op / In-Surgery / Post-Op / Recovered) with filter chips at the top. |
| Patient chart | A popup that opens when they click a patient name. Holds Operation snapshot, Vitals, Allergies, Conditions, Nursing Assess., Medications, Lab/Imaging Orders, Results, Care Plans, Consents. |
| Recording observations | They can add new vitals, allergies, conditions, and nursing assessments directly from the chart popup. Vitals form has an EtCO2 chip alongside the standard BP/HR/Temp/SpO2/RR/Pain. |
| Placing orders | The + Order button on each row opens Quick Orders (Prescription / Lab / Imaging). Pharmacy / Laboratory / Radiology are notified but invisible to the surgical clinician. |
| Ward transfer | When the patient is post-op or recovered (and still admitted), Transfer to Ward opens a structured handoff form (wing, room, ward type, bed, attending nurse, post-op care plan). |
| Pre-op checklist | Pre-op diagnosis, instructions (NPO, labs, consent), and consents — visible on the Operation snapshot card and on the Consents card. |
A.2 What they cannot do
The Operations shell is intentionally narrow — kiosk-style, like ICU / Maternity / Emergency:
- No sidebar, no global navigation, no dashboard.
- No access to lab, pharmacy, radiology, billing, HR, or admissions screens.
- No access to other wards (ICU, Maternity, Emergency) — only Transfer to Ward for downstream recovery.
- No access to patients who are not on the operations board.
Forbidden URLs land on the standard Forbidden page.
A.3 What the screen looks like
When an operations doctor or nurse logs in:
┌──────────────────────────────────────────────────────────────────────────────┐
│ M Mando · Operations [ Operations ] 🔔 Dr. Tarek Younes ┄ │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ⚙ Operations & Surgery + Schedule Operation │
│ 3 total procedures scheduled or completed │
│ │
│ ┌ All (3) ┐ ┌ Pre-Op (1) ┐ ┌ In Surgery (1) ┐ ┌ Post-Op (1) ┐ │
│ │
│ ┌ pre-op ─ Anna Taylor — Appendectomy ─ Surgeon: Dr. Tarek Y ─ [ pre-op ] ┐│
│ │ Scheduled: 2026-04-26 09:30 OR-1 Anesthesia: general (Dr. Khaled) ││
│ │ Pre-Op Diagnosis: Acute appendicitis ││
│ │ Pre-Op Instructions: NPO since 22:00, IV access, consent signed ││
│ │ ───────────────────────────────────────── [+ Order] [Edit] [🗑] ││
│ └────────────────────────────────────────────────────────────────────────┘│
└──────────────────────────────────────────────────────────────────────────────┘
Top bar: brand → single static tab “Operations” → notification bell → user pill → Sign out.
A.4 The day, end to end
- Sign in. The system bounces them straight to
/operations. No dashboard. - Read the board. Four status cards across the top (All / Pre-Op / In-Surgery / Post-Op). Filter the list by clicking one.
- Schedule a new operation. Click + Schedule Operation → modal opens with admitted-patient picker, surgery type (elective / urgent / emergency), procedure name, anaesthesia type & anaesthesiologist, scheduled date/time, OR, pre-op diagnosis & instructions. Save.
- Click the patient name. The chart popup opens with 11 cards: Operation, Vitals, Allergies, Conditions, Nursing Assess., Medications, Lab Orders, Imaging Orders, Results, Care Plans, Consents. Each card shows a count.
- Click “Operation”. Read-only snapshot: procedure, surgery type, OR, scheduled date/time, duration, anaesthesia & anaesthesiologist, pre-op diagnosis & instructions, post-op notes, complications, status. Banner highlights complications (red) or urgent/emergency surgery (orange). The chart’s bottom hint reminds the user that editing the operation record happens on the board (Edit / Transfer to Ward).
- Click “Vitals” → + Add. Form has seven chips: BP, HR, Temp, SpO2, RR, EtCO2, Pain. Click a chip → fields pre-fill → type the value → Save. Useful both intraoperatively (anaesthesia monitoring) and in PACU.
- Click “Allergies / Conditions / Nursing Assess.” → + Add. Same flow. The Nursing Assess. dropdown adds OR-specific types (Aldrete, Apfel, Wound check) alongside the shared ones.
- Place an order. Close the chart, click
+ Orderon the row. Three tabs: Prescription, Lab, Imaging. Submit → Pharmacy / Lab / Radiology gets the alert. - Move the case along. Click Edit to bump status (
pre-op → in-surgery → post-op → recovered), record duration, post-op notes, complications. - Transfer to Ward. When status is
post-oporrecoveredand the patient is still admitted, Transfer to Ward appears on the row → handoff form (wing, room, ward type, bed, attending nurse, post-op care plan, notes). Submit → ward gets the alert; the operations row is closed out from the OR’s perspective.
A.5 Notifications
Inbound (the bell flashes):
- Patient transferred from Emergency for emergency surgery — fired by ER’s “To Operation” handoff.
- Surgical admission landed on the wing — fired by Reception with admission_type =
surgery. - Stat lab or imaging result finalised on one of their surgical patients (planned).
Outbound (they create them implicitly):
- Placing a Lab order → Laboratory.
- Placing an Imaging order → Radiology.
- New prescription → MAR / pharmacy queue.
- Transfer to Ward → ward charge nurse for post-op care.
A.6 Common pitfalls
- “I want to update post-op notes from the chart.” The Operation card is read-only. Close the chart, click Edit on the row, record post-op notes there. (Use the Vitals card for intraop / PACU vitals.)
- “Transfer to Ward isn’t showing up.” It only appears once the operation is
post-oporrecoveredAND the underlying admission is still active. Bump the status via Edit first. - “I can’t find the patient I want to schedule.” They aren’t admitted as a
surgery/operationadmission. Reception creates that admission first; until then the picker on + Schedule Operation won’t list them. - “I tried to open the lab page and got Forbidden.” Correct — Operations staff place orders but never browse lab/pharmacy/radiology. Use
+ Orderon the row. - “The patient just had emergency surgery — where do I see them?” ER’s “To Operation” transfer creates the operation_details record automatically. They should be on the board with status
pre-oporin-surgery.
Part B — Technical level
B.1 Identity & ward shell
A user is treated as an “Operations ward user” when all of these are true:
users.roleisdoctorornurse.users.department(case-insensitive, trimmed) is one of:operations,surgery,general surgery,orthopedics,orthopedic,urology,neurosurgery.
This list lives in AppRoot.WARD_CONFIG.operations.depts and matches WARD_NAV in frontend/src/services/role-permissions.js.
Shell decision is generic — AppRoot.wardForUser(user) returns the ward key ('icu' / 'maternity' / 'emergency' / 'operations') or null. When non-null, app-root.js:
- Sets the post-login home to
#/<wardRoute>(skips/dashboard). - Bounces any
#/dashboardhit back to the ward route. - Renders
renderWardShell(wardKey)— brand label, tab label, and embedded page tag come fromWARD_CONFIG[wardKey]. For operations the slot hosts<operations-page>directly. renderWardPage(wardKey)switches on the key and returns the right page element.
All four wards (ICU / Maternity / Emergency / Operations) now use this generic kiosk shell — adding or removing one is a single map entry plus a switch arm.
B.2 Seed data
Four ward-doctor logins are created idempotently on every boot by ensureWardDoctors. For Operations:
- email:
operations.doctor@hospital.com - password:
admin123 - name: Dr. Tarek Younes
- department:
Operations - role:
doctor
Idempotency: users.email UNIQUE → ON CONFLICT (email) DO NOTHING for users; INSERT … WHERE NOT EXISTS for the matching doctors row.
Nurses are seeded the same way once a user record with role='nurse' and department='Operations' (or one of the surgery aliases) is created (no nurse seed today — add via /hr or /users).
B.3 RBAC
Backend (path-based middleware): the doctor and nurse role permission tables in backend/internal/middleware/roles.go do not include lab, pharmacy, pharmacy-dispense, radiology, general-inventory. They allow prescriptions, service-requests, diagnostic-reports, imaging-studies, observations, allergies, conditions, nursing-assessments, care-plans, consents, plus the ward routes (icu, emergency, maternity, operations).
Frontend: getNavigationForUser(user) in frontend/src/services/role-permissions.js narrows frontDesk to ['operations'] for any doctor/nurse whose department resolves to operations. The extras for operations adds 'or-utilization' to the clinical baseline (OR throughput dashboard) — though that page is reachable only via the chart’s Care Plans / Quick Orders flow today, not the kiosk shell tab.
B.4 Operations board
frontend/src/pages/operations-page.js — unchanged in shape, plus the chart wiring:
loadData()callsGET /api/operations,GET /api/admissions?...&type=operation,GET /api/wingsin parallel.- Status segment cards (
all / pre-op / in-surgery / post-op) at the top, withrecoveredcases reachable via the underlyingop_statusfilter. _isWardUsergetter (new) is wired in for parity with the other ward pages.- Patient name click now calls
openChart(o)→<operations-patient-chart>.show(operationDetailsRecord)instead of the older<patient-encounter-popup>. The popup is still imported and stays available. - The schedule modal and the Transfer to Ward modal keep their existing logic — the chart does not duplicate that.
B.5 Operations patient chart popup
frontend/src/components/operations-patient-chart.js is a sibling of icu-patient-chart.js, maternity-patient-chart.js, and emergency-patient-chart.js with one extra card. Two views inside one panel:
Grid view (default after show() is called):
- Header:
name • MRN • gender • DOB · surgery_type · procedure_name. “All categories” button hidden. - Info bar: gender, DOB, blood type, phone, admission #, op_status pill (colour-coded).
- Body: 11 category cards. Each card has icon + label + hint + count badge.
- Counts are loaded by
loadCounts()— Operation is always 1 (the operation_details record passed in viashow()); the rest mirror the other wards.
Detail view (after a card click):
- Operation renders as a single read-only snapshot card (procedure, surgery type, OR, scheduled date/time, duration, anaesthesia, anaesthesiologist, pre-op diagnosis & instructions, post-op notes, status). Complications get a red banner; urgent/emergency surgeries get an orange banner. A tip-banner reminds users that edits happen on the operations board.
- The remaining 10 categories are identical to ICU / Maternity / ER.
B.6 Categories — list and create endpoints
| Card | List API | Add API | Editable |
|---|---|---|---|
| Operation | passed in via show(operationDetails) | (use Edit / Transfer to Ward on the board) | no |
| Vitals | GET /api/observations/patient/:id/vitals | POST /api/observations category: vital-signs | yes |
| Allergies | GET /api/allergies/patient/:id | POST /api/allergies | yes |
| Conditions | GET /api/conditions/patient/:id | POST /api/conditions | yes |
| Nursing Assess. | GET /api/nursing-assessments/patient/:id | POST /api/nursing-assessments | yes |
| Medications | GET /api/prescriptions?patient_id= | (use Quick Orders → Prescription) | no |
| Lab Orders | GET /api/service-requests?patient_id= filter category ~ “lab” | (use Quick Orders → Lab) | no |
| Imaging Orders | same, filter category ~ “rad|imag” | (use Quick Orders → Imaging) | no |
| Results | GET /api/diagnostic-reports?patient_id= | n/a | no |
| Care Plans | GET /api/care-plans?patient_id= | (use the care-plan workflow) | no |
| Consents | GET /api/consents?patient_id= | (use the consents workflow — surgical consents live here) | no |
For each editable category the chart’s submitAdd(e) method assembles the FHIR-shaped payload and POSTs it. On success it re-fetches the active category and re-runs loadCounts().
B.7 Vitals quick chips
Vitals add form has seven chips. The first six match ICU / ER; the seventh swaps in EtCO2 (end-tidal CO2 — anaesthesia monitoring):
| Chip | code | display | unit |
|---|---|---|---|
| BP | 85354-9 | Blood Pressure | mmHg |
| HR | 8867-4 | Heart Rate | bpm |
| Temp | 8310-5 | Body Temperature | °C |
| SpO2 | 59408-5 | Oxygen Saturation | % |
| RR | 9279-1 | Respiratory Rate | /min |
| EtCO2 | 19891-2 | End-tidal CO2 | mmHg |
| Pain | 38208-5 | Pain Severity | 0-10 |
Click chip → code, display, unit pre-fill → user only types the value.
B.8 Quick Orders & ward transfer
The + Order button opens frontend/src/components/quick-orders.js with source="operation". Submitting routes to:
| Tab | Endpoint | Receiving alert |
|---|---|---|
| Prescription | POST /api/prescriptions source=operation | Pharmacy queue |
| Lab | POST /api/service-requests category=laboratory | Laboratory department |
| Imaging | POST /api/service-requests category=radiology | Radiology department |
Ward transfer stays on the page itself:
- Transfer to Ward →
POST /api/operations/:id/transfer-to-wardwith wing, target room, ward type, bed, attending nurse, post-op care plan, notes. - Edit → updates the operation_details record itself (status, duration, post-op notes, complications).
B.9 Build / verification
- Backend:
go build ./...— clean. - Frontend:
npx vite build— 1.45 MB / 230 kB gzip in ~1.2s.
B.10 Known follow-ups (not done yet)
- Operation edit from inside the chart. Today the chart is read-only on the Operation card; users have to close the popup and click Edit on the row. Worth wiring an inline status-bump (pre-op → in-surgery → post-op → recovered) and post-op notes/complications field directly on the chart.
- In-chart op_status timer. Once
op_status='in-surgery'is set, surface elapsed-time so the OR team can see runtime without checking the schedule. - OR utilisation dashboard surfacing. WARD_NAV adds
or-utilizationto clinical extras; consider a small “OR throughput” pseudo-card on the chart for the surgeon. - Critical-result back-alerts on stat labs/imaging. Same gap noted in the other ward guides.
- Per-patient row-level filter on reads. RBAC is path-based today.
- All four wards now share the same kiosk shell + chart popup pattern. Refactor opportunity: extract the four chart components into a single
ward-patient-chartcomponent that accepts a wardKey + extra category descriptor — they currently duplicate ~600 lines each.
Last updated: 2026-04-26