Scheduling Service — Service Risk Register
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 11 risks-and-tradeoffs
Risk Register
| ID | Risk | Likelihood | Impact | Owner | Mitigation | Status |
|---|---|---|---|---|---|---|
| RISK-SCHED-01 | Overbooking / double-booking — two concurrent booking requests both pass slot-availability check before either commits, creating two appointments for the same slot | Low | High | Engineering Lead | Atomic slot status transition using SELECT ... FOR UPDATE on the Slot row; unique constraint on (slot_id, status=booked); SCHEDULER/ADMIN override requires explicit flag + audit event | Open |
| RISK-SCHED-02 | No-show cascade — high no-show rate at a facility leaves waitlisted patients unpromoted and slots wasted; waitlist auto-fill may not fire reliably under load | Medium | Medium | Clinical Ops | Waitlist auto-fill triggered by appointment.no_show event; SLA alert if waitlist-fill rate drops below threshold; human confirmation gate before final booking to prevent mis-notifying patient | Open |
| RISK-SCHED-03 | Slot lock contention under load — concurrent availability searches and booking attempts on the same provider or facility slot table cause lock waits and query timeouts | Medium | Medium | Platform SRE | Slot table partitioned by (schedule_id, start_time) range; read-path uses snapshot isolation (no lock); write-path uses row-level lock only at commit; HPA scales booking pods under high RPM; circuit breaker on slot lock wait > 500ms | Open |
| RISK-SCHED-04 | Timezone / DST edge cases — appointments booked across a DST transition render at the wrong wall-clock time; "fall back" creates ambiguous 1-hour window | Medium | High | Engineering Lead | All timestamps stored as UTC; Schedule carries IANA timezone string; appointment UI renders using schedule timezone + DST-aware formatting; integration tests cover DST transition boundaries; facility timezone validated at schedule creation | Open |
| RISK-SCHED-05 | Cascade cancellation failures — bulk cancellation of a provider schedule (e.g., provider sick) partially completes; some appointments remain booked without patient notification | Low | High | Engineering Lead | Bulk cancellation uses saga pattern with per-appointment idempotent compensation; outbox guarantees appointment.cancelled event per appointment; incomplete saga retried by cron; alert fires if any appointment remains in transitional cancelling state > 10 min | Open |
| RISK-SCHED-06 | FHIR Slot status sync lag — the Slot.status exposed via FHIR R4 lags behind the internal slot state after high-volume booking, causing external FHIR clients to see stale availability | Low | Medium | Integration Lead | FHIR Slot projection updated in the same transaction as internal slot status change; no separate sync job; ETag / Last-Modified headers on FHIR responses allow consumer cache validation; alert on interop-service FHIR slot projection lag metric | Open |
| RISK-SCHED-07 | Timezone configuration error — facility misconfiguration — a facility is configured with the wrong IANA timezone, causing all appointment times to render incorrectly for that facility | Medium | High | DevOps | IANA timezone validated against tzdata on schedule creation; facility timezone shown prominently in schedule admin UI; onboarding runbook includes timezone verification step | Open |
| RISK-SCHED-08 | Reminder dispatch duplication — idempotency failure in reminder worker causes a patient to receive multiple reminder notifications for the same appointment | Low | Medium | Platform SRE | Reminder dispatch key: (appointment_id, lead_time_minutes); deduplication enforced in NATS consumer with inbox table; retry bounded to 3×; duplicate reminder alert fires if same key processed twice within 1 hour | Open |
| RISK-SCHED-09 | Deceased patient receives reminder — patient.vital-status-changed event not processed before reminder fires | Medium | Medium | Integration Lead | Subscribe to REGISTRATION.patient.vital_status_changed.v1; appointment creation guard blocks scheduling for deceased patients; cron marks existing appointments cancelled on vital status change event receipt | Open |
| RISK-SCHED-10 | HL7 v2 SIU inbound creates malformed appointments — poorly formatted SIU^S12 message from a legacy system produces a partial or invalid Appointment record | Medium | Medium | Integration Lead | Strict SIU parser with schema validation; failed messages routed to dead-letter queue with alert; no partial appointment persisted on parse failure; interop team reviews DLQ weekly | Open |