Automations Feature
Event-driven workflows—when a patient signs up, require forms, send emails, and unlock features automatically.
What this enables
Onboarding automation: New patient registers → auto-require Privacy Policy form + Terms form + send welcome email + unlock booking.
Appointment prep: Patient books first appointment → send video consent form (blocking) + "What to expect" email + notify specialist.
Follow-up sequences: Treatment plan completed → offer post-care survey + schedule follow-up appointment + send progress email.
Smart triggers: "When patient is 65+ AND pain level is high AND no appointments in 3 months" → send "time for checkup" reminder.
Treatment plan workflow: Specialist assigns plan → patient gets welcome email → unlocks exercise videos → gets session reminders → auto-book follow-up after completion.
How it works
- Admin defines trigger: "When patient.onboarded" or "When appointment.first_booked"
- Admin adds conditions (optional): "Only if patient age >= 65"
- Admin adds actions:
- Require Privacy Policy form (blocks until signed)
- Send welcome email
- Grant telerehab access
- Add to "New Patients" segment
- Trigger fires: Patient registers → Privacy form created, email sent, access granted, segment updated—all automatically
- Validation: If privacy form isn't signed, patient can't proceed to booking (blocking)
- No code needed: All built in UI, no developer required
Technical Reference
Overview
Automations enable organizations to configure event-driven workflows that trigger actions in response to patient and appointment lifecycle events. Instead of hardcoding "required forms at onboarding," admins can build flexible rules like "when patient.onboarded → require GDPR form + send welcome email + create intake survey."
Think of it as: Zapier/Make.com for your telemedicine platform, but built-in and HIPAA-compliant.
Core Concepts
Triggers (When)
System events that can fire automations:
Patient Lifecycle:
patient.onboarded- New patient registeredpatient.first_login- Patient logs in for first timepatient.profile_completed- All required profile fields filled
Appointment Lifecycle:
appointment.first_booked- Patient's very first appointmentappointment.booked- Any new appointment bookedappointment.before_start- X hours/days before startappointment.started- Appointment beginsappointment.completed- Appointment finishesappointment.canceled- Appointment canceled
Service Plan Lifecycle:
service_plan.enrolled- Patient enrolled in multi-session planservice_plan.session_started- Session in plan startedservice_plan.session_completed- Session finishedservice_plan.completed- All sessions completed
Treatment Plan Lifecycle:
treatment_plan.created- New treatment plan created (draft)treatment_plan.assigned- Plan assigned to a patient (patient_treatment_plan created)treatment_plan.activated- Plan becomes active (direct publish or after approval)treatment_plan.session_completed- Patient finished a sessiontreatment_plan.completed- All sessions completed (plan status → completed)treatment_plan.expired- Plan passed end_date without completion (background job)
Form Lifecycle:
form.created- Form instance createdform.completed- Form filled (not yet signed)form.signed- Form signed and immutable
Time-Based:
schedule.daily- Every day at specific timeschedule.weekly- Every week on specific dayschedule.date_reached- Specific date reached (birthdays, plan anniversaries)
Actions (What)
What the system executes when a trigger fires:
Data Collection:
require_form- Create form instance, block until signedsuggest_form- Create form instance, optional (non-blocking)request_profile_fields- Prompt to complete profile fields
Communication:
send_email- Send transactional or marketing emailsend_sms- Send SMS notificationshow_notification- In-app notification/bannersend_push- Push notification
Access Control:
block_booking- Prevent appointment booking until condition metgrant_access- Enable feature (video, plans, etc.)require_consent- Block until specific consent granted
Data Management:
update_segment- Add/remove from segment
Treatment Plans:
assign_treatment_plan- Assign a treatment plan to the triggering patientsend_session_reminder- Send reminder for next scheduled session (push + email)book_followup_appointment- Book a follow-up appointment with the specialist for plan review
Scheduling:
schedule_action- Delay another action (send email in 3 days)
External Integrations (Use Webhooks Feature)
For external system integrations, use the Webhooks feature instead of automation actions:
Automations = Internal workflows (forms, emails, notifications) Webhooks = External event forwarding (Make.com, Zapier, custom APIs)
Both listen to the same event catalog and fire independently when events are published.
Conditions (If)
Optional filters that control when actions execute:
Patient Attributes:
patient.country = "RO"patient.city = "Bucharest"patient.age >= 18patient.segment_id = 5
Appointment Attributes:
appointment.type = "video"appointment.service_id = 10appointment.specialist.specialty = "kinesitherapy"
Form Attributes:
form.type = "disclaimer"form.template_id = 42
Treatment Plan Attributes:
treatment_plan.type = "telerehab"treatment_plan.type = "in_clinic"treatment_plan.requires_approval = truetreatment_plan.sessions_completed >= 6treatment_plan.adherence_rate < 0.5
Temporal:
time.hours_before_appointment = 24time.day_of_week = "Monday"
Database Schema
-- Automation rules per organization
CREATE TABLE automation_rules (
id BIGSERIAL PRIMARY KEY,
organization_id BIGINT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
-- Metadata
name TEXT NOT NULL,
description TEXT,
enabled BOOLEAN NOT NULL DEFAULT true,
-- Trigger configuration
trigger_event TEXT NOT NULL, -- 'patient.onboarded', 'appointment.first_booked', etc.
trigger_config JSONB DEFAULT '{}', -- Event-specific config (e.g., hours_before for appointment.before_start)
-- Conditions (optional filters)
conditions JSONB DEFAULT '{}', -- { "patient.country": "RO", "appointment.type": "video" }
-- Actions to execute (ordered)
actions JSONB NOT NULL, -- [{ "type": "require_form", "form_template_id": 42, "blocking": true }, ...]
-- Execution tracking
execution_count INT NOT NULL DEFAULT 0,
last_executed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Execution history (audit trail)
CREATE TABLE automation_executions (
id BIGSERIAL PRIMARY KEY,
organization_id BIGINT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
automation_rule_id BIGINT NOT NULL REFERENCES automation_rules(id) ON DELETE CASCADE,
-- What triggered it
trigger_event TEXT NOT NULL,
trigger_entity_type TEXT, -- 'patient', 'appointment', 'form'
trigger_entity_id BIGINT,
-- Execution result
status TEXT NOT NULL, -- 'success', 'partial_failure', 'failure'
actions_executed JSONB, -- [{ "action": "require_form", "status": "success", "form_id": 500 }, ...]
error_message TEXT,
executed_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_automation_rules_org ON automation_rules(organization_id);
CREATE INDEX idx_automation_rules_trigger ON automation_rules(organization_id, trigger_event) WHERE enabled = true;
CREATE INDEX idx_automation_executions_org ON automation_executions(organization_id);
CREATE INDEX idx_automation_executions_rule ON automation_executions(automation_rule_id);Example Automations
Example 1: New Patient Onboarding (GDPR)
Trigger: patient.onboarded
Actions:
- Require Privacy Policy form (blocking)
- Require Terms of Service form (blocking)
- Send welcome email
- Show "Complete your profile" notification
Configuration:
{
"name": "New Patient GDPR & Welcome",
"trigger_event": "patient.onboarded",
"conditions": {},
"actions": [
{
"type": "require_form",
"form_template_id": 42,
"blocking": true,
"description": "Privacy Policy & GDPR Consent"
},
{
"type": "require_form",
"form_template_id": 43,
"blocking": true,
"description": "Terms of Service"
},
{
"type": "send_email",
"email_template": "welcome_patient",
"delay_minutes": 5
},
{
"type": "show_notification",
"message": "Welcome! Please complete your medical profile.",
"duration_days": 7
}
]
}Example 2: First Appointment - Video Consent
Trigger: appointment.first_booked
Conditions: appointment.type = "video"
Actions:
- Require video recording consent (blocking)
- Send "What to expect" email
- Create intake questionnaire
Configuration:
{
"name": "First Video Appointment Setup",
"trigger_event": "appointment.first_booked",
"conditions": {
"appointment.type": "video"
},
"actions": [
{
"type": "require_form",
"form_template_id": 50,
"blocking": true,
"description": "Video Recording Consent"
},
{
"type": "send_email",
"email_template": "first_appointment_video_guide"
},
{
"type": "suggest_form",
"form_template_id": 51,
"description": "Medical History Questionnaire"
}
]
}Example 3: Service Plan Enrollment
Trigger: service_plan.enrolled
Actions:
- Require biometric consent (for exercise tracking)
- Send program welcome email
- Create baseline assessment form
- Schedule reminder emails for each session
Configuration:
{
"name": "Multi-Session Plan Welcome",
"trigger_event": "service_plan.enrolled",
"conditions": {
"service_plan.has_exercise_tracking": true
},
"actions": [
{
"type": "require_form",
"form_template_id": 60,
"blocking": true,
"description": "Biometric Data Consent"
},
{
"type": "send_email",
"email_template": "plan_welcome",
"variables": {
"plan_name": "{{service_plan.name}}",
"session_count": "{{service_plan.session_count}}"
}
},
{
"type": "suggest_form",
"form_template_id": 61,
"description": "Baseline Assessment"
}
]
}Example 4: Pre-Appointment Reminder
Trigger: appointment.before_start
Trigger Config: { "hours_before": 24 }
Actions:
- Send SMS reminder
- Check if intake forms completed
- Send video call link (if video appointment)
Configuration:
{
"name": "24h Appointment Reminder",
"trigger_event": "appointment.before_start",
"trigger_config": {
"hours_before": 24
},
"actions": [
{
"type": "send_sms",
"template": "appointment_reminder",
"variables": {
"specialist_name": "{{appointment.specialist.name}}",
"time": "{{appointment.started_at}}"
}
},
{
"type": "send_email",
"email_template": "appointment_reminder_with_video_link",
"conditions": {
"appointment.type": "video"
}
}
]
}Example 5: Birthday Greetings + Discount
Trigger: schedule.daily
Conditions: patient.birthday = TODAY
Actions:
- Send birthday email
- Create discount code
- Add to "Birthday This Month" segment
Configuration:
{
"name": "Patient Birthday Campaign",
"trigger_event": "schedule.daily",
"trigger_config": {
"time": "09:00"
},
"conditions": {
"patient.birthday_today": true
},
"actions": [
{
"type": "send_email",
"email_template": "happy_birthday",
"variables": {
"discount_code": "BDAY2025"
}
},
{
"type": "update_segment",
"segment_id": 15,
"action": "add"
}
]
}Example 6: Treatment Plan Assignment — Biometric Consent + Welcome
Trigger: treatment_plan.assigned
Conditions: treatment_plan.type = "telerehab"
Actions:
- Require biometric consent form (blocking — needed for pose tracking)
- Send program welcome email with exercise overview
- Show in-app notification with "Start your first session" CTA
Configuration:
{
"name": "Telerehab Plan Assignment",
"trigger_event": "treatment_plan.assigned",
"conditions": {
"treatment_plan.type": "telerehab"
},
"actions": [
{
"type": "require_form",
"form_template_id": 70,
"blocking": true,
"description": "Biometric Data Consent (camera/pose tracking)"
},
{
"type": "send_email",
"email_template": "treatment_plan_welcome",
"variables": {
"plan_name": "{{treatment_plan.name}}",
"frequency": "{{treatment_plan.frequency_per_week}}x/week",
"duration": "{{treatment_plan.duration_weeks}} weeks",
"specialist_name": "{{treatment_plan.specialist.name}}"
}
},
{
"type": "show_notification",
"message": "Your treatment plan is ready! Start your first session.",
"duration_days": 3,
"cta_url": "/treatment-plans/{{patient_treatment_plan.id}}/today"
}
]
}Example 7: Treatment Plan Session Reminder
Trigger: schedule.daily
Conditions: Patient has an active treatment plan with a session due today
Actions:
- Send push notification reminding patient to do today's session
- Send email if session not completed by end of day
Configuration:
{
"name": "Daily Session Reminder",
"trigger_event": "schedule.daily",
"trigger_config": {
"time": "09:00"
},
"conditions": {
"patient.has_active_treatment_plan": true,
"patient.session_due_today": true
},
"actions": [
{
"type": "send_session_reminder",
"channel": "push",
"message": "Time for your exercises! Today's session takes about {{session.estimated_duration}} minutes."
},
{
"type": "schedule_action",
"delay_hours": 10,
"action": {
"type": "send_session_reminder",
"channel": "email",
"email_template": "session_reminder_evening",
"conditions": {
"patient.session_completed_today": false
}
}
}
]
}Example 8: Treatment Plan Completed — Follow-Up + Assessment
Trigger: treatment_plan.completed
Conditions: Only for specialist-assigned plans (not self-service)
Actions:
- Book follow-up appointment with the prescribing specialist
- Create outcome assessment form
- Send congratulations email
- Add patient to "Completed Rehab" segment
Configuration:
{
"name": "Treatment Plan Completion — Follow-Up",
"trigger_event": "treatment_plan.completed",
"conditions": {
"patient_treatment_plan.self_assigned": false
},
"actions": [
{
"type": "book_followup_appointment",
"specialist_id": "{{treatment_plan.specialist_id}}",
"service_id": "{{treatment_plan.followup_service_id}}",
"within_days": 7,
"description": "Treatment plan review — {{treatment_plan.name}}"
},
{
"type": "suggest_form",
"form_template_id": 72,
"description": "Post-Treatment Outcome Assessment"
},
{
"type": "send_email",
"email_template": "treatment_plan_completed",
"variables": {
"plan_name": "{{treatment_plan.name}}",
"sessions_completed": "{{patient_treatment_plan.sessions_completed}}",
"pain_improvement": "{{patient_treatment_plan.pain_reduction_percentage}}%"
}
},
{
"type": "update_segment",
"segment_id": 20,
"action": "add"
}
]
}Example 9: Low Adherence Alert
Trigger: treatment_plan.session_completed
Conditions: Adherence rate dropped below 50%
Actions:
- Notify assigned specialist
- Send motivational email to patient
Configuration:
{
"name": "Low Adherence Alert",
"trigger_event": "treatment_plan.session_completed",
"conditions": {
"treatment_plan.adherence_rate": { "lt": 0.5 },
"patient_treatment_plan.sessions_completed": { "gte": 3 }
},
"actions": [
{
"type": "show_notification",
"target": "specialist",
"message": "{{patient.name}} has low adherence ({{treatment_plan.adherence_rate}}%) on plan \"{{treatment_plan.name}}\"",
"priority": "high"
},
{
"type": "send_email",
"email_template": "adherence_encouragement",
"variables": {
"patient_name": "{{patient.first_name}}",
"sessions_remaining": "{{patient_treatment_plan.sessions_remaining}}",
"specialist_name": "{{treatment_plan.specialist.name}}"
}
}
]
}How It Replaces Current System
Old (Hardcoded):
- Organizations have
template_policy_idandtemplate_terms_id - Onboarding automatically creates these 2 forms
- No flexibility, no other triggers, no conditional logic
New (Automation Rules):
- Organizations create automation rules
- Trigger:
patient.onboarded→ Actions: [require forms X, Y, Z, send email, etc.] - Fully configurable, unlimited forms, conditional logic
- Migration: On first deploy, auto-create 1 automation rule per org that replicates old behavior
Migration Path:
- Keep
template_policy_idandtemplate_terms_idcolumns (backward compatibility) - On first app start, auto-create automation rule:
patient.onboarded→ require these forms - Deprecate old columns in 6 months
- Remove columns in 12 months
Admin UI Flow
Automation List Page:
- Table showing all automation rules
- Columns: Name, Trigger, Actions Count, Execution Count, Enabled
- Toggle to enable/disable
- Click to edit
Create/Edit Automation:
- Name & Description - Human-readable label
- Trigger Selection - Dropdown: "When does this run?"
- Trigger Config (if needed) - e.g., hours_before for
appointment.before_start - Conditions (optional) - Visual builder: "If patient country is RO AND appointment type is video"
- Actions (ordered list) - Drag-and-drop:
- "Require Privacy Policy form (blocking)"
- "Send welcome email"
- "Show notification"
- Test - Preview what would happen for sample event
- Save - Enable immediately or save as draft
Execution History:
- Shows all automation executions
- Filter by rule, status, date
- Click to see detailed logs (which actions succeeded/failed)
Technical Architecture
Event Bus:
- When
patient.onboardedhappens, publish event to internal queue - Automation engine listens for events
- Matches events to enabled automation rules
- Executes actions in order
- Logs results to
automation_executions
Execution Engine:
- Fetches all rules matching trigger event
- Filters by conditions
- Executes actions sequentially
- Handles failures gracefully (continue or stop)
- Records execution history
Action Handlers:
- Each action type has a handler (e.g.,
RequireFormHandler,SendEmailHandler) - Handlers are stateless and idempotent
- Return success/failure + metadata
Telemetry Integration
Automation executions generate analytics events for tracking automation effectiveness and troubleshooting:
POST /v1/analytics/track
{
"event_name": "automation.executed",
"event_category": "automation",
"resource_type": "automation_rule",
"resource_id": "15",
"properties": {
"trigger_event": "appointment.first_booked",
"actions_count": 3,
"status": "success"
}
}This happens automatically — no configuration needed. The data flows to ClickHouse (analytics_events) and enables:
- Automation execution frequency by trigger type
- Success/failure rates per rule
- Most active automations per organization
Consent: Level 2+ (analytics consent). Automation execution tracking is operational analytics — no patient PII is included (actor IDs are hashed by the Telemetry middleware).
Audit: All automation executions are also captured by the audit middleware (automatic on every authenticated request), providing the HIPAA-compliant trail in the local audit_log table with async forwarding to Telemetry PostgreSQL.
See ../../telemetry/api.md for the full Telemetry API specification and ../../reference/telemetry.md for how features integrate with telemetry.
Related Features
- Forms - Forms created/required by automations
- Treatment Plans - Treatment plan lifecycle triggers and actions
- Exercise Library - Exercises referenced by treatment plans
- Webhooks - External integrations triggered by automations
- Segments - Patient groups updated by automations
- Organizations - Automation rules are org-scoped
Future Enhancements
Phase 2:
- Visual workflow builder (drag-and-drop)
- Branching logic (if/else)
- Loop actions (for each session in plan)
- Delay actions (send email in 3 days)
- External webhooks as triggers (Stripe payment → automation)
Phase 3:
- AI-powered automation suggestions ("You might want to...")
- A/B testing (test 2 email templates)
- Analytics dashboard (conversion rates, form completion rates)
- Templates marketplace (share automation templates)