From marking complete to ~45 days of automated follow-up — 7 to 12 messages depending on procedure, ending with a Google Review request
Most procedures (Botox, Fillers, Laser, PRP, General): 7 messages at Days 1, 3, 7, 14, 28, 42, 45. Liposuction: 8 messages with extra Day 21 and 30. Weight Loss / Semaglutide: 12 messages with daily check-ins for the first week.
Dr. Rockhead or a staff member marks the procedure complete via the backend dashboard or by messaging Karen on Telegram: "Botox done for Sarah." Karen logs the completion, updates the care plan status, and fires the post-care sequence for that patient.
src/telegram_actions/care_analytics.jsrecord_payment, mark_procedure_complete
mark_procedure_complete, updates the patient's care plan status to active, and queues the first post-care BullMQ job. The record_payment action also fires if a balance was outstanding.care_plans (status updated), care_eventsThe system starts the procedure-specific aftercare sequence. Each procedure has its own schedule — Botox is different from Lipo, which is different from Semaglutide. 7 templates exist: Botox, Fillers, Laser, PRP, Liposuction, Weight Loss, General. Every plan runs ~45 days and ends with a Google Review request on Day 45.
src/actions/care/plans.js → startCarePlan() (line 181)
startCarePlan() normalizes the procedure type, looks up the matching template in DEFAULT_TEMPLATES (plans.js lines 67–156), and creates a care_plans row. Every step in the template is scheduled as a BullMQ delayed job at its configured day offset. Templates currently defined: Botox, Fillers, Laser, PRP, Liposuction, Weight Loss, General — ranging from 7 to 12 steps each. Each step's prompt is procedure-aware: Botox patients get swelling guidance, Lipo patients get compression garment reminders, Semaglutide patients get daily hydration + nausea tips for the first week.care_plans, care_eventsKaren sends procedure-specific check-ins on the schedule baked into the template. Each message is personalized by Karen's AI from a detailed prompt — not a static template. She asks how the patient is doing, gives procedure-specific aftercare reminders, and watches every reply for escalation signals.
| Procedure | # Messages | Schedule (days after procedure) |
|---|---|---|
| Botox | 7 | 1, 3, 7, 14, 28, 42, 45 |
| Fillers | 7 | 1, 3, 7, 14, 28, 42, 45 |
| Laser | 7 | 1, 3, 7, 14, 28, 42, 45 |
| PRP | 7 | 1, 3, 7, 14, 28, 42, 45 |
| General | 7 | 1, 3, 7, 14, 28, 42, 45 |
| Liposuction | 8 | 1, 3, 7, 14, 21, 30, 42, 45 |
| Weight Loss / Semaglutide | 12 | 1, 2, 3, 4, 5, 6, 7, 14, 21, 30, 42, 45 |
Every message routes through the patient's preferred channel (WhatsApp, Telegram, Chatwoot). Every reply is captured as a care_event and scanned for escalation keywords before Karen composes her response.
src/actions/care/plans.js → DEFAULT_TEMPLATES (lines 67–156)src/actions/care/plans.js → processCarePlanStep()src/actions/care/escalation.js → detectEscalation()
DEFAULT_TEMPLATES[procedure_type] is scheduled as a BullMQ delayed job at day × 24h after activation. When each job fires, processCarePlanStep() loads the step's prompt (a detailed instruction for Karen, not a fixed message), Karen generates a personalized message from it, and delivers via the patient's preferred channel. Patient replies run through detectEscalation() before Karen composes her response — if keywords match, the flow diverts to Step 5 (escalation).care_events, care_plans (current_step advances)The final step of every care plan, 3 days after the last check-in (Day 45). Karen thanks the patient warmly for trusting Oshun and asks — low pressure — if they'd be willing to share their experience as a Google review. The review link is included if the tenant has one configured; otherwise Karen just points them at "Oshun Medical" on Google.
src/actions/care/plans.js — review_request step (Day 45 in every template)
message_key: 'review_request' and a prompt instructing Karen to thank the patient warmly, ask for a Google review, and keep it short, warm, and low-pressure. The review link is pulled from tenant config (GOOGLE_REVIEW_URL) — if configured, it's included in the message; otherwise Karen directs the patient to search for "Oshun Medical" on Google. After this step fires, the care plan status updates to completed.care_plans (status → completed), care_eventsGOOGLE_REVIEW_URL (tenant config)If a patient reports pain, swelling, infection signs, or any medical concern at any point during the care sequence, escalation activates immediately. Karen responds with empathy and appropriate first-response guidance, while simultaneously alerting the clinical team on Telegram. The care team takes it from there.
src/actions/care/escalation.js → detectEscalation() (line 43)src/actions/care/escalation.js → detectEscalationKeywords() (line 32)src/actions/care/escalation.js → notifyEscalation() (line 103)
detectEscalationKeywords() runs regex patterns against the patient's message, scanning for medical concern signals (pain, swelling, infection, bruising, numbness, etc.). If matched, detectEscalation() flags the care event and calls notifyEscalation(). Karen sends the patient a calm, empathetic reply with immediate guidance. Simultaneously, notifyEscalation() fires a Telegram alert to the clinical team with the patient name, procedure, and their exact message. The case is tracked in cases for follow-through.care_events (flagged), cases