← All work

Food import and wholesale trade — the local market · Deployed and running

Zad Al-Khair

An Arabic web system that follows an imported shipment from the order until its price is collected, and holds trade debt in gold instead of pounds so inflation does not eat it.

System type
Internal operations system (imports · inventory · credit sales · treasury · reports)
Our role
Full build — operations discovery, engineering, deployment
Zad Al-Khair
1 / 6

An internal operations system covering imports, inventory, credit sales, cash accounts and reports as a single chain: every clearing expense is posted as a ledger entry and immediately raises the landed unit cost, goods are sold out of a named inventory batch, and each invoice is measured in gold grams on its issue day and settled at the gold rate of each payment day. The interface is Arabic and right-to-left in its structure, and runs with the same capabilities on desktop and phone.

18
screens
21
database tables
44
server actions
39
indexes and unique constraints
11
database CHECK constraints
27
automated tests, all passing
12,318
lines of code
Sector
Food import and wholesale trade — the local market
System type
Internal operations system (imports · inventory · credit sales · treasury · reports)
Coverage
18 screens, 7 API routes, 21 tables
Users
Two roles: owner (all permissions) and staff (daily operation)
Language and direction
Fully Arabic, right to left (RTL) — not a translation layer over an English interface
Devices
Desktop and phone — the same system, with no cut-down version
Currency and time
Local currency · local time zone · Gregorian dates DD/MM/YYYY

The problem before the system

The trader imports 18 products — beans, rice, oils, spices and salt — from overseas suppliers as well as local ones. The problem was never selling. It was three gaps that cost him real money.

Read the detailHide the detail3 points
The real cost of a shipment was unknown until it ended.
A single shipment passes through customs, the port quay, the chamber of commerce, the food safety authority and transport — each expense paid on a different day and recorded on a different sheet or spreadsheet. The true price per kilo only appeared once the papers were added up by hand, usually after the goods had already been sold at a price set by guesswork.
The books were spread across separate notebooks and spreadsheets.
One notebook for customers, one file for shipments, another for expenses — and figures moved between them by hand. Every transfer was a chance to make a mistake, and there was no single truthful copy.
Selling on credit lost its value silently.
The trader sells on 30 to 90 day terms. When the exchange rate and inflation move during the term, the same amount comes back with less purchasing power. His workaround was to convert the invoice into its gold equivalent on a calculator, write the number in the margin of the notebook, and redo the arithmetic by hand with every partial payment. The idea was right, but it was slow, error-prone, and nobody could audit it later.

Understanding the trade before writing the code

Read the detailHide the detail

We started from one question: what makes this business profit or lose? The answer was two numbers — the landed unit cost after every expense, and the value of a receivable on the day it is collected rather than the day it was issued.

So we built the system around those two numbers rather than around data-entry screens. Every structural decision serves one of them: shipment expenses are real financial entries attached to the shipment, so they appear in the cost and in the ledger at once with no double counting; and every gold conversion is stored at the rate in force the moment it happened, so today's price never changes a past effect.

The system is not a set of independent screens but one chain in which each link feeds the next: the shipment is ordered, clears the port, leaves it, enters the warehouse — each clearing expense being posted and added to the cost. Landed unit cost = (purchase price + all expenses) ÷ quantity. It becomes an inventory batch at that cost; a sale is made from a specific batch and the quantity leaves stock immediately; the invoice is measured in gold at issue — invoice grams = total ÷ the price of a gram of 24k that day; each payment settles at its own day's price — grams settled = amount paid ÷ the gram price on the payment day; and what remains is remaining grams, valued in pounds at today's rate.

The practical consequence: an invoice may be settled with more pounds than it was issued for, and that is correct. In the demo data shown, an invoice issued at EGP 297,500 was settled by two payments totalling EGP 305,800 — the difference is not a surcharge on the customer, it is the same weight of gold he took on the purchase day, priced on the payment day.

Engineering decisions

The rules the core enforces, and the choices that follow from them.

Read the detailHide the detail11 points
  1. 01

    No selling out of thin air

    Every sale line is tied to a real inventory batch, the quantity leaves stock the moment the invoice is issued, and it returns in full if the invoice is cancelled.

  2. 02

    The rate used is stored, never recomputed

    The gold price on the invoice's issue day, and the price on the day of each payment, are both fixed records. A change in today's price does not touch a letter of the past.

  3. 03

    Amounts are never computed in floating point

    All money and gram arithmetic runs through exact Decimal: money to two places, grams to three.

  4. 04

    An invoice with payments cannot be deleted

    Deletion is available only for what nothing has touched yet, so an existing financial trace cannot be wiped out.

  5. 05

    A shipment expense is a single entry

    It appears on the shipment page and in the ledger at the same time — not two records that can drift apart, and no double counting in the totals.

  6. 06

    Paying the supplier does not enter the import cost

    The purchase price is already recorded on the shipment — a decision that stops the same money being counted twice.

  7. 07

    Units carry a physical dimension

    Mass (kg/tonne) and volume (litre) never mix; an unknown unit returns 'no measure' instead of assuming kilograms — a missing number is safer than a wrong one that looks right.

  8. 08

    Weight is shown in tonnes above a tonne and in kilograms below it

    The trader's language, not the database's.

  9. 09

    The gold price comes from the local market

    With an automatic fallback to the global price if the source fails, and then to the last known price — the service never blocks the issuing of an invoice.

  10. 10

    A sudden-jump valve

    Any price reading more than 15% away from the last known price is rejected automatically — protection against a faulty scrape that looks plausible after the source's markup changes.

  11. 11

    An honest 'live' indicator

    It only goes green when the price really is local and current, and it tells the user plainly when the price is global or stale.

Platform-level guarantees

Protection sits in the layer that cannot be bypassed, not in the interface alone.

Read the detailHide the detail7 points

Constraints in the database itself

11 CHECK constraints prevent negative quantities and amounts.

Idempotency keys

They stop an invoice or a shipment being created twice on a double click or a weak connection.

Session invalidation at the root

A session version number lives in the database; incrementing it drops every previously issued token on every device at once.

A limit on sign-in attempts

A time window applied to the identifier and to the network address together.

Indexing built for the queries that exist

39 indexes and unique constraints on the columns that are actually searched and sorted, plus a permanent serial number for the ledger that is displayed without an expensive recount on every view.

Automatic daily backup

To cloud storage, keeping the last 60 copies, with restore from inside the system and a full export at the press of a button.

An audit log

It records who performed any sensitive operation, when, and on which entity — on a best-effort basis, so a failure to record never blocks the operation itself.

Arabic, RTL and responsiveness

The interface is fully Arabic and right-to-left in its structure, not by visual mirroring — and the system runs on a phone with the same capabilities.

Read the detailHide the detail4 points
  • Navigation, tables, forms and printed documents are all built on dir="rtl" and logical properties (padding-inline-start rather than padding-left).
  • Numbers, dates and codes are forced into Latin direction inside Arabic text so they do not flip.
  • Wide tables scroll inside their own container instead of breaking the page, and navigation becomes a sliding side menu.
  • A dark mode (the default) and a light mode are built on colour variables, and the choice is saved for the user.

Sales on the phone

1 / 10

Governance and traceability

Read the detailHide the detail

Two roles with different permissions: the owner holds deletion, restore, user management and transfers between cash accounts; staff run the day (selling, collecting, shipments, expenses) and hold none of those. The same URL yields two different interfaces — the permission governs what is built, not what is visually hidden.

The activity log shows the time, the user, the type of operation and a short summary.

Every number can be traced back to its source: from the debt to the invoice, from the invoice to the inventory batch, from the batch to the shipment, and from the shipment to its clearing expenses.

The screens

32 screens

The software is real; the data shown in the screenshots is not. Every name and figure in these images is generated demo data: suppliers, customers, warehouses, bank accounts, phone numbers, tax numbers, amounts and gold prices are all invented, created on a completely isolated local database with no connection to the production database — which was never read. What is real: the software itself (a production build, with its screens, calculations and behaviour unchanged), the business name and logo, the product names taken from the business's real catalogue, the system-size figures measured from the repository, and the test results.

The full cycle — from order to collection

The shipment register, grouped by stageThe whole operating state on one screen, with no search and no filtering.
A shipment's detail and its landed costThe landed cost is computed from real posted expenses, not typed in by hand.
Warehouses and what is in themStock value is derived from each batch's cost, not entered as a number.
Inside a warehouse and its batchesEvery item in the warehouse leads back to the shipment it came from.
Sales and debt held in goldDebt is kept in grams and valued in pounds at today's rate.
A customer statementEvery pound collected is tied to its invoice, and gold settlement is visible in the figures.
Cash accounts and their balancesEach account's balance is derived from its movements, not an editable field.

Importing and shipments

A shipment still in clearingThe system works on a shipment that is not finished yet, not only on completed ones.
The new shipment formTotal weight is calculated, never typed.
Editing a shipmentAn edit carries through to everything built on the shipment.

Selling linked to gold

Starting a sale: choosing the customerA sale begins from a known customer, so no debt exists without an owner.
Choosing the item from stockOnly what exists is sold, and at a known cost.
Fully settled invoicesThe archive is available without weighing down the daily screen.
Searching inside salesSearch understands how the user writes, not a stored format.
The sale cart with cost and profitProfit is computed on the spot before confirming, not discovered afterwards.

Customers and suppliers

The customer registerCards with complete data, not empty shells.
A customer past dueLateness is counted in days from the due date, not shown as a colour alone.
The supplier registerForeign and local suppliers in one system.
A supplier with his invoices and shipmentsThe payable side closes arithmetically exactly as the receivable side does.

The ledger and the cash accounts

The unified transaction ledgerOne source of financial truth, with no scattered files.
The ledger filtered to one customerFull traceability: from the aggregate figure down to the single movement.
An account statement with a running balanceThe balance can be verified by eye, line by line.
The ledger's second pageThe ledger is built to grow, not for a small sample.

Governance and permissions

Settings under the owner's permissionsFull user management, and a log of what happened that is not erased.
Settings under staff permissionsThe permission governs what the page builds, not what CSS hides.
Sales under staff permissionsStaff run the whole day without holding the destructive tools.

Printed documents

The monthly reportA report that balances and reads, not a raw export.
The document as it prints on paperThe printed page is designed, not a screenshot sent to a printer.

Signing in

The sign-in screenA single protected gate, carrying the business's own visual identity.

Light mode

Sales in light modeThe theme is built on colour variables, not an automatic inversion of colours.
Shipment detail in light modeTables and cards read equally well in both themes.
The warehouse in light modeThe densest data screen stays orderly in the light theme.

What changed

BeforeAfter
A shipment's cost was added up by hand after it endedThe landed unit cost appears instantly with every expense posted
Linking an invoice to gold on a calculator, redone with every paymentConversion and settlement happen automatically, and every rate used is kept as a fixed record
Data spread across separate notebooks and spreadsheetsOne truthful copy: 21 linked tables behind 18 screens
Knowing who was late meant going through the notebookLate accounts are flagged automatically with the number of days late and sorted first
The cash balance was a mental estimateA balance derived from the movements themselves, with a running statement that can be checked line by line
A backup whenever someone rememberedAn automatic copy every dawn, keeping the last 60

This table describes a change in capability — what the system is now able to do — not measured gains. There is no documented before/after measurement of time saved or errors avoided, so no percentage is claimed.

The numbers

System size

Screens
18
API routes
7
Database tables
21
Migrations applied
8
Indexes and unique constraints
39
CHECK constraints in the database
11
Server actions (across 10 files)
44
UI components
19
Lines of application code
12,318
Lines in the data model
424
Unique Arabic strings in the interface
898
Automated tests, all passing (across 4 files)
27

Measured from the repository with re-runnable commands, not estimated. Date of measurement: 30 July 2026.

Test run

goldProvider
5
goldSettlement
7
landedCost
9
formatQty
6
Run time
679 ms

npx vitest run, 30 July 2026: 4 files passed, 27 tests passed. Coverage: the import cost engine, the gold linking and settlement engine, the gold price provider, and quantity formatting.

Size of the demo dataset

Suppliers
6
Customers
14
Warehouses
3
Cash accounts (cash and bank)
3
Shipments
14
Inventory batches
10
Inventory movements
53
Supplier invoices
14
Sales invoices
28
Sale lines
41
Customer payments
30
Ledger entries
127
Days of gold prices
151
Audit log entries
20
Categories
25

These are not real operating figures. They are the size of the generated data that appears in the screenshots, listed for transparency only, and counted with SELECT count(*) on the local demo database.