2026 · Data engineering

Shipping a revenue warehouse solo in 8 weeks

A high-ticket sales education company had revenue data in 8 tools and attribution in none of them. Here is the architecture that fixed it, the discipline that kept it trustworthy, and an honest account of what agentic AI did and did not do.

The problem was not the data, it was the seams

Every tool in the stack was working correctly. The CRM knew about contacts and opportunities. The accounting system knew about invoices. The payment processor knew about cash. The social channels knew about conversations. Nobody knew about all of it at once.

That is the ordinary condition of a growing business, and it produces a specific kind of pain: a founder can tell you revenue for the month and can tell you the team is busy, but cannot tell you which activity produced which dollar. The question "should we hire another setter" has no defensible answer without that link.

So the goal was never a dashboard. The goal was a single place where a number means one thing, and where you can trace that number back to the event that caused it.

Three layers, one rule each

The warehouse runs on Supabase Postgres in three layers, and the value is less in the layers than in the rule attached to each one.

Staging is append only. Raw payloads land as JSONB exactly as the source returned them, and nothing ever mutates them. When a vendor changes a field, history does not silently rewrite itself. When a transform has a bug, the source of truth for re-running it is still sitting there untouched.

Core is typed and entity resolved. This is where a contact stops being five records across five systems and becomes one person with five identities. A legacy CRM account had to be merged into a clean contact spine here, which is the least glamorous work in the whole project and the reason every downstream number is trustworthy.

Logic is views only. No tables, no materialized shortcuts that drift. Every human and every machine reads the business through this layer, which means there is exactly one definition of "a sale" in the system, and changing it changes it everywhere at once.

Schema changes only happen through versioned migrations. That sounds like bureaucracy for a team of one, and it is precisely what makes a team of one safe to trust with production.

The rule that made it honest: verify before you move

The discipline that mattered most was not architectural. It was this: no phase was considered done until a concrete check proved it. A count query, a spot-checked record, a curl against the endpoint, a reconciliation against a known figure from the source system.

This is worth being blunt about, because it is where AI-assisted development goes wrong. A model will produce a puller that looks correct, reads correct, and returns rows. Whether those rows match what the vendor's UI says is a separate question, and only a check answers it. Roughly 30 pull requests went through this loop across the engagement.

The compounding effect is real. When phase 6 misbehaves, you are debugging phase 6, because phases 1 through 5 were each proven when they shipped.

Eight integrations, and what each one taught

The CRM pull needed deduplication more than it needed volume. Accounting needed a daily cron plus a manual trigger, because month-end always produces an "I need it now" moment. Payments turned out to be the highest-value gap in the whole build: instrumenting the closer's sale form is what finally made revenue and cash collected reconcilable against each other.

The community channels were the surprise. A Discord backfill of 14,297 messages across 26 channels, plus a live bot capturing ongoing messages and voice activity, converts a chat server from an unmeasurable blob into a queryable record of how members actually behave before they buy. A 692-video YouTube backfill did the same for content.

The attribution model mattered most commercially: tying A$208k of revenue to specific outbound DM conversations gave the founder the first hard number on what an entire team's daily activity produces.

What agentic AI actually changed

The whole engagement ran through Claude Code with a pull-request workflow. The honest version of what that bought:

It compressed the distance between deciding to do something and having it running. Writing a puller, a transform, and a test used to be an afternoon; it became a focused hour. Across dozens of those, that is the difference between an 8-week project and a 6-month one.

It did not remove the need to know what correct looks like. Every architectural decision above, the append-only rule, the view-only read surface, the entity resolution strategy, came from judgment about how revenue data goes wrong over time. An agent executes a plan well. Deciding that staging must never mutate is not execution, it is knowing what future problem you are preventing.

That is the shape of the job now: judgment about systems, delivered at a speed that used to require a team.

What the first tracked month showed

15 sales, A$147k in revenue, A$54k in cash collected, all traceable to source. Not a bigger number than before, the same business, honestly measured for the first time. That distinction is the entire point of the work.

Building something similar, or want this built for you? Get in touch.