← Matt Giallourakis

A server-driven driver-workflow platform

Rewriting a native app hard-coded for two facilities into an interpreter for a process-flow IR, so any facility can be onboarded without an app release


Built at Haneke Design for an industrial manufacturer. The architecture was my design and implementation; it's described at the "you could rebuild it" level.

The problem

Trucks arriving at one of the client's facilities need to be walked through a facility-specific process — where to park, when to move to the scale, which bay door to load at, whether this particular load needs to be tarped, when to weigh out — and facility staff need to hold a driver at a step or wave them forward as conditions change. The existing native apps were hard-coded for two facilities. Every new facility, every change to a flow, meant an app release across two platforms, and the client wanted to bring many more facilities online.

The redesign: an app that interprets a process-flow IR

I rewrote the mobile application from native to React Native / Expo, and redesigned it so that instead of encoding any one facility's process, the app is an interpreter: it receives a facility's workflow as a small intermediate representation — screens, the actions available on them, and the transitions between them — and executes it. The server-driven UI and action system was my design and implementation, informed by Airbnb's published server-driven-UI work and earlier research of my own. Every screen is the same five regions (two headers, two footers, and a main-content area drawn from a small vocabulary — map, form, instruction, waiting, and so on), so a facility's entire flow is data the app renders rather than code it ships. The backend footprint was deliberately tiny: the existing Rails server needed one new field on the facility model and a couple of REST lookup endpoints.

Real-time gating and geofenced progression

Two things drive a driver forward. The first is location: each facility is described by geofenced points of interest — parking area, scale waiting point, truck line, bay doors, tarping station, exit scale — and the app polls position against them to advance to the next step. The second is staff: at certain steps a driver is gated, and facility staff advance or redirect them from an admin dashboard. Those events reach the device as highest-priority push notifications so they're received and processed even with the app in the background, and the flow includes weigh-in, safety screens, and dynamic instructions (tarping, for example) that depend on the specific load. Because a driver can be interrupted at any point, the app persists its state and resumes exactly where it left off.

Per-facility workflows from typed configuration

Onboarding a facility is configuration, not development. Each facility is a TypeScript module — its constants, its geofenced points of interest, and workflow generators that are pure functions of those points and a language (en / es / fr) — with code-generated scaffolding for new facilities, workflows, and screens, and generated JSON that ships to QA and production. The type system keeps every facility's flow consistent with what the app can actually render.

Where it landed

When I left, four facilities were online in production and in full active use, processing roughly 100 drivers a day, with additional facilities configured and staged. It's the clearest example in my professional work of the thing I keep building: a harness that turns a fixed application into a platform — where the capability lives in one interpreter and the variation lives in data — so that the people who own the process can change it without waiting on a release.