1. Nightly Eligibility Calculation and Cohort Assignment
Trigger: scheduled nightly across the active panel.
Actions in order:
- For each panel patient, read last_wellness_visit_date and compute eligibility_start_date using the practice's recorded interval rule. Where no prior visit exists, use the practice's rule for new patients rather than defaulting to today. A never-visited patient and a patient due again are different cohorts with different messages.
- Set eligibility_window_end and recall_year.
- Assign recall_cohort_month. Default to the patient's own anniversary month, which spreads the panel naturally. Where anniversaries bunch (common after a past mass-recall) redistribute the overflow into adjacent months against the practice's monthly capacity figure, keeping the most overdue patients in the earliest month. Capacity, not enthusiasm, sets cohort size.
- Create the card in Eligibility Pending. Do not create a duplicate if a card already exists for this patient and recall_year.
- At 30 days before eligibility_start_date, apply awv-due-soon. On the date, apply awv-due and move the card to Eligible, Not Contacted.
- Maintain the overdue bands: 60 days past eligibility_start_date unbooked applies awv-overdue-60; 120 days applies awv-overdue-120. These bands drive the wave-three call priority.
- Never send from this workflow. It only computes state. All sending is gated behind workflow 2, so there is exactly one place where a send can be stopped.
Exit: card terminal, or patient leaves the panel.
2. Suppression and Safety Battery
Trigger: immediately before every outreach send, every letter queue and every call task creation. Not once per cohort: every time.
Checks in order, any hit stops the send:
- Deceased. Checked against the records system on every send. This is the check that matters most and the one a quarterly list-pull gets wrong. A recall letter arriving for someone who has died is the kind of harm that no conversion rate justifies, so it is checked first, checked every time, and a card that hits it moves to Suppressed permanently with no further automation of any kind.
- Clinician hold. Any clinician-hold flag suppresses outreach. Clinicians need an easy, one-click way to set it, with no obligation to record a reason in this system. Some patients should not receive routine recall messages and the clinical team should not have to explain why to an automation.
- Already booked or already attended this recall year. Move the card forward rather than suppressing it.
- Record inactive, transferred out, or duplicate. Suppress with the reason, and create a data-quality task for duplicates rather than just skipping them.
- Recall opt-out. recall_opt_out suppresses the whole program for that patient, not just one channel.
- Channel consent. Email and SMS each require their own recorded consent. A patient with neither skips to the letter and call waves rather than being counted as unreachable.
- Address validity. A letter is queued only when mailing_address_verified is true and mail_returned_flag is false. Returned mail sets the flag and creates an address-update task.
- Frequency cap. No patient receives more than one recall touch in any rolling 7 days, or more than 4 recall touches in the whole year, across all channels and all programs. A recall program running alongside other campaigns is the most common source of patients feeling harassed by a practice.
- Content guardrail. Verify the body and subject line against the merge-field allow-list: first name, practice name, provider name, booking link, preferences link, portal link, location, eligibility date. Every clinical field, every screening name, every condition and every past-visit detail is blocked. A failing send is blocked and alerted, never silently rewritten.
- Quiet hours. Hold to the configured window in the patient's timezone. A recall is never urgent; there is no reason for it to ever arrive outside business hours.
Exit: runs permanently as the single gate in front of every send.
3. Staged Outreach Ladder
Trigger: stage becomes Eligible, Not Contacted and the card's recall_cohort_month is the current month.
Actions in order:
- Wave 1: email, day 0. Move to Outreach Wave 1, apply outreach-w1. Subject line: “Your yearly check-in with {{practice_name}} is due”. Body: “Hi {{contact.first_name}}, you're due for your annual wellness visit with {{practice_name}}. It's a longer appointment set aside to review how you're doing overall and plan the year ahead. Nothing specific, just the yearly one. Pick a time that suits you: {{booking_link}}. Prefer a different way to hear from us, or want to skip this year? {{preferences_link}}.” Increment outreach_touch_count, set last_touch_date and last_touch_channel.
- Wait 14 days. If booking_date is empty, run wave 2: escalate channel, do not resend the email. Move to Outreach Wave 2, apply outreach-w2. SMS: “Hi {{contact.first_name}}, it's {{practice_name}}, your yearly wellness visit is due. Book in a couple of taps: {{booking_link}}. Reply STOP to stop texts.” Send a portal message in parallel for active portal users; the portal version may include a little more plain-language detail about what the visit involves.
- Wait 21 days. If still unbooked, run wave 3. Move to Outreach Wave 3, apply outreach-w3. Queue a letter where the address is verified, and create a live call task. Prioritize the call queue by overdue band first, then by any recorded barrier: transport_barrier_flag, interpreter_needed, no portal, no digital consent. Call the patients the digital waves could never have reached, first.
- Caregiver branch. Where caregiver_contact_on_file exists with documented authorization, the wave-three call task includes that contact as the alternate. Documented authorization is the condition, not convenience.
- Wait 14 days after wave 3. If unbooked, apply channel-exhausted and stop outreach. The card stays open until eligibility_window_end so an inbound booking still lands correctly, but no further messages go out. Four touches and a phone call is enough; a fifth teaches the patient to ignore the practice.
- Engagement interception. Any open, click, reply or inbound call sets engagement_signal and, if no booking follows within 72 hours, moves the card to Engaged: No Booking and creates a same-week call task. This interception jumps the queue ahead of cold patients because someone who clicked and did not book is usually one short conversation away.
- Window close. At eligibility_window_end with no booking, move to Lapsed, record which waves ran, and feed the panel gap report.
Exit: booked, declined, suppressed, or lapsed.
4. Booking Funnel and Conversion
Trigger: a booking is made from the Wellness Visit Booking page, by BO, or by staff.
Actions in order:
- Hard eligibility gate. Reject any booking dated before eligibility_start_date and offer the earliest eligible date instead: “We can book you from {{eligibility_start_date}}, here are the first available times.” The gate is absolute and applies to staff bookings too, with a documented override path for the clinical exceptions.
- Write booking_date, booked_provider and booking_source: wave and channel. Without booking_source you cannot tell which wave is earning its cost, and wave three is the expensive one.
- Apply awv-booked, remove outreach tags, move the card to Booked, and cancel every pending outreach step immediately. A patient who books on Tuesday must not get wave two on Wednesday.
- Send confirmation: “You're booked, {{contact.first_name}}, {{visit_day}} {{visit_time}} at {{location}} with {{provider_name}}. Allow about {{duration}} minutes. We'll send a short form to fill in beforehand so we can spend the time on you rather than paperwork.”
- Abandonment branch. If the booking page is opened and availability viewed but no booking completes, wait 2 hours and send one recovery message: “Hi {{contact.first_name}}, looked like you were booking your wellness visit and got interrupted. Here's your link again: {{booking_link}}. Reply HELP and we'll book it for you.” Once only, then route to Engaged: No Booking.
- Capacity guard. If the cohort month's bookings exceed the configured capacity, notify the practice manager and hold the next cohort's wave one rather than booking patients eleven weeks out. A recall that books people beyond their own attention span converts into no-shows.
- Hand to workflow 5.
Exit: booking confirmed, or card returned to the outreach ladder.
5. Pre-Visit Questionnaire Chase
Trigger: stage becomes Booked.
Actions in order:
- Publish the Pre-Visit Health Questionnaire to the portal, set previsit_sent_date, apply previsit-outstanding. Send a doorbell only: “Hi {{contact.first_name}}, there's a short form in your secure portal to fill in before your visit: {{portal_link}}. Takes about five minutes.” The clinical questions live in the portal; the message says nothing about them.
- Wait until 7 days before the visit. If incomplete, send reminder one on preferred_channel.
- Wait until 3 days before. If incomplete, send reminder two and offer the alternative: “Easier by phone? Book a 10-minute call and we'll fill it in with you: {{previsit_call_link}}.”
- Wait until 1 day before. If incomplete, create a front desk task to complete it at check-in and allow extra time. Notify the provider that the questionnaire is outstanding so the visit is not derailed by it.
- On completion, set previsit_complete_date, swap the tags, move the card to Pre-Visit Complete, and make the responses available to the provider through the normal clinical route, not as an email attachment and not pasted into a notification.
- Portal-inactive branch. If portal_activated is false, skip the digital chase entirely and create the Pre-Visit Phone Review task at booking. Do not send three portal reminders to a patient who has no portal.
Exit: questionnaire complete, phone review booked, or front desk task created.
6. Visit Reminders and No-Show Recovery
Trigger: stage becomes Booked, running alongside workflow 5.
Actions in order:
- 7 days before: the reminder that matters, because wellness visits are booked weeks ahead. Include a one-tap reschedule, not just a confirm: “Hi {{contact.first_name}}, your wellness visit with {{practice_name}} is {{visit_day}} at {{visit_time}}. Still good? Confirm or move it here: {{manage_link}}.” Offering the reschedule openly converts a future no-show into a kept appointment on another day.
- 2 days before: short confirmation with location and duration.
- 3 hours before: final doorbell with location and parking or arrival detail. Nothing clinical.
- Reschedule branch. A reschedule keeps the card in Booked, rewrites booking_date, restarts the reminder ladder and leaves the questionnaire progress intact. It is explicitly not treated as a cancellation.
- Cancellation branch. Return the card to Engaged: No Booking, not to the cold waves, and create a rebooking task within 2 business days. Release the slot to the cancellation-fill process if the practice runs one.
- No-show branch. Same day: “Hi {{contact.first_name}}, we missed you today. No problem at all. Grab another time whenever suits: {{booking_link}}.” No fee language, no reproach. Wait 3 days, send one more. Wait 7 days, create a call task. Two no-shows in a recall year route to a staff review rather than a third automated attempt.
Exit: attended, or returned to Engaged: No Booking.
7. Attendance, Outcome Capture and Next-Year Enrollment
Trigger: the appointment is marked attended.
Actions in order:
- Set attended_date, apply awv-attended, move the card to Visit Attended.
- Create a documentation-confirmation task on the provider, confirming the visit outcome has been recorded in the chart by the practice's normal process. This build does not hold the clinical record; it holds the recall state.
- Follow-up branch. If the visit generated further actions (a referral, a screening order, a medication review) create or link the relevant card in the appropriate pipeline. The wellness visit is where downstream care gets generated, and that generation should not depend on someone remembering.
- Update last_wellness_visit_date to attended_date. Move the card to Recall Complete, apply awv-complete.
- Create next year's card in Eligibility Pending with a fresh recall_year, a computed eligibility_start_date, and recall_cohort_month assigned against next year's capacity. This step is what makes the program a system instead of a campaign.
- Wait 2 days. Send one short satisfaction prompt if the practice runs a review or experience program, kept entirely separate from the recall messaging and subject to its own consent.
Exit: next year's card created.
8. Decline, Opt-Down and Preference Management
Trigger: Recall Preferences or Decline Record submitted, an inbound decline in conversation, or any opt-out keyword.
Actions in order:
- Offer the ladder down before the door out. The preferences page leads with change channel, change language, phone only, and pause for this year: with full opt-out last. Most patients who click want fewer messages, not none, and losing them from recall entirely is a worse outcome for them than a quieter channel.
- Channel change: update preferred_channel and the consent flags, and resume the ladder from the current wave on the new channel.
- Pause this year: move the card to Declined with decline_reason of declined this year, and still create next year's card. A single no is not a permanent no, and treating it as one is how panels quietly shrink.
- Seen elsewhere: record the reason, suppress this year, and create a task to request records and update last_wellness_visit_date. A patient who had the visit elsewhere is current, not lapsed, and the panel report should say so.
- Full recall opt-out: set recall_opt_out, apply recall-opt-out, and stop the program for that patient across all channels and all years until they reverse it. Notify panel_provider once, so the clinical team knows this patient will no longer be reminded.
- SMS or email opt-out keyword: set only that channel's flag to no, apply the revoked tag, confirm once in plain language: “You're unsubscribed from texts from {{practice_name}}. We'll still write or call you about your yearly visit unless you tell us not to: {{preferences_link}}.”, and continue on remaining channels. A channel opt-out is not a program opt-out and must not be treated as one.
- Write consent_captured_at, consent_language_version and consent_source on every change, and keep the prior state as history rather than overwriting it.
Exit: preferences recorded; program state updated.
9. Monthly Cohort Performance and Panel Gap Report
Trigger: scheduled monthly, plus a weekly operational slice.
Actions in order:
- Weekly, internal: the Engaged: No Booking queue with owners, overdue-band counts, previsit-outstanding cards inside 3 days of a visit, letters queued against unverified addresses, and any suppression hit that needs a human: duplicates, mail returned, address updates.
- Monthly, by cohort: eligible, contacted, booked, attended, declined, suppressed by reason, lapsed. Report booking rate by wave and by channel, and cost per booking for wave three so the expensive wave is judged on its real yield.
- Panel gap view per provider: share of their panel current, due, overdue and lapsed. This is the number that changes clinician behavior, because it is about their own patients rather than the practice's average.
- Equity view: completion rate split by channel availability (patients with email, SMS only, no digital channel, no portal) and by language and recorded barrier. If completion is materially lower for patients with no digital channel, wave three is under-resourced, and that is a finding about who the program is failing rather than a tuning detail.
- Send internally only, to the practice manager and clinical lead, on an access-controlled channel. It contains patient identifiers and panel-level clinical state.
- Create tasks for the actionable slices rather than leaving a report to be admired.
Exit: never.