Care plan scheduling
Care Plan Scheduling for FHIR Backends
A recurring patient program (biweekly PHQ-9, monthly KCCQ-12, daily medication reminders, post-surgical milestones, study check-ins) is a schedule plus an activity plus an enrolled population. Fire Arrow Server treats the patient's care plan as the schedule, each scheduled occurrence as its own searchable record on the FHIR timeline, and the notification to your application as a subscription event. The patient app stays a thin frontend; the timeline, the timing, the audit trail, and the access control are shared with the rest of your FHIR backend.
What you can build
- Recurring patient programs without a separate scheduler
The patient's care plan defines the cadence. The server creates each upcoming occurrence on its own and marks it due at the right local time. No cron job, no background worker, no external job runner.
- Each occurrence is its own searchable record
A clinician dashboard like "patients with a check-in due this week" or "patients who missed last weekend's questionnaire" is one FHIR query, not a custom reporting pipeline.
- Reminders that fit the channel you already use
When an occurrence becomes due, the server pushes a notification to a webhook, an email address, a WebSocket, or an Azure Storage Queue. Push notifications, SMS, in-app messages, and call-centre systems all consume the same event stream.
- Patient app stays a thin frontend
The app fetches the due occurrence, renders the linked activity (questionnaire, medication acknowledgement, symptom check-in), and saves the result. The schedule, the timezone, the recurrence, and the audit live in the backend.
- Schedule changes without code or deploys
Switching a program from biweekly to weekly, swapping the activity, or shortening the duration is a data update on the care plan. The server picks it up on the next pass. No code change, no redeployment.
- Timezone-correct timing
Each occurrence is anchored to the patient's local time, so a 9 AM reminder still fires at 9 AM after a daylight-saving transition without per-application bug fixes.
- Same mechanic across every program type
Questionnaires, medication adherence reminders, follow-up appointments, study check-ins, post-surgical milestones all run on the same primitive. New program types are configuration, not a new subsystem.
How it works
- 1 Describe the program once, reuse it for every patient
Define the recurring schedule as a reusable FHIR PlanDefinition: which activity to run, how often, and for how long. For example, a PHQ-9 questionnaire every two weeks for six months, or a daily medication acknowledgement for the duration of a course. The cadence lives in data, so changing biweekly to weekly is a configuration update, not a code release.
- 2 Enroll a patient on the program
Apply the template to a specific patient with their start date and timezone. The server generates that patient's own care plan and anchors every future occurrence to their local time. Each enrolled patient runs on their own timeline; nothing about one patient's schedule influences another's.
- 3 Turn on scheduling and due-event notifications
A single call activates the schedule and registers your application to be notified when each occurrence becomes due. From this point the server takes care of when to fire what (including timezone, daylight-saving, and recurrence) without any cron or background workers on your side.
- 4 The server keeps a rolling window of upcoming occurrences
Each upcoming occurrence is created as a real record on the FHIR timeline (thirty days ahead by default), so care teams can search them like any other clinical data: "what is due for this patient this week?", "who has a check-in due tomorrow?", "who missed last weekend's questionnaire?". As time advances, the window rolls forward and new occurrences appear.
- 5 Each occurrence is marked due at the patient's local time
When an occurrence's scheduled moment arrives, the server transitions it to a due state and pushes a notification to whichever channel you registered: a webhook, an email address, a WebSocket, or an Azure Storage Queue. Your patient app, a reminder service, a call-centre integration, and an operations dashboard can all listen on the same event stream.
- 6 Your application captures the response
The patient app fetches the due occurrence, presents the linked activity (questionnaire, medication acknowledgement, symptom check-in) to the patient, and posts the result back. The to-do is closed and the clinical record is updated in the same step. Care teams see the response on the patient's timeline immediately.
- 7 Update or stop the program as data, not deploys
Changing the cadence, swapping the activity, or shortening the program is an update to the patient's care plan; future occurrences within the rolling window are revised accordingly. Already-completed occurrences stay as they are. Stopping enrollment is a single status change on the patient's care plan.
What you get out of the box
The schedule belongs in the FHIR data, not in code
In a conventional implementation, monitoring or follow-up logic lives in application code: a cron schedule, a configuration file, hardcoded intervals in a backend service. A change to the cadence (different frequency, different activity, different duration) requires a developer, a code change, and a redeployment.
When the schedule lives on the patient's care plan instead, a clinician or administrator can update the cadence, switch the activity, or change the duration without touching code. The same template can be applied across an enrolled population by re-running the apply step.
Every occurrence is its own searchable record
Each scheduled occurrence is captured as a small FHIR Task that links back to the patient and to the program it came from, and carries the state of the work: due, in progress, completed, or missed. Because Tasks are standard FHIR data, a dashboard like "patients with an overdue check-in this week" is one FHIR query, not a custom reporting pipeline.
Tasks live under the same authorisation rules as the rest of the FHIR data, so nothing has to be reimplemented per app. A patient signed in to the patient app sees only their own Tasks. A clinician sees only the Tasks belonging to their organisation. A service account that sends reminders gets only the operations it needs.
Reminders and clinical follow-up stay independent
"Patient has a check-in due" and "patient just submitted a concerning result" are different events with different audiences. Treating them as separate notification streams keeps the reminder pipeline and the clinical-follow-up pipeline from being tangled into one piece of code.
One stream tells the patient app when an occurrence is due, which drives reminders. A second stream can be set up on the responses themselves, telling a scoring or escalation service when a result comes back. Swapping the push-notification provider, adding a new scoring rule, or changing the escalation path can each happen on its own without disturbing the other side.
Operational controls, with sensible defaults
Two settings tune the scheduling engine: how far ahead occurrences are prepared (thirty days by default) and how often the engine checks. A cap on the number of open occurrences per activity keeps a multi-year program from accumulating thousands of pending records at once.
Notifications cannot pile up unnoticed. Every subscription has a required end date and a configurable maximum lifetime, so a forgotten one expires on its own. Delivery failures are tracked, and the server can auto-disable a subscription after too many consecutive failures or after a configurable stretch with no successful delivery.
Timezone is the one setting worth getting right at enrollment. With it, recurring reminders fire at the patient's local wall-clock time and survive daylight-saving transitions. Without it, the server still creates the work, but it cannot put it in front of the patient at the right hour.
Example deployments
- Patient questionnaire programs
A depression-monitoring program runs PHQ-9 every two weeks for six months. A heart-failure follow-up runs KCCQ-12 monthly. Each enrolled patient has their own care plan; the server creates the upcoming occurrences and notifies the patient app on the right day.
- Medication adherence reminders
A medication course schedules a daily acknowledgement for the duration of the course. The patient confirms taking the medication and the response is captured on the patient's clinical record. Care teams see compliance over time on the same timeline as the rest of the patient's data.
- Post-surgical follow-up milestones
Check-ins at the two-week, six-week, and twelve-week milestones after a procedure. Each occurrence is anchored to the patient's procedure date rather than to a fixed recurring interval, so the schedule still works when a procedure slips by a few days.
- Clinical study check-ins
Recurring questionnaires across a study population on a single template. Different audiences (operational staff, investigators, sponsors) can see different views of the same occurrences by configuring access rules. No duplicate pipeline per audience.
FAQ
What kinds of recurrence does the schedule support?
Daily, weekly, monthly, and custom intervals using the standard FHIR timing fields (frequency, period, period unit). Time-of-day and timezone are part of the schedule, so a "9 AM weekly" reminder behaves correctly across daylight-saving transitions.
Can I change the schedule for an enrolled patient?
Yes. Update the patient's care plan and the upcoming occurrences within the rolling window are revised. Already-completed occurrences stay as they are. Updates to the underlying template can be re-applied programmatically across the enrolled population.
What happens if a patient misses an occurrence?
The occurrence stays as a record with its state set accordingly, so a clinician can see what was missed and decide whether to act. The next scheduled occurrence is unaffected and the program continues. How to handle a missed occurrence is a clinical decision, not a server one.
How does Fire Arrow handle timezones and daylight saving?
Timezone is set when a patient is enrolled, either on their care plan or on the patient record itself. Daylight-saving transitions are handled centrally so recurring patient communication fires at the correct local wall-clock time without per-application bug fixes.
Does it work for non-clinical workflows like study check-ins?
Yes. The mechanics are the same: a template defines the schedule and the activity, the patient (or participant) is enrolled on it, occurrences materialise on the timeline, and responses are captured back. Authorisation rules can serve different views to operational staff, investigators, and sponsors without rebuilding the workflow.
Is care plan scheduling available on Fire Arrow Core?
Materialisation runs server-side on Fire Arrow Server. On Core, the upstream FHIR service stores the care plan, but the timeline materialisation has to be handled by the client or an external scheduler.