← All work

Industrial manufacturing · Live in production

A fully custom ERP for a manufacturer

From paper, Excel and WhatsApp to one platform covering 13 departments.

Client
Good Steel Chute Systems — Manufacture and installation of waste and refuse chute systems
System type
Fully custom ERP — built around the company’s actual operations, not an off-the-shelf package bent to fit
Build time
~10 weeks
Our role
End to end — discovery, design, build, deployment
A fully custom ERP for a manufacturer
1 / 6

We took a manufacturer whose entire operation was spread across paper, Excel, WhatsApp and a separate program for every department, and replaced it with one platform covering 13 departments — from the first customer call to the quote, the contract, manufacturing, the warehouse, quality, on-site installation, the invoice and the accounting entry — in one interface, with data entered once, and a record of every movement.

13
departments
191
screens
384
API endpoints
192
database tables
17,057
bilingual strings
50–100
internal users
~10
weeks to production
Sector
Industrial manufacturing and installation — chute systems for residential and commercial towers, hotels and hospitals
System type
Fully custom ERP, built around the company’s actual operations
Coverage
13 departments · 191 screens · 384 API endpoints · 192 database tables
Users
50 to 100 internal users, with different permissions for every role
Languages
Fully Arabic + English with real RTL support — 17,057 translated strings
Devices
Desktop, tablet and mobile (iOS and Android) — staff work from site the same way they work from a desk
Build time
~10 weeks from nothing to live operation

The problem before the system

The company works in a field that combines technical selling, manufacturing and installation on construction sites — three worlds that operate nothing like each other. The result was that every department built its own tools.

Read the detailHide the detail8 points
Sales
tracked opportunities in Excel files, and follow-ups lived in someone’s head or on WhatsApp.
Pricing
was calculated by hand from scratch every time, so the price changed depending on who calculated it.
Contracts and documents
were printed paper plus folders on different machines, and any review meant hunting for the latest version.
Warehouses
ran on handwritten sheets, and the real balance was only known after a stocktake.
Procurement
happened by phone and WhatsApp, and supplier offers were compared on a sheet of paper.
Sites
requested material by message, material was issued on a slip, and consumption was recorded later — or not at all.
Finance
re-entered everything from the beginning, because it did not trust anyone else’s numbers.
HR
kept attendance, leave and payroll on paper and in Excel.

The core problem was not a shortage of tools. It was that the same piece of data was re-entered in every department, which produced conflicting versions of the truth with no way to tell which one was right. Alongside it sat real problems that existed but were invisible: dead stock, neglected opportunities with no follow-up, quantity discrepancies, and purchase orders nobody could explain.

Understand how the work actually runs, then build on it

Read the detailHide the detail

We did not start by writing code. We started by sitting with each department and documenting how it actually works — not how it is supposed to work — then formalised that into a single official operating cycle, and built a system that enforces that cycle in the code itself.

This is the fundamental difference between this system and any off-the-shelf product. An off-the-shelf product asks the company to change to suit it. Here it is the other way round: the system knows that a chute is measured by number of buildings and floors, that the central store is the single control point for material, that quality is what allows material into the warehouse, and that pricing is built on engineering drawings that must be attached first.

The operational core: a governed material loop

The most important thing about the system is that it does not just store data — it blocks skipped steps. The full material loop is implemented in code, in its mandatory order.

Execution on site01Central store02Procurement03Goods receipt04Quality05Into stock, then tosite06A GOVERNED LOOP6
Read the detailHide the detail10 points
  1. 01

    Execution on site

    The project engineer raises a material request.

  2. 02

    Central store

    The single control point. Material available → a transfer note moves it to the site store. Material short → a purchase request.

  3. 03

    Procurement

    Request for quotation, three-supplier comparison on the same line items, then a purchase order and its approval.

  4. 04

    Goods receipt

    Received from the supplier in a pending-inspection state. Not stock yet — it moves no balance.

  5. 05

    Quality

    Inspection. Approval posts the quantity into stock; a rejection stops it and opens a non-conformance report.

  6. 06

    Into stock, then to site

    Official stock entry, transfer to the site store, installation, final inspection.

The central store is the single control point

Every material movement passes through a warehouse and is written to an append-only ledger that cannot be edited or deleted from — the balance is a calculated result of the movements, not a number typed in by hand.

Procurement never buys for a project directly

Every purchase order traces back to a purchase request raised by the store, which traces back to a material request from a site. There is no path in the system that lets an execution user buy anything.

Execution requests, it does not buy

Material demand originates in the projects workspace only.

Quality is the gate to stock

Received goods are not available stock until they are inspected. The quality approval is what posts the quantity; a rejection opens a non-conformance report.

The practical result: anyone reading a material balance today can trace every unit of it back to the purchase order, the supplier, the inspection report, and the site that consumed it.

The departments

13
MarketingSalesContractsDocument controlProject managementTechnical officeProcurementWarehousesManufacturingQuality controlFinance & accountingHuman resourcesAdministration13departmentsONE PLATFORM
Read the detailHide the detail13 points
Marketing
Capture leads, qualify them, hand them to Sales with credit retained on both sides (dual attribution), and a return queue for anything that needs completing.
Sales
Opportunities across 12 stages, follow-ups with overdue alerts, contacts, pricing requests, approved supplier lists and performance dashboards — with the pricing tools: a quick calculator (a range) and a detailed one (a firm number) built on an item catalog and material cost, plus a print-ready customer quote.
Contracts
Turn a won opportunity into a contract, bills of quantities that derive the contract value, and financial and technical reviews.
Document control
A coded document register, revisions and issues, transmittals, approvals, an archive, and 15 ready print forms — payment certificate, inspection request, non-conformance, technical query, meeting minutes, as-built and more.
Project management
The project with its phases, tasks and calculated progress, site visits, material requests, daily consumption, snag lists and final handover.
Technical office
Shop drawings, quantity take-off, submittals and technical queries.
Procurement
Requests for quotation, three-supplier comparison on the same line items, purchase orders and their approval, and supplier evaluation.
Warehouses
Balances against min/max levels and a reorder point, the movement ledger, receiving, transfer notes, and stocktaking with its variances.
Manufacturing
Work orders, the production schedule, machines, daily output and maintenance.
Quality control
Inspections by type, checklists, tests and their results, non-conformance reports and corrective actions, and certificates.
Finance & accounting
Customer and supplier invoices, payments and their allocation, expenses, budgets, cost centres — and a full accounting cycle: chart of accounts, journal entries, trial balance, income statement, balance sheet, general ledger and tax reports.
Human resources
A complete employee file, an interactive org chart, geolocated attendance, leave and balances, payroll and payslips, advances and deductions, insurance, end of service, performance appraisal and recruitment.
Administration
Permissions, a central activity log, user tracking, announcements, internal requests, backups and company identity.

The engineering decisions that make the difference

This is not a feature list. These are the decisions that let the system hold up in daily use.

Read the detailHide the detail14 points
  1. 01

    The workflow is enforced in code, not in instructions

    A step cannot be skipped because the path does not exist.

  2. 02

    An immutable stock movement ledger

    The balance is calculated, the history is complete, and a stocktake compares against the calculated figure.

  3. 03

    Quality as a gate

    No stock without inspection — an operating rule that became a software rule.

  4. 04

    A central permission model

    A permission matrix per role, enforced on every API endpoint, not only in the interface.

  5. 05

    A central activity log, generic by design

    Any new department or feature appears in the log automatically with no screen changes — with a full before/after snapshot of every change.

  6. 06

    An on-device cache

    A page opens instantly from the device and then revalidates in the background — no blank waiting screen for data the user has already seen, and every edit invalidates the affected cache immediately so stale data is never shown.

  7. 07

    Hardening against database failures

    A momentary outage degrades gracefully: the page returns a state the user can understand and retries, instead of taking the whole application down.

  8. 08

    Real bilingual support, enforced by a test

    New text is not accepted without both Arabic and English — the build fails without them.

  9. 09

    Direction-safe layout

    Built with logical CSS properties, so the flip to RTL is complete rather than a surface translation, while numbers, dates and codes keep their correct order.

  10. 10

    One standard table system

    Every table gets the same set: sorting, search, filters, table/kanban/card views, column show/hide, column resizing, multi-select with bulk actions, pagination, and per-user saved state.

  11. 11

    Explainable pricing

    Every figure in a quote traces back to its line items, its materials and their quantities — never an opaque number.

  12. 12

    Print-ready documents

    Official forms are generated from the same data, so there is no re-typing and no difference between what is in the system and what the customer receives.

  13. 13

    A quality gate before deployment

    Type checking, language checking and tests block incomplete work from shipping.

  14. 14

    A daily off-platform backup

    With a restore page.

Engineering standards we hold across every project

Written up from this build and from an adversarial review of it that surfaced 24 real defects after the work was considered finished. Each one below was measured, not assumed.

Read the detailHide the detail8 points

A write is never dropped

An operation is not removed from the outbox until the server confirms it was recorded. Anything else turns a write the user was told had succeeded into a write that only exists on their screen.

Shared devices change what a cache is

On a shop-floor machine used by several people, every cached copy is sealed with four stamps — schema version, deployment, user id and timestamp — and any mismatch throws the copy away. A cache is a security question there, not a speed one.

An allowlist at path level, never at root level

Nothing is stored on a device unless it is written down as allowed. A permitted root can contain a query that returns a national ID or an address — so permission is decided per path, and a guard ties sensitive columns to blocked paths.

A generic dispatcher runs as the caller

A shared server-side dispatcher that runs with owner rights silently disables row-level security on everything it calls. Measured: the same ordinary user was refused calling a function directly and succeeded through the dispatcher. It runs as the invoker.

Proof has to resemble use

Server-side tests prove the server is right, not that the user will get there. Seven of those 24 defects were impossible to see in a server test or a code review; all of them appeared in the first real browser measurement.

A guard is not trusted until it fails

A guard that reports "all clear" while blind is worse than no guard. Every check is verified by breaking the thing it protects and confirming it fails.

Every sentence in the interface is a promise

Copy is compared against actual behaviour before shipping. "Not stored on this device" is better than a spinner that will never finish, and a promise wider than the truth is more dangerous than a missing feature.

Cost is measured before it is optimised

No `select *`, an explicit column set per permission level, a limit on every list, counts done on the server, and no unbounded prefetch. In a small project the quota is usually burned by development, not by users — so we measure where it goes first.

Arabic and English, equally

Read the detailHide the detail4 points
  • 17,057 translated strings in a single source, and any new text without its translation stops the build.
  • A complete direction flip: the sidebar, column order, arrows, menus, forms and charts.
  • Arabic names for employees, job titles and departments appear exactly as they do in the company’s own documents, while numbers, dates and document codes keep their correct Latin order so the browser cannot reorder them.
  • Switching language is instant and remembered on the user’s device — no reload, no waiting on the server.

In this image set, every screen is captured in both versions so you can compare them yourself.

English

Arabic

One platform, every departmentThe same screen in both languages — a full direction flip, not a translated layout.

English

Arabic

Sales engineer's home screenThe same screen in both languages — a full direction flip, not a translated layout.

English

Arabic

Live sales dashboardThe same screen in both languages — a full direction flip, not a translated layout.

Works from anywhere, including mobile

A large share of the system’s users do not sit at a desk: site engineers, installation supervisors, storekeepers, procurement staff. The interface is responsive at every size and tested on iOS, Android and desktop.

Read the detailHide the detail4 points
  • Staff record attendance from site with geolocation, request material, log the day’s consumption and file a site visit — from a phone.
  • A manager approves a purchase order, a leave request or a contract review from mobile without going back to the office.
  • Wide tables scroll horizontally inside their own frame instead of breaking the page, forms collapse to a single column, and touch targets and font sizes are set so the phone does not zoom the screen when typing.
  • Dynamic viewport units are used so the Android address bar does not cut off the bottom of the screen.

One platform, every department

1 / 10

Who did what, when, and what changed

Read the detailHide the detail

Every create, update or delete in any department is recorded in one central activity log, with the actor, the time, the entity, a direct link to it, and a description in plain language — plus a before/after snapshot of the fields that changed.

This settled a long-standing management problem: the argument about "who changed the number" ended, because the answer is now written down. Alongside it, a tracking dashboard shows which parts of the system are actually used and which are neglected — information that was used to improve the system itself.

The screens

97 screens

The screens on this page are from the live system in operation, captured in both the Arabic and English versions and at different screen sizes. All names of people, customers, suppliers and projects, contact details and document numbers are demo data, fully substituted, to protect the confidentiality of the company and its clients. The functionality, the calculations, the layout and the business logic are exactly as they are in the system.

Overview

One platform, every departmentone platform across every department
Sales engineer's home screenone URL, a different home per role
Project engineer's home screencomputed progress, not typed
Central store home screenthe operating procedure is the interface
Live sales dashboardevery figure drills down to its deals
Sales analytics report packone filter set, every chart follows
Account settings and preferencesfull RTL, not a translation layer

Sales

Opportunities — the reference tablesame table system on every screen
The same data as a Kanban boardthree views over one query
The same data as cardsphone-first by default, same data
The deal file, end to endcomputed scores, not self-reported
Guided new-deal forma deal starts with a real first touchpoint
Follow-up queue with overdue flagsfollow-up quality is measured, not assumed
Pricing-request queue and gatea gate enforced before the ask, not after
Client contact registrythe same client is never approached twice
Vendor registration approval trackingan approval chain tracked to its decision
In-app field guide for staffthe guide ships with the screen
The same URL, a narrower apppermissions enforced server-side, not hidden in the UI

Marketing

Marketing lead pipelinesame table system in every workspace
Lead hand-off tracking to Salescredit kept on both sides of a hand-off
Leads returned to Marketing to re-qualifynothing is dropped between two departments

Pricing

Quick project price with narrowing hintsan explainable price, not a guess
Product catalogue with derived selling priceone price list behind every quote
Cost build-up from bill of materialscost computed from its inputs

Contracts & document control

Contract register with review trailtwo-department sign-off on every row
Contract intake from a won dealno contract without a won deal behind it
Two-department contract review queueenforced two-department approval
Coded controlled-document registersame table system on every screen
Revision history per controlled documentone revision history, no parallel copies
Transmittals to consultant and clientthe hand-over and its answer in one record
Document approval with consultant codesthe decision keeps its exact meaning
Printable interim payment certificatefull RTL, down to the printed sheet
Printable non-conformance reportissue and its correction on one sheet
Printable transmittal noteprint-ready official paperwork, no retyping

Project management

Project portfolio with computed progresscomputed progress, not typed
One project file, seven tabsentered once, read by every department
Material request raised from siteworkflow order enforced in code
Daily site consumption recordconsumption posts to the stock ledger
Site visit log from the fieldworks from the site on a phone
Installation inspection requests to QCseparation of request and approval
Project handover certificatesclosure recorded as a signed document

Warehouses

Stock against minimum and maximumbalances computed from an append-only ledger
The store's decision queuesingle control point for all materials
Shared material catalogueone shared master list, no re-keying
Stocktake register with variancesevery correction leaves a traceable movement
Requested versus supplied per projectrequested and supplied reconciled by material

Procurement

Purchase requests raised by the storeprocurement acts only on the store's request
RFQ register with quote countsquote collection tracked, not chased by phone
Supplier quotes compared line by linethe award decision is visible on the sheet
Purchase orders and their lifecycleorder totals computed, never typed
Purchase order with its activity trailevery state change attributed and dated
Supplier master with approval statusapproval enforced on the server, not the screen

Quality control

Inspections — the gate on stock entryno stock without an inspection
Non-conformance register by severityno delete path — findings stay on record
Material tests and their verdictsspec against measured, kept on record
Quality certificates registercertificate traceable to its inspection

Manufacturing

Production orders on the shop floorstatus changed from the row, not a form
Production order with material consumptionplanned against consumed, then locked
Shop loading by scheduled dateone live queue, finished work out of the way
Machine maintenance logevery machine has a service history

Finance & accounting

Supplier invoices and outstanding balancesoutstanding computed from payments, not typed
Payments allocated to invoicesallocation updates the invoice automatically
Expense ledger by cost centreapproval writes the accounting entry
Budget against actual with variancevariance rolled up from the lines
Funding release for purchase ordersspending authorised before it is committed
Chart of accounts, both languagesaccounts named in both languages, not translated
Journal entries with double-entry gateposting blocked until debit equals credit
Trial balance with balance checkthe balance check sits on the page
Profit and loss for the periodstatements read from the ledger, not a spreadsheet
Balance sheet as of a dateassets equal liabilities plus equity, checked
General ledger with running balanceevery figure traceable to its entry
VAT report for the returnthe VAT return prepared from the books
Fixed assets and depreciation schedulesdepreciation scheduled and posted, not remembered

Human resources

Employee register and login linkagesame table system on every screen
Complete employee master filepermission-gated compensation data
Interactive reporting-line org chartchart derived from data, not drawn
Daily attendance with late and overtimelate and overtime computed, not typed
Geofenced check-in boardcheck-in tied to an approved site
Leave requests and balancesapproval that moves the balance
Payroll runs with forward-only approvalforward-only money lifecycle
Monthly timesheet, day by dayfull month readable in one grid
Employee self-service dashboardevery employee reads their own payslip
Payroll, insurance and tax reportsstatutory forms derived from the same payslips
End-of-service settlement registersettlement computed from service dates

Technical office

Material submittals and consultant reviewactions that follow the document's stage
Shop drawings and revision historycurrent issue and its full history
Quantity take-off with running totalprinted schedule matches the filtered view
Requests for information, raised to closedstatus follows the action, not memory

Platform & governance

Users, roles and departments
Users, roles and permission matrixpermissions enforced server-side, not in the UI
Delegated per-department permissions editoradministration delegated without opening the whole system
One activity log for every departmentevery change attributable, with before and after
Off-app work sessions reviewtime off the screen still accounted for
Internal requests between colleaguesa request is a record, not a chat message
Improvement tickets raised by staffthe users' backlog lives inside the system
Live database schema documentationdocumentation that ships with the schema
Nightly backup and guarded restoreoff-platform nightly backups, guarded restore

The impact on the business

BeforeAfter
Paper + Excel + WhatsApp + a separate program per departmentOne platform, 13 departments, one source of data
The same data re-entered in every departmentEntered once — every other department reads from it
Every department had its own version of the truthOne agreed figure, calculated rather than typed
Work ran on memory and trustEvery movement documented and auditable
Problems existed but were invisibleThe system surfaced them, so they could be fixed
Errors were caught late, at the invoicePrevented at entry, or visible the same day
Follow-up depended on staff rememberingOverdue alerts, and no opportunity is forgotten
Work was tied to the office and to paperDone from site and from a phone

Tangible results as the company describes them: fewer errors · less time per process · higher data accuracy · problems that surfaced for the first time and could therefore be solved · data entered only once · and new customers won because the way the company works is now professional and documented in front of the client and the consultant.

The numbers

System size

Departments built in full
13
Screens
191
API endpoints
384
Database tables
192
Lines of code
~212,600 · 984 files
Bilingual strings
17,057
Shared UI components
109
Document types · print forms
28 · 15
Test files
83
Build time
~10 weeks · 1,808 updates

Live operating volume

Sales opportunities tracked
412
Projects
401
Customers and parties
375
Registered documents
1,938
BOQ line items
1,004
Activity entries on opportunities
5,287
Events in the central log
2,255
Security events · login sessions
3,216 · 682
Employees on the system
67
Users with accounts
58

Figures from the production database while in use.