Shared constraint helpers for the IHE profile pack.
Most IHE profiles (PAM, PIX, PDQ, LTW, RAD-SWF) share a common base set of MSH/EVN/PID requirements. This module composes those into reusable building blocks so each profile module stays declarative and focused on the transaction-specific rules.
These helpers are deliberately fine-grained. Profile modules pipe them together in whatever combination their transaction requires.
Summary
Functions
Requires EVN-2 (Recorded Date/Time). Used by all IHE ADT-based transactions.
Adds the IHE PAM/PIX MSH baseline — requires MSH-9/10/11/12 and forbids MSH-8 (Security), which IHE marks as "X" (not supported).
Custom rule: validates the IHE "PID-3 must have either namespace_id or universal_id" OR semantics that cannot be expressed with the declarative component DSL.
IHE patient identification baseline — requires PID-5 (Patient
Name), declaratively requires CX-1 (ID Number) for every PID-3
repetition via Profile.require_component/5, and adds a small
custom rule for the IHE Assigning Authority requirement
Pins PV1-2 (Patient Class) to a specific value. Used by IHE
transactions that operate outside a visit context (ITI-30 A28/A31,
ITI-10) where PV1-2 SHALL be "N" (Not Applicable).
Requires a specific segment AND a specific field within that segment in one call. Convenience for the common IHE pattern of "this transaction requires segment X, and within X field N must be populated".
Functions
@spec evn_core(HL7v2.Profile.t()) :: HL7v2.Profile.t()
Requires EVN-2 (Recorded Date/Time). Used by all IHE ADT-based transactions.
NOTE: EVN-1 (Event Type Code) is NOT forbidden. Although the HL7 v2.5.1 base marks it as "B" (backwards compat) and the IHE PAM TF recommends carrying the trigger in MSH-9 instead, real-world systems (Epic, Cerner Millennium, Meditech, most Spanish HIS products) still populate EVN-1 with the trigger event code. Forbidding it would flag conformant messages.
@spec msh_pam_core(HL7v2.Profile.t()) :: HL7v2.Profile.t()
Adds the IHE PAM/PIX MSH baseline — requires MSH-9/10/11/12 and forbids MSH-8 (Security), which IHE marks as "X" (not supported).
NOTE: MSH-14 (Continuation Pointer) is deliberately NOT forbidden here. ITI-9 PIX Query uses it for the continuation protocol; IHE PAM leaves it as "not used" (O) rather than strictly forbidden, and real-world wires from vendors occasionally populate it.
@spec pid3_assigning_authority_rule(HL7v2.TypedMessage.t()) :: [map()]
Custom rule: validates the IHE "PID-3 must have either namespace_id or universal_id" OR semantics that cannot be expressed with the declarative component DSL.
@spec pid_core(HL7v2.Profile.t()) :: HL7v2.Profile.t()
IHE patient identification baseline — requires PID-5 (Patient
Name), declaratively requires CX-1 (ID Number) for every PID-3
repetition via Profile.require_component/5, and adds a small
custom rule for the IHE Assigning Authority requirement:
- every non-empty CX carries CX-4 (Assigning Authority) with
either a
namespace_idOR auniversal_idpopulated
The CX-4 OR semantics cannot be expressed with require_component
alone (which checks a single subcomponent), so the rule is kept as
a custom closure — but it is now ~25 lines instead of ~60, since
CX-1 handling moved to the declarative DSL.
This is the single most common IHE constraint across PAM/PIX/PDQ/LAB/RAD-1.
@spec pin_patient_class(HL7v2.Profile.t(), String.t()) :: HL7v2.Profile.t()
Pins PV1-2 (Patient Class) to a specific value. Used by IHE
transactions that operate outside a visit context (ITI-30 A28/A31,
ITI-10) where PV1-2 SHALL be "N" (Not Applicable).
Sugar for Profile.require_value("PV1", 2, expected).
@spec require_segment_field(HL7v2.Profile.t(), String.t(), pos_integer()) :: HL7v2.Profile.t()
Requires a specific segment AND a specific field within that segment in one call. Convenience for the common IHE pattern of "this transaction requires segment X, and within X field N must be populated".