Skip to main content

Rule types & applicator

Outcome

You know exactly what each rule type does, the order the applicator runs them in, and which combinations are safe vs. which produce surprising output.

Prerequisites

A working understanding of the editor (7.1 — The companion guide editor). Familiarity with X12 segment structure (9.2 — Segment cheat-sheet).

The four rule types

TypeWhat it doesMost common use
overrideReplaces the value of an element with a literal, a template, or a computed expression.Payer wants NM109 to carry their proprietary ID instead of NPI.
suppressRemoves a segment, loop, or element.Payer rejects a 2310 rendering provider when the rendering provider equals the billing provider.
appendInserts a new segment at a defined position.Payer requires a payer-specific K3 segment in 2300.
validateAsserts that an element / segment matches an expression; fails outbound generation if not.Payer's billing provider taxonomy must match a fixed set.

The applicator order

The applicator runs in a deterministic order so two guides producing overlapping rules give the same result every time:

Why this order:

  • Validate first — if the input is unfit, fail before mutating anything.
  • Suppress second — removing segments first means override / append selectors do not have to handle "may not exist".
  • Override third — operates on the surviving segments only.
  • Append last — newly inserted segments cannot themselves be validated / suppressed / overridden by the same guide.

Code reference: packages/x12/src/companion-guides/applicator.ts.

Selector syntax

All rules use the same selector grammar:

<segmentId>[<index>][.<elementIndex>][:<subElementIndex>]

Examples:

SelectorMatches
NM1Every NM1 segment in the transaction.
NM1[NM101=85]The NM1 whose first element equals 85 (billing provider).
NM1[NM101=85].NM109The 9th element of the billing-provider NM1.
CLM[loop=2300].CLM05:1The 1st sub-element of CLM05 in the 2300 loop.
2400.LX[1].SV1.SV101The first element of the SV1 in line 1 of loop 2400.

A selector that matches more than one segment applies to all matches (common for the 2400 loop where every line gets the same override).

Override values

Override values can be one of:

FormExampleMeaning
Literal"PRX"The literal string.
Template"{billingProvider.taxonomy}"A {path} reference into the source claim record.
Expression"upper({patient.lastName})"A small expression DSL — upper, lower, pad-left, slice, concat.

The full expression DSL is documented inline in applicator.ts as the evaluateValue function.

Validate expressions

Validate rules use the same expression grammar plus comparators:

OperatorExampleMeaning
eqeq({NM109}, "1234567890")Element equals literal.
matchmatch({NM103}, "^[A-Z]+$")Element matches regex.
oneOfoneOf({NM101}, ["IL", "QC"])Element is in set.
lenlen({NM103}) >= 1Length comparison.
and / or / notand(match({NM109}, "^\\d{10}$"), oneOf({NM108}, ["XX"]))Boolean composition.

Failed validations halt outbound generation with a structured error record that the operator can read on /transactions/:id.

Common patterns

Payer-specific provider ID

rule_type: override
location: 2010AA.NM1[NM101=85].NM109
value: "{billingProvider.payerSpecificId.UHC}"
note: UHC requires their proprietary submitter ID, not NPI.

Suppress redundant rendering provider

rule_type: suppress
location: 2310B
condition: "eq({billingProvider.npi}, {renderingProvider.npi})"
note: Some payers reject when rendering equals billing.

Append payer-required K3

rule_type: append
location: 2300.HI[*]+1
segment: K3*OHIODOH-PSC*0~
note: Ohio DOH requires a K3 carrying the program specifier.

Validate taxonomy

rule_type: validate
location: 2010AA.PRV[PRV01=BI].PRV03
expression: oneOf({PRV03}, ["171M00000X", "171R00000X", "183500000X"])
note: Anthem only accepts a fixed taxonomy set for IDD waiver claims.

Multi-guide composition

A trading partner can have multiple guides active at once (e.g. one for state Medicaid, one for the clearinghouse layered on top). The companion-guide-resolver in edi-gateway picks the active set based on effective dates; the applicator runs each guide's rule set in partner- declared order. Conflicts across guides resolve last-wins per location.

See apps/edi-gateway/src/service/companion-guide-resolver.ts.

Validation

CheckExpected
validate rules halt generation when they failYes — the transaction record carries the structured error.
suppress removes the segment everywhereYes — confirm via the live preview's "appliedRules" list.
override does not silently fail when the path does not existCorrect — a non-matching selector is logged and the rule is treated as SKIPPED.
Multi-guide order matches partner declarationYes — see the Resolver chain tab on the trading partner detail page.

Troubleshooting

SymptomCauseFix
Override applied to too many segmentsSelector is looseAdd a qualifier (e.g. NM1[NM101=85] instead of NM1).
Append produces a segment in the wrong orderPosition selector mis-spelledUse +1 to mean "after the matched anchor"; -1 for "before".
Validate expression always passesExpression has no comparison (e.g. just a path reference)Wrap in an explicit comparator like eq(…, …).
Rule has no effect at runtime but works in previewGuide's effective window does not include today, or the partner's resolver chain places another guide last that re-overridesInspect the resolver chain.

Next

7.3 — Versioning & cloning