Hazem Salama
All work

Mo3anمُعانLead Engineer2024 · built from scratch · Saudi Arabia · Arabic-first

An installment-financing back office on Next.js, Node.js and PostgreSQL with role-based access control. It carries the cycle from client file to contract, schedule, collections and treasury in one Arabic-first system.

Stack: Next.js, React, TypeScript, Node.js, Express, PostgreSQL, Prisma, Socket.io, Docker

Mo3an today dashboard: live treasury balance, monthly collections, arrears indicators, a six-month chart, and dues needing follow-up, all Arabic RTL
The morning dashboard, from the production system.

A financing office that ran on its employees’ memory

The problem

A client signs a contract, the contract becomes monthly installments, and each installment is either paid on time or slips. Before Mo3an the whole cycle was manual.

The bet was one system for the whole cycle, where every number on screen is the outcome of an accounting entry and not a manual input. That rule is easy to state and expensive to keep. The three decisions below are where it was kept.

The cycle before Mo3an
ContractsKept in spreadsheets.
CollectionsKept in notebooks.
TreasuryNobody knew the real balance without a hand tally.
ArrearsSurfaced only when someone asked.

Three choices, and what each one cost

Decisions

Balances are computed, never typed

ChoseThe treasury has no editable balance. Each payment method’s balance is the running result of its entries: opening capital, collected payments, expenses, transfers between methods, and adjustments recorded with who changed what and why.
OverA stored balance field on each payment method that staff or code update directly. Simpler to build and to read, but once it drifts from the real cash nothing explains the difference.
CostNothing can be corrected by typing a new number. Every fix is another entry, and every payment, expense and transfer has to post its own entry rather than adjust a total.

Contract terms lock when the contract is created

ChoseEntering the amount, margin, installment count and collection day generates the full schedule with dates and amounts. From then on the financial fields are read-only, because changing them would corrupt the schedule the client committed to and break consistency with recorded payments.
OverEditable contracts that regenerate the schedule on every change, which is friendlier to staff but has to reconcile a new schedule against payments already recorded.
CostTerms cannot be corrected in place on an active contract. Only the guarantor, notes and status stay editable, and a reduction in what the client owes goes through an approved discount that adjusts the remainder without touching the original schedule.

Permissions enforced on the server, mirrored in the interface

ChoseFine-grained permissions, granted per user from the settings screen and checked in dedicated middleware at every endpoint. The interface hides what a user lacks, but it is a convenience and never the guard.
OverA few fixed roles such as collector, accountant and manager, with the interface deciding what each one sees. Quicker to build and to administer, but any signed-in user who calls the API directly gets past it.
CostEach permission exists in two places, the endpoint and the screen, and both have to be kept in step. Setting up a new user means granting permissions one by one instead of picking a role.

One installment, four states

The unit of everything

Clients rarely pay an exact installment. The payment service takes an amount and a method, walks the open installments in order, and can close one while partially opening the next. All of it happens inside one transaction that fully succeeds or fully fails.

Lateness is never recorded by hand. Only the nightly job can mark an installment overdue.

The four states of an installment and what sets each one
Moved by payments
  1. Pending
  2. Partially paid
  3. Paid
Set by the nightly job onlyOverdueCreates an arrears record with the days-late count and updates the client’s risk class.

Three months in production

Result

Mo3an in its first three months of deployment
3M+ SAR ($800K+)In transactions supported over the first three months of deploymentnote 1
500+Documents generated daily by automated reporting, as PDF and Excel outputnote 2

The treasury balance, the arrears list and the client-risk classes are all derived from recorded entries. Every operation leaves an audit entry with the user, the module and the before and after values.

The production system

Real screenshots, all Arabic RTL

From client file to collected installment

Client file: header with a medium-risk badge and 13-installment count, contract card CNT-2026-002 showing total, paid, remaining, monthly installment, and a progress bar
Client file · contract cards
New contract, step 1, terms: 18,000 SAR financing at 8% margin over 12 installments; the live calculator shows the 1,620 SAR monthly installment and 19,440 SAR total
New contract · terms and live calculator
Client payments tab: the generated installment schedule with five rows paid and one flagged 158 days late, with inline payment recording and a discount action
The generated schedule · inline collection
Collections workspace: today’s overdue installments flagged by days late, with collect and remind actions per row and a 67% collection rate
Collections · the morning work list

Treasury, reports and oversight

Finance overview: net after expenses, treasury split across a bank account and cash, a six-month collections-versus-expenses chart, and an expense breakdown led by rent
Finance · the treasury view
Inventory: cards available with their book value, a low-stock warning banner, and a movement table of opening stock in and per-contract OUT entries
Inventory · a ledger of movements
Users and permissions settings: three users with their per-user permission counts and active status, a tab only managers can see
Users and permissions · granted per user
Audit log: every operation with user, module, IP, and success or failure status, filterable per module
Audit log · every operation recorded

By the numbers

Counted from the source

Mo3an by the numbers, counted from the source
71REST endpoints in 15 modules
23Data models
35Permissions
13Screens, all Arabic RTL

Notes

How each figure on this page is defined

  1. 1Transactions the platform supported in its first three months of deployment. A transaction total, not revenue.
  2. 2Documents the platform’s automated reporting generates each day, as PDF and Excel output.