Enterprise MRO Workflow Platform
From a maintenance request to a signed, regulator-recognized release certificate — held in software, not memory.
- My role
- Lead backend engineer · primary author of the core platform (~2 yrs)
- Domain
- Aerospace MRO — AS9110-regulated maintenance, repair & overhaul
- Scope
- Modular monolith · ~10 React/TS apps · approvals, signatures, scheduling
- Stack
- .NET · CQRS/MediatR · EF Core + Dapper · WorkflowCore · SQL Server · SignalR
A regulated aerospace MRO platform — a .NET modular monolith behind a suite of ~10 React apps — that carries a component from intake through repair to a signed release, with every approval and document state explicit and auditable. I was lead backend engineer and primary author of the core the whole suite runs on.

It exists to kill double entry.
A technician used to record the same tool twice — once against the job, once in the equipment log — and the two copies drifted, which stops being clerical the moment a regulated recall has to prove which tool touched which component. Tagging a tool to a job now generates the log entry from it, so there is one record instead of two that can disagree.
One deployable core, eight engineers.
A modular monolith over microservices — MediatR, EF Core + Dapper — for the transactional integrity and end-to-end traceability a regulated shop needs, without the operational weight a lean team would have to run in production. The module boundaries are strict and modules talk through integration events instead of each other's entities, so eight engineers could ship ten apps against one core without colliding inside it.
One deployable core — and the only legal way between two modules
The signature is a card, not a password.
Certification decides who may perform work and who may sign it off, and the stamp recording it is shape-coded to the level of authority behind it — scoped to an ATA chapter, so authority covers one aircraft system rather than the whole aircraft. Signing means putting your eID card in the reader: the key lives on the card, not in our database, so a release is bound to someone who was physically there and can't be lent out like a login. An unqualified sign-off isn't caught later in review — the state machine will not let you submit it.
Why an unqualified sign-off can't be submitted
A permission code is never renamed.
Only deprecated. Renaming one silently changes what a role means for everyone already holding it, and no migration catches that — so new capability gets a new code and the old one stays until nothing references it. A cross-application activity log records who changed what, where, and when, which is the difference between believing the access rules held and being able to show it.
The schedule says why, not just no.
Technician skill, machine availability, approved leave, overtime and public holidays all collide on the same bar, so a job that won't fit is the ordinary case rather than the exception. The planner names the constraint — which resource, which window, and what it displaced — and stores it as a coded record rather than a colour computed at render time. A refusal you can't cite is one you can't defend later, and hover text doesn't exist in an audit.

- 01Unavailability states its own reason. Not a red cell you have to interpret — a hatched band spanning exactly the interval, with the cause set inside it.
- 02A label that won't fit hangs, never truncates. Too narrow a band and the reason moves into free space on a leader line. Hover doesn't exist in a screenshot, a printout, or an audit.
- 03The refusal names its consequence. Not just what blocked the job, but the earliest slot that works and how far past the due date that lands — what a planner would say out loud.
- 04Every constraint is an addressable record. Coded, with the window it covers and what it displaced. Months later you can point at a row and say this is why — a colour computed at render time can't be cited.
A SAP sync that fails safely.
Bidirectional over scheduled jobs and SFTP, timezone-safe, batch-recovering — because in a single source of truth, data that silently drifts is far worse than a job that stops, flags itself, and retries.
The same timeout, committed as you go versus committed on a fence
The certificate is generated, not typed.
The release document renders from live process state and QR-stamps straight off the record: fields populate from the job, the signatory and stamp number come from the authenticated session rather than a text box, and the date is locked against back-dating. Amendments increment a revision instead of overwriting one, and the window shuts for good once the job closes — so what the regulator reads and what the system holds can't drift apart.

- 01Paper is the only light surface in the product. Everything the shop runs itself with is dark board. The one object that physically leaves the building as a regulator-facing record is the one thing rendered as stock.
- 02The route accretes; it never overwrites. Nine stages, each printing the stamp and date that closed it. Completed, in work, and not reached are told apart by border weight, not colour.
- 03The failing rule prints the evidence it read. "Authority 2231 covers ATA 21, 30, 73; this record is ATA 36." A tick and a cross are unfalsifiable — a printed sentence is something an auditor can check.
- 04Unsigned is drawn, not just implied. An empty ruled box with one diagonal through it. Anyone who has handled paperwork reads that instantly, and it needs no colour at all.
In aerospace maintenance, a wrong signature isn't a bug — it's a failed audit or a grounded plane. So on this platform, correctness is something the software enforces, not something people are trusted to remember.