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
| Responsibility | Detail |
|---|---|
| Maternity board | The 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 chart | A 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 observations | They 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 form | A 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). |
| Delivery | When 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 registration | After delivery, Add Baby registers an additional newborn against the maternity case. Bracelets get colour + ID; NICU flag picks an incubator room. |
| Placing orders | The + 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 bonding | Postnatal nursing assessments (Edinburgh score, bonding) are logged from the chart’s Nursing Assess. card. |
| Milk Bank | Manage 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
- Sign in. The system bounces them straight to
/maternity. No dashboard intermediate step. - Read the board. Four tabs: Mothers, Newborns, Premature, Milk Bank. Mothers tab segments by labor stage.
- 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.
- 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).
- Click “Newborns”. Lists every baby on this maternity case with weight, length, Apgar, blood type, bracelet colour + ID, premature / NICU badges, status.
- 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.
- 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).
- Place an order. Close the chart, click
+ Orderon 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. - 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.
- Register a late-arrival baby. If a baby is added later (paperwork, transfer), use Add Baby on the row.
- 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.
- 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.
| Tab | What goes in it | When you fill it |
|---|---|---|
| Pregnancy History | Gravida / 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 Risk | Free-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 & Delivery | Labor 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. |
| Postpartum | Postpartum 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:
| Section | What you do there |
|---|---|
| Overview | Seven 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. |
| Donors | Register 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. |
| Recipients | Register 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. |
| Donations | Receive 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. |
| Distributions | Dispense 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
availablestatus 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 → statusavailablefirst. - “The donor is eligible but the donation form rejects me.” Active flag is a separate switch from eligibility — make sure
Activeis 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
+ Orderon 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.roleisdoctorornurse.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:
- Sets the post-login home to
#/<wardRoute>(skips/dashboard). - Bounces any
#/dashboardhit back to the ward route. - Renders
renderWardShell(wardKey)instead of the sidebar shell. Brand label, tab label, and embedded page tag come fromWARD_CONFIG[wardKey]. For maternity the slot hosts<maternity-page>directly. 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 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='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()callsGET /api/maternity-details,GET /api/admissions,GET /api/newborns,GET /api/roomsin 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). _isWardUsergetter 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 aformTabstate field driving four panels (Pregnancy History / Antenatal Risk / Labor & Delivery / Postpartum). All four panels are always in the DOM; tab switching isstyle="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):
| Group | Columns |
|---|---|
| Pregnancy history | blood_type, rh_factor, prenatal_visits, previous_csections |
| Antenatal risk | antenatal_risk, gdm (bool), preeclampsia (bool), hiv_status, hbv_status, gbs_status, rubella_immune, allergies, current_medications |
| Labor & delivery | membrane_status, rom_time, amniotic_fluid, labor_onset, induction_method, anesthesia, episiotomy (bool), perineal_tear, blood_loss_ml, placenta_status |
| Postpartum | postpartum_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 withCOALESCEon every nullable column soScan()never seesNULL.scanMaternity(rows, &m)helper — single Scan binding reused byListMaternityDetailsand would-beGetMaternityDetail.CreateMaternityDetailandUpdateMaternityDetailwrite 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 viashow()); Newborns is fetched bygetNewborns({ 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
| Card | List API | Add API | Editable |
|---|---|---|---|
| Pregnancy | passed in via show(motherCase) | (use Edit / Deliver on the board) | no |
| Newborns | GET /api/newborns?maternity_id= | (use Deliver / Add Baby 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) | 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:
| 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 |
| Wt | 29463-7 | Body Weight | kg |
| Pain | 38208-5 | Pain Severity | 0-10 |
| FetalHR | 11947-9 | Fetal Heart Rate | bpm |
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:
| Tab | Endpoint | Receiving alert |
|---|---|---|
| Prescription | POST /api/prescriptions source=maternity | Pharmacy queue |
| Lab | POST /api/service-requests category=laboratory | Laboratory department |
| Imaging | POST /api/service-requests category=radiology | Radiology department |
Delivery and newborn registration stay on the maternity page itself:
- Deliver → 2-step modal (
renderDeliveryModal), submitsPOST /api/maternity-details/:id/deliverwith the babies array. - Add Baby →
renderBabyModal, submitsPOST /api/newborns. - Edit → updates the maternity_details record itself.
B.10 Milk Bank — backend
Four new tables in database.go:
| Table | Purpose | Key columns |
|---|---|---|
milk_donors | Donor mother roster + screening + eligibility | donor_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_recipients | Authorised recipient babies | recipient_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_donations | Per-batch deposits with status walk | donor_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_distributions | Dispensings to recipients with chain of custody | recipient_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, plusbaby_patient_name/mother_patient_name.MilkDonation— carriesdonor_nameanddispensed_ml(subquery sum) so the kiosk’s table doesn’t need a second round trip.MilkDistribution— carriesrecipient_nameanddonor_name.MilkBankDashboard— KPI snapshot returned byGET /api/milk-bank/dashboard.
Handlers in milk_bank.go — full CRUD plus dashboard. Server-side guardrails:
CreateMilkDonationrefuses if the donor’seligibility_statusisineligibleordeferred(HTTP 403).CreateMilkDistributionrefuses ifdonation.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
dispensedvia adefer-scheduled UPDATE. DeleteMilkDonor/DeleteMilkRecipientsoft-archive (setactive=FALSE/status='completed') when downstream rows exist; only hard-delete when nothing references them.DeleteMilkDonationreturns HTTP 409 when distributions exist; the caller is told to mark the donationdiscardedinstead.
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 amodalKindto 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-bankto 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_mlis 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='-'andbaby_blood_typeis 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
newbornsrow. The recipient form hasbaby_patient_idbut 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_countis computed for the dashboard, but no daily job auto-flips expired donations todiscarded. Today the milk-bank operator does it manually. - Pasteurization curve / quality control.
pasteurized_methodis 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