Resource-graph scheduling with multi-stage visit types, provider/room/equipment constraints, and waitlist automation.
Data Classification: All 7 entities are org-scoped. Partition key: OrganizationID. No cross-org data sharing.
See Data Model for ownership conventions.
Schedule P0
A named block of availability for a provider at a location.
Schema
Field
Type
Required
PK
FK
Notes
ScheduleID
UUID
Yes
Yes
ProviderID
UUID
Yes
Provider
LocationID
UUID
Yes
Location
ScheduleName
String(200)
Yes
ScheduleKind
String(50)
Yes
InPerson | Telehealth | Hybrid | GroupVisit
EffectiveStart
DateTimeUTC
Yes
EffectiveEnd
DateTimeUTC
No
Null = open-ended
IsActive
Bool
Yes
OrganizationID
UUID
Yes
Organization
Partition key
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTimeUTC
DateTimeUTC
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTimeUTC
DateTimeUTC
Yes
Audit
IsDeleted
Bool
Yes
Soft-delete
RBAC
Role (Tier)
Access
Patient (10)
Read public schedule metadata
FrontDesk (30)
Read
MA / RN (40)
Read
Provider (50)
Read & edit own schedules
PracticeMgr (70)
Full CRUD
EditAMI (90+)
Schema management
Slot P0
A discrete time segment on a schedule, governed by optimistic concurrency via ResourceVersion.
Schema
Field
Type
Required
PK
FK
Notes
SlotID
UUID
Yes
Yes
ScheduleID
UUID
Yes
Schedule
VisitTypeID
UUID
Yes
VisitType
SlotStart
DateTimeUTC
Yes
SlotEnd
DateTimeUTC
Yes
SlotStatus
String(50)
Yes
Free | Held | Busy | Cancelled
HoldExpires
DateTimeUTC
No
TTL for Held status
ResourceVersion
Int
Yes
Optimistic concurrency vector
OverbookAllowed
Bool
Yes
OrganizationID
UUID
Yes
Organization
Partition key
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTimeUTC
DateTimeUTC
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTimeUTC
DateTimeUTC
Yes
Audit
IsDeleted
Bool
Yes
Soft-delete
RBAC
Role (Tier)
Access
Patient (10)
Read self-bookable slots only
FrontDesk (30)
Read & book (Hold/Busy transitions)
MA / RN (40)
Read
Provider (50)
Read
PracticeMgr (70)
Full CRUD
EditAMI (90+)
Schema management
Appointment P0
The core booking record linking a patient to a slot. Tracks status through a full lifecycle with reminder-ladder automation and reschedule chains.
Template defining duration, eligibility requirements, and self-scheduling rules. Stages break each visit into granular resource demands.
Schema
Field
Type
Required
PK
FK
Notes
VisitTypeID
UUID
Yes
Yes
VisitTypeName
String(200)
Yes
VisitTypeCode
String(50)
Yes
TotalDurationMinutes
Int
Yes
Denormalized sum of stages
RequiresEligibilityCheck
Bool
Yes
RequiresPriorAuth
Bool
Yes
SelfSchedulable
Bool
Yes
Exposed to Patient Portal
NewPatientAllowed
Bool
Yes
DefaultProviderRole
String(50)
No
MD | DO | NP | PA | RN | MA
IsActive
Bool
Yes
OrganizationID
UUID
Yes
Organization
Partition key
CreatedByUserID
UUID
Yes
User
Audit
CreatedDateTimeUTC
DateTimeUTC
Yes
Audit
UpdatedByUserID
UUID
Yes
User
Audit
UpdatedDateTimeUTC
DateTimeUTC
Yes
Audit
IsDeleted
Bool
Yes
Soft-delete
RBAC
Role (Tier)
Access
Patient (10)
Read self-schedulable visit types only
FrontDesk (30)
Read
MA / RN (40)
Read
Provider (50)
Read
PracticeMgr (70)
Full CRUD
EditAMI (90+)
Schema management
VisitStage P0
An ordered step within a visit type. Each stage declares which resource kinds and capabilities it requires, enabling the resource-graph solver to allocate rooms and staff.
The scheduling engine uses a constraint-satisfaction approach. Each VisitStage declares required resource kinds and capability tags.
The solver finds a feasible allocation of resources across all concurrent stages in the time window, respecting capacity limits and provider availability.
P0 The system shall create, read, update, and soft-delete Schedules per provider per location with effective date ranges.
P0 The system shall auto-generate Slots from a Schedule template, respecting block-time windows and VisitType durations.
P0 The system shall enforce optimistic concurrency on Slot updates via ResourceVersion to prevent double-booking.
P0 The system shall transition Appointment status through the full state machine (Booked, Confirmed, CheckedIn, InProgress, Completed, NoShow, Cancelled, Rescheduled).
P0 The system shall fire an eligibility check when VisitType.RequiresEligibilityCheck is true and surface the result on the Appointment.
P0 The system shall support the resource-graph solver to allocate Resources (rooms, staff, equipment) across VisitStages.
P0 The system shall maintain a ReminderLadder on each Appointment, triggering SMS/email/voice at configurable cadence.
P0 The system shall support multi-channel booking (FrontDesk, Portal, Phone, WalkIn, WaitlistOffer) with channel recorded on each Appointment.
P0 The system shall enforce all 12 constraint rules during slot selection and booking.
P1 The system shall maintain a priority-scored Waitlist and auto-offer freed slots to the highest-scoring entry.
P1 The system shall expire WaitlistEntry offers after OfferExpires and re-queue the entry.
P1 The system shall track reschedule chains via RescheduledFromAppointmentID and warn at chain length > 3.
P1 The system shall support group visits via VisitType.ScheduleKind = GroupVisit with shared slot capacity.
P2 The system shall provide a provider utilization dashboard showing slot fill rate, no-show rate, and average wait time.
Non-Functional Requirements
Latency: Slot availability query must return within 200 ms for a 30-day window.
Concurrency: System must handle 50 concurrent booking attempts per location without data loss.
Uptime: 99.9% availability for booking endpoints during business hours.
Scalability: Support 500 providers and 10,000 appointments/day per organization.
Audit Trail: Every state transition must be logged with actor, timestamp, and prior value.
HIPAA: All PHI fields encrypted at rest (AES-256) and in transit (TLS 1.2+).
Timezone: All timestamps stored as UTC; UI renders in practice-local timezone.
Idempotency: Booking API must be idempotent; duplicate requests return the existing Appointment.
Retention: Completed/Cancelled appointments retained for 7 years per HIPAA retention guidance.
Accessibility: Scheduling UI must meet WCAG 2.1 AA, including keyboard-navigable calendar.
icApplication Overrides
How the Scheduling noun-apps are generated by IC on top of Cosmos DB + a constraint-solver library, surfaced as FHIR Schedule / Slot / Appointment, and dispatched through a pre-visit reminder ladder. The scheduling-engine is one of the few rev.health modules that ships a domain-specific binding override (the resource-graph component) on top of the IC default component generation.
Shared generation map. The IC platform code-gen flow, default bindings, environment cascade, RBAC model, and CLI commands are identical across all modules. See the IC Reference for the canonical shared reference. This section covers only Scheduling-specific content.
Technology Stack P0
The shared platform stack (Cosmos DB, Redis, IC-generated API, Angular 21, SQS+SNS, OpenTelemetry, etc.) is documented in the IC Reference. Module-specific additions:
Layer
Choice
Notes
Solver library
Google OR-Tools CP-SAT (primary) / Timefold (fallback)
The scheduling-engine library and FHIR facade are hand-written and consumed by the generated API layer.
Domain-Specific Override Bindings P1
One binding is overridden at the module level: the default ic-ng21-core-1-jtable for Slot is replaced by ic-ng21-scheduling-1-resource-graph. The default jtable presents Slots as a flat grid keyed on SlotStartDateTimeUTC; the resource-graph component renders Slots as paths through the resource graph and surfaces feasibility explanations inline.
Entity / Surface
Default Binding
Override Binding
Reason
Slot search / availability view
ic-ng21-core-1-jtable
ic-ng21-scheduling-1-resource-graph
Flat grid cannot express multi-resource paths; the resource-graph view shows provider, room, MA, and equipment lanes simultaneously.
Live status board
(no IC default)
ic-ng21-scheduling-1-status-board
SSE-driven board purpose-built for back-office wall display.
Reminder ladder editor
ic-ng21-core-1-text-area on JSON state
ic-ng21-scheduling-1-reminder-ladder
Visual T-30/T-14/T-3/T-day cadence editor with TCPA opt-in checkbox per channel.
VisitType / VisitStage composer
ic-ng21-core-1-jtable on VisitStage
ic-ng21-scheduling-1-stage-composer
Drag-to-reorder stages with named-resource picker per stage.
Pre-Visit Reminder Ladder Dispatcher P1
The reminder dispatcher is a scheduled worker (reminder-ladder.worker.ts) that fires four reminders per appointment by default. The cadence is configurable per VisitType, but the v1 default is T-30, T-14, T-3, and T-day.
// Every minute, the worker scans the ReminderLadderState index for due rungs.
for each Appointment a in due_rungs(now):
rung = a.next_due_rung()
if !patient_opted_in(a.PatientID, rung.channel):
skip_rung(a, rung, reason="opt-out")
continue
if a.AppointmentStatus in ["Cancelled", "NoShow", "Completed"]:
cancel_remaining_rungs(a)
continue
body = render_template(rung.template, a)
dispatcher.send(a.PatientID, rung.channel, body)
audit_log.write(a, rung, "sent")
a.ReminderLadderState = advance(a.ReminderLadderState, rung)
persist(a)
The dispatcher runs on a 60-second tick. NFR-6 requires that 99.5% of messages dispatch within 5 minutes of their scheduled fire-time; the queue is sized to absorb 100K appointments-in-flight per tenant without breaching the SLA.
Versioning — Worked Example P0
Every versionable artifact in the Scheduling module follows IC SemVer per Hard Rule #9: break.feature.bug.buildtimestamp. The example below traces the lifecycle of the Slot AMI from its initial schema shape through a feature addition and a bug fix.
Break: rename SlotStatusString50 → SlotStatusEnum with constrained domain; legacy String kept on 1.x
ic-ng21-slot-2-app
New tag (break segment 2); per IC Hard Rule #13, new database; ETL from 1.x to 2.x runs blue-green; 1.x stays live for rollback
Illustrative example. The version timestamps and the precise contents of each release above are illustrative — they describe how the SemVer contract would apply to the Scheduling module if a real change were made. They are not derived from a checked-in change log.
Scheduling environment details
Key
Dev
QA
UAT
Prod
scheduling.solver.timeoutMs
500
500
250
250
scheduling.solver.workerCount
1
2
4
8
reminder.dispatcher.dryRunBool
true
true
false
false
reminder.sms.provider
twilio-test
twilio-test
twilio-prod
twilio-prod
Scheduling RBAC notes
ABAC overlays for patient-context apply (a patient sees only their own appointments).
Operation
Min permission level
ABAC predicate
Read own appointments
10 (Patient)
Appointment.PatientID = subject.PatientID
Search slots / book
30 (Front-Desk)
OrganizationID = current_org()
Update appointment status
40 (MA/RN)
OrganizationID = current_org()
Edit own schedule blocks
50 (Provider)
Schedule.ProviderID = subject.ProviderID
Edit any schedule / VisitType / VisitStage
70 (Practice Manager)
OrganizationID = current_org()
Override block schedules
60
OrganizationID = current_org()
Edit AMI / break-change
90 (Org Admin / EditAMI)
—
Cross-Module Links
Eligibility — EligibilityCheck triggered at booking/T-24h/check-in; result surfaced on Appointment.EligibilityStatus.