Selected work · financial data pipeline

Premium Billing Reconciliation

Principle 02Fail loud

Every month, six analysts reconciled a ~60-client premium-billing book by hand — roughly 500 carrier reports, each client consolidated from as many as 20 carrier feeds, scrubbed line by line into invoice packages that have to be penny-exact, because accounting rejects a payment one cent off. The team’s own charter put the burden at ~80 hours a week, all of it key-person dependent. This is a Python pipeline that does the consolidation: drop the month’s files into carrier folders, type the month, run. It detects each source, parses every layout, applies the team’s own scrub and wash rules, reconciles to the penny, and writes the same deliverables the analysts produced by hand. And wherever a source is missing or ambiguous, it refuses loudly with a named error — nothing is ever quietly guessed.

Stack
Python 3.11 ·
pandas · openpyxl
Scope
46 clients ·
336 carrier feeds
Output
workbooks + invoices
+ coverage report
Result
~80 h/wk manual →
one run + review
How a run flows

Drop the month in. Get the book back, reconciled.

Drop

The month’s files go into per-carrier folders — the folder decides the carrier, so a misfiled report can’t masquerade as another source.

Detect

Each file is identified from its content against configured detection patterns — never trusted on filename alone.

Parse

Workbooks, PDFs, and portal exports are read by per-layout parsers into one normalized model.

Reconcile

Scrub tiers and per-carrier wash rules apply, then enrollment is matched to billing — exact to the penny on the invoice side.

Package

Client workbooks, per-carrier invoices, and a coverage report land in the output folder; inputs are archived untouched.

Flagged, never guessed

It would rather stop than be confidently wrong.

In billing, the dangerous failure isn’t the crash — it’s the plausible number that’s wrong. So every gap here is a named refusal: a missing source, an unreadable file, an unresolvable rate each halt the run with exactly what and where, and the run exits non-zero until the month is genuinely complete.

A coverage report accounts for every configured carrier on every run — expected, produced, or why not — so an unknown stays visible instead of becoming a silent “nothing expected.”

run · month closefail-loud
46 clients · 336 carrier feeds · one pass
invoice side reconciled · tolerance $0.00
carrier source missing → named refusal · exit non-zero
sub-dollar rounding drift → flagged for review
coverage: expected vs produced vs why-not, per carrier
Every gap is recorded, surfaced, and blocking — never a silent fallback.
Codified, not tribal

No two clients bill alike — so the book lives in config.

The reason this took a team is heterogeneity: one to twenty carrier feeds per client, three billing scenarios, per-carrier wash rules, carrier-specific templates. All of it now lives in reviewable configuration — the knowledge that was key-person dependent is written down, versioned, and executable.

Onboarding the next client is configuration, not new code — and the config is the count: the roster file, not a number typed into a doc, is the source of truth.

the book, in config
+1–20 carrier feeds per client · median 7
+self-bill, self-bill with retro, and list-bill scenarios
+241 invoice templates · 48 carrier render profiles
+per-carrier wash rules, codified from the analysts’ method
+a generated drop list — every file a real run actually opens
The analysts’ judgment, engineered

Deterministic where it can be. A human call where it must be.

“Scrubbing” was the team’s craft: reviewing every self-bill-with-retro line and removing what isn’t billable. The engine splits that craft honestly — four deterministic tiers are gated automatically and reproducibly; four judgment tiers are detected, counted, and surfaced for review.

The line it never crosses: it never auto-deletes on a judgment call. Those rows are flagged for a person, because turning a visible unknown into an invisible deletion is how billing goes quietly wrong.

scrub · self-bill with retro4 + 4 tiers
gated: retro-prior-month · footer · future-month · zero-premium
surfaced: net-zero · duplicate · same-month · override
wash rules applied per carrier billing rules
judgment rows → review flags · never auto-deleted
Reproducible from a row’s own columns where possible; flagged for a person where not.
Proven against the real months

It earns trust by reproducing the team’s own work.

The rollout standard isn’t “looks right” — it’s byte-for-byte. The pipeline runs the same months the analysts worked and its deliverables are compared to theirs document by document: 239 of 244 tracked documents tying, with every remaining gap waiting on externally supplied files or answers, not code.

Under it all sits a test suite where every rule is exercised — including the refusals. The failure modes are tested as deliberately as the successes.

pytest -q -n auto98.0% tying
client deliverables reproduce byte-for-byte end to end
refusal paths under test — it fails loud on purpose
Tests 1,335 passed · 2 skipped
parity: 239 of 244 tracked documents tying · 98.0%
Shadow the manual months until they tie — then, and only then, cut over.
Built with

A pipeline the operators run by double-click.

Python 3.11 · pandas · openpyxl · PyMuPDF · pytest — zero-install for the operator: the first run bootstraps its own environment, and every month after is drop, type the month, double-click.

Fail loud
A missing or ambiguous source is a named, blocking refusal.
Penny-exact
Invoice-side tolerance is $0.00; sub-dollar drift is flagged, not absorbed.
Nothing deleted
Inputs archive untouched; judgment rows are surfaced, never dropped.
Scott Matthews · Selected workPremium Billing Reconciliation · Pythonscottmatthews.dev