NOW PLAYING · SOLO BUILD
2026
goserve
Point of sale for cafés that have an actual floor to run.
A multi-tenant POS and back-office for cafés and restaurants, built for how they really operate: open a tab on a table or a walk-in, send it to a kitchen screen, settle it in cash or a QR wallet. One deployment, one database, and a tenant boundary the database itself enforces.

- 192K
- LINES OF CODE
- 10
- WORKSPACES
- RLS
- TENANT BOUNDARY
- NPR
- PAISA-EXACT
the problem
A café in Kathmandu runs on a paper tab, a calculator and somebody’s memory of who ordered the second chai. The software that would fix it is priced per terminal in dollars, assumes card rails that aren’t there, and has no idea what 13% VAT on a paisa-denominated bill looks like.
The multi-tenant part is where this kind of thing usually goes wrong. Every café on one deployment is the only way the economics work — and it’s also one missing WHERE clause away from showing one owner another’s takings.
how it works
Tenant isolation is enforced by Postgres row-level security, not by application code. The runtime connects as a role created NOBYPASSRLS, so a query that forgets its tenant filter returns nothing rather than everything — the boundary holds even when the code above it is wrong, which is the only version of that boundary worth having.
The service flow is the real one: a tab opens on a table or as a named walk-in, items are added and sent to a kitchen screen, tickets advance from cooking to ready to served, and only then does the tab offer to settle. The kitchen view updates over WebSockets, because a second screen that needs refreshing is a second screen nobody looks at.
Money is integer paisa end to end, with 13% VAT and cash plus eSewa and Khalti QR reconciled by hand — the honest version of a payment integration in a market where the rails are QR codes and a bank statement.
It’s a Turborepo of four apps — API, web, landing, mobile — over six shared packages, including design tokens, an RBAC model, receipt formatting, and API types generated from the Go service so the client cannot drift from the server it calls.
▸ ATTRACT MODE
the rest of the screens.

▸ RUNS ON
the back of the box.
- api
- Go 1.25chipgxPostgreSQL 16row-level securityWebSockets
- web
- ReactTypeScriptViteshared design tokens
- monorepo
- Turborepopnpm workspacesgenerated api-typesrbacreceipt-format
- domain
- multi-tenant workspacesinventory & COGSshift & drawerNPR / 13% VATeSewa · Khalti
- ops
- Docker Compose dev stackGo migrationsFly.iorunbook + audit docs
▸ GAME OVER · CONTINUE?
the bit that bit.
Putting the tenant boundary in the database instead of a middleware was the one decision that stopped mattering afterwards — which is how you know it was right.