
Implementation Guide: Surface patients with declining phq-9 or gad-7 scores for immediate clinician review
Step-by-step implementation guide for deploying AI to surface patients with declining phq-9 or gad-7 scores for immediate clinician review for Allied & Mental Health clients.
Hardware Procurement
Next-Generation Firewall/UTM Appliance
$645–$717 per unit (MSP cost) / $850–$950 suggested resale. Annual Unified Threat Protection (UTP) bundle: $300–$500/yr MSP cost, resale at $450–$700/yr.
Perimeter security for the practice network. Enforces TLS inspection, network segmentation between clinical and guest Wi-Fi, VPN for remote clinician access, and intrusion prevention. Required for HIPAA Security Rule compliance—protects all ePHI traffic including PHQ-9/GAD-7 data flowing between the EHR, MBC platform, and analytics layer.
Uninterruptible Power Supply
$400–$600 per unit (MSP cost) / $550–$800 suggested resale
Battery backup for the firewall, network switch, and any on-premises workstations. Ensures continuous uptime during power events—critical for maintaining data integrity of in-progress assessment submissions and preventing mid-session data loss.
HIPAA-Configured Clinician Laptops
$900–$1,300 per unit (MSP cost) / $1,200–$1,700 suggested resale
Clinician workstations pre-configured with full-disk encryption (BitLocker), Microsoft Intune enrollment, MFA via Microsoft Authenticator, and browser bookmarks to the MBC dashboard. Each laptop serves as the primary interface for reviewing score decline alerts and patient outcome trends.
Managed Network Switch
$350–$500 per unit (MSP cost) / $475–$650 suggested resale
Managed switch integrated with FortiGate for network segmentation. Creates separate VLANs for clinical workstations, guest/patient Wi-Fi, and IoT devices. Simplifies HIPAA network access control requirements.
Wireless Access Point
$400–$550 per unit (MSP cost) / $550–$725 suggested resale
Provides secure Wi-Fi for clinician devices and a segregated patient network for completing PHQ-9/GAD-7 assessments on personal devices or practice-provided tablets in the waiting room. Managed centrally via FortiGate.
Patient Check-In Tablets
$329–$449 per unit (MSP cost) / $450–$575 suggested resale
Kiosk-mode tablets stationed in the waiting room or check-in area for patients to complete PHQ-9/GAD-7 assessments before their appointment. The MBC platform (Blueprint or Greenspace) delivers assessments via a browser-based kiosk URL. Tablets are enrolled in Intune or Apple Business Manager for remote management and lockdown.
Software Procurement
Blueprint Health Plus or Pro
Plus: $39/clinician/month; Pro: $59/clinician/month. Free Core tier available for pilot. For a 10-clinician practice: $390–$590/month.
Primary MBC platform. Delivers PHQ-9 and GAD-7 assessments to patients automatically (via SMS, email, or kiosk), calculates scores, tracks trends over time, generates real-time clinician alerts when scores decline, and provides intervention recommendations. Pro tier adds provider benchmarking and auto-generated MBC insurance claims (CPT 96127).
Greenspace Health MBC 2.0
Custom pricing—contact vendor. Estimated $50–$100/clinician/month for SMB practices based on market positioning. Includes managed EHR integration.
Alternative/upgrade MBC platform for larger groups (10+ clinicians) or practices needing AI-driven automated insights, 300+ assessment library, managed integration across 85+ EHR systems, and population-level analytics. SOC 2 Type II certified. Recommended over Blueprint when the practice requires deeper analytics or has a complex multi-EHR environment.
Microsoft 365 Business Premium
$22/user/month (MSP CSP cost) / $30–$35/user/month suggested resale. For 15 users: $330–$525/month.
Core productivity and security platform. Provides HIPAA-compliant email (Exchange Online with BAA), Azure Active Directory (Entra ID) for identity and MFA, Microsoft Intune for endpoint management, Microsoft Defender for Business for endpoint protection, and conditional access policies. Foundation for all HIPAA technical safeguards.
Microsoft Power BI Pro
$14/user/month (starting April 2025). $28–$70/month.
Custom analytics and dashboards beyond the MBC platform's native reporting. Used to build population-level outcome trend visualizations, compliance reporting dashboards, clinician performance comparisons, and aggregate PHQ-9/GAD-7 score distributions. Connects to MBC platform via REST API or exported data.
Veeam Backup for Microsoft 365
$5–$10/user/month (MSP cost) / $12–$18/user/month suggested resale
HIPAA-compliant backup of all Microsoft 365 data including Exchange, OneDrive, and SharePoint where clinical documentation and exported reports may reside. Provides 6-year retention capability required by HIPAA. Encrypted at rest and in transit.
Fortinet FortiGate Unified Threat Protection (UTP) Bundle
$300–$500/year (MSP cost) / $450–$700/year suggested resale
Annual security subscription for the FortiGate 60F firewall. Includes antivirus, intrusion prevention (IPS), web filtering, application control, and FortiCare support. Required for maintaining up-to-date threat signatures protecting the practice network. License type: Annual subscription (renewal).
TherapyNotes or SimplePractice (existing EHR)
TherapyNotes: $49/mo solo, $59 + $30/additional clinician for groups. SimplePractice: starts at $49/month. These are typically already in place—not a new procurement.
The practice's existing behavioral health EHR serves as the primary data source for patient demographics, appointment scheduling, and (in some cases) native PHQ-9/GAD-7 score collection. The MBC platform integrates with or overlays the EHR. If the practice does not yet have an EHR with outcome measure support, TherapyNotes is recommended for its built-in GAD-7/PHQ-9 scoring.
Duo Security or Microsoft Authenticator (MFA)
Microsoft Authenticator: included with M365 Business Premium. Duo MFA: $3–$9/user/month if needed for non-Microsoft systems.
Multi-factor authentication for all systems accessing ePHI. Required by HIPAA Security Rule. Applied to EHR login, MBC platform login, Microsoft 365, VPN access, and Power BI.
Prerequisites
- Active behavioral health EHR (SimplePractice, TherapyNotes, Valant, CarePaths, or equivalent) with PHQ-9 and GAD-7 assessment capability already in use or ready to activate
- Business-class internet connection: minimum 50 Mbps symmetrical; 100+ Mbps recommended if the practice uses telehealth extensively
- Microsoft 365 Business Premium licenses deployed (or ready to deploy) for all staff members who will access clinical systems
- A designated Clinical Champion at the practice—a licensed clinician with authority to define alert thresholds, validate clinical workflows, and approve go-live
- Executed Business Associate Agreements (BAAs) with: the EHR vendor, the selected MBC platform vendor, Microsoft (via M365 admin center), the MSP, and any other subprocessors
- Completed or scheduled HIPAA Security Risk Assessment within the past 12 months (if not current, include as Phase 1 deliverable)
- Administrative access credentials for the practice's EHR system, including API access or integration settings panel
- A current patient roster export (CSV or API-accessible) including: patient name, DOB, MRN, assigned clinician, and appointment schedule
- Practice-approved consent forms for measurement-based care data collection (review with practice's legal counsel for state-specific mental health privacy requirements)
- Network infrastructure assessment completed: document current firewall, switch, Wi-Fi, and ISP details; identify any equipment that must be replaced for HIPAA compliance
- Confirmation of whether the practice treats substance use disorders (SUD)—if yes, 42 CFR Part 2 requirements apply and must be addressed in the compliance layer
- Identify all clinician roles and access levels: who should receive alerts (treating clinician only vs. clinical supervisor), who should access population dashboards (clinical director, practice owner)
- Budget approval from practice ownership for: MBC platform subscription, any new hardware, MSP implementation project fee, and ongoing managed services agreement
Installation Steps
...
Step 1: Conduct Discovery and Compliance Gap Analysis
Meet with the practice Clinical Champion and practice manager to document current clinical workflows, technology stack, and compliance posture. Map the patient journey from appointment scheduling through assessment completion, score review, and clinical action. Identify gaps in HIPAA compliance, network security, and data flow. Determine whether 42 CFR Part 2 applies (SUD treatment). Document all findings in a Discovery Report that will guide the remainder of the implementation.
Use MSP's standard HIPAA risk assessment template. This step typically requires 2–3 on-site or virtual meetings over 1–2 weeks. Deliverable: Discovery Report with current-state architecture diagram, gap analysis, and recommended remediation items. If a full HIPAA Security Risk Assessment has not been completed in the past 12 months, conduct one now using a tool like Compliancy Group's The Guard or NIST SP 800-66 framework.
Step 2: Deploy and Configure Network Security Infrastructure
Install and configure the Fortinet FortiGate 60F firewall, FortiSwitch 108F managed switch, and FortiAP 231G wireless access points. Create network segmentation with separate VLANs for: (1) Clinical workstations, (2) Patient/guest Wi-Fi, (3) IoT/printers, (4) Management. Configure SSL VPN for remote clinician access. Enable TLS 1.2+ inspection, IPS, web filtering, and application control via the UTP subscription. Set up FortiGate logging to forward to a SIEM or log aggregation service for HIPAA audit trail requirements.
# FortiGate initial setup via CLI (connect via console cable at 9600 baud)
config system interface
edit port1
set mode static
set ip 192.168.1.1/24
set allowaccess ping https ssh
next
end
# Create VLANs
config system interface
edit vlan10-clinical
set vdom root
set type vlan
set vlanid 10
set interface port2
set ip 10.10.10.1/24
set allowaccess ping https
next
edit vlan20-patient
set vdom root
set type vlan
set vlanid 20
set interface port2
set ip 10.10.20.1/24
set allowaccess ping
next
edit vlan30-mgmt
set vdom root
set type vlan
set vlanid 30
set interface port2
set ip 10.10.30.1/24
set allowaccess ping https ssh
next
end
# Enable logging for HIPAA audit trail
config log fortianalyzer setting
set status enable
set server <FortiAnalyzer-IP-or-Cloud>
set enc-algorithm high
set ssl-min-proto-ver tls1-2
end
# Configure SSL VPN for remote clinicians
config vpn ssl settings
set servercert <cert-name>
set tunnel-ip-pools SSLVPN_TUNNEL_ADDR
set port 10443
set source-interface port1
set source-address all
set default-portal full-access
end
# Enable MFA for VPN (integrate with FortiToken or Azure MFA)
config user fortitoken
edit FTK-<serial>
next
endIf the practice already has a compliant firewall (e.g., recent FortiGate, Meraki MX, or WatchGuard), assess whether it meets requirements before replacing. The FortiGate 60F supports up to 200 users—sufficient for practices up to 50 clinicians. Register the FortiGate on Fortinet's support portal and activate the UTP license before configuring security profiles. For remote practices, ship the pre-configured firewall with a USB-based auto-install config.
Step 3: Configure Microsoft 365 Business Premium for HIPAA Compliance
Deploy Microsoft 365 Business Premium licenses for all practice staff. Configure Azure Active Directory (Entra ID) with security defaults and conditional access policies. Enable MFA for all users via Microsoft Authenticator. Deploy Microsoft Intune for endpoint management with HIPAA-compliant device configuration profiles. Configure Data Loss Prevention (DLP) policies to prevent PHI from being emailed to unauthorized recipients. Execute the Microsoft BAA via the M365 admin center.
# Accept Microsoft BAA (must be done by Global Admin)
# Navigate to: Microsoft 365 Admin Center > Settings > Org Settings > Security & Privacy > HIPAA
# Accept the BAA - this is a prerequisite for HIPAA-compliant use of M365
# PowerShell: Connect to Microsoft 365 and enforce MFA via Conditional Access
Install-Module -Name Microsoft.Graph -Force
Connect-MgGraph -Scopes 'Policy.ReadWrite.ConditionalAccess'
# Create Conditional Access policy requiring MFA for all users
$params = @{
displayName = 'Require MFA for All Users'
state = 'enabled'
conditions = @{
users = @{ includeUsers = @('All') }
applications = @{ includeApplications = @('All') }
}
grantControls = @{
operator = 'OR'
builtInControls = @('mfa')
}
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
# Configure Intune compliance policy for BitLocker
# Navigate to: Intune Admin Center > Devices > Compliance Policies > Create Policy
# Require: BitLocker enabled, minimum OS version, password complexity, device encryption
# Configure DLP policy for PHI
# Navigate to: Microsoft Purview Compliance Center > Data Loss Prevention > Policies
# Create policy using 'U.S. Health Insurance Act (HIPAA)' template
# Apply to: Exchange Online, OneDrive, SharePoint, TeamsThe Microsoft BAA covers Exchange Online, SharePoint Online, OneDrive, Teams, and Intune when properly configured. It does NOT cover consumer services like Outlook.com. Ensure all staff understand they must use their @practicedomain.com email for any PHI communication—never personal email. Create a 'Break Glass' global admin account with a physical FIDO2 security key stored in a secure location.
Step 4: Deploy and Enroll Clinician Endpoints
Configure clinician laptops (Dell Latitude 5550 or Lenovo ThinkPad L14 Gen 5) with Windows 11 Pro, BitLocker full-disk encryption, and auto-enrollment into Microsoft Intune. Install required applications: Microsoft Edge (primary browser), Microsoft 365 Apps, and any EHR client applications. Configure browser bookmarks for the MBC platform dashboard, EHR login, and Power BI workspace. Deploy Microsoft Defender for Business endpoint protection. Enroll patient check-in tablets (iPad or Samsung Galaxy Tab) in Apple Business Manager or Samsung Knox for kiosk-mode lockdown.
# Windows Autopilot deployment (preferred method)
# 1. Obtain hardware hash from new devices
Install-Script -Name Get-WindowsAutopilotInfo
Get-WindowsAutopilotInfo -OutputFile C:\autopilot.csvOrder laptops with Windows 11 Pro pre-installed (not Home). If the practice has existing laptops less than 3 years old, evaluate whether they can be re-enrolled and hardened rather than replaced. For tablets, the iPad is preferred due to superior MDM support via Apple Business Manager. Configure guided access (kiosk mode) to lock the tablet to the MBC platform's assessment URL only. Provide a charging station in the waiting room with anti-theft cable locks (Kensington or similar, ~$30–$50 each).
Step 5: Select and Procure MBC Platform
Based on discovery findings, select the appropriate MBC platform. For practices with fewer than 10 clinicians and straightforward EHR environments (SimplePractice, TherapyNotes), recommend Blueprint Health Pro ($59/clinician/month) for its ease of setup, free Core pilot tier, and mobile-first patient experience. For practices with 10+ clinicians, multiple locations, or complex EHR environments, recommend Greenspace Health MBC 2.0 for its managed integration service, AI-driven insights, and 300+ assessment library. Execute the vendor agreement and BAA. Obtain API credentials or integration tokens.
- Blueprint Health setup — Visit https://www.blueprint-health.com and create organization account
- Blueprint Health setup — Select plan tier (start with Core for free pilot, upgrade to Pro for alerts)
- Blueprint Health setup — Navigate to Settings > Integrations > Connect EHR
- Blueprint Health setup — Follow EHR-specific integration guide (SimplePractice, TherapyNotes, etc.)
- Blueprint Health setup — Obtain API key: Settings > Developer > API Keys > Generate New Key
- Greenspace Health setup — Contact sales@greenspacehealth.com for enterprise onboarding
- Greenspace Health setup — Complete vendor security questionnaire and BAA execution
- Greenspace Health setup — Greenspace managed integration team will schedule kickoff call
- Greenspace Health setup — API access: https://api.greenspacehealth.com/docs
- Greenspace Health setup — Obtain OAuth2 client credentials for API access
Start with a 2–4 week pilot using 2–3 clinicians before full rollout. Blueprint's free Core tier is excellent for this purpose—it allows score tracking without the alerting features, letting clinicians get comfortable with the workflow. Upgrade to Pro once the pilot validates the workflow. For Greenspace, the managed integration service handles most of the technical setup—coordinate closely with their implementation team. Ensure the BAA is fully executed BEFORE any patient data flows to the platform.
Step 6: Configure EHR Integration
Establish the data connection between the practice's behavioral health EHR and the selected MBC platform. This integration synchronizes patient demographics, appointment schedules, and (optionally) assessment scores. The integration method depends on the EHR: API-based for modern platforms, SFTP/CSV for legacy systems, or native integration for supported EHRs. Configure bidirectional data flow where supported so that assessment results flow back into the patient's EHR chart.
# Example: Blueprint Health + TherapyNotes integration
# TherapyNotes does not offer a public API; use Blueprint's native integration
# 1. In Blueprint: Settings > Integrations > TherapyNotes > Connect
# 2. Enter TherapyNotes practice credentials (admin-level)
# 3. Map clinician accounts between systems
# 4. Configure auto-enrollment: new patients added to TherapyNotes
# automatically appear in Blueprint for assessment scheduling
# Example: Greenspace Health + AdvancedMD API integration
# 1. Greenspace integration team provides endpoint specifications
# 2. In AdvancedMD: Admin > API Settings > Create Application
# 3. Generate OAuth2 credentials
# 4. Provide credentials to Greenspace implementation team
# 5. Greenspace configures: patient sync, scheduling sync, score writeback
# Example: Custom FHIR R4 integration (for Epic, Cerner, etc.)
# Greenspace supports FHIR R4 endpoints for larger health systems
# 1. Register Greenspace as an approved FHIR application in the EHR
# 2. Configure SMART on FHIR authorization
# 3. Map FHIR resources: Patient, Encounter, QuestionnaireResponse
# 4. Test with synthetic data before enabling production sync
# For EHRs without API: SFTP-based CSV integration
# 1. Configure scheduled export from EHR (daily patient roster + scores)
# 2. Set up SFTP endpoint (Greenspace provides credentials)
sftp -i /path/to/key greenspace_user@sftp.greenspacehealth.com
put /exports/daily_roster_$(date +%Y%m%d).csv /incoming/
# 3. Greenspace ingests CSV on configurable scheduleIntegration complexity varies significantly by EHR. SimplePractice and TherapyNotes have limited APIs but Blueprint has pre-built connectors for both. Greenspace's managed integration service handles the heavy lifting for their 85+ supported EHRs. For EHRs without API support, the SFTP/CSV approach works but introduces a delay (typically 1–24 hours) between score collection and alert generation. Test the integration thoroughly with synthetic/test patient data before enabling production sync. Verify that no ePHI is transmitted before the BAA is executed.
Step 7: Configure PHQ-9 and GAD-7 Assessment Delivery
Set up the automated assessment delivery workflow in the MBC platform. Configure which assessments are delivered (PHQ-9 for depression, GAD-7 for anxiety), delivery frequency (typically before each session or at configurable intervals), delivery method (SMS, email, patient portal, or kiosk), and delivery timing (e.g., 24 hours before appointment or upon check-in). Configure assessment language options (English, Spanish) and customize the patient-facing messaging.
- Navigate to: Organization Settings > Assessment Library
- Enable PHQ-9 (Patient Health Questionnaire-9)
- Enable GAD-7 (Generalized Anxiety Disorder-7)
- Optional: Enable PHQ-A (adolescent version) if practice sees minors
- Optional: Enable Columbia Suicide Severity Rating Scale (C-SSRS) for patients with PHQ-9 Item 9 (suicidal ideation) endorsement
- Navigate to: Organization Settings > Assessment Schedule
- Recommended default — PHQ-9: Every session (or every 2 weeks minimum)
- Recommended default — GAD-7: Every session (or every 2 weeks minimum)
- Recommended default — Delivery method: SMS preferred (highest completion rate)
- Recommended default — Delivery timing: 24 hours before scheduled appointment
- Recommended default — Reminder: 2 hours before appointment if not completed
- Recommended default — Kiosk fallback: Available on waiting room tablets
- Navigate to: Organization Settings > Notifications > Patient Messages
- Customize SMS template: 'Hi [FirstName], please complete your brief check-in before your appointment with [ClinicianName] tomorrow. It takes about 2 minutes: [AssessmentLink]'
SMS delivery consistently achieves the highest completion rates (60–80%) compared to email (30–50%) or portal-only (20–40%). Ensure the practice has patient consent for SMS communication—add an SMS consent checkbox to the intake paperwork. For practices treating adolescents, use the PHQ-A (adolescent-modified version). Some MBC platforms automatically add the C-SSRS as a safety screener when a patient endorses PHQ-9 Item 9 (thoughts of self-harm)—verify this is configured and that the practice has a safety protocol in place. Spanish-language assessments should be available for practices with Spanish-speaking patients.
Step 8: Configure Score Decline Detection Rules and Alert Thresholds
This is the core intelligence layer. Configure the MBC platform's alerting rules to detect clinically significant score declines (worsening) and notify the assigned clinician for immediate review. Define multiple detection rules: (1) Absolute increase in score above a threshold, (2) Transition to a higher severity band, (3) Consecutive increases across multiple administrations, (4) Critical item endorsement (e.g., PHQ-9 Item 9 for suicidality). Work with the Clinical Champion to calibrate thresholds to the practice's population and clinical protocols.
- Navigate to: Organization Settings > Alerts > Clinical Alerts
- Rule 1 – Significant Score Increase (Absolute Change): PHQ-9: Alert when score increases by >= 5 points from previous administration. GAD-7: Alert when score increases by >= 4 points from previous administration. Rationale: Reliable Change Index for PHQ-9 is ~5 points; for GAD-7 ~4 points.
- Rule 2 – Severity Band Transition (Categorical Worsening): PHQ-9 Severity Bands: 0-4 Minimal, 5-9 Mild, 10-14 Moderate, 15-19 Moderately Severe, 20-27 Severe. GAD-7 Severity Bands: 0-4 Minimal, 5-9 Mild, 10-14 Moderate, 15-21 Severe. Alert when patient moves to a HIGHER severity band.
- Rule 3 – Consecutive Increases: Alert when score increases for 2 or more consecutive administrations (regardless of whether the increase crosses the absolute threshold). This catches slow, steady deterioration.
- Rule 4 – Critical Item Endorsement (HIGHEST PRIORITY): PHQ-9 Item 9: 'Thoughts that you would be better off dead, or of hurting yourself in some way'. Alert IMMEDIATELY if patient endorses this item at ANY level (>0). This alert should trigger a same-day clinician callback.
- Rule 5 – High Severity Score: PHQ-9 >= 20 (Severe depression): Immediate alert. GAD-7 >= 15 (Severe anxiety): Immediate alert.
- Alert delivery – In-app notification: Always ON (appears on clinician dashboard).
- Alert delivery – Email notification: ON for Rules 1–3; include score summary.
- Alert delivery – SMS/urgent notification: ON for Rules 4–5 only.
- Alert delivery – Escalation: If clinician does not acknowledge Rule 4 alert within 2 hours, escalate to clinical supervisor.
Alert threshold calibration is critical—too sensitive creates alert fatigue, too conservative misses at-risk patients. The Reliable Change Index (RCI) is the gold standard: a change must exceed measurement error to be clinically meaningful. For PHQ-9, the RCI is approximately 5 points; for GAD-7, approximately 4 points. Start with these evidence-based thresholds and adjust based on the practice's first 30 days of data. The Clinical Champion must approve all threshold settings before go-live. Rule 4 (suicidal ideation screening) requires a documented safety protocol at the practice—verify this exists and that all clinicians are trained on it. Document the alert rules in a clinical protocol document that becomes part of the practice's policies and procedures.
Step 9: Build Custom Power BI Dashboard (Optional Advanced Analytics)
For practices requiring population-level analytics, compliance reporting, or clinician performance benchmarking beyond the MBC platform's native dashboards, deploy a Microsoft Power BI Pro workspace. Connect to the MBC platform's REST API to ingest score data, build visualizations for: (1) population-level PHQ-9/GAD-7 score distributions, (2) percentage of patients with declining scores by clinician, (3) assessment completion rates, (4) average time-to-review for alerts, (5) outcomes over time (practice-wide improvement trends). This dashboard is primarily for the clinical director and practice owner.
// Power Query M script for Blueprint Health API connection
// In Power BI Desktop: Get Data > Web > Advanced
let
Source = Web.Contents(
"https://api.blueprint-health.com/v1/assessments",
[
Headers = [
#"Authorization" = "Bearer " & ApiKey,
#"Content-Type" = "application/json"
],
Query = [
assessment_type = "PHQ-9,GAD-7",
date_from = Date.ToText(Date.AddMonths(DateTime.LocalNow(), -6), "yyyy-MM-dd"),
date_to = Date.ToText(DateTime.LocalNow(), "yyyy-MM-dd"),
page_size = "1000"
]
]
),
JsonResponse = Json.Document(Source),
Assessments = Table.FromList(JsonResponse[data], Splitter.SplitByNothing()),
Expanded = Table.ExpandRecordColumn(Assessments, "Column1",
{"patient_id", "clinician_id", "assessment_type", "score",
"severity_band", "administered_date", "previous_score", "score_change"})
in
Expanded// Score Decline Rate:
Score Decline Rate =
DIVIDE(
COUNTROWS(FILTER(Assessments, Assessments[score_change] > 0)),
COUNTROWS(Assessments),
0
)
// Average PHQ-9 Score by Clinician:
Avg PHQ9 by Clinician =
CALCULATE(
AVERAGE(Assessments[score]),
Assessments[assessment_type] = "PHQ-9"
)
// Patients Needing Review (declining):
Patients Needing Review =
COUNTROWS(
FILTER(
Assessments,
Assessments[score_change] >= 5
&& Assessments[assessment_type] = "PHQ-9"
&& Assessments[administered_date] >= TODAY() - 30
)
)The Power BI dashboard is optional—both Blueprint and Greenspace provide built-in dashboards that cover most use cases. Deploy Power BI only when the practice leadership needs: (1) cross-platform data aggregation, (2) custom KPIs not available in the MBC platform, or (3) integration with other practice data sources (billing, scheduling, satisfaction surveys). Use the Power BI On-premises Data Gateway if connecting to any local data sources. All Power BI workspaces containing PHI must be in a HIPAA-compliant tenant with the BAA executed. Restrict workspace access to authorized users only via Azure AD security groups.
Step 10: Configure Clinician Notification Workflow
Set up the multi-channel notification workflow that ensures declining-score alerts reach clinicians promptly and are acknowledged. Configure: (1) In-app dashboard alerts in the MBC platform, (2) Email notifications to clinician's M365 mailbox, (3) Urgent SMS notifications for critical alerts (suicidality endorsement, severe scores), (4) Escalation to clinical supervisor if primary clinician does not acknowledge within the defined timeframe. Optionally, integrate with Microsoft Teams for a dedicated clinical alerts channel.
# HTTP trigger payload schema for MBC platform webhook
{
"type": "Request",
"kind": "Http",
"inputs": {
"schema": {
"type": "object",
"properties": {
"alert_type": { "type": "string" },
"patient_id": { "type": "string" },
"patient_name": { "type": "string" },
"clinician_email": { "type": "string" },
"assessment_type": { "type": "string" },
"current_score": { "type": "integer" },
"previous_score": { "type": "integer" },
"score_change": { "type": "integer" },
"severity_band": { "type": "string" },
"timestamp": { "type": "string" }
}
}
}
}- Action: Post adaptive card to Teams channel
- Action: Send email to clinician
- Action: If alert_type == 'critical_safety', also send SMS via Twilio connector
- Action: Create Planner task for clinician with due date = today
- Action: If not acknowledged in 2 hours, send escalation to supervisor
Microsoft Teams integration adds a real-time collaboration layer where clinicians can discuss cases flagged by the alert system. However, Teams is NOT a replacement for the MBC platform's in-app alerts—it is a supplementary channel. All PHI in Teams is covered by the M365 BAA, but ensure that the private Team channel membership is restricted to appropriate clinicians only. For the Power Automate webhook, use an HTTPS endpoint and validate the webhook signature to prevent unauthorized posts. The Twilio SMS connector in Power Automate requires a HIPAA-compliant Twilio account with BAA—alternatively, use the MBC platform's native SMS alerting for critical notifications.
Step 11: Implement HIPAA Compliance Controls and Audit Logging
Configure all required HIPAA administrative, technical, and physical safeguards across the solution stack. This includes: role-based access control (RBAC) across all systems, comprehensive audit logging with 6-year retention, encryption validation at rest and in transit, workforce training scheduling, incident response plan documentation, and BAA inventory management. Deploy a centralized audit log aggregation approach using Microsoft Sentinel or a lightweight SIEM.
# Role-Based Access Control configuration
# Azure AD Security Groups:
# SG-Clinicians: Access to MBC platform (own patients only), EHR, Teams alerts
# SG-ClinicalSupervisors: Access to all patient data, escalation alerts, Power BI
# SG-PracticeAdmin: Access to billing, scheduling, aggregate reports (no PHI scores)
# SG-MSP-Admins: Access to infrastructure only (firewall, Intune, M365 admin)
# PowerShell: Create security groups
Connect-MgGraph -Scopes 'Group.ReadWrite.All'
New-MgGroup -DisplayName 'SG-Clinicians' -MailEnabled:$false -MailNickname 'sg-clinicians' -SecurityEnabled:$true
New-MgGroup -DisplayName 'SG-ClinicalSupervisors' -MailEnabled:$false -MailNickname 'sg-clinicalsupervisors' -SecurityEnabled:$true
New-MgGroup -DisplayName 'SG-PracticeAdmin' -MailEnabled:$false -MailNickname 'sg-practiceadmin' -SecurityEnabled:$true
# Enable Microsoft 365 Unified Audit Logging
# PowerShell:
Connect-ExchangeOnline
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true
# Verify audit logging is enabled:
Get-AdminAuditLogConfig | Format-List UnifiedAuditLogIngestionEnabled
# Configure audit log retention (requires M365 E5 or compliance add-on for >90 days)
# For standard M365 Business Premium: default 180-day retention
# For 6-year HIPAA retention: export logs monthly to Azure Blob Storage
# Azure Blob Storage for long-term audit log retention
# PowerShell:
az storage account create --name practiceauditlogs --resource-group rg-healthcare --location eastus --sku Standard_GRS --encryption-services blob
az storage container create --name audit-logs --account-name practiceauditlogs
az storage account management-policy create --account-name practiceauditlogs --policy @lifecycle-policy.json
# lifecycle-policy.json - move to cool storage after 90 days, archive after 1 year
# {
# 'rules': [{
# 'name': 'audit-log-lifecycle',
# 'type': 'Lifecycle',
# 'definition': {
# 'filters': { 'blobTypes': ['blockBlob'] },
# 'actions': {
# 'baseBlob': {
# 'tierToCool': { 'daysAfterModificationGreaterThan': 90 },
# 'tierToArchive': { 'daysAfterModificationGreaterThan': 365 },
# 'delete': { 'daysAfterModificationGreaterThan': 2555 }
# }
# }
# }
# }]
}
# Document BAA inventory
# Create a BAA tracking spreadsheet with:
# Vendor | BAA Execution Date | Expiration | Signatory | Copy Location
# Microsoft | [date] | Perpetual | [name] | SharePoint/Compliance/BAAs/
# Blueprint Health | [date] | Per contract | [name] | SharePoint/Compliance/BAAs/
# [MSP Name] | [date] | Per MSA | [name] | SharePoint/Compliance/BAAs/HIPAA requires audit logs that capture who accessed ePHI, what they accessed, when, and from where. M365 Business Premium provides 180-day audit log retention by default. For the 6-year HIPAA requirement, implement monthly automated exports to Azure Blob Storage with immutability policies. The estimated Azure Blob Storage cost for audit logs is minimal—typically under $5/month for a small practice. Create a compliance documentation SharePoint site with folders for: BAAs, Risk Assessments, Policies & Procedures, Training Records, and Incident Response. Schedule quarterly audit log reviews as part of the ongoing managed services agreement.
Step 12: Conduct Pre-Launch Testing with Synthetic Data
Before enabling production patient data flow, conduct comprehensive testing using synthetic (fake) patient data. Create 10–15 test patients in the EHR with known PHQ-9 and GAD-7 score histories that will trigger each alert rule. Verify: (1) assessments are delivered correctly via all channels (SMS, email, kiosk), (2) scores are ingested and calculated correctly, (3) each alert rule fires as expected, (4) notifications reach the correct clinician via all configured channels, (5) escalation rules trigger appropriately, (6) Power BI dashboards display correct data, (7) audit logs capture all access events.
- Test Patient 1: 'Test Decline-Absolute' — PHQ-9 increases by 7 points | Visit 1: PHQ-9 = 8 (Mild) | Visit 2: PHQ-9 = 15 (Moderately Severe) → Should trigger Rule 1 + Rule 2
- Test Patient 2: 'Test Decline-Consecutive' — Slow steady increase | Visit 1: PHQ-9 = 6 | Visit 2: PHQ-9 = 8 | Visit 3: PHQ-9 = 11 → Should trigger Rule 3 (consecutive increases)
- Test Patient 3: 'Test Critical-Item9' — Suicidality endorsement | Visit 1: PHQ-9 = 12, Item 9 = 0 | Visit 2: PHQ-9 = 14, Item 9 = 1 → Should trigger Rule 4 (CRITICAL)
- Test Patient 4: 'Test Severe-Score' — Enters severe range | Visit 1: PHQ-9 = 17 | Visit 2: PHQ-9 = 22 → Should trigger Rule 5 (Severe)
- Test Patient 5: 'Test GAD7-Decline' — GAD-7 worsening | Visit 1: GAD-7 = 5 (Mild) | Visit 2: GAD-7 = 12 (Moderate) → Should trigger Rule 1 + Rule 2
- Test Patient 6: 'Test Improvement' — Scores improving (NO alert expected) | Visit 1: PHQ-9 = 18 | Visit 2: PHQ-9 = 12 → Should NOT trigger any alert
- Test Patient 7: 'Test Stable' — Scores stable (NO alert expected) | Visit 1: PHQ-9 = 10 | Visit 2: PHQ-9 = 11 → Should NOT trigger (below RCI threshold)
Use clearly labeled test patients (prefix names with 'TEST-' or 'ZZ-Test') to ensure they are easily identifiable and can be purged after testing. Do NOT use real patient data during testing. Involve the Clinical Champion in validating that alert rules align with clinical expectations. Document all test results in a Testing Validation Report. Any failed tests must be resolved and re-tested before proceeding to go-live. Allow 1–2 weeks for thorough testing.
Step 13: Conduct Clinician and Staff Training
Deliver structured training to all practice staff who will interact with the system. Training should be role-specific: (1) Clinicians: how to review alerts, interpret score trends, document clinical response, and acknowledge alerts; (2) Front desk/admin staff: how to assist patients with tablet-based assessment completion, troubleshoot delivery issues, and manage the assessment schedule; (3) Clinical supervisor/director: how to use population dashboards, review escalated alerts, and generate compliance reports; (4) Practice owner/manager: how to interpret outcome reports and ROI metrics. Record all training sessions for future onboarding of new staff.
- Training agenda template
- Session 1: Clinician Training (90 minutes) 1. Overview of Measurement-Based Care and evidence base (15 min) 2. PHQ-9 and GAD-7 scoring interpretation refresher (15 min) 3. Hands-on: Navigating the MBC platform dashboard (20 min) - Viewing patient score trends - Understanding alert notifications - Acknowledging and responding to alerts - Documenting clinical response 4. Workflow walkthrough: Pre-session score review (15 min) 5. Critical safety protocol: PHQ-9 Item 9 response procedure (15 min) 6. Q&A and practice scenarios (10 min)
- Session 2: Admin Staff Training (45 minutes) 1. Overview of the assessment delivery process (10 min) 2. Hands-on: Patient check-in tablet kiosk mode (15 min) 3. Troubleshooting: What to do when a patient can't access assessment (10 min) 4. FAQ and role-specific scenarios (10 min)
- Session 3: Clinical Director/Supervisor Training (60 minutes) 1. Population dashboard walkthrough (20 min) 2. Clinician performance benchmarking (15 min) 3. Escalation alert management (10 min) 4. Compliance reporting and documentation (15 min)
- Session 4: Practice Owner/Manager Briefing (30 minutes) 1. ROI overview: MBC billing (CPT 96127) and payer requirements (15 min) 2. Key metrics dashboard walkthrough (10 min) 3. Ongoing support and escalation to MSP (5 min)
Schedule training during a slow period (e.g., Friday afternoon) to minimize disruption to patient care. Provide printed quick-reference cards for clinicians to keep at their workstations. Record training via Teams for future playback. Create a SharePoint-hosted training resource library with: user guides, video recordings, FAQ documents, and the practice's clinical protocol for responding to alerts. HIPAA requires documented workforce training—log all attendees, dates, and topics covered. Plan a 30-minute refresher session 2 weeks after go-live to address real-world questions.
Step 14: Go-Live and Hypercare Period
Execute the production go-live in a phased approach. Phase A (Week 1): Enable for 2–3 early-adopter clinicians who served as pilot users during testing. Phase B (Week 2): Expand to remaining clinicians. Provide on-site or virtual MSP support during the first week of each phase. Monitor system health, alert volume, and clinician adoption daily during the 4-week hypercare period. Address any integration issues, false-positive alerts, or workflow friction immediately.
curl -H 'Authorization: Bearer <API_KEY>' \
https://api.blueprint-health.com/v1/organization/healthcurl -H 'Authorization: Bearer <API_KEY>' \
https://api.blueprint-health.com/v1/integrations/status- Assessments delivered: target 100% of eligible appointments
- Assessments completed: target >60% by end of week 2
- Alerts generated: should be 5–15% of completed assessments
- Alert acknowledgment time: target <4 hours average
- False positive rate: target <10% (clinician-reported)
The hypercare period is the most critical phase for adoption success. Clinician resistance to MBC is common—research shows that tailoring implementation to existing workflows is the single most important factor. Be prepared to adjust alert thresholds during hypercare if clinicians report excessive alerts (lower sensitivity) or missed cases (increase sensitivity). Assign a single MSP point-of-contact for the practice during hypercare who can respond within 2 hours to any issue. Track and resolve all issues in a shared tracker visible to the practice. Schedule a formal hypercare review meeting at the end of week 4 to review metrics, finalize alert thresholds, and transition to standard managed services support.
Custom AI Components
PHQ-9/GAD-7 Score Decline Detector
Type: workflow A configurable rule-based engine that analyzes sequential PHQ-9 and GAD-7 assessment scores for each patient and generates structured alerts when clinically significant decline patterns are detected. This component implements five detection rules: (1) absolute score increase exceeding the Reliable Change Index, (2) severity band transition, (3) consecutive score increases, (4) critical safety item endorsement, and (5) high-severity threshold breach. It is designed to run either within the MBC platform's native alerting system or as a standalone Power Automate + Azure Function workflow for practices that need custom logic beyond what the MBC platform provides.
Implementation:
# Azure Function (Python) triggered by MBC platform webhook or scheduled API
# poll
# PHQ-9/GAD-7 Score Decline Detector
# Implementation as an Azure Function (Python) triggered by MBC platform webhook
# or scheduled to poll the MBC platform API
import json
import logging
import os
from datetime import datetime, timedelta
from typing import List, Dict, Optional
import azure.functions as func
import requests
# Configuration - set via Azure Function App Settings
MBC_API_BASE = os.environ.get('MBC_API_BASE', 'https://api.blueprint-health.com/v1')
MBC_API_KEY = os.environ.get('MBC_API_KEY')
TEAMS_WEBHOOK_URL = os.environ.get('TEAMS_WEBHOOK_URL')
SMTP_SERVER = os.environ.get('SMTP_SERVER')
ESCALATION_EMAIL = os.environ.get('ESCALATION_EMAIL')
# Clinical thresholds (evidence-based defaults)
PHQ9_RCI_THRESHOLD = 5 # Reliable Change Index for PHQ-9
GAD7_RCI_THRESHOLD = 4 # Reliable Change Index for GAD-7
PHQ9_SEVERE_THRESHOLD = 20
GAD7_SEVERE_THRESHOLD = 15
CONSECUTIVE_INCREASE_COUNT = 2
# PHQ-9 Severity Bands
PHQ9_BANDS = [
(0, 4, 'Minimal'),
(5, 9, 'Mild'),
(10, 14, 'Moderate'),
(15, 19, 'Moderately Severe'),
(20, 27, 'Severe')
]
# GAD-7 Severity Bands
GAD7_BANDS = [
(0, 4, 'Minimal'),
(5, 9, 'Mild'),
(10, 14, 'Moderate'),
(15, 21, 'Severe')
]
def get_severity_band(score: int, assessment_type: str) -> str:
bands = PHQ9_BANDS if assessment_type == 'PHQ-9' else GAD7_BANDS
for low, high, label in bands:
if low <= score <= high:
return label
return 'Unknown'
def get_band_index(score: int, assessment_type: str) -> int:
bands = PHQ9_BANDS if assessment_type == 'PHQ-9' else GAD7_BANDS
for i, (low, high, _) in enumerate(bands):
if low <= score <= high:
return i
return -1
def analyze_patient_scores(patient_id: str, scores: List[Dict]) -> List[Dict]:
"""Analyze a patient's score history and return any triggered alerts."""
alerts = []
if len(scores) < 2:
return alerts # Need at least 2 data points
# Sort by date ascending
scores.sort(key=lambda x: x['administered_date'])
current = scores[-1]
previous = scores[-2]
assessment_type = current['assessment_type']
current_score = current['score']
previous_score = previous['score']
score_change = current_score - previous_score
rci_threshold = PHQ9_RCI_THRESHOLD if assessment_type == 'PHQ-9' else GAD7_RCI_THRESHOLD
severe_threshold = PHQ9_SEVERE_THRESHOLD if assessment_type == 'PHQ-9' else GAD7_SEVERE_THRESHOLD
# Rule 1: Absolute score increase exceeding RCI
if score_change >= rci_threshold:
alerts.append({
'rule': 'ABSOLUTE_INCREASE',
'priority': 'HIGH',
'patient_id': patient_id,
'assessment_type': assessment_type,
'current_score': current_score,
'previous_score': previous_score,
'score_change': score_change,
'message': f'{assessment_type} increased by {score_change} points '
f'(from {previous_score} to {current_score}), '
f'exceeding the Reliable Change Index of {rci_threshold}.',
'administered_date': current['administered_date']
})
# Rule 2: Severity band transition (worsening)
current_band_idx = get_band_index(current_score, assessment_type)
previous_band_idx = get_band_index(previous_score, assessment_type)
if current_band_idx > previous_band_idx:
current_band = get_severity_band(current_score, assessment_type)
previous_band = get_severity_band(previous_score, assessment_type)
alerts.append({
'rule': 'BAND_TRANSITION',
'priority': 'HIGH',
'patient_id': patient_id,
'assessment_type': assessment_type,
'current_score': current_score,
'previous_score': previous_score,
'score_change': score_change,
'message': f'{assessment_type} severity worsened from '
f'{previous_band} ({previous_score}) to '
f'{current_band} ({current_score}).',
'administered_date': current['administered_date']
})
# Rule 3: Consecutive increases
if len(scores) >= CONSECUTIVE_INCREASE_COUNT + 1:
recent = scores[-(CONSECUTIVE_INCREASE_COUNT + 1):]
consecutive_increases = all(
recent[i+1]['score'] > recent[i]['score']
for i in range(len(recent) - 1)
)
if consecutive_increases:
trend_scores = [s['score'] for s in recent]
alerts.append({
'rule': 'CONSECUTIVE_INCREASE',
'priority': 'MEDIUM',
'patient_id': patient_id,
'assessment_type': assessment_type,
'current_score': current_score,
'previous_score': previous_score,
'score_change': score_change,
'message': f'{assessment_type} has increased for '
f'{CONSECUTIVE_INCREASE_COUNT} consecutive '
f'administrations: {" \u2192 ".join(map(str, trend_scores))}.',
'administered_date': current['administered_date']
})
# Rule 4: Critical safety item (PHQ-9 Item 9 - suicidality)
if assessment_type == 'PHQ-9' and current.get('item_scores'):
item9_score = current['item_scores'].get('item_9', 0)
if item9_score > 0:
alerts.append({
'rule': 'CRITICAL_SAFETY',
'priority': 'CRITICAL',
'patient_id': patient_id,
'assessment_type': assessment_type,
'current_score': current_score,
'previous_score': previous_score,
'score_change': score_change,
'message': f'CRITICAL: Patient endorsed PHQ-9 Item 9 '
f'(suicidal ideation) with a score of {item9_score}. '
f'Immediate clinician review required.',
'administered_date': current['administered_date']
})
# Rule 5: High severity threshold
if current_score >= severe_threshold:
alerts.append({
'rule': 'SEVERE_SCORE',
'priority': 'CRITICAL',
'patient_id': patient_id,
'assessment_type': assessment_type,
'current_score': current_score,
'previous_score': previous_score,
'score_change': score_change,
'message': f'{assessment_type} score of {current_score} is in the '
f'Severe range (\u2265{severe_threshold}). '
f'Immediate clinician review required.',
'administered_date': current['administered_date']
})
return alerts
def send_teams_notification(alert: Dict, patient_info: Dict, clinician_info: Dict):
"""Send an adaptive card to Microsoft Teams."""
priority_colors = {
'CRITICAL': '#FF0000',
'HIGH': '#FF8C00',
'MEDIUM': '#FFD700'
}
card = {
'type': 'message',
'attachments': [{
'contentType': 'application/vnd.microsoft.card.adaptive',
'content': {
'$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
'type': 'AdaptiveCard',
'version': '1.4',
'body': [
{
'type': 'Container',
'style': 'attention' if alert['priority'] == 'CRITICAL' else 'warning',
'items': [
{
'type': 'TextBlock',
'text': f"\U0001f6a8 {alert['priority']} ALERT: {alert['assessment_type']} Score Decline",
'weight': 'Bolder',
'size': 'Medium',
'color': 'Attention' if alert['priority'] == 'CRITICAL' else 'Warning'
}
]
},
{
'type': 'FactSet',
'facts': [
{'title': 'Patient', 'value': patient_info.get('name', 'N/A')},
{'title': 'Clinician', 'value': clinician_info.get('name', 'N/A')},
{'title': 'Assessment', 'value': alert['assessment_type']},
{'title': 'Current Score', 'value': str(alert['current_score'])},
{'title': 'Previous Score', 'value': str(alert['previous_score'])},
{'title': 'Change', 'value': f"+{alert['score_change']}" if alert['score_change'] > 0 else str(alert['score_change'])},
{'title': 'Rule Triggered', 'value': alert['rule']},
{'title': 'Date', 'value': alert['administered_date']}
]
},
{
'type': 'TextBlock',
'text': alert['message'],
'wrap': True
}
],
'actions': [
{
'type': 'Action.OpenUrl',
'title': 'View in MBC Platform',
'url': f"{MBC_API_BASE.replace('/v1', '')}/patients/{alert['patient_id']}"
},
{
'type': 'Action.OpenUrl',
'title': 'Acknowledge Alert',
'url': f"{MBC_API_BASE.replace('/v1', '')}/alerts/acknowledge"
}
]
}
}]
}
requests.post(TEAMS_WEBHOOK_URL, json=card, timeout=10)
def main(req: func.HttpRequest) -> func.HttpResponse:
"""Azure Function entry point - processes webhook from MBC platform."""
logging.info('Score decline detector triggered')
try:
payload = req.get_json()
except ValueError:
return func.HttpResponse('Invalid JSON', status_code=400)
patient_id = payload.get('patient_id')
assessment_type = payload.get('assessment_type')
# Fetch patient score history from MBC platform API
headers = {'Authorization': f'Bearer {MBC_API_KEY}'}
response = requests.get(
f'{MBC_API_BASE}/patients/{patient_id}/assessments',
params={'type': assessment_type, 'limit': 10},
headers=headers,
timeout=30
)
if response.status_code != 200:
logging.error(f'Failed to fetch scores: {response.status_code}')
return func.HttpResponse('API error', status_code=502)
scores = response.json().get('data', [])
alerts = analyze_patient_scores(patient_id, scores)
if alerts:
# Fetch patient and clinician info for notifications
patient_resp = requests.get(
f'{MBC_API_BASE}/patients/{patient_id}',
headers=headers, timeout=10
)
patient_info = patient_resp.json() if patient_resp.ok else {}
clinician_info = patient_info.get('assigned_clinician', {})
for alert in alerts:
logging.info(f"Alert triggered: {alert['rule']} for patient {patient_id}")
send_teams_notification(alert, patient_info, clinician_info)
return func.HttpResponse(
json.dumps({'alerts_generated': len(alerts), 'alerts': alerts}),
mimetype='application/json',
status_code=200
)
# --- Azure Function configuration files ---
# function.json
# {
# "scriptFile": "__init__.py",
# "bindings": [
# {
# "authLevel": "function",
# "type": "httpTrigger",
# "direction": "in",
# "name": "req",
# "methods": ["post"]
# },
# {
# "type": "http",
# "direction": "out",
# "name": "$return"
# }
# ]
# }
# requirements.txt
# azure-functions
# requests
# Azure Function App Settings (environment variables):
# MBC_API_BASE = https://api.blueprint-health.com/v1
# MBC_API_KEY = <from MBC platform>
# TEAMS_WEBHOOK_URL = <from Teams channel connector>
# ESCALATION_EMAIL = supervisor@practice.comAssessment Completion Rate Monitor
Type: agent A scheduled monitoring agent that runs daily to identify patients who have missed their scheduled PHQ-9/GAD-7 assessments. Low completion rates undermine the entire decline detection system—if patients don't complete assessments, declining scores cannot be detected. This agent identifies gaps, sends reminders, and alerts practice staff when completion rates fall below target thresholds (60% minimum, 80% target). Implementation:
# Azure Function (timer trigger), runs daily at 7:00 AM
# Assessment Completion Rate Monitor
# Implemented as a scheduled Azure Function (timer trigger) or Power Automate scheduled flow
# Runs daily at 7:00 AM before first appointments
import json
import logging
import os
from datetime import datetime, timedelta
from typing import List, Dict
import azure.functions as func
import requests
MBC_API_BASE = os.environ.get('MBC_API_BASE')
MBC_API_KEY = os.environ.get('MBC_API_KEY')
TEAMS_WEBHOOK_URL = os.environ.get('TEAMS_WEBHOOK_ADMIN_URL') # Admin channel
COMPLETION_TARGET = 0.80 # 80% target
COMPLETION_MINIMUM = 0.60 # 60% minimum - alert if below this
def get_completion_stats(lookback_days: int = 7) -> Dict:
"""Fetch assessment completion statistics for the past N days."""
headers = {'Authorization': f'Bearer {MBC_API_KEY}'}
start_date = (datetime.now() - timedelta(days=lookback_days)).strftime('%Y-%m-%d')
end_date = datetime.now().strftime('%Y-%m-%d')
response = requests.get(
f'{MBC_API_BASE}/assessments/stats',
params={'date_from': start_date, 'date_to': end_date},
headers=headers, timeout=30
)
return response.json() if response.ok else {}
def get_missing_assessments(date: str) -> List[Dict]:
"""Get list of patients who had appointments but didn't complete assessments."""
headers = {'Authorization': f'Bearer {MBC_API_KEY}'}
response = requests.get(
f'{MBC_API_BASE}/assessments/missing',
params={'date': date},
headers=headers, timeout=30
)
return response.json().get('data', []) if response.ok else []
def send_completion_report(stats: Dict, missing: List[Dict]):
"""Send daily completion report to admin Teams channel."""
total_sent = stats.get('total_sent', 0)
total_completed = stats.get('total_completed', 0)
rate = total_completed / total_sent if total_sent > 0 else 0
status_emoji = '✅' if rate >= COMPLETION_TARGET else ('⚠️' if rate >= COMPLETION_MINIMUM else '🔴')
card = {
'type': 'message',
'attachments': [{
'contentType': 'application/vnd.microsoft.card.adaptive',
'content': {
'type': 'AdaptiveCard',
'version': '1.4',
'body': [
{'type': 'TextBlock', 'text': f'{status_emoji} Daily MBC Completion Report', 'weight': 'Bolder', 'size': 'Medium'},
{'type': 'FactSet', 'facts': [
{'title': 'Period', 'value': 'Last 7 days'},
{'title': 'Assessments Sent', 'value': str(total_sent)},
{'title': 'Assessments Completed', 'value': str(total_completed)},
{'title': 'Completion Rate', 'value': f'{rate:.0%}'},
{'title': 'Target', 'value': f'{COMPLETION_TARGET:.0%}'},
{'title': 'Missed Yesterday', 'value': str(len(missing))}
]},
{'type': 'TextBlock', 'text': 'Patients who missed assessments yesterday:', 'weight': 'Bolder', 'isVisible': len(missing) > 0},
] + [
{'type': 'TextBlock', 'text': f"• {m.get('patient_name', 'Unknown')} (Clinician: {m.get('clinician_name', 'Unknown')})"}
for m in missing[:10] # Show top 10
]
}
}]
}
requests.post(TEAMS_WEBHOOK_URL, json=card, timeout=10)
def main(timer: func.TimerRequest) -> None:
"""Timer trigger - runs daily at 7:00 AM."""
logging.info('Assessment completion monitor running')
stats = get_completion_stats(lookback_days=7)
yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
missing = get_missing_assessments(yesterday)
send_completion_report(stats, missing)
logging.info(f'Completion report sent. Rate: {stats.get("total_completed", 0)}/{stats.get("total_sent", 0)}')
# function.json for timer trigger:
# {
# "scriptFile": "__init__.py",
# "bindings": [
# {
# "name": "timer",
# "type": "timerTrigger",
# "direction": "in",
# "schedule": "0 0 7 * * *"
# }
# ]
# }MBC Platform Alert-to-EHR Documentation Bridge
Type: integration An integration component that writes a structured clinical note back into the patient's EHR record whenever a score decline alert is generated. This ensures that the alert and the clinician's response are documented in the official medical record, supporting continuity of care and compliance with documentation standards. The note includes the assessment type, scores, alert rule triggered, and a prompt for the clinician to document their clinical response.
Implementation:
# post-processing integration script
# MBC Alert-to-EHR Documentation Bridge
# Runs as a post-processing step after the Score Decline Detector generates an alert
# Writes a structured clinical note to the EHR via API or generates a document for manual import
import json
import os
from datetime import datetime
from typing import Dict
import requests
EHR_API_BASE = os.environ.get('EHR_API_BASE') # e.g., TherapyNotes, SimplePractice API
EHR_API_KEY = os.environ.get('EHR_API_KEY')
def generate_clinical_note(alert: Dict, patient_info: Dict) -> str:
"""Generate a structured clinical note for EHR documentation."""
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M')
note = f"""MEASUREMENT-BASED CARE ALERT NOTIFICATION
========================================
Date/Time Generated: {timestamp}
Assessment Type: {alert['assessment_type']}
Alert Rule: {alert['rule']}
Alert Priority: {alert['priority']}
SCORE SUMMARY:
- Current Score: {alert['current_score']} ({get_severity_description(alert['current_score'], alert['assessment_type'])})
- Previous Score: {alert['previous_score']} ({get_severity_description(alert['previous_score'], alert['assessment_type'])})
- Score Change: {'+' if alert['score_change'] > 0 else ''}{alert['score_change']} points
- Assessment Date: {alert['administered_date']}
ALERT DETAILS:
{alert['message']}
{'⚠️ CRITICAL SAFETY ALERT: PHQ-9 Item 9 (suicidal ideation) was endorsed. Follow practice safety protocol immediately.' if alert['rule'] == 'CRITICAL_SAFETY' else ''}
CLINICIAN RESPONSE (to be completed by treating clinician):
- [ ] Alert reviewed on: ___/___/______
- [ ] Clinical action taken: _________________________________
- [ ] Treatment plan modified: Yes / No
- [ ] Patient contacted: Yes / No / Not indicated
- [ ] Safety assessment completed (if applicable): Yes / No / N/A
- [ ] Supervision consulted (if applicable): Yes / No / N/A
- Clinician signature: ______________________ Date: ___/___/______
Note: This alert was generated automatically by the Measurement-Based Care
monitoring system. The alert does not replace clinical judgment. Clinicians
should review the full clinical context before determining appropriate action.
"""
return note
def get_severity_description(score: int, assessment_type: str) -> str:
"""Return severity band description for a score."""
if assessment_type == 'PHQ-9':
if score <= 4: return 'Minimal depression'
elif score <= 9: return 'Mild depression'
elif score <= 14: return 'Moderate depression'
elif score <= 19: return 'Moderately severe depression'
else: return 'Severe depression'
elif assessment_type == 'GAD-7':
if score <= 4: return 'Minimal anxiety'
elif score <= 9: return 'Mild anxiety'
elif score <= 14: return 'Moderate anxiety'
else: return 'Severe anxiety'
return 'Unknown'
def write_to_ehr(patient_id: str, note_text: str) -> bool:
"""Write the clinical note to the patient's EHR record."""
headers = {
'Authorization': f'Bearer {EHR_API_KEY}',
'Content-Type': 'application/json'
}
# Generic EHR API note creation (adapt endpoint per EHR vendor)
payload = {
'patient_id': patient_id,
'note_type': 'MBC_ALERT',
'note_text': note_text,
'created_date': datetime.now().isoformat(),
'status': 'pending_review',
'category': 'outcome_measure'
}
try:
response = requests.post(
f'{EHR_API_BASE}/patients/{patient_id}/notes',
json=payload, headers=headers, timeout=30
)
return response.status_code in (200, 201)
except requests.RequestException as e:
# Fallback: generate PDF and send via secure email
# or save to SharePoint for manual upload
logging.error(f'EHR API write failed: {e}')
return False
def process_alert_for_ehr(alert: Dict, patient_info: Dict) -> Dict:
"""Main entry point: generate note and write to EHR."""
note_text = generate_clinical_note(alert, patient_info)
success = write_to_ehr(alert['patient_id'], note_text)
return {
'patient_id': alert['patient_id'],
'note_generated': True,
'ehr_write_success': success,
'fallback_required': not success,
'timestamp': datetime.now().isoformat()
}
# For EHRs without API support (e.g., some TherapyNotes configurations):
# 1. Generate the note as a PDF
# 2. Save to a monitored SharePoint folder
# 3. Admin staff manually uploads to patient chart
# 4. Track pending uploads in a Power Automate flow with remindersPopulation Outcome Trend Analyzer
Type: prompt A system prompt template for use with Azure OpenAI GPT-4 (HIPAA-compliant deployment) that analyzes aggregate, de-identified practice outcome data and generates natural-language summary reports for the clinical director. This prompt produces weekly or monthly narrative summaries of practice-wide PHQ-9 and GAD-7 trends, identifies patterns (e.g., 'patients in the 25–35 age group show a 12% higher rate of PHQ-9 score increases'), and recommends focus areas. Only aggregate/de-identified data is sent to the model.
Implementation:
Only send aggregate, de-identified data to this model. Individual patient PHI must NEVER be included in prompts.
Azure OpenAI Configuration: Deploy GPT-4 model in Azure OpenAI Service (HIPAA-eligible with BAA). Endpoint: https://<your-instance>.openai.azure.com/ — API Version: 2024-02-15-preview or later. Data is NOT used for model training when using Azure OpenAI.
Population Outcome Trend Analyzer — System Prompt
Population Outcome Trend Analyzer — User Prompt Template
import os
from openai import AzureOpenAI
client = AzureOpenAI(
api_key=os.environ.get('AZURE_OPENAI_API_KEY'),
api_version='2024-02-15-preview',
azure_endpoint=os.environ.get('AZURE_OPENAI_ENDPOINT')
)
def generate_trend_report(aggregate_data: dict) -> str:
"""Generate a narrative trend report from aggregate practice data."""
user_prompt = USER_PROMPT_TEMPLATE.format(**aggregate_data)
response = client.chat.completions.create(
model='gpt-4', # Deployment name in Azure OpenAI
messages=[
{'role': 'system', 'content': SYSTEM_PROMPT},
{'role': 'user', 'content': user_prompt}
],
temperature=0.3, # Low temperature for factual reporting
max_tokens=2000
)
return response.choices[0].message.content
# Schedule this to run weekly (Sunday evening) via Azure Function timer trigger
# Send the generated report to the clinical director via email or TeamsCPT 96127 Billing Documentation Generator
Type: skill A utility skill that automatically generates the documentation required to bill CPT code 96127 (Brief emotional/behavioral assessment) for each PHQ-9 and GAD-7 administration. This supports the practice's revenue recovery from measurement-based care activities, which is a key ROI driver for the project. The skill generates a billing-ready note with the required elements: assessment name, standardized instrument used, score, interpretation, and time spent.
Implementation:
# CPT 96127 Billing Documentation Generator
# CPT 96127: Brief emotional/behavioral assessment (e.g., depression inventory,
# attention-deficit/hyperactivity disorder scale), with scoring and documentation,
# per standardized instrument
#
# Reimbursement: ~$5-$12 per administration (varies by payer)
# Can be billed up to 4 units per encounter (4 different instruments)
# Must be billed with an E/M code for the encounter
from datetime import datetime
from typing import Dict, Optional
def generate_96127_documentation(
patient_id: str,
encounter_date: str,
assessment_type: str, # 'PHQ-9' or 'GAD-7'
score: int,
clinician_name: str,
clinician_credentials: str,
administration_method: str = 'patient_self_report', # or 'clinician_administered'
time_minutes: int = 3,
item_scores: Optional[Dict] = None
) -> Dict:
"""Generate CPT 96127 billing documentation."""
# Determine severity interpretation
if assessment_type == 'PHQ-9':
instrument_name = 'Patient Health Questionnaire-9 (PHQ-9)'
condition = 'depression'
if score <= 4:
severity = 'Minimal depression'
clinical_action = 'Continue current treatment plan. Monitor at next visit.'
elif score <= 9:
severity = 'Mild depression'
clinical_action = 'Watchful waiting. Repeat PHQ-9 at follow-up. Consider treatment if symptoms persist.'
elif score <= 14:
severity = 'Moderate depression'
clinical_action = 'Treatment plan indicated. Consider psychotherapy and/or pharmacotherapy.'
elif score <= 19:
severity = 'Moderately severe depression'
clinical_action = 'Active treatment with psychotherapy and/or pharmacotherapy recommended.'
else:
severity = 'Severe depression'
clinical_action = 'Immediate treatment initiation. Consider combination therapy. Assess safety.'
elif assessment_type == 'GAD-7':
instrument_name = 'Generalized Anxiety Disorder-7 (GAD-7)'
condition = 'anxiety'
if score <= 4:
severity = 'Minimal anxiety'
clinical_action = 'Continue current treatment plan. Monitor at next visit.'
elif score <= 9:
severity = 'Mild anxiety'
clinical_action = 'Watchful waiting. Repeat GAD-7 at follow-up.'
elif score <= 14:
severity = 'Moderate anxiety'
clinical_action = 'Consider psychotherapy and/or pharmacotherapy.'
else:
severity = 'Severe anxiety'
clinical_action = 'Active treatment recommended. Consider combination therapy.'
else:
raise ValueError(f'Unsupported assessment type: {assessment_type}')
administration_desc = (
'Patient completed the assessment independently via electronic delivery '
'(tablet/smartphone) prior to the clinical encounter.'
if administration_method == 'patient_self_report'
else 'Assessment was administered by the clinician during the clinical encounter.'
)
# Generate the billing note
billing_note = (
f'BRIEF EMOTIONAL/BEHAVIORAL ASSESSMENT (CPT 96127)\n'
f'Date of Service: {encounter_date}\n'
f'Standardized Instrument: {instrument_name}\n'
f'Condition Screened: {condition.title()}\n\n'
f'Administration: {administration_desc}\n'
f'Scoring: Automated electronic scoring.\n'
f'Total Score: {score} out of {27 if assessment_type == "PHQ-9" else 21}\n'
f'Severity Classification: {severity}\n\n'
f'Clinical Interpretation: Patient\'s {assessment_type} score of {score} '
f'indicates {severity.lower()}. {clinical_action}\n\n'
f'Time: Approximately {time_minutes} minutes for administration, scoring, '
f'and interpretation.\n\n'
f'Performed by: {clinician_name}, {clinician_credentials}'
)
# Generate billing record
billing_record = {
'cpt_code': '96127',
'units': 1, # 1 unit per standardized instrument
'modifier': None, # Add modifier 59 if billing multiple instruments same encounter
'diagnosis_codes': [
'F32.9' if assessment_type == 'PHQ-9' and score >= 10 else
'F41.1' if assessment_type == 'GAD-7' and score >= 10 else
'Z13.31' if assessment_type == 'PHQ-9' else 'Z13.39'
],
'encounter_date': encounter_date,
'patient_id': patient_id,
'rendering_provider': clinician_name,
'credentials': clinician_credentials,
'documentation': billing_note,
'assessment_type': assessment_type,
'score': score,
'severity': severity
}
return billing_record
# Usage example:
# record = generate_96127_documentation(
# patient_id='PT-12345',
# encounter_date='2025-01-15',
# assessment_type='PHQ-9',
# score=16,
# clinician_name='Dr. Jane Smith',
# clinician_credentials='PhD, Licensed Psychologist',
# administration_method='patient_self_report',
# time_minutes=3
# )
#
# Revenue impact estimate:
# - 10 clinicians x 8 patients/day x 5 days/week x 48 weeks = 19,200 encounters/year
# - 80% completion rate = 15,360 billable 96127 units
# - At $8 average reimbursement = $122,880/year additional revenue
# - Even at 50% completion: $76,800/yearTesting & Validation
- TEST 1 - Assessment Delivery Verification: Schedule a test appointment for a synthetic patient. Verify that the MBC platform sends a PHQ-9 and GAD-7 assessment via SMS exactly 24 hours before the appointment time. Confirm the SMS contains a working assessment link. Complete the assessment on a mobile device and verify the score appears in the MBC platform within 5 minutes. Expected: assessment delivered on time, link functional, score calculated correctly.
- TEST 2 - Score Calculation Accuracy: Complete a PHQ-9 assessment with known item responses (e.g., all items scored 2 = total score 18, 'Moderately Severe'). Verify the MBC platform calculates the exact same total score and assigns the correct severity band. Repeat for GAD-7 with known responses. Expected: 100% accuracy in score calculation and severity band assignment.
- TEST 3 - Absolute Increase Alert (Rule 1): For a test patient, enter a first PHQ-9 score of 8 (Mild). Then enter a second PHQ-9 score of 14 (Moderate)—a 6-point increase exceeding the RCI of 5. Verify that an alert is generated within 5 minutes, appears on the clinician's MBC dashboard, and an email notification is sent to the assigned clinician's M365 mailbox. Expected: alert fires for 6-point increase; no alert fires if increase is only 3 points (below RCI).
- TEST 4 - Severity Band Transition Alert (Rule 2): For a test patient, enter a GAD-7 score of 9 (Mild) followed by a score of 11 (Moderate). Verify that a band transition alert is generated even though the absolute increase (2 points) is below the RCI threshold. Expected: alert fires because the patient moved from Mild to Moderate band.
- TEST 5 - Consecutive Increase Alert (Rule 3): For a test patient, enter three consecutive PHQ-9 scores: 6, 8, 10. Each increase is only 2 points (below RCI), but the consecutive pattern should trigger an alert after the third score. Expected: no alert after score 2 (6→8); alert fires after score 3 (8→10) due to consecutive increase pattern.
- TEST 6 - Critical Safety Alert (Rule 4): For a test patient, complete a PHQ-9 where Item 9 (suicidal ideation) is scored as 1 ('Several days'). Verify that a CRITICAL priority alert is generated immediately, appears on the dashboard with urgent styling, and triggers an SMS notification to the clinician (if configured). Verify the escalation timer starts. Expected: immediate critical alert with correct priority designation.
- TEST 7 - No False Positive for Improving Scores: For a test patient, enter PHQ-9 scores of 18, then 12 (a 6-point improvement). Verify that NO decline alert is generated. The system should only alert on worsening (increasing) scores. Expected: zero alerts generated for improving scores.
- TEST 8 - No False Positive for Stable Scores: For a test patient, enter PHQ-9 scores of 10, then 11 (a 1-point increase within the same severity band and below RCI). Verify that NO alert is generated for this clinically insignificant change. Expected: zero alerts generated.
- TEST 9 - EHR Integration Data Sync: Add a new patient in the EHR (SimplePractice, TherapyNotes, or other). Verify that the patient appears in the MBC platform within the expected sync interval (real-time for API; up to 24 hours for SFTP). Verify demographics match: name, DOB, assigned clinician. Expected: patient appears in MBC platform with correct demographics.
- TEST 10 - Multi-Channel Notification Delivery: Trigger a HIGH priority alert and verify it is received via: (a) MBC platform in-app notification, (b) email to clinician's M365 mailbox, (c) Microsoft Teams channel post (if configured). Verify all three channels show consistent information. Expected: alert received on all configured channels within 5 minutes.
- TEST 11 - Escalation Workflow: Trigger a CRITICAL alert and do NOT acknowledge it within the configured escalation timeframe (e.g., 2 hours). Verify that the system sends an escalation notification to the clinical supervisor's email and/or Teams. Expected: escalation fires at the configured interval.
- TEST 12 - Power BI Dashboard Data Accuracy (if deployed): After entering 10+ test assessment scores, verify that the Power BI dashboard correctly displays: total assessments, completion rate, average scores, score distribution by severity band, and patients with declining scores. Cross-reference dashboard numbers with MBC platform data. Expected: dashboard figures match MBC platform figures exactly.
- TEST 13 - Kiosk Tablet Assessment Flow: On a waiting room iPad/tablet in kiosk mode, navigate to the MBC platform assessment URL. Complete a PHQ-9 assessment as a patient would. Verify: the tablet is locked to the assessment app only (no access to Settings, other apps, or browser), the assessment submits successfully, and the score appears on the clinician's dashboard. Expected: locked kiosk experience with successful assessment completion.
- TEST 14 - HIPAA Access Control Verification: Log in to the MBC platform as Clinician A and verify they can ONLY see their assigned patients' scores (not Clinician B's patients). Log in as the Clinical Supervisor and verify they CAN see all patients. Log in as an Admin user and verify they can see aggregate reports but NOT individual patient scores (if configured). Expected: role-based access controls enforced correctly.
- TEST 15 - Audit Log Verification: Perform several actions in the MBC platform and M365 (access a patient record, generate a report, export data). Wait 30 minutes, then check the audit logs (M365 Unified Audit Log and MBC platform audit log). Verify that each action is logged with: timestamp, user identity, action performed, and resource accessed. Expected: all ePHI access events captured in audit logs.
- TEST 16 - Backup and Recovery Test: Verify that Veeam backup is running successfully for all M365 data (Exchange, OneDrive, SharePoint). Perform a test restore of a single email and a single SharePoint document. Expected: backup job completes without errors; test restore succeeds within 15 minutes.
- TEST 17 - VPN Remote Access Test: Connect to the practice network via the FortiGate SSL VPN from an off-site location. Verify that the clinician can access the MBC platform, EHR, and all clinical systems through the VPN. Verify MFA is required for VPN login. Expected: secure remote access functional with MFA enforcement.
- TEST 18 - CPT 96127 Billing Documentation: Complete a PHQ-9 and GAD-7 assessment for a test patient. Verify that the billing documentation generator produces a complete 96127 note with all required elements (instrument name, score, severity, clinical interpretation, time, performing provider). If Blueprint Pro is used, verify the auto-generated claim data is correct. Expected: complete, billable documentation generated for each assessment.
Client Handoff
The client handoff meeting should be scheduled as a 90-minute session with the practice owner, clinical director/supervisor, and office manager present. Cover the following topics in order:
Maintenance
Monthly Maintenance Tasks (MSP Responsibility)
Quarterly Maintenance Tasks
Annual Maintenance Tasks
SLA Considerations
- Critical alerts (system down, PHI exposure): 1-hour response, 4-hour resolution
- High (integration failure, alert system not working): 4-hour response, next business day resolution
- Medium (dashboard errors, non-critical feature issues): next business day response, 3 business day resolution
- Low (feature requests, optimization): 5 business day response, scheduled for next maintenance window
Escalation Path
Alternatives
Native EHR Outcome Tracking Only (No Separate MBC Platform)
Instead of deploying a dedicated MBC platform like Blueprint or Greenspace, rely solely on the behavioral health EHR's built-in PHQ-9/GAD-7 scoring capabilities (available in TherapyNotes, SimplePractice, Valant, and CarePaths). Clinicians administer assessments within the EHR workflow and manually review score trends. Custom Power BI dashboards or Excel-based tracking sheets provide the trend analysis and alerting layer.
Deploy Greenspace Health MBC 2.0 instead of Blueprint Health as the primary MBC platform. Greenspace offers a managed integration service (they handle the EHR integration end-to-end), AI-driven automated insights, a library of 300+ assessments, population-level analytics, and support for the Collaborative Care Model. Best suited for larger group practices (10+ clinicians) or multi-site organizations.
Custom-Built Solution with Azure Health Data Services + Power BI
Build a fully custom analytics pipeline using Azure Health Data Services (FHIR R4), Azure Functions for alert logic, Azure SQL for data storage, and Power BI for visualization. The practice's EHR exports data via FHIR or HL7 to Azure, where custom Azure Functions implement the score decline detection rules and route alerts via Power Automate, email, and Teams.
NeuroFlow BHIQ (Population Health Intelligence)
Deploy NeuroFlow's BHIQ (Behavioral Health Intelligence Quotient) platform, which goes beyond individual patient MBC to provide population-level behavioral health analytics across claims data, EMR encounters, pharmacy data, and consumer-generated data. Surfaces behavioral health risk across an entire patient population, not just those completing PHQ-9/GAD-7 assessments.
Mirah for Collaborative Care Model (CoCM) Practices
Deploy Mirah as the MBC platform specifically for practices that integrate behavioral health into primary care settings using the Collaborative Care Model (CoCM). Mirah is purpose-built for CoCM workflows including psychiatric consultant caseload management, care manager tracking, and registry-based outcome monitoring.
Want early access to the full toolkit?