You sell a taco.Zoqli deducts the tortilla.
Register the sale and your inventory moves on its own: every ingredient drops by the recipe, and when something is about to run out you hear about it before you run out.
No card, nothing to install. Create an account and try it with sample data.
The whole product, in five seconds
One sale. Three deductions. One alert.
Nobody types the inventory in by hand. You ring up the sale; Zoqli does the math.
Zoqli·Centro branch
Register sale
Tacos al pastor
Recipe · 4 ingredients
Total
3 × $45.00
$135.00
Stock
- Corn tortilla−0.3 kg4.2kgmin 2.0 kg
- Marinated pastor−0.3 kg2.8kgmin 1.5 kg
- Pineapple−0.1 kg1.1kgmin 0.5 kg
- Chihuahua cheese−0.3 kg0.9kgmin 0.8 kg
Stock alert
Chihuahua cheese is below its minimum
1You ring it up
2Zoqli deducts
3Zoqli warns you
Scroll to run the sale
This happens on every sale, at every branch, without anyone lifting a finger. Watch the numbers.
You ring it up
Register the sale like you always do — at the counter or on your phone.
Zoqli deducts
The recipe knows what each dish takes. The stock goes down by itself.
Zoqli warns you
The moment an ingredient crosses its minimum, the alert fires. Before service dies.
Under the hood
What I built, and why it is put together this way.
Zoqli is a personal project. It exists to work through the parts of a real product that tutorials skip: keeping tenants apart, background work, and shipping in two languages.
Isolation enforced by the database
Every tenant table runs FORCE ROW LEVEL SECURITY against an organization id derived from the server session and never accepted from the client. The app connects as a role without BYPASSRLS, so even a missed check in application code cannot leak one restaurant's data into another's.
Rate limiting in two layers
Writes pass through a Redis sliding window; reads are throttled in process, so a page load never pays a network round trip to be allowed through. When Redis fails the limiter degrades to the in-memory one rather than failing open.
Bilingual, with a gate
Every string lives in an English and a Spanish catalog, and the build fails if the two drift apart. No hardcoded copy reaches a component.
Tested at three levels
Unit tests for pure logic, integration tests against a real PostgreSQL with the security policies switched on, and browser end-to-end tests for the flows a person actually walks through.
Stack
Next.js App Router · TypeScript · PostgreSQL · Drizzle · Clerk · Inngest · Tailwind
Open it and drive it yourself.
The demo comes with a whole taquería already loaded: menu, recipes and stock. Register a sale and watch it deduct. We ask for no email and no card, and nothing is saved.
Sixty seconds. Two clicks.