Nexus Docs Documentation for the Nexus hospital management system

Guides

Maternity

Labour, postpartum, and newborn care board — the second specialty kiosk.

Two parts:

  • Part A — Business level. What Maternity 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/WORKFLOWS.md, docs/ADMISSIONS_OFFICER_GUIDE.md.


Part A — Business level

A.1 What a Maternity doctor / nurse owns

ResponsibilityDetail
Maternity boardThe single screen they sign in to. Four tabs at the top: Mothers, Newborns, Premature, Milk Bank. The mother list is segmented by labor stage (pre-labor / early-labor / active-labor / delivery / postpartum).
Mother chartA popup that opens when they click a mother’s name. Holds Pregnancy snapshot, Newborns, Vitals, Allergies, Conditions, Nursing Assess., Medications, Lab/Imaging Orders, Results, Care Plans, Consents.
Recording observationsThey can add new vitals (mother), allergies, conditions, and nursing assessments directly from the chart popup — no page hop. Vitals form has a FetalHR chip so fetal heart rate can be logged in one click.
Maternity admission formA 4-tab form covering the full obstetric pathway: Pregnancy History (gravida/para/EDD/blood type/Rh), Antenatal Risk (GDM, preeclampsia, infection screening, allergies, current meds), Labor & Delivery (membranes, ROM, amniotic fluid, anesthesia, episiotomy, perineal tear, blood loss, placenta), Postpartum (BP/pulse/temp, lochia, fundus, breastfeeding, RhoGAM, contraception plan, discharge education).
DeliveryWhen the mother is ready, Deliver on the row launches a 2-step delivery wizard (count of babies → per-baby form: weight, length, Apgar, bracelet, NICU flag, blood type, etc.).
Newborn registrationAfter delivery, Add Baby registers an additional newborn against the maternity case. Bracelets get colour + ID; NICU flag picks an incubator room.
Placing ordersThe + Order button on a mother’s row opens Quick Orders (Prescription / Lab / Imaging). Pharmacy / Laboratory / Radiology are notified but invisible to the maternity clinician.
Mother-baby bondingPostnatal nursing assessments (Edinburgh score, bonding) are logged from the chart’s Nursing Assess. card.
Milk BankManage the donor-mother programme: register donors, capture screening (HIV / HBV / HCV / Syphilis / HTLV), receive donations, pasteurize, dispense to recipient babies (premature, NEC prophylaxis, maternal-unable-to-feed, adoption). KPI dashboard tracks active donors, eligible donors, available pool mL, expiring-soon batches, and MTD donated / dispensed.

A.2 What they cannot do

The Maternity shell is intentionally narrow — kiosk-style, like ICU:

  • No sidebar, no global navigation, no dashboard.
  • No access to lab, pharmacy, radiology, billing, HR, or admissions screens.
  • No access to other wards (ICU, Emergency, Operations).
  • No access to patients who are not on the maternity board.

Forbidden URLs land on the standard Forbidden page.

A.3 What the screen looks like

When a maternity doctor or nurse logs in:

┌─────────────────────────────────────────────────────────────────────────────┐
│ M  Mando · Maternity     [ Maternity ]            🔔   Dr. Yara Saleh ┄     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   Maternity                                          + Maternity Admission  │
│   3 mothers • 2 newborns • 1 premature                                      │
│                                                                             │
│   [ Mothers (3) ]  Newborns (2)  Premature (1)  Milk Bank                  │
│                                                                             │
│   ┌─ All ─ Pre-Labor ─ Early Labor ─ Active Labor ─ Delivery ─ Postpartum ─┐│
│   │  Maria Garcia    Dr. Yara S • G2P1 • 39w           [active-labor]      ││
│   │  EDD: 2026-05-04   Dilation: 7cm   Fetal HR: 142   BP: 118/76         ││
│   │  ─────────────────────  [Deliver] [+ Order] [Edit] [🗑]                 ││
│   └────────────────────────────────────────────────────────────────────────┘│
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Top bar: brand → single static tab “Maternity” → notification bell → user pill → Sign out.

A.4 The day, end to end

  1. Sign in. The system bounces them straight to /maternity. No dashboard intermediate step.
  2. Read the board. Four tabs: Mothers, Newborns, Premature, Milk Bank. Mothers tab segments by labor stage.
  3. Click the mother’s name. The chart popup opens with 12 cards: Pregnancy, Newborns, Vitals, Allergies, Conditions, Nursing Assess., Medications, Lab Orders, Imaging Orders, Results, Care Plans, Consents. Each card shows a count.
  4. Click “Pregnancy”. Read-only snapshot: gravida/para, gestational weeks, EDD, LMP, labor status, dilation, fetal HR, contractions, BP, delivery type, baby status, Apgar, complications. The chart’s bottom hint reminds the user that editing the pregnancy record happens on the maternity board (Edit / Deliver / Add Baby).
  5. Click “Newborns”. Lists every baby on this maternity case with weight, length, Apgar, blood type, bracelet colour + ID, premature / NICU badges, status.
  6. Click “Vitals” → + Add. The form has eight chips: BP, HR, Temp, SpO2, RR, Wt, Pain, FetalHR. Click a chip → fields pre-fill → type the value → Save.
  7. Click “Allergies / Conditions / Nursing Assess.” → + Add. Same flow. The Nursing Assess. dropdown includes maternity-specific types (Edinburgh, Bonding) alongside the general ones (Braden, Morse, Pain).
  8. Place an order. Close the chart, click + Order on the row. Three tabs: Prescription, Lab, Imaging. Submit — Pharmacy / Lab / Radiology gets the alert; the maternity clinician sees nothing about who’s working on it until the result shows up under Results.
  9. Deliver. When the mother is in stage 2, click Deliver on the row → a 2-step wizard. Step 1 picks the number of babies (single / twins / triplets). Step 2 collects per-baby data including NICU flag and incubator room. Submit creates the newborn records and pushes the mother to postpartum.
  10. Register a late-arrival baby. If a baby is added later (paperwork, transfer), use Add Baby on the row.
  11. Edit the maternity record. Click Edit on the row to open the 4-tab form: Pregnancy History → Antenatal Risk → Labor & Delivery → Postpartum. Switching tabs preserves whatever you’ve already typed (the form is one panel; tabs only toggle which slice is visible). Save once at the end of the visit — the labor-status, dilation, fetal-HR, and BP changes you’d otherwise update repeatedly during the shift are still on the same form, so the workflow has not changed.
  12. Open Milk Bank. Click the Milk Bank tab on the top board. Sign-up flow: register donor → record screening → mark eligible → receive donation → pasteurize → mark available → dispense to a registered recipient. The dashboard’s Expiring (7d) tile is the one to watch — anything in the red number is at risk of being discarded.

A.5 The maternity admission form — 4 tabs

The form behind + Maternity Admission and Edit has grown from a single scrolling sheet to four named tabs. Everything is in one form — switching tabs is a CSS toggle, not a re-mount, so a half-typed value on tab 2 stays put when you click tab 3 and back.

TabWhat goes in itWhen you fill it
Pregnancy HistoryGravida / Para, previous C-sections, prenatal-visit count, LMP, EDD, gestational weeks, pregnancy type, blood type + Rh factor.At admission. The Rh field drives the postpartum RhoGAM given checkbox — leave it blank and you skip a downstream alert.
Antenatal RiskFree-text antenatal-risk summary, GDM and Preeclampsia checkboxes, infection screening (HIV / HBV / GBS / Rubella), allergy list, current medications.At admission. Everything is optional but missing GBS / HBV is a red flag for the delivery team.
Labor & DeliveryLabor status + dilation, labor onset (spontaneous / induced / planned C-section) + induction method, membrane status (intact / SROM / AROM) + ROM time, amniotic-fluid description, fetal HR, contractions, maternal BP, anesthesia, delivery type + date, episiotomy + perineal-tear grade, blood loss in mL, placenta status, complications, baby initial (status / gender / weight / Apgar).Updated through the labor-and-delivery shift. Most of these are filled at delivery time, not admission.
PostpartumPostpartum BP / pulse / temperature, lochia (rubra / serosa / alba / heavy / minimal), fundus, breastfeeding status (exclusive / mixed / formula / not feeding), lactation-consult flag, RhoGAM-given flag, contraception plan, planned discharge date, discharge education complete, free-text notes.Filled during the postpartum stay, finalised at discharge.

A few field-level notes that bite people:

  • Episiotomy + Perineal Tear are independent. A patient may have both, either, or neither; the form treats them as separate fields.
  • Blood loss in mL drives the postpartum-haemorrhage flag (>500 mL vaginal / >1000 mL C-section). Currently visual-only — there is no red banner yet, just the number on the postpartum card.
  • RhoGAM given only matters when the mother is Rh-negative. The form doesn’t enforce that — leave it unchecked for Rh-positive mothers.
  • Discharge education complete gates the discharge summary in nurse handoff.

A.6 Milk Bank

The Milk Bank tab is the donor-mother programme — a separate workflow inside the same kiosk. Five sections in the left rail:

SectionWhat you do there
OverviewSeven KPI tiles: active donors, eligible donors, deferred donors, active recipients, available pool (mL), quarantined volume, MTD donated, MTD dispensed, expiring within 7 days (red when > 0). The Expiring tile is the daily watch — items at risk of being discarded.
DonorsRegister a new donor mother, capture screening (HIV / HBV / HCV / Syphilis / HTLV negative checks, smoking / alcohol use, medications safe), record consent, set eligibility (pending / eligible / deferred / ineligible). The donor’s donation count and total volume aggregate into the row so you can see contribution at a glance. Donor numbers auto-allocate as DONOR-2026-00012.
RecipientsRegister a baby authorised to receive donor milk. Indication category drives the workflow: Prematurity, NEC prophylaxis, Maternal unable, Adoption / surrogacy, Other. Daily volume + feeding route + ordering doctor are captured here so the dispense step can pre-fill from this record. Status walks active → suspended → completed.
DonationsReceive a deposit. Each row carries volume, container count, storage location + temperature, milk type (colostrum / transitional / mature), expiry. Status walks received → screened → pasteurized → quarantined → available → dispensed → discarded. Pasteurization captures method (holder / HTST / raw) and date; bacteriology checkbox flips green when passed. Batch numbers auto-allocate as BATCH-2026-00033.
DistributionsDispense from the available pool to a recipient. Picks the donation batch from a dropdown showing remaining mL per batch, captures route (oral / NG / OG / gastrostomy), dispensed-by + witnessed-by + delivered-to-unit (chain of custody). Optional adverse-event log when something goes wrong.

Server-side guardrails (you will see error toasts when you hit one):

  • Receiving a donation from a donor with eligibility_status='ineligible' or 'deferred' is refused (HTTP 403).
  • Dispensing from a donation that is not in available status is refused (HTTP 403). Pasteurise → mark available first.
  • Dispensing more than what’s left in a batch is refused with the available-mL figure (HTTP 400).
  • A donation drained to zero auto-flips to dispensed.
  • Deleting a donor / recipient with rows on file soft-archives instead of hard-deleting so the audit trail survives.

Common pitfalls in the milk bank:

  • “The donation isn’t appearing in the dispense dropdown.” The dispense dropdown only shows donations in status available. Mark it pasteurised → status available first.
  • “The donor is eligible but the donation form rejects me.” Active flag is a separate switch from eligibility — make sure Active is on too.
  • “Distributions show no donor.” A pooled / unspecified-batch distribution leaves the donor name empty; that’s by design when you can’t trace a specific batch.

A.7 Notifications

Inbound (the bell flashes):

  • New maternity admission landed on the wing — fired by Reception/Admissions Officer at admit time.
  • Stat lab or imaging result finalised on one of their mothers (planned).
  • Blood-bank cross-match approval (when the blood-bank workflow is wired in).

Outbound (they create them implicitly):

  • Placing a Lab order → Laboratory.
  • Placing an Imaging order → Radiology.
  • New prescription → MAR / pharmacy queue.
  • Delivery completion → Records / billing (for room downgrades, postpartum charges).

A.8 Common pitfalls

  • “I want to change the EDD on the Pregnancy card.” That card is a snapshot. Close the chart, click Edit on the mother’s row to open the maternity form. Save there.
  • “Why doesn’t the Newborn list update after I deliver?” It does — but you have to close and re-open the chart, or click All categories → Newborns again. The card-grid count refreshes when you go back to it.
  • “I’m trying to add a baby but the form rejects me.” The mother record must already exist. Use Deliver the first time (creates babies via the wizard) or Add Baby for additional ones. Both buttons are on the mother’s row.
  • “The patient I’m looking for isn’t here.” They aren’t admitted to Maternity. Reception admits patients with admission_type = maternity — until that happens, the patient won’t appear on this board.
  • “I tried to open the lab page and got Forbidden.” Correct — maternity staff place orders but never browse lab/pharmacy/radiology. Use + Order on the row.

Part B — Technical level

B.1 Identity & ward shell

A user is treated as a “Maternity ward user” when all of these are true:

  • users.role is doctor or nurse.
  • users.department (case-insensitive, trimmed) is one of: maternity, obstetrics, gynecology, ob-gyn, obgyn.

This list lives in AppRoot.WARD_CONFIG.maternity.depts and matches WARD_NAV in frontend/src/services/role-permissions.js.

The shell decision is now generic — AppRoot.wardForUser(user) returns the ward key ('icu', 'maternity') or null. When non-null, app-root.js:

  1. Sets the post-login home to #/<wardRoute> (skips /dashboard).
  2. Bounces any #/dashboard hit back to the ward route.
  3. Renders renderWardShell(wardKey) instead of the sidebar shell. Brand label, tab label, and embedded page tag come from WARD_CONFIG[wardKey]. For maternity the slot hosts <maternity-page> directly.
  4. renderWardPage(wardKey) switches on the key and returns the right page element.

B.2 Seed data

Four ward-doctor logins are created idempotently on every boot by ensureWardDoctors. For maternity:

  • email: maternity.doctor@hospital.com
  • password: admin123
  • name: Dr. Yara Saleh
  • department: Maternity
  • role: doctor

Idempotency: users.email UNIQUEON 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='Maternity' 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, newborns, plus the ward routes (icu, emergency, maternity, operations).

Frontend: getNavigationForUser(user) in frontend/src/services/role-permissions.js narrows frontDesk to ['maternity'] for any doctor/nurse whose department resolves to maternity. The extras for maternity adds 'blood-bank' to the clinical baseline (mothers may need cross-matched units).

B.4 Maternity board

frontend/src/pages/maternity-page.js:

  • loadData() calls GET /api/maternity-details, GET /api/admissions, GET /api/newborns, GET /api/rooms in parallel.
  • Four tabs: Mothers / Newborns / Premature / Milk Bank. Milk Bank renders <milk-bank-panel>.
  • Mothers tab has six labor-stage filter chips (all, pre-labor, early-labor, active-labor, delivery, postpartum).
  • _isWardUser getter is wired in for parity with icu-page; it can be used to gate any future ward-specific links.
  • Patient name click calls openChart(m)<maternity-patient-chart>.show(motherCase). The older <patient-encounter-popup> is still imported — used for the newborn-tab “Mother:” link and “View Baby Encounter” link.
  • The maternity admission form is rendered by renderMaternityModal() with a formTab state field driving four panels (Pregnancy History / Antenatal Risk / Labor & Delivery / Postpartum). All four panels are always in the DOM; tab switching is style="display: ${formTab === X ? 'block' : 'none'}". This preserves user input on tabs that aren’t currently visible — Lit would otherwise destroy the unmounted DOM and lose the edits.

B.5 Expanded maternity_details schema

34 new nullable columns (added by ALTER TABLE … ADD COLUMN IF NOT EXISTS in database.go; existing rows stay valid):

GroupColumns
Pregnancy historyblood_type, rh_factor, prenatal_visits, previous_csections
Antenatal riskantenatal_risk, gdm (bool), preeclampsia (bool), hiv_status, hbv_status, gbs_status, rubella_immune, allergies, current_medications
Labor & deliverymembrane_status, rom_time, amniotic_fluid, labor_onset, induction_method, anesthesia, episiotomy (bool), perineal_tear, blood_loss_ml, placenta_status
Postpartumpostpartum_bp, postpartum_pulse, postpartum_temperature, lochia, fundus_status, breastfeeding_status, lactation_consult (bool), rhogam_given (bool), contraception_plan, discharge_planned_date, discharge_education (bool)

maternity.go was rewritten so the column ↔ field map lives in one place:

  • maternitySelectColumns — shared SELECT list with COALESCE on every nullable column so Scan() never sees NULL.
  • scanMaternity(rows, &m) helper — single Scan binding reused by ListMaternityDetails and would-be GetMaternityDetail.
  • CreateMaternityDetail and UpdateMaternityDetail write all 34 new columns; existing callers that don’t send the new fields write empty strings / zeros / FALSE.

The MaternityDetail model in models.go carries the new fields with omitempty JSON tags so the wire payload stays compact for older clients.

B.6 Maternity patient chart popup

frontend/src/components/maternity-patient-chart.js is a sibling of icu-patient-chart.js with two extra cards. Two views inside one panel:

Grid view (default after show() is called):

  • Header: name • MRN • gender • DOB • G…P… · …w · labor_status. “All categories” button hidden.
  • Info bar: gender, DOB, blood type, phone, admission #.
  • Body: 12 category cards. Each card has icon + label + hint + count badge.
  • Counts are loaded by loadCounts() — Pregnancy is always 1 (the maternity_details record passed in via show()); Newborns is fetched by getNewborns({ maternity_id }); the rest mirror ICU.

Detail view (after a card click):

  • Pregnancy renders as a single read-only snapshot card (gravida/para, gestational, EDD, LMP, labor, dilation, fetal HR, contractions, BP, delivery type, delivery date, baby status, Apgar). A tip-banner reminds users that edits happen on the maternity board.
  • Newborns renders as a list with per-row badges: premature {n}w, NICU, status. Bracelet colour + ID, weight, length, Apgar, blood type all show in the row.
  • The remaining 10 categories are identical to the ICU chart.

B.7 Categories — list and create endpoints

CardList APIAdd APIEditable
Pregnancypassed in via show(motherCase)(use Edit / Deliver on the board)no
NewbornsGET /api/newborns?maternity_id=(use Deliver / Add Baby on the board)no
VitalsGET /api/observations/patient/:id/vitalsPOST /api/observations category: vital-signsyes
AllergiesGET /api/allergies/patient/:idPOST /api/allergiesyes
ConditionsGET /api/conditions/patient/:idPOST /api/conditionsyes
Nursing Assess.GET /api/nursing-assessments/patient/:idPOST /api/nursing-assessmentsyes
MedicationsGET /api/prescriptions?patient_id=(use Quick Orders → Prescription)no
Lab OrdersGET /api/service-requests?patient_id= filter category ~ “lab”(use Quick Orders → Lab)no
Imaging Orderssame, filter category ~ “rad|imag”(use Quick Orders → Imaging)no
ResultsGET /api/diagnostic-reports?patient_id=n/ano
Care PlansGET /api/care-plans?patient_id=(use the care-plan workflow)no
ConsentsGET /api/consents?patient_id=(use the consents workflow)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.8 Vitals quick chips

Vitals add form has eight chips. The first seven match ICU; the eighth is maternity-specific:

Chipcodedisplayunit
BP85354-9Blood PressuremmHg
HR8867-4Heart Ratebpm
Temp8310-5Body Temperature°C
SpO259408-5Oxygen Saturation%
RR9279-1Respiratory Rate/min
Wt29463-7Body Weightkg
Pain38208-5Pain Severity0-10
FetalHR11947-9Fetal Heart Ratebpm

Click chip → code, display, unit pre-fill → user only types the value.

B.9 Quick Orders & delivery workflows

The + Order button on each maternity row opens frontend/src/components/quick-orders.js with source="maternity". Submitting routes to:

TabEndpointReceiving alert
PrescriptionPOST /api/prescriptions source=maternityPharmacy queue
LabPOST /api/service-requests category=laboratoryLaboratory department
ImagingPOST /api/service-requests category=radiologyRadiology department

Delivery and newborn registration stay on the maternity page itself:

  • Deliver → 2-step modal (renderDeliveryModal), submits POST /api/maternity-details/:id/deliver with the babies array.
  • Add BabyrenderBabyModal, submits POST /api/newborns.
  • Edit → updates the maternity_details record itself.

B.10 Milk Bank — backend

Four new tables in database.go:

TablePurposeKey columns
milk_donorsDonor mother roster + screening + eligibilitydonor_no (UNIQUE), patient_id, full_name, delivery_date, lactation_stage, screening date / result, 5 boolean serology checks (hiv_negative, hbv_negative, hcv_negative, syphilis_negative, htlv_negative), medications_safe, smoking, alcohol_use, eligibility_status (pending / eligible / deferred / ineligible), deferred_until, consent flag + date, active
milk_recipientsAuthorised recipient babiesrecipient_no (UNIQUE), baby_patient_id, mother_patient_id, baby_name, gestational_weeks, birth_weight, medical_indication, indication_category (prematurity / NEC / maternal_unable / adoption / other), ordered_by, ordering_doctor_id, daily_volume_ml, feeding_route, start/end dates, consent flag + date, status
milk_donationsPer-batch deposits with status walkdonor_id, batch_no, collection_date, collection_time, expressed_at (home / hospital), volume_ml, container_count, storage_location, storage_temp_c, milk_type (colostrum / transitional / mature), expiry_date, pasteurized + date + method, bacteriology done + passed, status (received → screened → pasteurized → quarantined → available → dispensed → discarded), discarded_reason, received_by
milk_distributionsDispensings to recipients with chain of custodyrecipient_id, donation_id (nullable for pooled), batch_no, dispensed_date + dispensed_time, volume_ml, feeding_route, dispensed_by, witnessed_by, delivered_to_unit, status, adverse_event

Six covering indexes on the most common reads (donor status, recipient status, donor + collection date, donation status, recipient + dispensed date, donation_id).

Models in models.go:

  • MilkDonor — carries aggregate fields populated by the List query: donation_count, total_volume_ml, patient_name.
  • MilkRecipient — carries aggregates: distribution_count, total_dispensed_ml, plus baby_patient_name / mother_patient_name.
  • MilkDonation — carries donor_name and dispensed_ml (subquery sum) so the kiosk’s table doesn’t need a second round trip.
  • MilkDistribution — carries recipient_name and donor_name.
  • MilkBankDashboard — KPI snapshot returned by GET /api/milk-bank/dashboard.

Handlers in milk_bank.go — full CRUD plus dashboard. Server-side guardrails:

  • CreateMilkDonation refuses if the donor’s eligibility_status is ineligible or deferred (HTTP 403).
  • CreateMilkDistribution refuses if donation.status != 'available' (HTTP 403) or if the requested volume exceeds the remaining pool on that donation (HTTP 400 with the available-mL figure).
  • A donation drained to zero is auto-flipped to dispensed via a defer-scheduled UPDATE.
  • DeleteMilkDonor / DeleteMilkRecipient soft-archive (set active=FALSE / status='completed') when downstream rows exist; only hard-delete when nothing references them.
  • DeleteMilkDonation returns HTTP 409 when distributions exist; the caller is told to mark the donation discarded instead.

Routes mounted in cmd/server/main.go under the auth middleware:

GET  /api/milk-bank/dashboard
GET/POST/PUT/DELETE /api/milk-bank/donors
GET/POST/PUT/DELETE /api/milk-bank/recipients
GET/POST/PUT/DELETE /api/milk-bank/donations
GET/POST/PUT/DELETE /api/milk-bank/distributions

RBAC: milk-bank resource added to the doctor and nurse permission tables in backend/internal/middleware/roles.go with {GET, POST, PUT, DELETE}. Same pattern as maternity — clinicians who land on the maternity kiosk can use the milk bank without a separate role.

B.11 Milk Bank — frontend

frontend/src/components/milk-bank-panel.js — single Lit component embedded by <maternity-page> under the new Milk Bank tab. Pink (#ec4899) accent threaded through CSS custom properties (--mb-accent, --mb-tint).

Five sub-sections in the left rail (dashboard / donors / recipients / donations / distributions). The component does its own data loading with a per-section call set in _load():

  • Dashboard fetches donors + recipients + the dashboard summary.
  • Donations / distributions fetch donors + recipients alongside their list so the modal pickers are populated.
  • Generic _open(kind, row), _save(), _delete(kind, id) dispatchers map a modalKind to one CRUD trio each.

The donation-batch dropdown in the distribution modal computes remaining-mL inline from the donation’s volume_ml - dispensed_ml so the dispenser sees what’s available without navigating away.

API methods on the frontend client live in api.js: getMilkBankDashboard, getMilkDonors, createMilkDonor, updateMilkDonor, deleteMilkDonor, plus the same trio for recipients / donations / distributions.

B.12 Build / verification

  • Backend: go build ./... — clean.
  • Frontend: npx vite build — 1.84 MB / 308 kB gzip in ~2s. The maternity-form expansion plus the milk-bank panel added ~470 kB raw / ~95 kB gzip on top of the deep-maternity baseline.

B.13 Known follow-ups (not done yet)

  • Pregnancy edit from inside the chart. Today the chart is read-only on the Pregnancy card; users have to close the popup and click Edit on the row. Wire an inline edit for fetal HR + dilation + contractions + BP (the values that change every assessment) so labour-stage updates don’t leave the chart.
  • Newborn register from inside the chart. Today the chart is read-only on the Newborns card; deliveries and late-arrival registrations stay on the board. Worth adding a thin “Register baby” form directly on the chart’s Newborns card for the postpartum case.
  • Cross-match / blood-bank pull-through. The frontend WARD_NAV already adds blood-bank to maternity’s clinical extras; surface a “Cross-match status” pseudo-category on the chart when an active blood request exists for the mother.
  • Postpartum-haemorrhage red banner. blood_loss_ml is captured but no alert fires when it crosses 500 mL (vaginal) / 1000 mL (C-section). Wire an alert-bar at the top of the postpartum tab.
  • RhoGAM auto-prompt. When rh_factor='-' and baby_blood_type is positive (or unknown), surface a “RhoGAM indicated” prompt on the postpartum tab. Currently the checkbox is there but nothing reminds the clinician to tick it.
  • Auto-link milk-bank recipient to a newborns row. The recipient form has baby_patient_id but the kiosk doesn’t yet offer a picker that lists in-house newborns; the field is typed by hand or filled programmatically.
  • Donation expiry sweep. expiring_soon_count is computed for the dashboard, but no daily job auto-flips expired donations to discarded. Today the milk-bank operator does it manually.
  • Pasteurization curve / quality control. pasteurized_method is captured but the holder-method temperature/time validation isn’t enforced server-side.
  • Per-patient row-level filter on reads. Same gap noted in ICU_GUIDE — RBAC is path-based today.
  • Critical-result back-alerts on stat labs/imaging.
  • Apply the same kiosk shell + chart popup pattern to Emergency / Operations.

Last updated: 2026-04-29