Home · Builds · Finance ETL · Part 5

Finance ETL · Part 5 of 8

A script, a timer, and a four-day outage.

The sync is a bash script under a systemd timer with its token sealed in a root-only file. It reconciles on every run. That reconciliation is how I found out the schema had been wrong for four days.

Scratch cut · 1:41 Screen recording of the timer firing, the log lines, the row count, and the reconciliation line. Then the sync_runs table. Demo data, scratch voice, real pipeline. The live recording takes over once it is shot.

The script

set -euo pipefail
trap 'rm -f /tmp/ynab_response_*.json' EXIT
cursor=$(psql ... "SELECT server_knowledge FROM ynab.sync_state WHERE endpoint='budget_detail'")
fetch budget_detail with last_knowledge_of_server=$cursor   # 429 -> sleep 60, retry
INSERT INTO ynab_raw.api_responses ...
SELECT ynab.apply_response(:id);
INSERT INTO ynab.sync_runs (mode, status, rows_upserted) ...
SELECT COUNT(*) FROM ynab.v_balance_check WHERE ABS(drift) > 0.01;

Running it

The hourly loop: clock, fetch, land, apply, and back to the clock.

The outage

Transaction ids were typed as uuid. The documentation calls them ids; most of them look like uuids. Then the first scheduled transaction occurred, and its ledger row carried an id shaped like <uuid>_<date>. The cast failed, the transaction rolled back, and every hourly run failed the same way for four days.

Skipping those rows was not an option either. One skipped occurrence produced exactly 30.59 dollars of drift on checking. Thirty dollars is a small amount to lose and a large amount to be wrong about. The balance check view caught it. A migration retyped the id columns as text, rebuilt the dependent views, and the replay from raw landed the missing rows.

Audio · 3 minThe four-day outage, told properly
Scratch narration How it was noticed, the wrong first theory, the 30.59 dollars, and what changed in the checklist.
The hourly loop: timer, fetch with the cursor, land, apply, and reconcile with the figure 30.59.
Plate V · The hourly loop
Free to borrow for your feed · Square edition

Where you are: a pipeline that runs and checks its own math. Next, you finally get to look at it.

Previous · ModelingNext · Part 6 of 8Seeing it: balances become a retirement date

Write to me

Is there a 30.59 hiding in your books?

Fractional CTO and CFO engagements start with a short call. No deck required, no pitch either. Bring the number you do not trust.

Tell me what is stuck