feat(mapper): map SIU scheduling messages to FHIR Appointments - #19
Merged
Conversation
Collaborator
Author
|
Rebased onto the regenerated SDK: interbox#112 now adds the scheduling segments by regenerating the HL7v2 surface with Still green against a locally built SDK: |
The v2-to-fhir sample handled ADT, ORU, ORM and VXU, so a scheduling feed had nowhere to land: every SIU message failed with unsupported/message_type. Route them all through one converter — every SIU trigger event uses the SIU_S12 structure — producing an Appointment plus the Patients, Practitioners and Locations it references, each emitted once even when several resource groups name the same room or clinician. Decisions worth knowing: - The Appointment id comes from SCH-2 (filler), so the booking (S12), its modifications (S13/S14) and its cancellation (S15) update one resource instead of piling up. SCH-3 is included for recurring appointments. - SCH-25 decides the status when it maps to table 0278; otherwise the trigger event does (S15 cancelled, S17 entered-in-error, S26 noshow, …). Neither usable is field/unknown_appointment_status rather than a guess. - Timing prefers TQ1, then SCH-11.4, then SCH-11.1, then AIS-4. That third step is for v2.4 senders like MEDITECH, which put the datetime in the TQ quantity and never populate TQ.4; a value that isn't at least a full date is ignored so a genuine TQ occurrence count is never read as a start. - No Encounter: ADT owns those, as in ORM_O01. No Device/HealthcareService for AIG either, so equipment resource groups are skipped. Needs the scheduling segment accessors added in interbox#78, so the SDK dependency has to be bumped before this lands. Refs HealthSamurai/interbox#78 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The SDK now generates the scheduling segments (HealthSamurai/interbox#112) instead of shipping the hand-written module this branch was first written against, and the codegen names a few fields differently: SCH-10 appointmentDurationUnit, SCH-25 fillerStatus, AIS-3 service, AIS-4 start, AIS-8 durationUnit, AIL-4 locationTypeAil. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The SIU mapper reads SCH/RGS/AIS/AIL/AIP, which the SDK only exports from 1.12.1 (HealthSamurai/interbox#112). The dependency was still ^1.0.0, so a workspace on an older SDK would fail to typecheck with no hint why. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ipasechnikov
force-pushed
the
feat/siu-support
branch
from
August 6, 2026 09:14
0c51efe to
7fd19cf
Compare
ipasechnikov
marked this pull request as ready for review
August 6, 2026 09:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mapper half of HealthSamurai/interbox#78.
Draft on purpose: this needs the scheduling segment accessors from
HealthSamurai/interbox#112, so CI here fails typecheck until that is merged,
released, and the SDK dep pinned to it. See Merge order below.
Why
The
v2-to-fhirsample handled ADT, ORU, ORM and VXU, so a scheduling feed hadnowhere to land: every SIU message failed with
unsupported/message_type.What
One converter serves every SIU trigger event — S12 through S26 all use the
SIU_S12 message structure — and reads the event only to infer a status when SCH-25
does not give one.
Emits, per message:
Each referenced resource is emitted once even when several RGS groups name the
same room or clinician, and every
Appointment.participant.actorresolves insidethe same bundle.
New files:
messages/siu-s12.ts,segments/sch-appointment.ts,segments/ail-location.ts;appointmentIdFromSchadded tosupport/identity.ts;routing added in
index.ts.Decisions worth reviewing
the SIU sender and keeps that ID stable, so the booking (S12), its
modifications (S13/S14) and its cancellation (S15) update one Appointment
instead of piling up. SCH-3 is included because a recurring appointment repeats
one ID pair per occurrence.
the appointment's status; the event only names the kind of notification, so an
S14 carrying a "Cancelled" filler status is cancelled. Fallbacks: S15/S16/S23 →
cancelled, S17 → entered-in-error, S24/S26 → noshow, S12/S13/S14/S18–S22 →
booked. Neither usable raises
field/unknown_appointment_statusrather thanguessing.
is for v2.4 senders like MEDITECH, which put the appointment datetime in the TQ
quantity component and never populate TQ.4 — reading only TQ.4 loses the
appointment time for all of that traffic. Guarded to require at least a full
date, so a genuine TQ occurrence count (or a month-precision value) is never
read as a start. Duration comes from SCH-9/10, falling back to AIS-7/8, with
unit conversion; the end is computed when not sent.
ORM_O01draws — and R4 links thetwo from
Encounter.appointment, not the other way.HealthcareService participants, which this mapper does not produce. Same
boundary the ave-parser reference draws.
DELETEfor appointment deletion; interbox's sender only upserts, so S17 arrives as
status: entered-in-error. Flagging in case you want deletion handleddifferently.
Tests
test/siu.test.ts, 12 cases: a real-shape MEDITECH v2.4SIU^S12end to end(ids, timing, serviceType, participants, notes, reference integrity); S12→S15
landing on one Appointment; SCH-25 vs trigger-event status resolution; two
resource groups sharing a clinician and repeating AIL-3; a blocked-slot S23 with
no PID; non-minute duration units; AIS-only timing; a TQ count not mistaken for a
datetime; day-precision timing; the SIU shape
utils/hl7v2-simulatoremits; andthe four domain errors (
missing_sch,missing_appointment_id,missing_appointment_participant,unknown_appointment_status).Merge order
interbox pin 1.13.0) — CI goes green🤖 Generated with Claude Code