CrushSuite · Client data dashboard · Shipped 2026

Product, design and engineering. One builder, end to end.

I designed, built and shipped a new analytics dashboard for CrushSuite on my own: product, design and engineering, end to end. This is how I decided what to build, the system I built it with, and how I kept one owner from becoming one point of failure.

RoleCo-founder · product, design and the build
WhenOctober 2026 · design to production in five days
OwnedThe problem, the scope, the data rules, the design, the build, the risk plan
ResultLive on real data, every number checked against Shopify. Now part of how we sell.
01 · The problem

Wineries don't have the data to understand their customers. We do.

When a winery sells a bottle on Shopify, the order goes to two more companies. A compliance partner checks that it's legal to ship to that state. A fulfillment partner packs it and ships it. Each company sees only its own step, and the winery never sees them together.

CrushSuite connects all of them. Our Compliance app runs inside the Shopify checkout, and our Clubs app runs the wine club. So every order passes through us at every step, across 50+ wineries.

A closed loop: the customer buys from the winery, which sells on Shopify. CrushSuite sits under every step and moves each order from Shopify to compliance, back, then to fulfillment, which delivers it to the customer.

That data was sitting unused. The product was simple: show each winery what we can already see.

02 · The club insight

We could see what a winery couldn't: which wines people come for, and which they add.

The Marigny has a club of about 800 members. Online, one of its white wines wasn't selling, so they stopped printing its labels.

In the next club release, that white was the number one optional add-on, and it sold out.

The data showed why. Nobody went online to buy that white. They went online for a red. In the club, members were already buying, so adding the white was easy, and at that price in a warm month it was the natural add.

Five wines in the same rows on two panels. In the online store the white barely sells and its labels are paused. In the club release it is the top add-on and sells out. They came for the red. They added the white.

It was never a bad wine. It was a wine people add, not one they go looking for. Reading online sales alone, a winery cuts it. We could see both sides.

03 · Stopped orders

I turned stopped orders into answers wineries look up themselves.

When an order stopped, the winery only saw that it didn't go through. So they emailed whoever they could think of: us, Shopify, their compliance partner, their warehouse. Hours went into finding out whose problem it was.

Every order passes through us, so we can see why it stopped. I built a responsibility matrix: for each reason an order stops, who caused it, who fixes it, and how.

Why it stoppedWho caused itWho fixes itHow
Card declined or no payment methodThe customerThe customerA working card, through Shopify payments
Out of stockThe fulfillment partner or the wineryThe wineryRestock at the warehouse, or swap the wine
State shipping or volume ruleA compliance partner ruleThe wineryAdjust the order to fit the state's rule
Setup or sync errorCrushSuiteCrushSuiteWe fix it. The winery does nothing.

I put the matrix in our knowledge base, so every winery can look up a stopped order before they email anyone.

A list of recent stopped orders beside a panel that explains each one in turn: the issue, who caused it, who is assigned to fix it, and how, answered from the knowledge base.

Then I automated it. When a stopped order comes in with a reason the knowledge base doesn't cover yet, it gets flagged, we solve it once, and the answer goes into the knowledge base. We handle each new issue one time. Repeat issues answer themselves.

That did two things:

  1. Less back-and-forth. Wineries check the matrix before they reach out.
  2. A product we never meant to sell. It became one of the reasons wineries value us.

And because we see 50+ wineries at once, when the same reason shows up everywhere, we know the cause is upstream, not at the winery.

Part two · How I built it

What I built: an analytics dashboard that reads every CrushSuite order and billing event, every night, and turns it into answers per winery. I designed it, built it and shipped it to production myself.

ReadsThe Shopify Partner API for billing and installs, our Compliance and Clubs databases for usage, our task tracker for client work
ShowsInstalls and plans by winery, club releases, stopped orders, open client tasks
Built onNext.js, Postgres on Neon, Vercel, Google sign-in, an agent team in Claude Code
ShippedDesign started October 2 · live on real data October 9 · $20 a month to run
04 · Judgment

What I decided before writing code, and what I chose not to build.

  • Production is read-only, forever. One read-only function is the only way in.
  • Code computes every number. Claude writes only words, and any text it writes that contains a digit is rejected.
  • No real number on a screen before a money spike matches Shopify.
  • $20 a month is the only allowed cost. Anything that adds a fee stops the work and comes to me.
  • Six slices, v1 first. A slice starts only when the last one's numbers reconcile.

I proved it on a small sample before trusting the whole. I picked four wineries that, together, hit every case that breaks billing math:

  1. Both apps installed
  2. More than one club
  3. A club migrated from another platform
  4. A plan change or a frozen store
  5. A Compliance-only store with high order volume

I worked out their numbers by hand first. The code had to match all four to the cent before it ran on the rest.

Not built yet, on purpose: a health score, money at risk and an MRR bridge. Those are judgments about money, and they wait for two months of money that reconciles.

05 · The system

How one person shipped product, design and engineering: an agent team, with gates I set.

Design started on a canvas on Oct 2. Code ran Oct 7 to 9, about 168 commits, and real data was on the screens by Oct 9.

A principal agent plans and six specialists build: backend, frontend, database, code review, QA, and one that keeps the docs true. I approve every plan and every merge. Every task runs plan, failing tests, code, checks, and I send back any plan that adds a dependency or skips tests.

I proved the gate before I trusted it. A deliberately failing test went in, CI turned the first PR red, and the revert turned it green. Then I cut the suite from 457 tests to 62 that guard what can actually be wrong: money rounding, totals that add up to their parts, no real winery names in sample data. It has grown since, as real data landed.

06 · Risk

How I kept one owner from becoming one point of failure.

Our lead engineer owns production. I gave him the controls.

  1. A read-only role with hard limits. The dashboard reads production through one role, dashboard_ro: a 15 second statement timeout, a 1 second lock timeout, two connections, and no grants on customer names, emails or addresses. A bug on my side can't load his databases.
  2. His review. Twenty minutes of his time on the PR before it touched production. Anything on his paths (the production reader, the money formulas, the nightly sync) waits for his comment.
  3. Work sequenced so each piece ran in isolation. The money spike was scripts with no UI and no production, the screens ran on sample data, and real data came in one slice at a time. His databases come last.
  4. His stop button. One command, ALTER ROLE dashboard_ro NOLOGIN, cuts the dashboard off, no deploy needed. Secrets never go into a chat or the repo, and test data is anonymized.
07 · Trade-offs

What I cut when the numbers didn't reconcile.

The plan was to derive monthly recurring revenue per winery from Shopify's app events. Every rule was a guess about money that hadn't arrived: when a trial ends, what an upgrade is worth, whether a closed store still pays. It didn't reconcile cleanly with Shopify.

So I cut it. A plan is a label, and money is only what Shopify's Partner API says came in. No MRR, no trial math. Once I cut it, the numbers matched Shopify to the cent.

08 · Outcomes

What it changed: answers wineries use without us, and numbers that match Shopify to the cent.

Stopped orders went self-serve: wineries check the matrix before they email us, repeat issues answer themselves, and a product we never planned to sell became one of the reasons they value us.

Every number on the dashboard matches the Shopify Partner Dashboard to the cent, and a test fails the build if one moves. It reads 98 stores and about 3,400 billing events every night, across 18 months of history. It runs for $20 a month, and we use what it shows when we sell.

09 · Ownership

What I owned, and what I didn't.

Mine

  • The problem, and what to cut.
  • The data rules.
  • The design, 14 boards.
  • The build: every plan and every merge.
  • The risk plan, and what I asked of our lead engineer.
  • The responsibility matrix, and putting it in the knowledge base.
  • The sales story.

Not mine

  • Production, the read-only role and the stop button. Those are our lead engineer's.
  • Typing the code. The agent team wrote it, inside the gates above.