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

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

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

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

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

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

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

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.