Product EngineeringFeaturesCritical CalloutBackend

CriticalReport Proxy

The CriticalReport Django proxy — parameter evaluation, email notification, single-report notify flow, and ES sync.

👤 Sachin Sharma📅 Updated: Apr 29, 2026🏷️ feature🏷️ backend🏷️ proxy

CriticalReport Proxy

File: report/proxies/critical_reports.py

CriticalReport is a Django proxy model that extends both LabReportRelation and AbstractEmail. It does not add DB columns — it adds behaviour on top of the existing LabReportRelation row.

class CriticalReport(LabReportRelation, AbstractEmail):
    category_id_mapper = {"critical_notification": 648}
    class Meta:
        proxy = True

Method overview

MethodPurpose
get_critical_notification_setting()Reads critical_notification_settings from Preferences (cached per lab)
get_critical_report_params()Evaluates each parameter against normal + critical bounds. Returns only critical parameters
process_list_field()Handles qualitative/list-type parameters — checks defaultDescription for is_critical == 2 flag
notify_by_email()Assembles recipient list, renders Jinja template, calls send_email()
notify_organisation_by_email()Org-specific email using CommunicationVariant if configured, falls back to orgEmail
notify()Single-report callout — sets status to CALLOUT_DONE, saves callout record, logs activity
prepare_message()Builds human-readable text for the activity log
prepare_activity_log_dumped_json()Builds structured JSON for ActivityLog.dumped_json
save_critical_callout()Thin delegate to CriticalCallout.save_critical_callout()
after_save()ES sync — pushes criticalValues + lastUpdated to patient_reports index

Parameter evaluation

get_critical_report_params() is the core logic that determines which parameters in a report are in the critical range. It is called both for single-report notify and for the bulk manager's batch fetch.

Normal range check: lower_bound <= val <= upper_bound → skip (normal)

Critical range check: critical_lower <= val <= critical_upper → skip (abnormal but not critical)

If neither check passes, the parameter is critical.

Age and sex-aware bounds

When reportID.ageFlag is true, ValueRanges records are fetched filtered by lowerAge < patient.age <= upperAge. Matching age ranges override the format's bound fields before evaluation.

Bounds are gender-specific:

  • lowerBoundMale / upperBoundMale / criticalLowerMale / criticalUpperMale
  • lowerBoundFemale / upperBoundFemale / criticalLowerFemale / criticalUpperFemale

Output per parameter

{
    "value": 75.0,
    "parameter_name": "WBC Count",
    "reference_range": "100.0 - 200.0",
    "critical_lower_bound": 50.0,
    "critical_upper_bound": 250.0,
}

Email notification

notify_by_email()

Builds the recipient list from the callout payload flags:

FlagRecipient email
is_referralbill.docId.docEmail
is_patientuserDetailsId.email
other.enableother.email
is_organizationorgId.orgEmail (comma-separated) or via CommunicationVariant

HIPAA mode (show_patient_name=True): patient name is appended to the email subject.

share_comment setting: comment is passed into the Jinja template only if the lab setting is on.

Email subject for single-report callout:

Critical Results Alert from {lab_name} for Accession Number {accession_no}

The subject is overridden by the bulk manager when called from BulkCriticalCalloutManager.trigger_email():

Critical Results Alert from {lab_name} for Order ID - {labBillId}

notify_organisation_by_email()

If the organisation has a CommunicationVariant configured for EMAIL_TRIGGERS.ORGANIZATION_CRITICAL_CALLOUT, it uses that variant's custom subject and template. Otherwise falls through to orgEmail in the main flow.


Single-report notify() flow

notify() is the legacy single-report path. The bulk manager bypasses it and calls notify_by_email() directly.


after_save() — ES sync

Called automatically by the Django model save() hook. Updates the patient_reports Elasticsearch index for the saved report:

client.update_by_query(
    index="patient_reports",
    filters={"bool": {"filter": [
        {"term": {"labReportId": self.labReportId}},
        {"term": {"labId": self.labId_id}},
    ]}},
    payload={
        "criticalValues": self.criticalValues,
        "lastUpdated": "<ISO timestamp>",
    },
)

This keeps the worklist's Elasticsearch data in sync after every single-report status change. For bulk callouts, BillSplitManager.sync_lab_reports() handles the full bill-level sync.

On this page