Skip to content

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

  1. Admin defines trigger: "When patient.onboarded" or "When appointment.first_booked"
  2. Admin adds conditions (optional): "Only if patient age >= 65"
  3. Admin adds actions:
    • Require Privacy Policy form (blocks until signed)
    • Send welcome email
    • Grant telerehab access
    • Add to "New Patients" segment
  4. Trigger fires: Patient registers → Privacy form created, email sent, access granted, segment updated—all automatically
  5. Validation: If privacy form isn't signed, patient can't proceed to booking (blocking)
  6. 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 registered
  • patient.first_login - Patient logs in for first time
  • patient.profile_completed - All required profile fields filled

Appointment Lifecycle:

  • appointment.first_booked - Patient's very first appointment
  • appointment.booked - Any new appointment booked
  • appointment.before_start - X hours/days before start
  • appointment.started - Appointment begins
  • appointment.completed - Appointment finishes
  • appointment.canceled - Appointment canceled

Service Plan Lifecycle:

  • service_plan.enrolled - Patient enrolled in multi-session plan
  • service_plan.session_started - Session in plan started
  • service_plan.session_completed - Session finished
  • service_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 session
  • treatment_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 created
  • form.completed - Form filled (not yet signed)
  • form.signed - Form signed and immutable

Time-Based:

  • schedule.daily - Every day at specific time
  • schedule.weekly - Every week on specific day
  • schedule.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 signed
  • suggest_form - Create form instance, optional (non-blocking)
  • request_profile_fields - Prompt to complete profile fields

Communication:

  • send_email - Send transactional or marketing email
  • send_sms - Send SMS notification
  • show_notification - In-app notification/banner
  • send_push - Push notification

Access Control:

  • block_booking - Prevent appointment booking until condition met
  • grant_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 patient
  • send_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 >= 18
  • patient.segment_id = 5

Appointment Attributes:

  • appointment.type = "video"
  • appointment.service_id = 10
  • appointment.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 = true
  • treatment_plan.sessions_completed >= 6
  • treatment_plan.adherence_rate < 0.5

Temporal:

  • time.hours_before_appointment = 24
  • time.day_of_week = "Monday"

Database Schema

sql
-- 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:

  1. Require Privacy Policy form (blocking)
  2. Require Terms of Service form (blocking)
  3. Send welcome email
  4. Show "Complete your profile" notification

Configuration:

json
{
  "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
    }
  ]
}

Trigger: appointment.first_booked

Conditions: appointment.type = "video"

Actions:

  1. Require video recording consent (blocking)
  2. Send "What to expect" email
  3. Create intake questionnaire

Configuration:

json
{
  "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:

  1. Require biometric consent (for exercise tracking)
  2. Send program welcome email
  3. Create baseline assessment form
  4. Schedule reminder emails for each session

Configuration:

json
{
  "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:

  1. Send SMS reminder
  2. Check if intake forms completed
  3. Send video call link (if video appointment)

Configuration:

json
{
  "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:

  1. Send birthday email
  2. Create discount code
  3. Add to "Birthday This Month" segment

Configuration:

json
{
  "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"
    }
  ]
}

Trigger: treatment_plan.assigned

Conditions: treatment_plan.type = "telerehab"

Actions:

  1. Require biometric consent form (blocking — needed for pose tracking)
  2. Send program welcome email with exercise overview
  3. Show in-app notification with "Start your first session" CTA

Configuration:

json
{
  "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:

  1. Send push notification reminding patient to do today's session
  2. Send email if session not completed by end of day

Configuration:

json
{
  "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:

  1. Book follow-up appointment with the prescribing specialist
  2. Create outcome assessment form
  3. Send congratulations email
  4. Add patient to "Completed Rehab" segment

Configuration:

json
{
  "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:

  1. Notify assigned specialist
  2. Send motivational email to patient

Configuration:

json
{
  "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_id and template_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:

  1. Keep template_policy_id and template_terms_id columns (backward compatibility)
  2. On first app start, auto-create automation rule: patient.onboarded → require these forms
  3. Deprecate old columns in 6 months
  4. 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:

  1. Name & Description - Human-readable label
  2. Trigger Selection - Dropdown: "When does this run?"
  3. Trigger Config (if needed) - e.g., hours_before for appointment.before_start
  4. Conditions (optional) - Visual builder: "If patient country is RO AND appointment type is video"
  5. Actions (ordered list) - Drag-and-drop:
    • "Require Privacy Policy form (blocking)"
    • "Send welcome email"
    • "Show notification"
  6. Test - Preview what would happen for sample event
  7. 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.onboarded happens, 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:

json
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.

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)