ServicesCrelio AppArchitectureApp Modules interfacing
Lab device integration, HL7/ASTM parsing, and result validation
- Device management - Lab analyzer configuration
- Result parsing - HL7/ASTM message parsing
- Result validation - Manual/auto review workflow
- Format mapping - Device code to test mapping
- QC integration - Quality control data
core/ - BaseModel, utilities
admin/ - Tests, departments, labs
report/ - Lab reports for result assignment
finance/ - Billing for result context
- External vendor APIs (belongs in
integration/)
- Report rendering (belongs in
report/)
- Sample collection (belongs in
accession/)
| Model | Responsibility | Lines | Key Fields |
|---|
Device | Analyzer configuration | 57772 | name, type, connection, lab_id |
DeviceResultsValidation | Result review workflow | 3338 | sample_id, parameter_code, value, status |
DeviceFormatMapping | Code translation | 11029 | device_code, test_id, format_id |
DeviceTestMapping | Test association | 6526 | device_id, test_id, machine_code |
DeviceQcResultsValidation | QC workflow | 15452 | QC-specific validation |
Key Methods:
| Method | Purpose | Lines |
|---|
save_device_results() | Store incoming results | 76-278 |
get_device_wise_results() | Dashboard summary | 280-462 |
get_device_results() | Fetch pending results | 464-565 |
release_parameters() | Release to reports | 567-803 |
release_tox_parameters() | Toxicology release | 805-1057 |
post_process_report() | Auto-sign logic | 1117-1194 |
sign_or_save_report() | Report signing | 1196-1302 |
Result Flow:
Purpose: Translate device-specific codes to internal test/parameter IDs.
| Method | Purpose |
|---|
get_mapping() | Lookup by device code |
create_or_update_mapping() | Configure translation |
validate_mapping() | Check consistency |
Device integration is complex:
- Multiple message formats (HL7, ASTM, proprietary)
- Two-phase validation (receive → validate → release)
- Post-processing rules (auto-sign, auto-approve)
- QC integration
All logic must be traceable for regulatory compliance.
| Status | Meaning | Next Action |
|---|
PENDING | Awaiting review | Manual validation |
VALIDATED | Reviewed, ready to release | release_parameters() |
RELEASED | Assigned to report | View report |
REJECTED | Rejected during review | Investigate/rerun |
| Rule | Enforcement |
|---|
| Unique device code per lab | DB constraint |
| Valid format mapping required | Validation before release |
| QC values within control limits | DeviceQcResultsValidation |
# Get pending validation results
DeviceResultsValidation.objects.filter(
device_id=device_id,
lab_id=lab_id,
status="PENDING",
received_date__range=(from_date, to_date)
).select_related(
"device",
"lab_report_relation"
).order_by("-received_date")
# interfacing/models/device_results_validation.py
@classmethod
def release_parameters(cls, lab_details, device_id, parameters):
"""Atomic release of validated parameters"""
with transaction.atomic():
# Update validation records
for param in parameters:
validation = cls.objects.get(pk=param["id"])
validation.status = "RELEASED"
validation.save()
# Update lab report
report = LabReportRelation.objects.get(pk=param["report_id"])
report.update_value(param["value"])
report.save()
# Post-processing
cls.post_process_report(report_detail, logs, lab_details)
| Endpoint | View | Purpose |
|---|
GET /interfacing/devices | DeviceListView | List lab devices |
GET /interfacing/results/pending | PendingResultsView | Validation queue |
POST /interfacing/results/release | ReleaseView | Release to reports |
POST /interfacing/results/save | SaveResultsView | Receive from device |
GET /interfacing/qc/results | QcResultsView | QC data |
class ReleaseParametersView(GenericView):
@transaction.atomic
def post(self, request, device_id, *args, **kwargs):
lab_details = {
"lab_id": self.get_lab_id_from_session(request.session),
"session": request.session,
...
}
DeviceResultsValidation.release_parameters(
lab_details=lab_details,
device_id=device_id,
parameters=request.data.get("parameters", [])
)
return JsonResponse({"status": "success"})
| Protocol | Handler | Direction |
|---|
| HL7 v2.x | HL7 parser | Inbound |
| ASTM | ASTM parser | Inbound |
| TCP/IP | Socket handler | Bidirectional |
| File watch | File processor | Inbound |
# interfacing/models/device_results_validation.py
@classmethod
def post_process_report(cls, report_detail, logs, lab_details):
"""Apply lab-specific post-processing rules"""
post_process_type = lab_details.get("post_process_type")
if post_process_type == "SIGN_AUTOMATICALLY":
cls.sign_or_save_report(report_detail, is_sign=True, ...)
elif post_process_type == "SAVE_AND_NOTIFY":
# Save and trigger notification
...
| Import | Used For | Risk |
|---|
report.models.lab_report_relation | Report updates | High |
finance.models.billing | Bill context | Medium |
admin.masters.models.all_tests | Test mapping | Low |
admin.account.models.departments | Access control | Low |
[!WARNING]
DeviceResultsValidation has high coupling to report app. Changes to report structure require corresponding updates here.
| Table | Volume | Indexes Needed |
|---|
deviceResultsValidation | Very high | device_id, status, received_date |
deviceFormatMapping | High | device_id, machine_code |
device | Low | Lab-indexed |
# Use bulk operations for release
DeviceResultsValidation.objects.filter(
id__in=parameter_ids
).update(status="RELEASED")
- Result parsing can be async via Fusion
- Post-processing should be atomic
- QC calculations can be batched
- Add device configuration to
Device model
- Create parser in
device_parser.py
- Add format mappings
- Test with sample messages
- Add rule type to
post_process_type choices
- Handle in
post_process_report():
elif post_process_type == "NEW_RULE":
cls.handle_new_rule(report_detail, ...)
- Extend
DeviceQcResultsValidation
- Add validation logic
- Update QC dashboard
- Atomic transactions for release/sign
- Log all device communications
- Validate mappings before release
- Use bulk updates for performance
- Synchronous parsing in request path
- N+1 queries in result lists
- Skipping format validation