Patient Management
Vantrexia provides a comprehensive patient management system that is fully FHIR R4 compliant, with all protected health information (PHI) encrypted at the field level using AES-256. Patients can be created manually, imported from eClinicalWorks, or enrolled through the API — and every operation is audit-logged for HIPAA compliance.
The patient data model maps directly to the FHIR R4 Patient resource. Every patient record can be serialized to and from a valid FHIR Patient JSON resource, enabling interoperability with any FHIR-capable system.
Manual Patient Creation
Authorized users (Admin, Clinician, Staff) can create patients directly through the dashboard or API. The creation form collects FHIR-compliant demographics, contact information, and the medical record number (MRN).
Patient Fields
| Field | FHIR Mapping | Encrypted | Required | Description |
|---|---|---|---|---|
| First Name | name[0].given[0] |
Yes (AES-256) | Yes | Patient's legal first name |
| Last Name | name[0].family |
Yes (AES-256) | Yes | Patient's legal last name |
| Date of Birth | birthDate |
Yes (AES-256) | Yes | ISO 8601 date format (YYYY-MM-DD) |
| Gender | gender |
No | Yes | FHIR values: male, female, other, unknown |
| MRN | identifier[mrn] |
Yes (AES-256) | Yes | Medical Record Number — unique within the practice |
| Phone | telecom[phone] |
Yes (AES-256) | No | Primary contact phone number |
telecom[email] |
Yes (AES-256) | No | Patient's email address | |
| Street Address | address[0].line |
Yes (AES-256) | No | Street address line(s) |
| City | address[0].city |
Yes (AES-256) | No | City name |
| State | address[0].state |
No | No | Two-letter state abbreviation |
| ZIP Code | address[0].postalCode |
Yes (AES-256) | No | 5-digit or ZIP+4 format |
curl -X POST /api/v1/patients/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Doe",
"date_of_birth": "1965-03-15",
"gender": "female",
"mrn": "MRN-2026-001042",
"phone": "+15551234567",
"email": "jane.doe@example.com",
"address": {
"line": ["123 Main Street", "Apt 4B"],
"city": "Springfield",
"state": "IL",
"postal_code": "62704"
}
}'
All fields marked as "Encrypted" in the table above are stored using AES-256 encryption via django-encrypted-model-fields. The encryption key is derived from the FIELD_ENCRYPTION_KEY environment variable and is never stored in the database. Encrypted fields cannot be queried directly — use the search API for patient lookup.
Importing from eClinicalWorks
Vantrexia integrates directly with eClinicalWorks (eCW) via the FHIR R4 API to import and synchronize patient records. The integration supports four import modes:
Bulk Sync
Downloads all active patients from eCW and creates corresponding records in Vantrexia. Used for initial setup or full resynchronization. The bulk sync runs as a background Celery task and processes patients in batches of 50 to avoid API rate limits.
curl -X POST /api/v1/integrations/ecw/sync/bulk/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"mode": "full",
"batch_size": 50,
"notify_on_complete": true
}'
# Response:
{
"task_id": "celery-task-abc123",
"status": "queued",
"estimated_patients": 1250,
"message": "Bulk sync queued. You will be notified on completion."
}
Delta Sync
Fetches only patients modified since the last sync timestamp. Scheduled to run automatically every hour via Celery Beat. Delta sync is the primary mechanism for keeping Vantrexia in sync with eCW during normal operations.
Single Patient Import
Import a specific patient by their eCW patient ID or FHIR resource ID. Useful for on-demand imports when a clinician needs to add a specific patient to RPM monitoring.
Conflict Resolution
When a sync detects that a patient already exists in Vantrexia (matched by MRN or external identifier), the system applies the following conflict resolution strategy:
| Field | Strategy | Rationale |
|---|---|---|
| Demographics (name, DOB, gender) | eCW wins | EMR is the authoritative source for patient identity |
| Contact info (phone, email) | eCW wins | Patients typically update contact info at the front desk |
| Address | eCW wins | EMR is the authoritative source for mailing address |
| RPM-specific fields (thresholds, devices) | Vantrexia wins | RPM configuration is managed within Vantrexia |
| Clinical notes from eCW | Merged (append) | Clinical context from eCW supplements RPM-specific notes |
Monitor sync status on the Dashboard activity feed or via GET /api/v1/integrations/ecw/sync/status/. The response includes the last sync timestamp, records processed, records created, records updated, and any errors encountered.
Patient Archival
Vantrexia uses HIPAA-compliant soft deletion for patient archival. Archived patients are not permanently deleted — they are marked as inactive and excluded from active queries, but their data is retained for the legally required retention period.
Initiate Archival
An authorized user (Admin or Clinician) initiates archival from the patient detail view or via the API. A reason must be provided — common reasons include: patient deceased, discharged from RPM, transferred to another provider, or patient request.
Confirmation Required
The system displays a confirmation dialog showing the impact of archival: active billing records that will be finalized, pending alerts that will be closed, and device assignments that will be released. The user must explicitly confirm.
Soft Delete Executed
The patient's active field is set to False, archived_at is timestamped, archived_by records the user, and archive_reason stores the provided reason. All related data (observations, alerts, billing records) is preserved but excluded from active queries.
Retention Period
Archived patient data is retained for a minimum of 6 years from the date of archival (or longer based on state regulations). After the retention period expires, a scheduled task flags the record for permanent deletion review by an administrator.
curl -X POST /api/v1/patients/{patient_id}/archive/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"reason": "Patient discharged from RPM program per physician order",
"finalize_billing": true,
"release_devices": true
}'
Archived patients can be restored to active status by an administrator using POST /api/v1/patients/{patient_id}/restore/. The restoration action is audit-logged and requires a justification reason. Device assignments will need to be reconfigured after restoration.
External Identifier Architecture
Vantrexia uses a generic ExternalIdentifier model to link patients to their records in external systems. This architecture supports any EMR, not just eClinicalWorks — making the platform extensible to future integrations.
class ExternalIdentifier(models.Model):
"""
Links a Vantrexia patient to their record in an external system.
Supports multiple external systems per patient.
"""
patient = models.ForeignKey(
Patient, on_delete=models.CASCADE, related_name='external_identifiers'
)
system = models.CharField(
max_length=100,
help_text="Identifier system URI (e.g., 'eclinicalworks', 'epic', 'cerner')"
)
value = models.CharField(
max_length=255,
help_text="The patient's ID in the external system"
)
type = models.CharField(
max_length=50,
choices=[
('MR', 'Medical Record Number'),
('PT', 'Patient ID'),
('FHIR', 'FHIR Resource ID'),
('SS', 'Social Security Number'),
('DL', 'Driver License'),
],
default='PT'
)
is_primary = models.BooleanField(
default=False,
help_text="Whether this is the primary identifier for the external system"
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
unique_together = ['patient', 'system', 'value']
indexes = [
models.Index(fields=['system', 'value']),
]
This design allows a single patient to have identifiers in multiple external systems. For example, a patient imported from eClinicalWorks would have:
| System | Type | Value | Primary |
|---|---|---|---|
eclinicalworks |
PT | ECW-PT-58291 |
Yes |
eclinicalworks |
FHIR | Patient/fhir-abc-123 |
No |
vantrexia |
MR | MRN-2026-001042 |
Yes |
Search & Filtering
Because PHI fields are encrypted at rest, Vantrexia provides a dedicated search API that decrypts and matches against patient records server-side. The search supports the following query parameters:
| Parameter | Type | Description |
|---|---|---|
q |
string | Free-text search across name, MRN, phone, and email (encrypted fields decrypted server-side) |
status |
enum | Filter by patient status: active, archived, all |
risk_level |
enum | Filter by triage risk level: critical, warning, normal, no_data |
assigned_to |
UUID | Filter by assigned clinician ID |
has_device |
boolean | Filter to patients with at least one connected device |
non_compliant |
boolean | Filter to patients who have missed 2+ consecutive transmission days |
created_after |
date | Filter to patients created after this date (ISO 8601) |
page / page_size |
integer | Pagination controls (default page size: 25, max: 100) |
curl -X GET "/api/v1/patients/?q=jane+doe&status=active&risk_level=warning&page=1" \
-H "Authorization: Bearer <token>"
# Response:
{
"count": 2,
"next": null,
"results": [
{
"id": "uuid-abc-123",
"first_name": "Jane",
"last_name": "Doe",
"mrn": "MRN-2026-001042",
"gender": "female",
"status": "active",
"risk_level": "warning",
"risk_score": 62,
"active_alerts": 3,
"last_transmission": "2026-02-06T10:15:00Z"
}
]
}
Encrypted field search operates in O(n) time because each record must be decrypted for comparison. For practices with fewer than 5,000 patients, this completes in under 500ms. For larger datasets, consider using the MRN or external identifier lookups which use indexed, non-encrypted columns for faster retrieval.