Skip to main content

Gateway architecture for EDI staff

You will rarely need to dive into the internals — the operator-facing UIs cover almost every workflow. But knowing how the pieces fit together makes "the platform did X for me" debuggable rather than mysterious.

The pieces

Components in plain English:

ComponentWhat it does
rcm-core / rcm-appThe billing / clinical platform. When a claim, eligibility check, or auth needs to go out, they publish an event; they do not call the gateway directly.
Service BusAzure Service Bus. Carries claim.submission_queued, eligibility.sweep_queued, auth.request_queued, and the inbound dispatch counterparts.
ConsumersSmall services inside edi-gateway that subscribe to specific event topics. One consumer per event class.
edi-gatewayThe HTTP service that hosts the consumers, the admin API, and the transport workers.
packages/x12Pure functions for generate / parse of every transaction set. No I/O. Easy to test in isolation.
Companion guide applicatorLoads guides bound to the partner + transaction; applies rules at generate-time and validates inbound shapes.
Control number managerAllocates ISA13, GS06, ST02 per partner per direction. Strictly monotonic; survives restarts.
Transport workersOne per partner: SFTP poll loop, AS2 push/pull, real-time HTTP client.
Response processorPicks up inbound files, parses, dispatches to the right rcm-core endpoint or auth/claim status updater.
edi-app UIThe web app you're using. Calls edi-gateway's admin API.

A claim's outbound journey

Key facts:

  • Event-driven, not request-response. rcm-core publishes; the gateway consumes. There is no synchronous call from rcm-core to the gateway.
  • Fail-and-retry. A failed transport, parser, or generator step raises a _failed event. The originating claim / auth stays in the pre-submit state until a retry succeeds. This means partial runs are safe — you can re-queue without producing duplicates.
  • Control numbers come from the gateway. rcm-core never picks an ISA13. The gateway's manager guarantees monotonic-per-partner.

An ack's inbound journey

Key facts:

  • Correlation is critical. Every inbound must map back to an outbound. Failed correlation puts the inbound in quarantine for manual handling.
  • Multiple acks per outbound. A single 837 produces a TA1, a 999, and a 277CA. Each runs through the same response-processor cycle independently; each updates the source claim's status with its outcome.

Where transactions are stored

Two tables matter:

TableHolds
billing.edi_transactionOne row per transaction (inbound or outbound). Includes the raw envelope, parsed structure, status, control numbers, correlation ID.
billing.edi_batchOne row per batch (typically one per cron tick per partner). Each batch references many transactions.

The transaction record is immutable once written — replays produce new records. This means audit history is complete by construction.

Where companion guides are stored

TableHolds
edi.companion_guideOne row per guide version. The active set is resolved by (partner_id, transaction_set_id, effective_from).
edi.companion_guide_rulePer-rule data — type, location, value, condition.

The applicator loads the active set at generate time; rules are not compiled into the generator code.

What you cannot reach from edi-app

The operator UI gives you almost everything. Things that are deliberately hidden:

CapabilityWhere it lives
Service Bus topic / subscription managementAzure portal — platform admin's job.
Control number resetDB-only operation, requires platform admin. Reserved for partner-side migrations.
Adding a new transaction set (e.g. 820)Code change in packages/x12; not configurable.
Database queries on billing.edi_transactionTenant-isolated; reachable via the rcm-core API only.

Next

1.3 — Page tour of the edi-app