Faux POS
in plain words
A restaurant register you can actually use, set up for a restaurant group called ACME. Open a table, ring up an order, catch a guest's allergy, redeem a reward, fire to the kitchen and pay.
under the hood
How it works
- One Cloudflare Worker serves the REST API and the SvelteKit site, so there is one deploy and no CORS.
- Each visitor gets a private SQLite Durable Object seeded with ACME's data. It deletes itself after an idle hour.
- Allergy checks run on the server when an item is added. A conflict returns 409 with the trigger ingredients and safe replacements.
- Payments go through a mock processor shaped like Stripe, and idempotency keys stop a repeated charge.
- If the Worker fails or nears its rate limit, Safe Mode runs the same API in the browser on WebAssembly SQLite and keeps the order.
- A test fails if openapi.yaml and the routes differ, and Postman runs the guided demo with assertions.
Stack
- SvelteKit
- Register, kitchen display and Present mode, prerendered as static shells and rendered in the browser
- TypeScript
- The app, the API and the seed data, so totals and loyalty points are computed and can't disagree
- Cloudflare Workers
- One Worker serves the API and the static site, with per-IP rate limits
- Durable Objects
- One private SQLite database per visitor, removed by an alarm after an idle hour
- SQLite
- Check, ledger and kitchen data, with an append-only loyalty ledger and reset as one atomic batch
- WebAssembly
- Safe Mode runs the real API in the browser on SQLite WASM and replays the open order on takeover
- OpenAPI
- 36 operations written by hand, with a test that fails if the file and the routes differ
- Postman
- A collection that runs the guided demo: 14 requests and 28 assertions, also run against production with Newman
- Vitest
- API tests for allergen matching, loyalty, payment idempotency, reset determinism and the failure paths
- Playwright
- Browser tests of the register, the kitchen display, Present mode and Safe Mode
- GitHub Actions
- Type checks, API tests, a production build and the browser tests on every push to main
