Skip to main content
Case studies

Pre-seed · Retail AI

NDA

AI Stock Ordering Management System

A retail operator had historical sales data, an ERP they could export from, and nothing built. We shipped a working stock-ordering MVP in four weeks — a deep ML pipeline paired with a Claude interpretation layer — and cut everything that was not the proof.

Timeline
4 weeks
Status
Live, in Phase 2
Engagement
Sprint → ongoing
Stack
  • Next.js
  • Postgres
  • PyTorch
  • TensorFlow
  • scikit-learn
  • Claude API

Day one

Worth stating plainly, because four weeks means nothing without it.

What existed when we started: historical sales and ordering data, and an ERP they could export from. That is the whole list. No code, no models, no interface, no data pipeline, no prior attempt to hand over. The four weeks below runs from an empty repository.

What they also had was a thesis and a deadline. The thesis was that the gap between their best and their newest operators — which lines to reorder, in what quantity, on what cadence — was learnable. Their best operators ordered well. Their newest ordered badly. The gap was costing them money every week, and they believed a system trained on the patterns in their own data could close it: not by replacing the operators, but by surfacing the decision a good operator would have made and explaining why.

What they did not have was time to build it the long way. Eighteen months of engineering, a hired ML team, an off-the-shelf inventory platform stitched together with custom logic — none of it fit the runway. They needed a Sprint.

The cut

The scoping call took an hour. Most of it was about what to leave out.

The temptation in a build like this is to ship the cathedral — multi-warehouse logic, complex SKU hierarchies, integrations with three different ERPs, an ML system sophisticated enough to model promotional effects, seasonality, and supply-chain disruption all at once. All of that would have been correct over time. None of it would have shipped in a month.

What we kept: one warehouse, flat SKU model, a single ERP read connection (no write — recommendations went out as flagged suggestions, not auto-submitted purchases), and a deep ML pipeline scoped to two jobs only — forecasting near-term demand per SKU, and classifying SKUs into behavioural cohorts. The Claude interpretation layer would take both signals and produce a ranked recommendation list with operator-readable rationales.

What we cut, and why:

  • Multi-warehouse. The thesis was testable at one site. Adding sites multiplies the data-cleaning work without changing the answer.
  • Full seasonal modelling. Replaced with a six-month rolling window. Seasonality is real, but proving it needs more than one season of clean data, which they did not have.
  • ERP write-back. Recommendations the system submits itself are a different risk conversation and a different sign-off. Flagged suggestions answered the question.
  • The CEO's dashboard. The hardest cut, and the one worth naming. The CEO wanted a dashboard. Dashboards take time. The honest answer was that the dashboard was not part of the proof — the proof was whether the recommendations were any good, and that could be tested without a dashboard at all. We shipped a CSV export instead. The CEO did not love it. Four weeks later, the recommendations were good enough that nobody mentioned the dashboard again.
  • Three of the four integrations they had already paid for. Sunk cost is not scope. They stayed paid for and unbuilt until Phase 2.

All of it went into the Phase 2 scope on day one. None of it belonged in the Sprint.

The build

The architecture had two layers: a deep ML pipeline doing the prediction work, and a Claude interpretation layer turning predictions into language an operator could act on. Each layer was scoped to do the thing it was actually good at — and nothing else.

Weeks one and two went to the data pipeline and the deep ML layer. The client's existing ERP export was a CSV mess — denormalised, inconsistent date formats, half the SKUs without categories. The first three days were scikit-learn pipelines for cleaning, normalisation, feature engineering, and the cohort labelling used downstream. Day four through the end of week one: TensorFlow for the pattern classification — grouping SKUs into behavioural cohorts so the forecasting model could specialise rather than averaging across the whole catalogue. Week two: PyTorch for the time-series forecasting — a sequence model trained per cohort against the rolling window of the client's sales history. Both models trained, evaluated against a hold-out set, tuned, and serialised by end of week two. On data the models had not seen, the forecasts were directionally correct on roughly 78% of SKUs — good enough to be useful, with the override loop catching the rest.

Week three went to the Claude interpretation layer and the operator-facing UI. This was where the LLM earned its place. Claude received the model outputs — forecast, confidence interval, cohort, recent override history — and produced a single recommendation per SKU with a short, plain-English rationale. The rationale was the actual product. Operators did not want a number; they wanted to know why. "Forecast is 12% above the trailing average for this cohort, and the last two reorders of this line undershot demand" is the kind of sentence that closes the gap between a model and a decision. The UI was simple: a list of recommendations, each with a confidence score, the rationale, and two buttons — accept or override. Every override fed back into the prompt context for the next decision. By the end of the week, the override rate had dropped from 41% to 19%.

Week four was hardening. Auth, rate limiting, logging, the handover docs, the retraining script (so the deep ML models could be re-fit monthly without engineering involvement), and a single round of polish on the rationale strings — the first-pass outputs were too long and too hedged; we tightened them.

Ship day: Thursday of week four, one day ahead of the call sheet. The system went live with one warehouse and one operator team.

What happened next

We do not publish a client's business outcomes without written clearance, and we do not have it for this one. So this section is about our own engagement rather than their results — which is the less impressive half of the story, and the half we can actually stand behind.

The engagement did not end at ship. Within the first two weeks of the MVP being live, the Phase 2 scope — multi-warehouse, the dashboard, the public-facing platform layer, additional model heads for promotion and seasonality — moved from "later" to "now", and the work extended into ongoing backend management under the same engineering lead.

The original system is still in production. The forecasting and classification models have been retrained against larger windows and improved twice; the architecture is unchanged. The Claude interpretation layer has been swapped to newer Claude models as they shipped, but the schema and the feedback loop are unchanged. The UI from week three is still what the operator team uses.

The lesson worth naming: a Sprint is not a deadline you force a project into. It is a discipline you apply to the project. Four weeks was the number we committed to on the scoping call, in writing, before any work started — and the reason the proof at the end of it held up is that nothing in the build was rushed past the point where it would survive contact with real data. The dashboard is the tell. A team that could not say no to the dashboard would have shipped a prettier system that answered a smaller question.

The MVP wasn't the goal. The MVP was the proof that the goal was worth building.

> phoenix://book

Have a build that looks like this?

Book a scoping call and we'll work out whether a Sprint is the right cut.

30 minutes. No pitch.