Case study · client work
Jad Elevateur
Built for an elevator installation and maintenance company in Morocco: one back office for worksites, stock, invoicing, cash, attendance and payroll.
- Role
- Sole engineer, from the brief to production
- Year
- 2026
The challenge
An elevator company wanted its whole operation in one back office, under Moroccan legal rules, with the margins hidden from anyone not cleared to see them.
In numbers
- 9 days17 to 25 July 2026: every business module in place, 534 of the project’s 605 commits.
- 186API routes, each naming the roles and the scope allowed to call it.
- 13Business rules, numbered P1 to P13 and cited in the code where they apply.
- 3Languages: French first, then English and Arabic, right to left.
What it does
One loop, from contract to cashbox
A client signs a worksite contract or places an order. Products leave the stock, a quote becomes an invoice or a delivery note with its legal number, and payments arrive in cash, by cheque or by transfer before landing in a cashbox.
Purchasing runs through supplier requests that restock the inventory when they are received. On the people side: daily attendance, leave against an 18-day yearly quota, missions to other cities at a per-diem rate, and a monthly salary statement for each member.
Every change is written to an append-only journal, and the dashboard is split by role: operations for everyone, finance only for those cleared to see it.
The operating loop
How a worksite turns into cash
One worksite from the signature to the cashbox, and the purchase that refills the stock it used. Each arrow is a flow the API implements.
Money
Money is never a float, and never edited
Every amount is an integer number of centimes and every VAT rate is in basis points: 2000 is 20%. Counters such as what has been paid or a cashbox’s balance move only by atomic increments, never by assignment.
The cashbox ledger is append-only. Each row carries the balance after it, and a mistake is corrected the way an accountant would: by a contre-passation, an inverse row, never by editing or deleting the first one.
Prices, costs, the issuer’s legal identifiers (ICE, IF, RC, patente, CNSS, RIB) and the buyer are frozen into a document when it is issued. Closing a worksite freezes its margin; validating a salary statement freezes its numbers, so a later attendance fix cannot move a month already paid.
How it was built
Every module, the same six steps
Step 1 of 6
Spec
A deep-dive before any code: schema, endpoints, screens and acceptance criteria. Ten of them, kept in the repository.
Step 2 of 6
API module
One module per domain on Bun and Hono: Mongoose models, Zod schemas, and routes that each declare their roles and scope.
Step 3 of 6
Back office
The matching slice in React: typed routes, query hooks, forms validated with the same rules, French first.
Step 4 of 6
Scopes
The back office’s permission list is synced from the API by a script, so no button shows for an action the server would refuse.
Step 5 of 6
API tests
Thirty Python scripts drive the real API flow by flow: orders, payments, closures, payroll, reversals.
Step 6 of 6
Claude Code
Both repositories carry Claude Code’s instructions, skills and agents: the same playbook, applied to every module.
Finance visibility
Margins never leave the server
Who may see costs, margins and payroll totals is decided on two floors: an organisation-wide switch per role, on for managers and off for HR by default, then a block on a single member. Admins always see them.
The rule is applied to the response itself, not to the screen. For someone not cleared, the fields are absent from what the API sends, so no browser tool can reveal them.
A block on a member takes effect on their next request. The organisation switch is cached for 30 seconds, so flipping it lands within half a minute, without anyone logging out.
Built with
- Bun
- Hono
- MongoDB
- Mongoose
- Redis
- WebSocket
- Zod
- React 19
- Vite
- TanStack Router
- TanStack Query
- TanStack Table
- Zustand
- Tailwind CSS
- shadcn/ui
- PM2
- Docker
- Claude Code
Where it stands
Every module of the brief, built
Attendance, payroll and missions, leave, products and stock, worksites, clients and invoicing, the two cashboxes, cheques, supplier requests and the dashboards are in, in French, English and Arabic. Still to come: a read-only login for employees and interns.
Talk about yours- Modules in the client’s brief, each built as an API module and a back-office slice.
- 11
- Roles, from intern to admin; three of them sign in to the back office.
- 5