Every figure in tabular mono
Columns of money only read when digits line up. Fonts load with display: optional; with the default swap, every figure changes width when the font arrives and the whole table jumps.
Mar del Plata, ArgentinaOpen to roles in Buenos Aires or remote
Software for small stores to sell at the counter, keep their stock and close the cash register. I built it alone, end to end. Three stores pay for it and have used it for about three months.
Own product, 2026 – now. Product, design, code and operations.
Next.js, TypeScript, Tailwind CSS 4, shadcn/Radix, PostgreSQL (Neon), Drizzle, Vitest, Playwright, fast-check. Repository (public) (opens in a new tab). Screens come from a test store with demo data.
In daily use for about three months, on counter computers and phones.
A local catalogue and a queue of sales on the counter. When the connection returns, sales replay without being counted twice.
ARCA is Argentina’s tax agency: every invoice has to be authorized online. Invoices A and B and credit notes, plus a test store in production where real invoicing is blocked.
The scene is a store counter during opening hours, in daylight, sometimes in a hurry with a customer waiting. The app runs in the browser of the counter computer and on phones. The owner sees everything; employees sell, check products and run the cash register. The type of business is part of the model: a restaurant gets tables and kitchen tickets, a card shop gets variants by set, condition and language.
The core rule: stock is deducted in one transaction when a sale goes through, and you can’t sell without an open cash session. Online, a sale without enough stock is rejected. Offline is the deliberate exception, explained below.
All of it: scope, design, code, tests and production. Each store’s data is isolated from the others, with owner and employee roles. Stores load their catalogue from a spreadsheet, or from a photo or PDF of a supplier invoice read with AI.
The design brief, in one line: the numbers are the interface. Money, stock, SKUs and dates read like a ledger you can trust at a glance. The tokens and rules are written down in the repository, so every new screen follows them.
Columns of money only read when digits line up. Fonts load with display: optional; with the default swap, every figure changes width when the font arrives and the whole table jumps.
A green zero makes you look up to read that nothing happened. Here the only color is the red 7 for low stock; the zero closings with a difference stay black. Negative amounts go in parentheses, like a bank statement.
Two grey borders give the density: one separates, one structures. Shadows are reserved for the paper documents on screen, like the delivery note, which is what makes them look like paper.
“No customers yet” (dotted border) is not the same as “no results for this filter” (solid border, with a way to clear it). Saying “nothing here” when 400 products are hidden by a filter is the worst case.
Instead of rejecting an offline sale when stock ran out, the sale is recorded, stock may go negative and an alert is raised. It lands in the cash session that was open when it happened, even if that session is closed now. Device clocks are bounded: a date more than 30 days old or 5 minutes ahead is replaced with the sync time.
By the time the sale syncs, the goods have left the store and the money is in the drawer. Rejecting it doesn’t bring the units back; it only loses the record.
Hiding a button is not a permission.
Every action is authorized server-side, per store and per role. I found and closed a privilege-escalation bug in the replay endpoint, and added CI in the same change.
Instead of only example tests, plus a manual test sale after each deploy: property tests for totals, prices, cash counts, accounts and tax amounts, alongside example and end-to-end tests, and a production check that replaced the manual sale.
Totals, prices, cash counts and tax amounts have rules that must hold for any input, and a handful of examples misses edge cases.
A store in production where real invoicing is blocked, to exercise the real production setup without issuing real invoices.
Open to design engineering and full-stack roles, in Buenos Aires or remote (UTC−3). Spanish (native), English (professional, spoken and written).