Skip to content

feat(COG-148): Add bulk lab order import from external reference lab - #19

Open
devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/COG-148-1774672949
Open

devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/COG-148-1774672949

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new bulk lab result import feature that accepts HL7 v2.5.1 ORU^R01 files (.hl7) or CSV files (.csv) from external reference labs (Quest, LabCorp, etc.), auto-matches results to pending lab orders, and queues unmatched results for manual review.

New files (20 changed):

  • REST endpoint: POST /v1/lab-results/import (multipart file upload), plus GET endpoints for import status, history, and unmatched results
  • Parsers: HL7ResultParser (HAPI v2.5.1) and CsvResultParser (flexible header aliases)
  • Service: LabResultImportService — orchestrates parsing, matching (by order number, then MRN+test code fallback), result creation, and provider notification
  • Domain: LabResultImport, UnmatchedLabResult entities with enums (ImportStatus, ReviewStatus)
  • DTOs: LabResultImportResponse, ParsedLabResult, UnmatchedLabResultDTO
  • Repositories: LabOrderRepository, LabResultRepository, LabResultImportRepository, UnmatchedLabResultRepository
  • Migration: V3__lab_result_import.sql — creates lab_result_imports and unmatched_lab_results tables
  • Dependencies: hapi-structures-v251

Updates since last revision

  • Replaced Page<UnmatchedLabResult> with Page<UnmatchedLabResultDTO> in controller/service to avoid LazyInitializationException from the @ManyToOne relationship to LabResultImport
  • Added deterministic ORDER BY lo.orderDateTime DESC to MRN+testCode fallback query so the most recent pending order is matched first
  • Added @Transactional(readOnly = true) at class level on LabResultImportService (follows PatientService pattern)
  • Removed unused commons-io dependency

Review & Testing Checklist for Human

  • No auth/authorization on controller — No @PreAuthorize or role-based access control on any of the import endpoints. Consistent with existing controllers, but verify this is acceptable given HIPAA requirements for importing external lab data.
  • Verify Flyway V3 migration against JPA entities — Confirm V2 exists and V3 column types/constraints align with entity definitions (especially BIGSERIAL/IDENTITY for ID generation, enum column string widths, nullable constraints). No integration tests validate this.
  • Synchronous import + single transaction — The entire importFile() runs synchronously in the request thread within a single @Transactional. Large files could cause request timeouts and long-held DB locks. Notifications are @Async, but the import itself is not.
  • MRN+testCode fallback now picks most recent order — When multiple pending orders match the same patient MRN + test code, the query now returns them ordered by orderDateTime DESC and the service picks the first (most recent). Verify this is the desired behavior vs. routing to unmatched queue when ambiguous.

Recommended test plan: Deploy to a dev environment, run the Flyway migration against the actual DB, then upload a sample .hl7 file and a sample .csv file via the POST /v1/lab-results/import endpoint. Verify matched results appear on the correct lab orders, unmatched results are queued and returned as DTOs via /import/unmatched, and the import history/status endpoints return correct data.

Notes

  • All 23 unit tests pass (6 HL7 parser, 10 CSV parser, 7 service). Tests are all mock-based — no integration tests against a real DB.
  • HL7 datetime parsing handles yyyyMMddHHmmss and yyyyMMddHHmm formats only; other HL7 timestamp variants (timezone offsets, fractional seconds) will silently result in null resultDateTime.

Link to Devin session: https://app.devin.ai/sessions/18dc2cfa1fe546ba9a3fb2495f448e6c
Requested by: @stephencornwell

- Add HL7 v2.5.1 ORU^R01 parser using HAPI library
- Add flexible CSV parser with column alias support
- Add import service with auto-matching to pending lab orders
- Add REST endpoint POST /v1/lab-results/import
- Add Flyway migration V3 for lab_result_imports and unmatched_lab_results tables
- Add domain entities, repositories, and DTOs
- Add unmatched results queue for manual review
- Add async provider notifications on result match
- Add audit logging via @AuditAccess
- Add 23 unit tests for parsers and import service

Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration Bot and others added 2 commits March 28, 2026 04:55
…ons-io dep

- Add @transactional(readOnly=true) at class level on LabResultImportService
  following PatientService pattern
- Remove unused commons-io dependency from pom.xml
- Add getUnmatchedCount convenience method

Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
- Replace Page<UnmatchedLabResult> with Page<UnmatchedLabResultDTO> in controller
  to avoid LazyInitializationException from ManyToOne relationship
- Add deterministic ORDER BY orderDateTime DESC to MRN+testCode fallback query
  so most recent pending order is matched first
- Create UnmatchedLabResultDTO to flatten entity for API response

Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant