Skip to content

Purpose-Built Analytics Dashboard

Sol de Mendocino

A reporting dashboard over a dispensary's point-of-sale data, built to say only what the data can actually support.

Owner overview: revenue, gross margin and inventory capital, each against the period before, above a list of products to reorder with days of stock left
The overview: what the shop took in, what it kept, and what to order, on one screen.Representative interface; figures are illustrative.

A cannabis dispensary in Mendocino. Every sale, every delivery, and every jar on the shelf was already recorded in the shop's point-of-sale system, and none of it was in a shape anyone could run a shop by. Mary owns the place. She wanted plain answers: what did we take in, what are we keeping, and what is about to run out. Getting one meant an export and an evening with a spreadsheet, and by the time the spreadsheet was assembled the question had moved on.

The shop

A dispensary on the Mendocino coast, with staff who work the floor, place the reorders, and pull vendor reports. The point-of-sale system is Meadow, and because this is regulated retail it holds more than a till roll: every package has a state track-and-trace record behind it, with a harvest date, a lab licence, and a wholesale cost. The information needed to run the shop well was all there. What was missing was any way to ask it a question.

The problem

Two questions cost real money, and neither had a quick answer.

The first is discounts. A promotion that moves a lot of units and quietly loses margin looks exactly like one that works, right up until the month closes. Without the wholesale cost sitting next to the sale price, a busy week and a profitable week are the same week.

The second is stock. On-hand is a number anyone can look up. The rate a product is leaving at is not, and it is the one that matters, because it is what tells you whether a shelf empties before the next delivery. The first anyone knew about a fast mover was the gap where it used to be.

What we built

A private, staff-only dashboard over a nightly copy of the shop's own point-of-sale data. Reports never touch the live system, so a report is fast and a busy Saturday is never slowed down by someone running one.

The Overview is the landing screen and the business layer: revenue, gross margin, traffic, trading pattern, channel, and customers, each read against the period before and against the same period last year, with the capital tied up in inventory sitting beside them, banded by how many months of supply it represents. Every card opens the data behind it rather than asking you to trust the headline. On a phone the page reads figures, then what to do, then why it moved; on a wide screen the same markup becomes a rail beside the charts.

Discounts shows, per product, what it cost, what it sold for, how deep the discount went, how many moved, and what that did to margin. Reorder and stock reads sales velocity against stock on hand to give a days-of-supply estimate and an order-now flag while there is still time to order. Shelf life tracks what is aging. Alerts collects the whole lot into one page of what needs doing today, in the order you would actually do it. A search box finds any product and opens a panel carrying its lab results, its stock, and its recent sales. There is a What's new page, so the shop can see what changed in the app and when.

The number that got worse on purpose

California cannabis tax is charged inside the shelf price, and it is roughly a quarter of the till. Margin had been measured against the price with that tax still in it, which counts the state's money as the shop's. Profit kept was overstated by about eleven points, and two products that had sold below cost in a single month were not being flagged at all.

So we fixed it, and told Mary the headline figure on her own screen was about to fall, and why, before she saw it fall. A reporting tool earns its place by being right, and the day that matters most is the day right is worse than what it replaced.

The screen says what it does not know

The rule this build is held to is that every figure traces back to the register, and where the source cannot support a figure, none is shown. That sounds obvious. In practice it is most of the work.

On-hand was summed from the track-and-trace feed, which covers cannabis and, by law, never covers accessories. Treating that structural absence as a zero told the shop it was out of lighters, papers, batteries, and glass while boxes of them sat under the counter, and sorted them to the very top of the reorder list. Those rows now read as having no count, stay out of the percentages so a rate is measured against the products it can describe, and the page prints how many of them there are. We then went looking for a feed that could answer, found the count on an endpoint the nightly sync was already calling, checked it against the shelf by hand, and wired it in.

A date field present on every item in the shop looked like the freshness clock and was not one. For most of the shelf it dates the source material rather than the product, so published as an age it would have told Mary that nearly half her capital was over a year old. Each kind of stock now gets a clock that fits it: a use-by where a use-by exists, and how long the shop has been holding it everywhere else.

And on a page whose job is to warn, silence is a claim. If the data behind an alert is not fit to judge on a given day, the page changes nothing and says it could not check, rather than quietly clearing alerts and reporting a broken feed as good news.

Product panel for an accessory: on hand reads no count, reorder reads no signal and days held reads no date, each with a line saying why, above a sales chart showing 22 units sold in 30 days
An accessory has no track-and-trace record, so the screen says so rather than filling the gap with a zero.Representative screen; figures are illustrative.

What changed

Mary can open one screen and see what the shop took in, what it kept, and what that looks like against last month and last year. A discount either earns its place or it does not, and the page says which. Products are reordered while there is still time to reorder them, and the shelf runs out less. The capital standing still in inventory is visible for the first time, because nothing in the point-of-sale had ever said so.

It also has to work on a phone on the sales floor. Unit tests pass happily while four panels sit flush against each other and a product name truncates to a prefix it shares with a different product, and both of those shipped here. There is now a check that drives every page in a real browser at five screen widths and fails the build on sideways scroll, truncated labels, panels with no gap, and anything too small to tap.


Every figure traces back to the register. Where one cannot, the screen says so.

Sol de Mendocino's dashboard is private to the shop's staff.