Multi-tenant SaaS
দর্জিখাতা — Tailor Shop Manager
Bangla-first, multi-tenant SaaS for Bangladeshi tailor shops: custom measurement fields, order workflow, and dues — built for owners who may not read fluently.
- Users
- Low-literacy
- Client JS
- Near zero
- Tests
- 105
- Languages
- বাংলা / EN

Screens

The shop floor. Orders grouped by urgency, with overdue work carrying the only red frame in the app and the balance owed as the largest number on each row.

A customer's saved measurements, read far more often than they are changed — so they are large read-only numbers, with editing on its own screen.

An order, with the six-stage tracker and the measurements frozen at the moment it was taken. Changing the customer's book will not change these.

Taking an order. Garment selection and its quantity and price reveal is pure CSS :has() — the picker costs no JavaScript.

Reports separate work taken from money collected — an order placed today may be paid next week, and one revenue figure answers neither question.

Sign-in by phone number, not email. The shop has a phone; it does not have an inbox.
Overview
Tailor shops in Bangladesh run on a paper register: a customer's measurements on one page, their order on another, the balance owed in the owner's head. The shop I built this for has an owner and three karigars, and the constraint that shaped every decision is that the owner may not read English — and may not read Bangla fluently either. That single constraint drove the architecture. The interface is Bangla first, not translated into Bangla: numerals are Bangla too, except money and phone numbers, which Bangladeshis write in Western digits and which is what the keypad produces. Every workflow stage carries a fixed colour and an icon so an order's state is readable before its label is. Overdue work gets the only red frame in the app. The screens are server-rendered with almost no client JavaScript, because these shops run on cheap Android handsets over slow mobile connections — the whole app is plain HTML forms and server actions, with four small client components where the platform genuinely offers no server-side route. Three data decisions carry the product. It is multi-tenant from the first migration: every table hangs off a Shop, uniqueness is composite rather than global, and a single getCurrentShopId() seam means auth landed later without touching another file. Measurement fields are data, not columns — each shop defines its own garments and their fields in JSONB, so a shop that cuts সালোয়ার adds it themselves without a migration. And every order snapshots the measurements it was cut to, so editing a customer's numbers never rewrites what a garment in progress was actually made from. Money is whole taka integers with nothing derived ever stored: the balance is always computed from the order total minus discount minus the sum of payments, and the payments table is append-only. Order numbers are per-shop and gap-free, allocated by incrementing a counter inside the same transaction as the order — verified with twelve concurrent creations producing twelve unique, contiguous numbers.
Key Features
- Multi-tenant from the first migration — composite uniqueness, one auth seam
- Shop-defined garments and measurement fields stored as JSONB, no migration per shop
- Measurements frozen onto each order, so history never rewrites itself
- Six-stage workflow (গ্রহণ → কাটিং → সেলাই → ট্রায়াল → প্রস্তুত → ডেলিভারি) read by colour and icon
- Gap-free per-shop order numbers, allocated inside the order transaction
- Whole-taka integers with an append-only payment ledger; balances always derived
- Printable job slip that travels with the cloth bundle to the workshop
- Reports separating work taken from money collected, compared period on period
- Bangla/English switch covering numerals, dates and workflow labels
- Server-rendered throughout; ~140ms page loads on a cheap handset