Home/Systems/Mango CRM
Agriculture & Supply

Fruit has a clock. So does the buyer.

Mango CRM runs a cold-storage operation from two dashboards. The stock room watches shelf life and stock levels and drafts the message you send to the crew. Reorders watches the buyers, works out when each one is genuinely due back, and decides who is actually worth messaging.

Powered by 27th Marketing
mango, stock room
Mango
Stock roomReordersAlertsOutboxBuyersSettings
Stock roomCold store A
On hand14.2t
Crates712
Value₱1.8M
Alerts5
Days of shelf life left
Alert centre
Carabao · lot 214Best-before in 2 daysMove now
Katchamita · lot 198Ripening in a cold storeCheck
PicoBelow reorder pointRestock
mango, reorders
Reorder clock14 buyers
Supplied6
Due4
Overdue3
Lapsed1
Nudge basket, today
Delgado Fruit Stand6 crates · due 3 days agoSend
Rivera Sari-Sari2 crates · due todayHeld, basket
Bay Hotel Groupheld: variety out of stockSuppressed
Sector
Mango cold storage & wholesale
Scope
Stock dashboard · Replenishment engine · Messaging
Stack
React · Vite · Strict MVC layering
Coverage
117 automated tests
The problem

Perishable stock
punishes guessing.

A crate that sits three days too long is not late, it's a loss. And a buyer who is silent for sixty days is either fine or gone, depending entirely on which variety they buy. Both answers were living in someone's head.

Shelf-life risk only visible once it was already spoilage
Reorder chasing done from memory, so the good buyers got missed
Everyone chased at the same interval, regardless of order size
No record of who had already been told what
What we changed

Every batch is plotted by days until its best-before date, so the lots about to become a problem are visible before they are one. Every buyer gets a cycle estimated from their own buying history and their own order size, so "due" means due for them, not due on average.

React + ViteDomain / services / hooks / viewsPure-function rulesOffline-capable storage117 tests
Dashboard one

The stock room, and
the six rules watching it.

Past best-before

Anything already over the line, first in the list, every time.

⚠️Best-before close

The lots about to become a problem, while there's still time to move them.

🚫Out of stock

A variety on the floor at zero, before a buyer finds out for you.

📉Below reorder point

Per-variety thresholds, editable, not one number for the whole warehouse.

🌡️Ripening in a cold store

The stage-and-room mismatch that quietly costs a whole lot.

📦Over capacity

A room holding more than it should, flagged as a room problem.

💬Message drafter

Pick an alert, get written wording, choose who to tell, copy it out.

📬Outbox log

What was drafted, copied and sent, so a shift handover reads it, not guesses.

We said the honest thing, in the product

A browser page cannot deliver an SMS or an e-mail. This drafts and logs; you copy into whichever app actually sends. The SMS part counter is there because a three-part message costs three times as much and arrives out of order on a bad network. Nothing here claims a delivery it cannot verify, and that's a design decision, not a limitation we hid.

Dashboard two

A reorder clock
per buyer, per product.

📐

The window scales with the order

Due date is the last order plus units multiplied by days-per-unit. A buyer who takes six crates is covered roughly three times as long as one who takes two. A flat cycle would nudge the big buyer two-thirds of a cycle too early, every single time, until they stopped reading.

🧮

The rate is learned, then reined in

The estimate follows the median gap, not the mean, so one fiesta order can't drag it by weeks. It's then blended toward the product default by how much evidence exists, and clamped between half and twice that default, so a data glitch can't invent a year-long cycle.

🪜

Four stages, measured in their own cycle

Supplied, due, overdue, lapsed, with every boundary a multiple of that buyer's own cycle. Sixty days of silence is nothing for one variety and terminal for another, so a fixed day-count would be wrong for nearly everyone.

🧺

The basket, not the blast

Due items go into a per-buyer basket instead of straight out the door, and the basket only sends once something in it is genuinely overdue. Everyone held back is listed with the reason, and every reason is fixable from the buyer's own record.

🔗

Joined to the warehouse on purpose

A restock nudge is suppressed when the cold store has none of that variety on the floor. Nothing is worse than a "time to reorder" message about something you cannot ship, and it's the reason the buyer side lives here instead of in a CRM that can't see the stock.

🎯

Proof that it's working

A fixed share of buyers is never nudged, so there is always an untouched group to measure the rest against. Without a holdout, "the nudges are working" is a feeling, not a number.

Under the hood

Built so the numbers
stay true.

This is a dashboard that lives on a warehouse wall for weeks at a time. Most of the engineering went into the failure modes nobody notices until they've already cost money.

Derived values are computed, never stored.
Weight, value and shelf life are worked out on read, so a stale column can't lie to you.
The clock is a dependency, not a constant.
A screen left open overnight re-reads the date, so an expired batch stops reading as fresh at midnight.
Restored data is treated as hostile.
Bad rows are dropped and bad settings replaced, so one malformed order can't take the whole warehouse down with it.
Alerts ignore your filters.
Filtering narrows what you're reading, it must never hide a problem you haven't looked at yet.
Storage falls back, loudly.
If the browser blocks local storage, it switches to memory and says so, instead of silently losing the shift's work.
2Dashboards, one operationstock room and reorders
6Alert rulesthresholds editable in settings
4Buyer stagesscaled to each buyer's cycle
117Automated testsrules covered as pure functions
Not just mangoes

Same engine.
Different nouns.

Ask about your stock
🥬Fresh produce

Harvest date, shelf life, spoilage risk, the exact same clock.

💊Pharmacy & clinic supply

Expiry-driven stock with reorder points per line item.

🍞Food production

Batch codes, best-before windows, and a wholesale reorder cycle.

🔧Parts & consumables

No spoilage, but the same "who's due back" question, answered per customer.

Designed, built and powered by 27th Marketing.

Rules you can edit, numbers you can trust, and a system that admits what it doesn't know. That's the standard on every build we ship.

27th Marketing
More systems

Stock going soft?
Buyers going quiet?

Tell us what you store and who buys it. We'll show you what the rules would catch in your first week.