Nikzerodraft.studio

Selected work

Situation, what I built, what changed

Only the work that speaks to a CPG operator. No logos, no client names, no real numbers. The first three items are phases of one engagement that started as a build and became a retainer, which is how I prefer to work.

Bottled water brand · phase 1

One reporting layer for sales and distributor data

The founder and the reps now look at one set of numbers every week, built in weeks, on a server the company owns.

Situation

A founder-led bottled water brand had sales and distributor data spread across spreadsheets, QuickBooks and an inventory system. Nobody had a single view. Revenue was reported on order date, so a large distributor order looked like a spike in one month when it actually shipped over a whole summer.

What I built

  • Nightly and on-demand syncs from the inventory system, QuickBooks and a forecast workbook into a Postgres warehouse on a VPS the client owns.
  • Google Sheets kept as the controlled input for forecasts and plan. The team keeps working where they already work.
  • Five sales screens: overview, revenue vs plan vs prior year, by customer, by SKU, and a value chain waterfall from gross to net.
  • Metabase embedded in the internal app behind company Google login, so the team builds its own reports without waiting on me.
  • Full sync logs and a data freshness page. When a number looks wrong, they can see when it last loaded and from where.

What changed

Revenue moved to ship date with realized and booked kept strictly apart. The Monday conversation went from "which spreadsheet is right" to "what do we do about it". Phase 2 is agents on top: accounting, distributor reporting, rep assistants in Slack.

Open the app, rebuilt with synthetic data

Next.js · Postgres · Drizzle · Metabase · Coolify on a client-owned VPS

Bottled water brand · phase 2

Inventory system integration and revenue reconciliation

Finance and ops stopped arguing about the revenue number, because both now read the same one.

Situation

The inventory system (Cin7) and the accounting close disagreed. Reports showed booked revenue where everyone expected realized revenue: orders scheduled but not shipped were counted as sales. Draft orders, partial shipments and uninvoiced shipments each broke the total a different way.

What I built

  • A direct integration with the inventory system: customers, products, price tiers, sales, stock, bills of materials, suppliers and purchase orders, synced on a schedule with a stop-on-first-failure rule.
  • Diagnosed the realized-vs-booked bug at the data layer and rewrote the rules: revenue on ship date, booked kept separate, drafts excluded, shipped-but-uninvoiced flagged.
  • A validation page that compares the warehouse to QuickBooks so any drift shows up before the board sees it.

What changed

Same number in the dashboard and in the close. I have worked inside inventory systems before. You do not have one yet, and I can help you pick one and wire it in so the reporting is right from day one.

Cin7 API · QuickBooks Online API · Postgres · scheduled sync jobs with logs

Bottled water brand · phase 3, ongoing

Supply planning: weeks of supply, production runs, plan vs actual

Per SKU, on one screen: how many weeks of coverage, what to order by when, and what the next production run has to cover.

Situation

Stock lived in the inventory system, demand lived in a forecast workbook, and the production schedule lived in someone's head. Reorder decisions were made late and the finished goods and raw materials questions were mixed together.

What I built

  • A weekly production and coverage grid: stock on hand, planned runs, forecast demand and resulting weeks of supply per SKU, colour-ramped so the thin weeks jump out.
  • Reorder plan against each item's own lead time, a "producible" number with the limiting component, and a what-if for a large order before committing it.
  • Production runs managed in the app (create, change, remove) with the workbook projection kept in sync, plus multi-site views.
  • Forecast accuracy scorecard, open orders report, and a Monday digest email so the week starts with the numbers already in the inbox.
  • Recomputes instantly in the browser: sorting, filtering, thresholds and what-ifs without a page reload.

What changed

This is the closest analog to WIP by co-packer and site, finished goods by DC, and weeks of supply. The pattern carries over directly: partners keep sending what they send, the warehouse normalises it, the grid tells you what is short.

Next.js · Postgres · Drizzle · hourly scheduled syncs · Resend for the digest

Automation

Email to pipeline: unstructured messages into structured records

No more manual re-keying. What arrives as prose in an inbox lands as validated rows with a log of what was read and what was rejected.

Situation

Operational updates arrived as unstructured emails and attachments. Someone read each one and typed the important parts into a tracker, late and with mistakes.

What I built

  • Gmail to n8n to an AI parsing step that extracts the fields, then validation against the schema before anything is written.
  • Records land in Postgres with the source message linked, so every row can be traced back to the email it came from.
  • Categorisation (urgent, important, follow-up), a daily brief with action items, and a full history of what was parsed.

What changed

This is exactly the mechanism for "our co-packers send us PDFs by email". The parser is one step in the pipeline; the validation and the log are what make it trustworthy.

eventops.zerodraft.dev →

n8n · Gmail · Claude via the Vercel AI SDK · Postgres · Next.js

Monitoring

Monitoring, AI scoring, alerts

A public feed watched daily, every new record scored for relevance, the ones that matter pushed to the people who need them.

Situation

A signal existed in a public data source weeks before anyone talked about it, but nobody had time to read the raw feed.

What I built

  • Daily ingest of SEC Form D filings, parsed into structured data, scored by an AI step against a written rubric, shown in a filterable dashboard.

What changed

Same pattern as threshold alerts to Slack: watch a source, apply a rule or a score, notify. Swap the feed for depletion by retailer or weeks of supply by SKU and it is the alerting layer of your reporting.

formd.zerodraft.dev →

Next.js · Postgres · Vercel AI SDK · scheduled jobs