The audit trail writes itself
Eighty database triggers, so a change that goes around the application is still recorded. Editing the audit is revoked from every account in the system — your administrator’s and ours alike.
The product, from the beginning
CargoSharks is the commercial and operational software a freight forwarder runs its day on: an enquiry arrives, it is priced from your own contracts, it is quoted, awarded, executed, documented and invoiced — and at no point is any of it typed into a second system. It is built in Arabic and English at the same time, and it runs on a database that belongs to you.
Open the live demoBook the 15-day pilotHow we are differentThe home page
01 — Why anyone changes
Your rates are in spreadsheets, so a quotation takes a day and a half. Your enquiries are in four mailboxes, so nobody owns them and nobody is timed. Your customers find out where their container is by ringing someone who has to go and find out. And your margin on a job is a number you reconstruct at month-end rather than one you knew when you quoted.
Every one of those is a system-of-record problem. None of them is a training problem, and none of them is fixed by a better spreadsheet. They persist because the job does not live anywhere — it lives in an inbox, a folder, a WhatsApp thread and somebody’s memory, and no two of those agree.
It costs you the jobs you priced too slowly, and the ones you priced too cheaply.
02 — What replaces it
A job enters as an enquiry and leaves as a paid invoice without ever being re-keyed into something else. Each state hands the next one everything it needs, which is the entire point: nothing is retyped, so nothing can be retyped differently.
One queue across every branch, one owner, one response clock.
Priced from your own card where one covers the lane; sent to agents where it doesn’t.
Acceptance converts the quote. Buy, sell and margin lock to the record.
Milestones, customs stage, containers, free-time clocks, exceptions.
Typed, versioned, attached — released to the customer where permitted.
Raised from the job’s own cost ledger, in the right entity, currency and language.
Six seeded milestone templates, at their real lengths
Two consequences follow from that shape, and they are the two things a forwarder notices first.
What you sold is what you costed. Accepting a quotation opens the job file with the buying and selling rates already attached to it, so the margin on the job is a live figure rather than one reconstructed at month-end from three sources that disagree.
Revisions supersede rather than overwrite. What the customer actually accepted stays recoverable, whatever has happened to the quotation since. That is a property of the database rather than a habit of the people using it — see what holds when people are careless.
03 — Modes
Freight is not billed on what a shipment weighs. It is billed on the greater of weight and volume, converted by a divisor that differs per mode, rounded up to that mode’s increment, then floored at that mode’s minimum. Approximating one mode with another’s arithmetic is where a rate quietly stops matching the invoice.
Volume never enters the calculation. Rated by container type and count, with demurrage, detention and storage clocks running per container against the carrier’s free days.
Weight or measure: whichever is greater of cubic metres and metric tonnes. A 1,000 cm³/kg divisor — one cbm to one tonne — with a 1,000 kg minimum.
The IATA 6,000 cm³/kg divisor, which is 166.67 kg to the cubic metre. Rounded up to the next half kilo, floored at 45 kg. Weight breaks apply as your carrier states them.
A 3,000 cm³/kg divisor, rounded up to the whole kilo, no minimum.
A 5,000 cm³/kg divisor, rounded up to the next half kilo, floored at half a kilo.
One pallet — 120 × 100 × 100 cm, 180 kg on the scale
Milestone sets and free-time rules are per mode in the same way. A sea import and an air import do not share a checklist here because they do not share one in the yard.
04 — The three halves of the day
Commercial, operations, finance. The screens below are captures of the running build, not renderings of one — the same screens you can open yourself in the demo.
Commercial
Every enquiry, wherever it came from, with an owner and a clock — and a price that comes from your own contracts.

Operations
Live shipments ordered by exception, oldest first — on the principle that the one nobody has looked at is the one the process missed.

Finance and documents
Job costing, invoicing and receivables across entities and currencies — and every document the job issues, versioned.

05 — The two that fall out
Everything in this category quotes, books and invoices. These two are what quietly does not survive the trip from a demo to a Kuwaiti operation — the first because it needs a scheduled job rather than a screen to look at, the second because it needs a currency the product was not designed around.
One container: five free days, then KWD 28.000 a day
3 of 11 seeded currencies carry three decimals
What this system stores
KWD 12.345
All three decimals kept, from the database through to the invoice
What a system built for dollars stores
KWD 12.35—
The fils is not a rounding error, it is money in circulation: five of them on every line
06 — Language
2,727 interface strings in Arabic and English, kept in sync, with right-to-left in the layout rather than bolted onto it. The quotation your customer opens in Arabic reads the way an Arabic document should, because it was built that way rather than mirrored.


Every product in this market was built in English and had Arabic added afterwards. You can tell within about four seconds, and so can your customer.
07 — Ownership and enforcement
One deployment per customer — your own database in your own instance, not a shared table with a customer column in it. Inside that deployment, branch separation is enforced by the database rather than by application code that can forget one query: ask for another branch’s shipment and it comes back not found, because the row is never in the answer.
Eighty database triggers, so a change that goes around the application is still recorded. Editing the audit is revoked from every account in the system — your administrator’s and ours alike.
Records are superseded, closed or deactivated. The permission to delete does not exist on the account the application runs as.
Kuwait, the UAE, Saudi Arabia or the EU, chosen by you and written into the contract rather than into a support ticket.
No colour, logo or company name is written into the product anywhere. The operator is a setting, so your customer never sees a supplier badge on anything.
Access is granted by your administrator, scoped to named branches, against a ticket reference, and it expires on its own. A banner shows while it is open, and one click revokes it.
88 tables, 197 policies, 80 audit triggers — counted against a live PostgreSQL 18.6, not estimated from a design document.
Seven seeded roles, six keys an auditor asks about
| Role | Issue an invoice | Credit one | Approve a supplier bill | Split a master cost | Book a job | Close one |
|---|---|---|---|---|---|---|
| Administrator | granted | granted | granted | granted | granted | granted |
| Finance | granted | granted | granted | granted | not granted | not granted |
| Operations Manager | not granted | not granted | not granted | granted | granted | granted |
| Coordinator | not granted | not granted | not granted | not granted | granted | not granted |
| Sales | not granted | not granted | not granted | not granted | not granted | not granted |
| Customs Broker | not granted | not granted | not granted | not granted | not granted | not granted |
| Read Only | not granted | not granted | not granted | not granted | not granted | not granted |
How each of those is implemented, and what is still open, is written out in the privacy policy and the data-processing addendum — both drafts, both pending review by counsel, and both honest about where the code and a standard clause disagree.
08 — The boundary
This is the section the instinct says to bury, and it is the one that makes the rest of the page believable. Five things are outside the product by decision rather than by accident, and none of them is coming.
One record, six states, no exits — and what is deliberately outside it
What is in the product today, and what is on the roadmap with dates against it — UAE e-invoicing, Saudi ZATCA, the agent portal, WhatsApp, scheduled reports, live carrier tracking — is kept in one place rather than two: the boundary section above, which is read straight off the specification’s own build-status table.
The demo is the build, running on a seeded dataset, with three sign-ins so you can see what your customer and your agent see as well as what you see. Nothing you do in it touches anything.