Hazem Salama
Hazem Salama
A finance and collections platform covering the complete funding cycle in one Arabic-first system: client files, installment schedules, collections, treasury, inventory, and risk reporting.
Mo3an runs the complete funding cycle of a Saudi financing operation in one system: the client file, contract and automatic installment schedule generation, the collections workspace with dues and overdue tracking, treasury and finance views derived live from operations, and risk reporting. Arabic-first, built from scratch, guarded by 35 fine-grained permissions — and tied to a 3M+ SAR profit contribution within 3 months of deployment.
3M+ SAR
Profit contribution in 3 months
71
API endpoints
23
Data models
35
Fine-grained permissions

The morning dashboard, from the production system. Every number here is the result of a real accounting entry.
The problem
Installment financing looks simple and is unforgiving in the details: a client signs a contract, the contract becomes monthly installments, and every installment is either paid on time or slips and compounds. Before Mo3an, the whole cycle was manual — scattered spreadsheets for contracts, notebooks for collections, a treasury whose real balance nobody knew without a hand tally, and arrears that surfaced only when someone asked about them. Or didn’t.
The bet was to build one system that carries the entire cycle, where every number on screen is the outcome of a real accounting entry rather than a manual input: the contract generates its own schedule, a payment is distributed across installments and hits the treasury balance in the same instant, arrears are discovered automatically every night, and every movement leaves an entry in an audit log that cannot be erased.
The approach
Enter the financing amount, margin, installment count, and collection day — the system builds the full schedule with dates and amounts, and prints the sale contract, promissory note, and collection contract as PDFs from the same templates.
Every payment, expense, and transfer posts against the balance of a specific payment method. The displayed balance is never an editable field but the running result of a complete movement ledger — every unit of currency traceable.
A nightly scheduled job sweeps due installments, flags the overdue, learns each client’s payment behavior, and classifies them by risk. The collections screen opens every morning on a ready work list.
35 fine-grained permissions checked at every endpoint on the server and hidden in the UI when the user lacks them. The collector sees collections, the accountant sees the treasury, and the manager sees everything.
The unit of everything
An installment is born with the contract as Pending; payments and the nightly job move it between four states. One payment can close an installment and partially open the next. Only the scheduled job — never a person — can mark an installment overdue.
Installment lifecycle · 4 states
A deliberate design decision: an active contract’s financial fields cannot be edited. Amount, margin, and installment count lock at creation, because changing them would corrupt the schedule the client committed to and break consistency with recorded payments. Only the guarantor, notes, and status can change. An approved discount adjusts the remainder without ever touching the schedule’s origin.
Inside the product
From login to backups in nine stages: the client file, the contract and its generated schedule, the collections workspace, treasury, inventory, and reports. All real screenshots of the production system — 13 screens and 15 tabs, all Arabic RTL.
Stage 01 · 09
A no-frills brand login (short-lived access token, 7-day refresh), then a dashboard where every number is backed by a real entry: live treasury balance, the month’s collections, arrears, and six months of in-vs-out.


Stage 02 · 09
The main work screen: four tabs over one dense table. Instant search by national ID or mobile, a risk badge on every client, and unified pagination across the system.


Stage 03 · 09
Everything about one client in four tabs: contract cards with paid vs remaining, the full payment record installment by installment, current arrears, and a document archive.


Stage 04 · 09
Three steps that end with a generated schedule and print-ready contracts. The calculator shows the installment value and the total with margin instantly on every keystroke.


Stage 05 · 09
A morning work list, not a display screen. Overdue installments with phone numbers and a WhatsApp button that opens a reminder message already drafted with the client’s name, amount, and due date.


Stage 06 · 09
Treasury and expenses in one place: net after expenses, balances per payment method, six months of in-vs-out, and where the money goes by expense type.


Stage 07 · 09
Financing cards managed as a movement ledger, not an edited count. Every new contract pulls its cards with an OUT entry tied to the contract number, so book stock always matches reality.

Stage 08 · 09
Four reports over any date range, exported to PDF or CSV in one click: collections split cash vs bank, expenses, standing arrears, and the client-risk report that decides who deserves a new contract.


Stage 09 · 09
The unglamorous parts done properly: a live audit log that streams new entries over Socket.io, and nightly pg_dump backups logged with size and result — plus a manual button before any big change.


Access control
Every one of the 35 fine-grained permissions is enforced in dedicated middleware at the endpoint — and mirrored in the UI, which hides what the user lacks so the button never even renders. The collector sees the collections workspace, the accountant sees the treasury, and the manager sees everything, including the permissions tab itself, which is invisible to everyone else.
Checked on the server at all 71 endpoints — the UI is a convenience, never the guard.
Hidden in the interface: a user without a permission never sees its button or tab.
Granted per user, permission by permission, from the settings screen.

Engineering deep dives
Clients rarely pay an exact installment. The payment service takes only an amount and a method, walks the open installments in order, creates partial and remaining states, credits the payment method’s balance, and issues a receipt number — all inside one transaction that fully succeeds or fully fails.
The displayed balance is never a stored number — it is the result of the entry sequence: opening capital, collected payments, expenses, transfers between methods, and documented adjustments via a BalanceAdjustment model that records who changed what and why.
Lateness is never recorded by hand. A scheduled job alone can move an installment to overdue: it creates an arrears record with the days-late count, updates the client’s payment behavior, and derives the low/medium/high risk class shown across client screens and reports.
Every create, edit, delete, and login is recorded with user, module, description, IP, and before/after values — kept by name even if the account is later deleted, and streamed to the audit screen over Socket.io the moment it happens. Nightly pg_dump backups are compressed and logged with size and result.
Architecture
An Arabic-RTL Next.js frontend talks to an Express API split into 15 independent modules over PostgreSQL via Prisma. Every request runs the same chain — no side doors:
Browser
API · Express
Scheduled · node-cron
Data & documents
Deployment you can explain in a minute: the frontend on Vercel with auto-deploy from main, the Express server in a Docker container on Render, and managed Render PostgreSQL. Local development runs a Docker Compose PostgreSQL rebuilt with one command, seeded with an admin, permissions, opening capital, and interlinked clients, contracts, and payments — so production data is never touched during experiments.
Security
Transport
HTTPS mandatory, a closed CORS allowlist, Helmet headers, and server-level rate limiting.
Identity
Short-lived JWT access tokens with a 7-day refresh, rotated and revocable server-side. Passwords never stored raw.
Permissions
35 fine-grained permissions checked per endpoint in dedicated middleware; the UI hides what the user lacks, so the button never appears.
Inputs
Joi schemas validate every request body before it reaches business logic; identifiers are checked for type and range.
Accountability
An audit entry for every operation — actor, IP, and before/after values — that survives account deletion.
Data
A daily compressed backup with a success/failure log, and a dev environment fully isolated from production data.
The delivery ledger
A complete operating system for an installment-financing office — from the accounting entry to the interface button — designed and built by one person, so that its numbers can be read, its effects traced, and its backups restored at any moment.
71
REST endpoints · 15 modules
23
Prisma models · 7 migrations
35
Fine-grained permissions
13
Screens · all Arabic RTL
3
PDF contract generators
31
Live screenshots in the dossier
Engineering metrics counted from the source. The 3M+ SAR profit contribution is a reported business result from the first three months of deployment.
Let's build the next one