Case study 01 / Retail operations

POS Flask — sales, stock, and the alerts that keep a shop moving.

A point-of-sale and inventory system that puts the four things a shop checks all day — what sold, what is left, what is running out, and what happened last week — into one screen instead of four places.

Role
Sole developer — database design, backend, frontend, deployment
Stack
Flask (Python) · Vue.js · SQLite · REST API
Type
Point-of-sale and inventory management

The problem

A small retail operation has a predictable failure mode. Sales get recorded in one place, stock in another, and the gap between them grows quietly until someone sells something that is not there. By the time the mismatch is noticed, nobody can reconstruct when it started.

The underlying issue is not that shop owners are careless. It is that the record of a sale and the record of stock are the same event, and any system that stores them separately guarantees they will drift apart.

What the system does

POS Flask treats a sale as a single transaction that moves stock and records revenue at the same moment. Everything else in the application is built on top of that one guarantee.

How it is built

Flask handles the backend and exposes a REST API; Vue.js drives the interface. The split matters for a point-of-sale system specifically: the sales screen needs to respond instantly to input, and pushing that interaction into the client keeps it fast even when the connection to the server is not.

SQLite stores the data. For a single-location shop, it is the right call — no separate database server to keep running, no extra thing to go wrong on a Saturday, and the whole dataset is one file you can back up by copying it. The schema is written so the move to MySQL is straightforward if a second location ever arrives.

The decision that shaped the rest

Stock adjustments are recorded as events rather than as edits to a running total. A sale, a delivery, a correction, and a write-off are all entries in the same ledger, and the current stock level is derived from them. It costs slightly more work upfront and makes every future question answerable: not just what is the stock now, but when did it change, by how much, and why.

Reusable pattern. Any system where a number has to be trusted — inventory, account balances, leave days — benefits from storing the events rather than the total. Retrofitting that later means reconstructing history you no longer have.

What I would change

The reporting layer grew feature by feature as questions came up, which left it less coherent than the rest of the system. Building it around a small number of composable filters from the start would have produced something more flexible with less code. The offline behaviour also stops at graceful failure rather than queuing transactions locally — a genuine improvement for anywhere with unreliable connectivity.

Need something similar?

POS and inventory is one of the most common builds I take on, particularly for shops and distributors in Cambodia. The business systems service covers what a build typically includes, and the Cambodia page covers working together locally.

Counting stock by hand?

If your sales and your stock live in different places, that gap is costing you money quietly. Let's talk about closing it.

Start a conversation ↗