Platform

One system from the shelf to the balance sheet

BluYards covers what a multi-outlet network actually does in a day: watch stock, chase what is running out, move goods, record what came in and went out, and keep books that agree with all of it.

2,000
SKUs per outlet
the scale the inventory matrix and alert sweep are built and tested against
1M+
stock level rows
threshold recomputation stays set-based in SQL at this size
<1s
alert to inbox
alerts are evaluated inside the movement transaction and fan out on commit
500
movements per API call
all-or-nothing batches, idempotent, deduplicated per outlet

01

Inventory visibility

The matrix is the product's centre of gravity: outlets down the side, products across the top, every cell a live position.

  • Virtualised grid that holds 2,000 SKUs per outlet without paging
  • Cells carry on hand, in transit, days of cover and a health band
  • Server-Sent Events push each change; changed cells flash rather than re-render the page
  • Drill into any cell for the movement ledger behind the number
  • Every query is scoped in SQL to the regions, outlets or warehouses the viewer may see
The inventory matrix: outlets down the side, products across the top, each cell coloured by stock status

02

Alerting and escalation

One alert follows an item from low to critical to out and back again, so the history reads as a story rather than a pile of duplicates.

  • Thresholds resolve global → category → product → outlet×product, in units or days of cover
  • Hysteresis on resolution stops alerts flapping around the reorder point
  • Escalation tiers per region, timed from the moment an alert turned critical
  • Quiet hours, hourly and daily digests, with urgent alerts able to bypass them
  • In-app, email, SMS and WhatsApp through one delivery log
The alerts centre listing low, critical and out-of-stock alerts with severity and age

03

Inward, outward and corrections

The three things staff do all day are one keystroke from any screen, and they post through the same movement service as the API.

  • Inward: supplier deliveries, with the purchase voucher posted alongside
  • Outward: counter sales at an outlet, issues from a warehouse, with the sales voucher
  • Adjustments, damage write-offs and count corrections, each needing a reason
  • Quick actions open over whatever page you are on — no navigation, no lost context
  • Cancelling a document reverses stock and withdraws the voucher; nothing is ever deleted
The inward register listing goods-in documents with supplier, settlement, units, value and the voucher each one posted

04

Transfers and open pools

Point-to-point transfers work when you know who needs the stock. An open pool is for when you do not.

  • Direct transfers: approve, dispatch, receive, with in-transit tracked at the destination
  • Open transfers: dispatch into a pool that belongs to no location
  • Any eligible location claims what it can sell; claims move units into its in-transit balance
  • Claims can be released back into the pool if plans change
  • Closing the pool returns whatever nobody claimed to the source, as a real movement
The open stock pool showing units claimed and awaiting arrival, and units still available for other outlets to claim

05

Ledger and Tally

A full double-entry ledger with Tally's group structure, and a two-way door to the Tally company your accountant already keeps.

  • Chart of accounts on Tally's primary groups, with parties as accounts
  • Day book, account statements, trial balance, profit & loss, balance sheet, ageing
  • Every balance is derived from posted vouchers — nothing is cached, so nothing can drift
  • Import masters and the day book straight over Tally's HTTP gateway, or from an XML export
  • Each imported voucher keeps its Tally GUID, so re-importing an overlapping range is a no-op
The day book listing posted sales, purchase and receipt vouchers with party, narration, amount and source

06

Outlet portal

A mobile-first workspace bound to one outlet, for the people actually standing at the shelf.

  • Barcode-first quick entry for sales, returns and damages
  • Blind stock counts: the system quantity is hidden until the count is approved
  • Receipts can be partial, and 'close short' finishes a delivery that will not be completed
  • Outlet staff never see another outlet's data, in the portal or through the API
The mobile outlet portal showing quick entry for sales, receipts, counts and returns

07

Integrations and reporting

A REST API built for POS networks that retry, and reports that export without a warehouse.

  • Per-outlet API keys with scopes, expiry and SHA-256 storage
  • Every movement batch requires an idempotency key; external refs dedupe per outlet
  • Signed webhooks with retries, backoff and a circuit breaker on dead endpoints
  • Reports run in SQL on demand, stream to CSV up to 100k rows, render to PDF for sharing
  • CSV import for sales and counts, validated server-side and committed exactly once
A stockout frequency report with per-outlet breakdown and export options

Architecture

Deliberately boring where it counts

One stateful dependency, one movement service, and permissions checked on the server every single time.

PostgreSQL and nothing else

Jobs run on pg-boss inside the same database. Realtime is LISTEN/NOTIFY fanned out over Server-Sent Events. Rate limits are fixed windows in Postgres. No Redis, no broker, no object store to operate or back up separately.

One movement service

The portal, the REST API, CSV imports, replenishment, transfers, counts, HQ corrections and the demo simulator all call the same code, so locking, validation, alert evaluation and events behave identically no matter where a change came from.

Authorization on the server

Every page, route handler and server action re-checks permissions and scope. Hiding a button is a convenience. The region switcher can only narrow what a user may see, never widen it.

Transactional side effects

Notifications and webhooks are enqueued inside the business transaction, so nothing is ever sent for a movement that rolled back. Realtime events fire on commit, for the same reason.

Idempotency by default

Movement batches need an idempotency key, lines may carry an external reference unique per outlet, and imports commit a stored batch under a row lock. Retries are safe everywhere they can happen.

Auditable by construction

The stock ledger is append-only, balances are derived from posted vouchers, and an organization-wide audit log records who changed what and what it was before.

The reasoning behind each of these choices is written down in the repository's decision log, and summarised on the blog.

Walk through it with an engineer

Not a slide deck — the running product, against data that looks like yours, with the person who built it answering questions.