Selected work / Chapter 03

Warsha ورشة

Arabic for “workshop”

Manufacturing execution

Light-manufacturing MES and work-in-progress tracking

A paperless shop-floor system for mid-market GCC fabricators: job orders from multi-level BOMs, a scan-driven operator kiosk, a drag-and-drop Gantt board with live work in progress, and OEE and scrap variance computed from the floor record.

Open live demo Demo password Warsha#2026 · roles to try
Used by
Production planners, Shift supervisors, Machine operators
Built with
Angular 21 · Django 5.2 LTS · Django REST Framework · PostgreSQL 16 · Celery + Redis · Docker Compose · Django Channels · Angular CDK virtual scroll
Languages
English and Arabic, with full right-to-left layouts
Source
Private repository — available on request by email
Warsha planning board: a Gantt chart with a lane per work centre, capacity load bars and job blocks coloured by state.
Fig. 1 Planning and dispatch board — one lane per work centre

The problemWhat the operation is up against.

Mid-market sheet-metal and fabrication plants in the GCC — enclosure, cable-tray and bracket makers supplying MEP contractors and utilities — typically run production from spreadsheets, paper job travellers and an ERP that only learns what happened at the end of a shift.

Machine stops go unrecorded or are written up hours later, a coil of the wrong grade can be fed without anyone noticing until parts fail inspection, and OEE is guessed rather than measured. Operators come from many countries and work in Arabic, English or neither, often with gloves on and a scanner in hand.

Who uses it3 roles, one system.

  • Production planners

    Release job orders, drag blocks on the Gantt board or auto-schedule, and maintain BOMs and routings.

  • Shift supervisors

    Watch live work in progress across work centres, review OEE and scrap variance, and put lots on QC hold.

  • Machine operators

    Use a rugged-tablet kiosk: scan a badge, a machine and lot tags; start, pause and stop with a reason; count good and scrap pieces on a keypad.

What was builtThe working parts.

  • Job orders from multi-level BOMs

    Routings such as slitting → stamping → welding → powder coating → packaging, with standard cycle times and machines. Releasing a job snapshots the routing, explodes the BOM into material requirements per stage and creates child job orders for parts made in-house. Circular BOMs are rejected.

  • An operator kiosk

    Dark and high-contrast with 72 px and larger targets; no dropdowns or text inputs — tiles and an on-screen keypad instead. Every scan gets unmistakable full-screen feedback: a one-second green confirmation, or a red refusal that says what was scanned and what the job needs, and waits to be acknowledged.

  • Scan anywhere

    A global keyboard-wedge listener recognises scanner bursts anywhere on the page and ignores human typing; the server says whether a code is a badge, a machine, a lot tag or a job travel card.

  • Start, pause, stop

    Run and down-time segments with 12 standard stoppage reasons in 7 categories, planned and unplanned; long unplanned stops escalate to supervisors.

  • Material that cannot be fed silently

    Scanning a lot checks it against the stage’s requirement — wrong grade, wrong material, on QC hold, expired, used up. Pieces can only be reported if scanned material covers their BOM quantity.

  • A Gantt dispatch board

    A lane per work centre with a capacity bar. Drag blocks in 15-minute steps or onto a sibling machine; the server re-validates each move and warns about overlaps, precedence and lateness. Auto-schedule re-plans everything not yet started, and the board works right to left in Arabic, drag included.

  • Live WIP, OEE and scrap variance

    Every committed transition is pushed over WebSockets to the board, the shop-floor wall and the kiosks. OEE — availability × performance × quality — is reported per shift, day, work centre and job, with downtime and defect Paretos; scrap variance compares material used with BOM standards.

  • Long lot histories

    A virtual-scrolled lot ledger (over 6,000 rows in the demo) streams keyset pages, and lot genealogy traces forward and backward down to mill heat numbers.

Design rulesThe rules it keeps.

The decisions that make the system trustworthy, enforced on the server and in the database rather than left to the screen.

Material backs every piece.

A stage can report N pieces only if scanned material covers N times the BOM quantity. That is what makes lot traceability and scrap variance trustworthy.

One machine, one job.

Starting a job locks the work-centre row, and a partial unique index on open time segments enforces it in the database too.

Operators never type a password.

The tablet signs in once as a kiosk device; operators identify with their badge and every write is recorded against them.

Moves are race-free.

Each kiosk transition is one transaction taking row locks in a fixed order, so issuing a coil, moving WIP and receiving finished goods commit together, and two kiosks cannot deadlock — proven by concurrency tests on PostgreSQL.

ArchitectureHow it fits together.

An Angular back office and kiosk app, a Django REST API with atomic kiosk services, Channels for live floor updates and Celery for escalations — on PostgreSQL with row-level security.

Front end
Angular 21 (standalone, zoneless, signals), Tailwind CSS 4, CDK BiDi and virtual scroll, a Gantt with right-to-left geometry, the scanner wedge and an on-screen keypad.
API
Django 5.2 LTS and Django REST Framework; kiosk transitions as single atomic services with row locks in a fixed order and idempotency keys; a forward, finite-capacity scheduler.
Analytics
Pure, unit-tested OEE and scrap-variance modules; ORM aggregation that clips time segments to the reporting window in one grouped query.
Real time and jobs
Django Channels pushes floor updates per tenant; Celery beat escalates long stops and expires lots.
Data
PostgreSQL 16 with row-level security, CHECK constraints so stock cannot go negative, a partial unique index for one open segment per machine, keyset-paginated ledgers.
Delivery
Docker Compose with NGINX, Gunicorn, Uvicorn, Celery worker and beat. CI runs pytest against PostgreSQL, Vitest, the production build and a Trivy scan.

Quality evidenceTested where it matters.

  • 60 backend tests (pytest), three of them PostgreSQL-only: two kiosks racing for one coil or one machine, and row-level security. They cover the OEE and variance maths, grade, hold and expiry checks, WIP gating, idempotent replays, rollback of failed transitions, BOM explosion, scheduling and WebSocket pushes.
  • 28 frontend unit tests (Vitest): scanner-burst detection, Gantt geometry including right-to-left drags and overlaps, the keypad, bilingual kiosk error messages and English/Arabic key parity.
  • CI: lint, a migration check, pytest against PostgreSQL, Angular tests and a production build with bundle budgets, then both Docker images built and scanned with Trivy.

ScreensOn the desk and in the field.

CSS-variable tokens for a light office theme and a dark kiosk theme: steel neutrals with safety yellow as the single accent, and every state expressed as shape, colour and word. Barlow, IBM Plex Mono and IBM Plex Sans Arabic, self-hosted; sortable tables with keyboard row navigation and a Ctrl/⌘K command palette.

Try the demoSign in as any role.

The demo runs on realistic seeded data, with a second tenant to show that one customer never sees another’s records.

The sign-in page offers each demo role in one click, and the demo data resets every night at 00:30 UTC.

Demo users
UserRoleWhat to try
plannerProduction plannerPlanning board: drag blocks, auto-schedule, release a job order, edit a routing.
supervisorShift supervisorShop-floor WIP, OEE and scrap variance, put a lot on QC hold and release it.
kioskKiosk tabletBadge EMP-1042 → machine WC-SLT-01 → start the urgent job → scan coil CL-24121 (wrong grade, blocked) → CL-24117 (accepted) → pause → count pieces → stop.
adminAdministratorEverything.
npi_adminAdmin of a second plantA plant in Dammam that sees none of the first plant’s data.

Password for every demo user Warsha#2026

  • The demo plant is a fictitious Dubai fabricator with 10 work centres and a week of replayed shop-floor history.
  • Operators have no password: badges such as EMP-1042 work only on the kiosk. There, the barcode tray (▥) types printed-label codes through the same path a USB scanner uses.

Out of scopeNot built yet — on purpose.

  • ERP integration — purchase receipts and standard costs are entered here.
  • Label printing — lot, badge and machine labels are assumed to exist.
  • Machine connectivity (PLC / OPC UA) — counts and stops come from operators at the kiosk.
  • An offline kiosk queue — the tablet needs plant Wi-Fi.

Work togetherNeed a platform like Warsha?

Tell me about the operation and the rules it can’t break.

Also on GitHub