Custom app · 2026
Production Planning
Industrial joinery. Out of respect for the company's privacy, no real screenshots of the application are shown.
Replaces paper order sheets and timesheets. Three purpose-built scheduling engines, machine contention and per-order traceability.
- Next.js
- TypeScript
- PostgreSQL
The problem
The office planned in spreadsheets and the floor's timesheets arrived on paper. Three consequences.
No single truth about the floor
Knowing which machine was free and when an order would start lived in the planner's head.
The loop never closed
The hours actually worked on the floor were never compared with the ones estimated in the office.
No traceability at all
No record of who changed what or when, on orders that run through six or seven stages over several weeks.
The process
- Phase 1
Understand the workshop
Conversations with the person who actually does the planning. That's where the odd rules came from, and they weren't in the original plan.
- Phase 2
Model the domain
Order → product → item → stage. Schema first, interface after.
- Phase 3
The engines
Three schedulers in plain TypeScript, with no React or Prisma in front, and their tests.
- Phase 4
Interface and rebrand
A token system, a validated Gantt palette and a single typeface in several weights.
- Phase 5
Production
Deployment and iteration with the workshop using it.
Three schedulers, not one
An application was rolled out where the office plans and the workshop clocks in: the spreadsheets and the paper time sheets become a single source both of them read.
Planning isn't one question, so there isn't one scheduler but three, each for a different way of looking at the same floor.
The one below is a cut-down version of two of them, running right here. The bars aren't drawn: they're computed.
7 days · 3 more from the machine queue
One row per machine
Cutting
CNC
Edge banding
Assembly
The model
The brief came with one condition ahead of everything else: it needed a solid database. An order runs through six or seven stages over several weeks, and what gets stored wrong in March is paid for in June.
It was the hardest part of the project and it's the part that has held up best: the model has absorbed new rules — product types, routings, templates — without painful migrations or orphaned data.
What you see below is its shape, not its design.
- polymorphic detaildepending on the product type
- materials
- operations and hours per stage
The rules that make it hard
A textbook Gantt chains stages and that's that. These four came out of the real business, and they're exactly the kind of logic that breaks quietly when you touch it. That's why it lives in pure functions with tests.
DATE-type stages
Supplier waits don't compete for a machine: they run in parallel across orders and act as a calendar milestone.
Hour overlap
A stage can start a configurable number of hours before the previous one ends.
Forced start and dragging
Manual dragging can only push later; a forced start wins in both directions. Above both, the machine always wins.
Stages completed at 0 h
Invisible to the scheduler: they show as done and reserve no resource. Above, with a zero-hour stage in the middle; below, without it. The lead time is the same.
The project in numbers
- 3scheduling engines
- 70unit tests
- 26models and enums
- 6.000lines across 67 files
- 112commits
- 3months, and counting
What I took away
Model the domain before the interface
The thing that paid off was making the schema speak the workshop's language. Forms, Gantt and reports came out of it almost on their own.
Hard logic gets isolated and tested
The three schedulers know nothing about React or Prisma. That's the only reason the precedence rules could be reworked without fear.
The odd rules are the product
Overlap, supplier waits and forced starts weren't in the plan: they came out of talking to the person who does the planning. They're also what makes the tool get used.
Authorisation on the server, no exceptions
Hiding a button isn't security. Every mutating action checks for itself.
And in your case?
Is there something in your business that still lives in spreadsheets and on paper?
This was built for an industrial carpentry shop, but the underlying problem — information scattered, nobody holding the whole picture — looks much the same from one trade to the next. I take freelance projects alongside my job, and if you tell me about yours I'll say plainly whether I can help.
Tell me about it →