MDClarity · Pipeline explainer
How RIA's scheduled pipelines work
RIA runs two MDClarity products on two very different rhythms against its Abbadox radiology system: a continuous, every-minute ClarityFlow patient-access loop (benefits, estimates, GFE letters, bidirectional HL7) and a monthly RevFind underpayment-recovery pass over billing files from MSN LLC.
Cadence · 01
Three Windows Scheduled Tasks under \MDC\ on WORKER-1, at three
wildly different frequencies. The HL7 loop is the surprise: its 00:01 is only a daily
anchor — a PT1M repetition runs it every minute for a full day, so it
effectively polls Abbadox around the clock.
Pipeline 1 · continuous · every minute · ClarityFlow
The main patient-access loop, and RIA's near-real-time interface to Abbadox. The
scheduled task HL7 - Processing - RIA fires every minute, all day
(<Repetition><Interval>PT1M</Interval><Duration>P1D</Duration>),
self-throttled by MultipleInstancesPolicy=IgnoreNew so a slow run never overlaps the next
tick. Each tick runs three sequential actions: the pipeline, then two PowerShell scripts that
finish and ship the outbound letters.
Flow-HL7-Processing
Flow-HL7-Processing.yaml
-
downloadDownload inbound HL7Abbadox SFTP
/Outbound/→{HL7Directory}Pulls ADT / SIU / ORM / DFT / ORU messages; deletes remote on success. This is the poll that fires every minute. -
load_hl7_filesLoadHL7FilesHL7 files →
HL7Archive+HL7*staging tablesAllowed types: ADT (A01/03/04/08/09/10/28/31), SIU (S12–S26), DFT^P03, ORM^O01. Archives files to{HL7Archive}. -
SQLHL7ProcessLog + HL7DeltaOpens a process-log row & computes the delta of changed messages to process
-
▶Flow-HL7-Transform— shape raw HL7 into Transform* tables · 15 SQL steps
- TruncateVisitDelta → reset delta
- TransformVisitIDMap · OrderSourceIDDelta → map source IDs / orders
- ImportHL7ADTCombined → consolidate ADT
- TransformPatient → TransformPatient
- ImportTransformPatientInsurance + merge into VisitDelta
- ImportTransformVisit + merge VisitDelta
- ImportTransformVisitInsurance + merge
- Recalculate Changed Bundles
- ImportTransformVisitCharge + merge
-
LoadPatientsLoadPatients
TransformPatient→Patient(upsert by PatientID)RIA-specific: forcesElectronicCommunicationConsent = 1("Per RIA") and derivesPreferredPhonefrom cell → home. -
▶Flow-HL7-Processing-Load-Entities— Facility, Provider, InsuranceMap
- Load Facility
- Load Provider (SQL)
- Load InsuranceMap → maps source payer names to MDClarity insurances
-
▶Flow-HL7-Processing-LoadDimensionMembers— refresh 15 reporting dimensions
- LoadInsuranceDimensionMembers → Insurance / QuoteInsurance / EligibilityInsurance
- Provider · Facility · VisitType · VisitStatus · Time · State
- Diagnosis Code · Modifier · Place of Service · SourceInsurance
- RadioIsotopes Code Dimension ← radiology-specific
-
▶Flow-HL7-Processing-LoadVisits— the estimation core: bundle · benefits · price · letters · sync · 20+ steps
- Load TempBatchVisit · Augment Visit Delta (SQL) → stage prospective visits
- ReprocessChangedConfigurations → queue visits hit by config changes
- LoadVisitBatch → VisitBatch / QuoteBatch
- AutoApplyBundlesToVisitBatch → swap in bundle charges, make quotes
- CheckBenefits → external eligibility API (billable)
- Re-Check Benefits · AutoApplyBenefits → apply copay/deductible/coinsurance
- CalculateVisits → compute patient responsibility
- LogVisitChangeEventsBatch → diff batch vs prod
- CheckVisitGFEComplianceBatch → GFE due-date / resend status
- Update Patient Email for Commercial Insurance · Load-CustomProperty-CoverageStatus
- AutoSendLetters → estimate/GFE letters for batch visits
- AutoSendLettersForFutureVisits → upcoming visits
- SyncBatch → promote *Batch tables to production Visit/Quote/…
- ExportBatchVisitEligibility · SearchForInsurance
- Generate-Report · Flow-HL7-Processing-LoadVisitFact · Update-Dashboard-Tables
-
SQLUpdate HL7ProcessLogCloses out the process-log row for this run
-
workqueue_assignmentWorkqueueAssignmentPopulate user workqueues from
WorkqueueAssignmentCriteria -
send_hl7SendHL7LettersUnsent letters → ORU^R01
.txt+ PDF written toD:\ClientData\RIA\ORUReceiving appAbbadox/ facilityRIA. These files are then finished & shipped by Actions 2–3 below. -
execute_processGenerate and send ORMs
D:\ClientData\RIA\OutboundORM\py.bat→generateORMs.pyIndependent outbound path (see Outbound ORM generator): coverage-verifiedORM^O01orders → Abbadox/Inbound.
Convert-Hl7PdfLinkToEmbeddedWithOrderID.ps1
-
scriptEmbed PDF + rewrite OrderID
ORU\→ORU\Processed\(archives originals →Processed/Archive/Error)For each ORU: reads the PDF linked inOBX.5, base64-embeds it as encapsulated data, and replaces the internalSourceIDinPV1.19with the real AbbadoxOrderIDlist (looked up inTransformOrderSourceIDMap).
winscpExport.ps1
-
scriptSFTP upload ORU letters
ORU\Processed\*→ Abbadox SFTP/InboundSuccessful uploads move toORU\Success\; failures logged tosftp_upload_errors.txt.
Pipeline 2 · daily @ 19:01 · ClarityFlow
A single-task job that runs once a day at 19:01 to send estimate/GFE letters for
upcoming appointments — the forward-looking counterpart to the continuous loop, which
explicitly yields to it. (One trigger, no repetition; the PT8H on it is a max-runtime cap,
not an interval.)
Flow-HL7-Processing-AutoSendLettersForFutureVisits
-
auto_send_letters_for_future_visitsAutoSendLettersForFutureVisitsQueries live future
Visits (ScheduledTime > now) →PatientLetter+ send eventsSends only when the visit is calculated, benefits are applied, and the patient has consent + valid contact. Shares the AutoSendLetters core, but reads live visits instead of the batch table.
Pipeline 3 · monthly, 15th @ 07:30 · RevFind
The underpayment-recovery side, entirely separate from the HL7 flow. Despite the job name
(Daily-Processing-RevFind), the trigger is monthly on the 15th — one calendar trigger,
no repetition. Ingests billing/remit files from MSN LLC (a radiology service bureau), rebuilds
the account substrate, and scores accounts against ~40 payer contracts to flag underpayments.
Daily-Processing-RevFind
-
▶Process-MSN-Files-RevFind— download & import MSN billing files
- Download ← mdcssh SFTP
/MSN Files/→ {SourceDataFolderRevFind} - Download ← MSN LLC vendor SFTP (
msnftp)/ - ExecuteJobForFiles → Load-MSN-ProcessDataFile-RevFind (per
*.csv) - process_file → scan structure, load Import*, merge into Source* tables
- Download ← mdcssh SFTP
-
▶Load-Account-Transform-Tables— 8 SQL transforms of source billing data
- TransformData · AccountDelta · TransformAccountMap
- TransformCharge · TransformAccount · TransformTransaction
- TransformChargeTransactionMeasure (×2)
-
▶Load-Entities-RevFind— Facility, Provider
- Load Facility
- Load Provider (SQL)
-
▶Load-Account-Data— build accounts & score them
- LoadPatients
- Load ChargeMeasures (SQL)
- LoadAccountData → merge Account / AccountCharge / AccountRemit / AccountInsurance
- Load-Dimension-Members · Load-Custom-Properties (sub-jobs)
- Score-Accounts → ~40 per-payer scoring rules (Aetna, BCBS, Humana, Cigna, Medicare + MA variants ECFOI/MICTIC/RAOC/IMI)
- Load AccountDetail · Load AccountChargeDetail · Load Recovery Report (SQL)
Reference · Interfaces
Every external hop is SFTP. Abbadox is bidirectional; the RevFind side is inbound-only from MSN LLC.
Reference · Scripts
The scheduled tasks and one pipeline step shell out to four scripts on WORKER-1. Three are generic/known; the fourth is a recent, self-contained outbound generator.
The final step of the HL7 loop —
a standalone uv-run Python script (its own bundled .venv), sitting outside the normal
task framework. It closes the loop back to Abbadox after coverage is verified:
- Query
RIAonprod-db-3for future visits wherePrimaryCoverageStatus = ActivebutActiveCoverageUpdate ≠ Sent— i.e. coverage just verified. - Pull the original inbound HL7 from
HL7Archive, extract theORCsegment, set ORC-25 (order status) = "Verified", wrap in a freshMSH … ORM^O01. - Write one
.hl7per order toGenerated\; mark the visitSentinCustomPropertyMap(transactional). - SFTP the files to Abbadox
/Inbound; move sent files toSent\.
Reference · Glossary
The native pipeline tasks used above, per docs/tasks.
Fir = HL7 / ClarityFlow,
coral = RevFind.
HL7Archive + type-specific staging tables; per-file, batch, import-only.Patient from a query over TransformPatient.DimensionMember metadata cache from core entity tables.EligibilityTxn. Billable.AutoBenefitsRule.AutoSendLetterConfig (consent + contact required).*Batch staging tables to production (delete-then-insert per entity, each in its own txn)..txt + PDF to disk (file-based integration).WorkqueueAssignmentCriteria; optional auto-unassign of non-matches.Dashboard_* rollup tables so dashboards read fast.Import{Base}, then merge into Source{Base}.