The problem
Small retailers, cafés and service businesses in Pakistan and similar markets run on spreadsheets, WhatsApp and paper. The software that exists for them is either enterprise-priced, built for a different market, or a one-off from a local agency with no upgrades and no support. They need tools that are cheap, work on the devices they already own, and don't disappear when the developer moves on.
What I built
Trakzen is a family of products on one shared platform: a point of sale, an e-commerce storefront, and further modules (travel, studio) in progress. I own the whole thing: the data model, the shared NestJS API, the Next.js front ends, auth, deployment and the open-source release of the reusable modules.
Decisions worth mentioning
- One API, many products. Every product is a module behind a single NestJS service, deployed as its own subdomain (
pos.trakzen.com,shop.trakzen.com) behind Caddy. Adding a product is a DNS record, a compose service and three lines of Caddyfile, not a new backend. - Multi-tenancy in Postgres with row-level security. Each business is a tenant; every table carries a
tenant_idand Postgres RLS enforces isolation at the database, so a bug in a query can't leak another shop's data. I chose RLS over schema-per-tenant because migrations stay trivial and one connection pool serves everyone. - Offline-tolerant POS. Sales get queued locally and synced when the connection returns, because a checkout counter can't stop when the internet does.
- Open source by default. The modules that aren't the business (auth, tenancy, printing, reporting) are published so buyers can inspect the code before they trust it with their sales.
What I'd do differently
- Start with one product, not four. The shared platform was the right call, but designing for POS, e-commerce, travel and studio at once slowed the first launch. I'd ship POS alone and let the second product prove the abstraction.
- Write the tenancy tests first. RLS is only as good as the policies, and a test that asserts "tenant A can never read tenant B" should have existed before the first table did.
Outcome
In development. The cleanest modules are on GitHub; a demo goes live at pos.trakzen.com when the first product is sale-ready. I post progress on LinkedIn as I build.