The Vantrexia triage system uses an exception-based model to enable a single clinician to effectively monitor up to 100 patients simultaneously. Rather than reviewing every patient's data, the system automatically identifies patients with abnormal readings, ranks them by clinical risk, and presents a priority-ordered queue that focuses clinical attention where it matters most.

1:100 Clinician-to-Patient Ratio

Traditional RPM workflows require clinicians to manually review each patient's readings. Vantrexia's exception-based approach surfaces only the patients who deviate from their expected parameters, making it feasible for a single clinician to oversee a panel of 100 patients with confidence.

Visual Severity Hierarchy

The triage dashboard uses a four-level color-coded severity hierarchy to provide instant visual understanding of patient status. Every triage view — from summary cards to patient lists to individual patient details — uses this consistent color system:

Level Color Risk Score Criteria Action Required
Critical Red 76–100 Vital signs severely outside threshold; multiple simultaneous breaches; STAT escalation active Immediate clinician review and intervention
Warning Orange 26–75 Vital signs moderately outside threshold; trending toward critical; repeated threshold breaches Review within 1 hour; consider escalation
No Data Gray No recent device transmissions; patient may be non-compliant or experiencing device issues Contact patient; verify device connectivity
Normal Green 0–25 All vitals within configured thresholds; device transmitting normally No action required; routine oversight

Triage Summary Cards

The top of the triage dashboard displays four summary cards, one for each severity level. Each card shows the count of patients currently at that level and the trend direction (increasing, stable, or decreasing) compared to the previous 24-hour period.

API Response — Triage Summary
GET /api/v1/triage/patients/stats/

{
  "critical": { "count": 3, "trend": "stable", "change": 0 },
  "warning": { "count": 18, "trend": "increasing", "change": 4 },
  "no_data": { "count": 42, "trend": "decreasing", "change": -7 },
  "normal": { "count": 784, "trend": "stable", "change": 2 },
  "total_patients": 847,
  "last_calculated": "2026-02-06T14:30:00Z"
}

Priority Patient List

Below the summary cards, the triage dashboard displays a priority-ordered list of patients sorted by risk score (highest first). Each row in the list shows:

  • Risk indicator — color-coded badge matching the severity hierarchy
  • Patient name and MRN — encrypted at rest, decrypted only for authorized viewers
  • Risk score — numeric value from 0 to 100
  • Primary alert — the most recent or most severe threshold breach
  • Last reading — timestamp of the most recent vital sign observation
  • Active alerts — count of unacknowledged alerts for this patient
  • Days since last transmission — highlights potential non-compliance
Filtering and Sorting

The priority list can be filtered by severity level, assigned clinician, vital type, or date range. Use the filter bar above the list to narrow your view. Sorting defaults to risk score descending but can be switched to sort by last reading time, alert count, or patient name.

Alert Management

When a patient's vital reading breaches a configured threshold, the system creates an alert record and updates the patient's triage summary. Clinicians manage alerts through a structured acknowledge workflow:

1

Alert Triggered

The observation pipeline detects a threshold breach and creates an alert with severity, the triggering vital values, and the threshold that was breached. The patient's risk score is recalculated immediately.

2

Clinician Notified

A push notification is sent to the assigned clinician. The notification contains a sanitized message (no PHI) with a deep link to the patient's triage detail view. The triage dashboard highlights the new alert.

3

Review & Acknowledge

The clinician opens the patient's detail view, reviews the vital sign data, and acknowledges the alert. Acknowledgment requires selecting an outcome: Resolved, Monitoring, or Escalated. An optional clinical note can be attached.

4

Risk Score Recalculated

After acknowledgment, the patient's risk score is recalculated factoring in the clinician's response. If the underlying readings return to normal, the patient moves to a lower severity tier. All actions are recorded in the audit log.

Acknowledge Alert — API Example
curl -X POST /api/v1/alerts/{alert_id}/acknowledge/ \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "outcome": "monitoring",
    "note": "Patient reports taking medication late. Will follow up in 2 hours.",
    "follow_up_minutes": 120
  }'

Escalation System

Alerts that require elevated clinical attention can be escalated through a three-tier priority system. Escalations create formal records that track the handoff between care team members and generate billable events.

Priority Response Time Trigger Criteria Notification
Routine Within 24 hours Clinician manually escalates for non-urgent follow-up; trending readings that need provider review In-app notification to assigned provider
Urgent Within 4 hours Repeated threshold breaches within 24 hours; patient-reported worsening symptoms; MA triage identifies concern Push notification + in-app alert to provider
STAT Immediate Critical vital signs (e.g., BP > 180/120); risk score > 90; multiple simultaneous critical breaches Push notification + SMS + in-app alert to provider and supervising physician
Escalation Billing

Each escalation event is automatically logged as a billable activity for CPT 99457/99458 (interactive communication with patient or caregiver). The billing engine captures the escalation time, involved staff, and priority level to support claims documentation.

Per-Patient Threshold Management

Vantrexia supports configurable alert thresholds on a per-patient basis. This allows clinicians to set individualized parameters based on the patient's condition, medications, and clinical history — rather than relying on population-wide defaults.

Default Thresholds

Vital Sign Low Warning Low Critical High Warning High Critical Unit
Systolic BP 90 80 140 180 mmHg
Diastolic BP 60 50 90 120 mmHg
Pulse Rate 50 40 100 130 bpm
SpO2 95 90 %
Blood Glucose 70 54 180 300 mg/dL
Weight Change 3 lbs/day 5 lbs/day lbs
Audit-Logged Changes

Every threshold modification is recorded in the HIPAA audit log with the clinician's identity, the previous value, the new value, the patient ID, and a timestamp. This creates a defensible record of clinical decision-making for compliance reviews.

Update Patient Threshold — API Example
curl -X PATCH /api/v1/patients/{patient_id}/vital-config/ \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "bp_systolic_min": 85,
    "bp_systolic_max": 190,
    "reason": "Patient on antihypertensive medication; adjusted per Dr. Smith"
  }'

Non-Compliance Tracking

The triage system monitors device transmission patterns to identify patients who are not using their monitoring equipment as prescribed. Non-compliance impacts both clinical outcomes and billing eligibility (CPT 99454 requires ≥16 transmission days per 30-day period).

Non-compliance is surfaced in three ways:

  • Triage list badge: A "Non-compliant" badge appears next to patients who have missed transmissions for 2+ consecutive days
  • Daily digest: The system generates a daily non-compliance report listing all patients below the transmission threshold
  • Risk score impact: Extended non-compliance increases the patient's risk score, as missing data may indicate worsening condition or patient disengagement

Data Models

PatientTriageSummary

The core triage model that aggregates a patient's current clinical status into a single queryable record:

Python — PatientTriageSummary Model
class PatientTriageSummary(models.Model):
    patient = models.OneToOneField(Patient, on_delete=models.CASCADE, related_name='triage_summary')
    risk_level = models.CharField(
        max_length=20,
        choices=[
            ('critical', 'Critical'),
            ('warning', 'Warning'),
            ('normal', 'Normal'),
            ('no_data', 'No Data'),
        ],
        default='normal',
        db_index=True
    )
    risk_score = models.IntegerField(
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        help_text="Composite risk score from 0 (lowest) to 100 (highest)"
    )
    active_alerts_count = models.IntegerField(default=0)
    last_vital_reading = models.DateTimeField(null=True, blank=True)
    last_transmission = models.DateTimeField(null=True, blank=True)
    days_non_compliant = models.IntegerField(default=0)
    assigned_clinician = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    last_reviewed_at = models.DateTimeField(null=True, blank=True)
    last_reviewed_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-risk_score', '-active_alerts_count']

EscalationEvent

Records formal escalation events in the clinical workflow:

Python — EscalationEvent Model
class EscalationEvent(models.Model):
    patient = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name='escalations')
    priority = models.CharField(
        max_length=10,
        choices=[('routine', 'Routine'), ('urgent', 'Urgent'), ('stat', 'STAT')]
    )
    reason = models.TextField(help_text="Clinical reason for escalation")
    triggering_alert = models.ForeignKey(Alert, null=True, on_delete=models.SET_NULL)
    escalated_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='escalations_created')
    escalated_to = models.ForeignKey(User, on_delete=models.CASCADE, related_name='escalations_received')
    status = models.CharField(
        max_length=20,
        choices=[('pending', 'Pending'), ('acknowledged', 'Acknowledged'), ('in_progress', 'In Progress'), ('resolved', 'Resolved'), ('cancelled', 'Cancelled')],
        default='pending'
    )
    resolution_note = models.TextField(blank=True)
    resolved_at = models.DateTimeField(null=True, blank=True)
    resolved_by = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    billable = models.BooleanField(default=True)
    billing_record = models.ForeignKey('billing.BillingRecord', null=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']

Risk Score Algorithm

The risk score is a composite value from 0 to 100 that represents the overall clinical urgency for a patient. It is recalculated every time a new observation arrives, an alert is created or acknowledged, or a threshold is changed.

The algorithm weighs the following factors:

Factor Weight Description
Active Critical Alerts 40% Each unacknowledged critical alert contributes up to 40 points
Active Warning Alerts 20% Each unacknowledged warning alert contributes up to 20 points
Threshold Deviation 20% How far the latest reading is from the threshold boundary (normalized)
Trend Direction 10% Worsening trend over last 3 readings increases score; improving trend decreases it
Non-Compliance 10% Days without transmission: 0–1 = 0 pts, 2–3 = 3 pts, 4–7 = 7 pts, 7+ = 10 pts
Python — Risk Score Calculation (Simplified)
def calculate_risk_score(patient):
    score = 0

    # Active critical alerts (up to 40 points)
    critical_count = patient.alerts.filter(severity='critical', acknowledged_at__isnull=True).count()
    score += min(critical_count * 20, 40)

    # Active warning alerts (up to 20 points)
    warning_count = patient.alerts.filter(severity='warning', acknowledged_at__isnull=True).count()
    score += min(warning_count * 10, 20)

    # Threshold deviation (up to 20 points)
    latest = patient.observations.order_by('-effective_datetime').first()
    if latest and latest.threshold_deviation:
        score += min(int(latest.threshold_deviation * 20), 20)

    # Trend direction (up to 10 points)
    trend = calculate_vital_trend(patient, readings=3)
    if trend == 'worsening':
        score += 10
    elif trend == 'stable':
        score += 3

    # Non-compliance penalty (up to 10 points)
    days_silent = (timezone.now() - patient.last_transmission).days if patient.last_transmission else 30
    if days_silent >= 7:
        score += 10
    elif days_silent >= 4:
        score += 7
    elif days_silent >= 2:
        score += 3

    return min(score, 100)