Product EngineeringFeaturesCritical CalloutBackend

ES Sync & Activity Log

Elasticsearch sync strategy and ActivityLog structure for critical callout.

👤 Sachin Sharma📅 Updated: Apr 29, 2026🏷️ feature🏷️ backend🏷️ elasticsearch🏷️ activity-log

ES Sync & Activity Log


Elasticsearch sync

Callout status changes must be reflected in the patient_reports Elasticsearch index because the worklist and all waiting lists read from ES, not the DB directly.

Two sync paths exist depending on the callout path taken:

CriticalReport.after_save()

Called by the Django save hook after every single-report status change (via notify()).

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>",
    },
)

Updates only the two fields that the worklist and badge logic depend on.

BillSplitManager.sync_lab_reports()

Called after every bulk callout (process_callout()). Syncs the full bill — all reports — to ensure the ES index reflects the latest state after bulk_update. This is a broader sync than after_save() and covers the case where multiple reports change status simultaneously.


Activity Log

Every callout action (draft or done) writes one ActivityLog record with logCategoryId=648.

Activity text format

Callout done|Attempted by - <performed_by>,
Callout for - <test1, test2>,
Method - <Email, Fax>,
Recipients - <Organization, Referral>,
Comment - <comment or ->

Example:

Callout done by - Dr. Smith, Callout for - WBC Count, HB, Method - Email, Recipients - Organization, Comment - Informed the doctor

dumped_json structure

dumped_json carries the machine-readable version of the same information, parsed by the frontend to render the history timeline:

{
  "bill_id": 1234,
  "lab_report_ids": [101, 102],
  "callout_for": ["WBC Count", "HB"],
  "method": "Email",
  "callout_done_by": "Dr. Smith",
  "recipients": "Organization",
  "comment": "Informed the doctor",
  "is_draft": true,                   // present only for Attempted entries
  "organization": {
    "name": "City Hospital",
    "email": "city@hospital.com",
    "fax": ""
  },
  "referral": {
    "name": "Dr. Jones",
    "email": "jones@clinic.com",
    "fax": "123456"
  },
  "patient": {
    "name": "Jane Doe",
    "email": "jane@example.com",
    "contact": "9999999999"
  },
  "other": {
    "name": "Nurse Patel",
    "email": "",
    "fax": "",
    "contact": "8888888888"
  }
}

is_draft is only present in the JSON when the callout was Attempted — its absence means Callout Completed. The frontend uses this to choose the icon and title in the VerticalTimeline.

Log record fields

FieldValue
log_category_id648
lab_idSession lab ID
bill_idThe order ID
lab_report_idFirst report in the selection (used for log indexing)
lab_user_namesession.labUserName or session.docName
lab_user_idsession.loginUser
tokenSession token

On this page