- Client
- A community market in Thailand (client kept anonymous)
- Sector
- Retail — point of sale
- Period
- June–July 2026
At a glance
A point-of-sale system for a physical market where dozens of independent sellers share the same tills. A cashier rings up one basket; the system knows which stall every item belongs to, splits the sale per seller at the moment it happens, and keeps the books each stall settles against. Thai-first interface with a synchronized English translation set, built on Laravel 12 with a Filament v4 admin panel and PostgreSQL underneath.
The challenge
A shared-till market breaks the assumption almost every off-the-shelf POS makes: that the shop is one business. Here a single basket routinely holds goods from three or four different sellers, and at the end of the month each of them needs to be paid exactly what their stall sold — no more accounting spreadsheet, no arguing with the till roll.
Money software also has two classic self-inflicted wounds waiting: floating-point prices that drift by a satang, and editable transaction tables where a typo "fix" quietly rewrites history. Both had to be impossible by construction, not by discipline.
The solution
A Laravel 12 application with the day-to-day sale screen kept deliberately simple — product grid, basket, charge — and a Filament v4 back office for products, sellers, shifts and reports. Every sale line carries its seller, so per-stall settlement is not a report bolted on top but a property of the data model itself.
Money is stored exclusively as integer satang (฿290 is the integer 29000); no float ever touches an amount. And every till action lands in an append-only audit log — rows are written once and can be neither updated nor deleted, so the history the settlement is based on is the history that actually happened. The interface is Thai-first, with the English translation set kept in lockstep by a sync command rather than by memory.
The results
The system is live and in daily use at the client's market (a private deployment, so it is not linked here). Cashiers work one shared basket per customer regardless of how many stalls it spans, and per-seller settlement falls straight out of the ledger instead of out of an end-of-month spreadsheet session.
The build runs on the same delivery model as the rest of this page: phased Trello cards worked by an AI agent under review, 19 database migrations and a PHPUnit suite grown alongside the features, and the production database covered by the server's nightly dump-and-backup routine from day one.