CASE · 03 / 12    Terhills × EasyMile × Rush Labs2023 — 2025 · MAASMECHELEN · BE

Real-time fleet oversight for autonomous shuttles.

▸ Scroll for the full case
WebIoTReal-timeAutonomous mobilityNestJS · GraphQLNext.js · ViteMapbox GL

We turned EasyMile's low-level “send a shuttle to coordinates” API into a full autonomous transit product — a real-time backend plus three purpose-built apps for passengers, station guests and fleet operators.

SIMULATION · ONE LIVE MOMENT, THREE SURFACES16:27:00
01 · OPERATOR · MAP VIEW
Kiewit PlasNational Park Hoge KempenTerhills Resort01 · HOTEL02 · CABLEPARK03 · PARKING04 · RESORT05 · ELAISAEZ-02EZ-05
02 · KIOSK · STATION 03
03
Parking
direction · Elaisa
16:27
ELAISAstops at Resort
14min
ELAISAstops at Resort
24min
HOTELstops at Cablepark
24min
METRO MODE · ACTIVENL · EN
03 · IN-SHUTTLE · EZ-02
16:27
DIRELAISA
Hotel
Cablepark
Parking
Resort
Elaisa
EZ-10 · SHUTTLE 02 EN ROUTE
01 / 06
Challenge
A product problem as much as a technical one

Terhills, a premier resort in Maasmechelen, Belgium, wanted its guests to move between accommodations, dining and activity zones on autonomous shuttles that felt like a public metro — not a fleet of self-driving cars.

The resort partnered with EasyMile to deploy EZ10 vehicles on site. EasyMile's Site CC API is deliberately minimal: it exposes individual shuttles as primitives you can send to a set of coordinates, and streams back live telemetry. Everything between that primitive and a functioning transit service — scheduled lines, live dispatching, collision avoidance, passenger information, and operator tooling — had to be built.

“Three distinct user groups — passengers inside a shuttle, guests waiting at a stop, and resort staff running the fleet — each needed a different experience, and all three had to stay in sync with a fleet of autonomous vehicles moving in real time.”

— Project brief
02 / 06
Solution
One backend · Three surfaces · One content model

We designed and built a complete transit product on top of EasyMile's API: a real-time backend and three purpose-built front-ends, each tailored to its audience.

Under the hood, a GraphQL service bridges the operator's metro abstraction and EasyMile's low-level API. A proprietary “metro mode” algorithm assigns shuttles to scheduled lines and recomputes starting points mid-trip from live telemetry. A collision-avoidance engine detects overlap across routes. A per-shuttle state machine reconciles the backend against shuttle events streamed over an authenticated WebSocket.

01 · IN-VEHICLE

In-Shuttle Display

A live trip timeline inside every shuttle — current destination, upcoming stops, and progress along the route. Packaged as a single-file Vite build so it deploys cleanly on in-vehicle hardware.

02 · STATION

Station Kiosk

A subway-style “next shuttles” board at every stop, showing live ETAs, destinations, and intermediary stops. Bilingual (NL / EN) and tied to station-scoped announcements operators publish directly from the back office.

03 · BACK OFFICE

Operator Dashboard

A live Mapbox view of the whole site with real-time shuttle positions, active trips, and route conflicts. Operators build metro lines, assign vehicles, broadcast messages, and tune operating parameters without developer involvement.

COLLISION AVOIDANCE · OPPOSING TRAFFIC

Two shuttles, one shared lane, one passing siding.

When two shuttles approach the same segment from opposite directions, the lower-priority vehicle automatically diverts to the nearest passing area and holds until the main lane clears.

Gap100%
B stateNOMINAL
CABLEPARKRESORTPASSING · AREA 02A →← BSHUTTLE ASHUTTLE B A · heading RESORT → ELAISA · speed 10 km/h · priorityB · en route to HOTEL · lane clear
04 / 06
Key features
What you get when primitives become a product

A product, not a prototype — shipped and running.

01
Three-surface product for three audiences

In-shuttle, station, and operator — one shared backend, one shared content model.

02
Metro abstraction over raw mobility

Scheduled lines, mid-trip replanning, and ETAs, built on a per-vehicle coordinate API.

03
Live collision avoidance

Opposing shuttles on a shared segment negotiate passing areas automatically — the trailing shuttle holds until the lane clears.

04
Operator self-service

Stations, lines, fleet, announcements and operating parameters — all configurable from the dashboard.

05
Bilingual passenger UX

NL / EN with station-scoped messaging operators publish in minutes, not sprints.

06
Per-shuttle trip state machine

Serialised reconciliation between WebSocket telemetry, scheduled jobs and admin actions — one source of truth per vehicle.

3
Purpose-built surfaces
1
Real-time GraphQL backend
5+
Stations on the live metro
NL·EN
Bilingual passenger UX

Three surfaces. One clock.

Click between the operator, kiosk and in-shuttle views — the same moment in a running resort day, rendered three ways. Use the controls to dispatch, broadcast, and scrub through the simulation.

ops.terhills.rushlabs.dev / site viewwss://api.terhills · connected
FLEET · 2 ACTIVE
METRO LINES · 1 / 3
LINE A · Hotel → Elaisa
LINE B · Resort Loop · off
LINE C · Elaisa ↔ Parking · off
PARAMETERS
Speed cap10 km/h
Min spacing35 m
Door dwell8 s
LIVESite view · Terhills Resort
16.450.9707° N · 5.6892° E
Kiewit PlasNational Park Hoge KempenTerhills Resort01 · HOTEL02 · CABLEPARK03 · PARKING04 · RESORT05 · ELAISAEZ-02EZ-05
Route · Metro Line A
Shuttle
Conflict zone

Operator Dashboard

Next.js · Mapbox GL · Apollo

Operators see live positions, active trips, and emerging conflicts on a Mapbox site view. They assign shuttles to lines, broadcast station-scoped messages, and tune operating parameters — all without developer involvement.

07 / 06
Results
What a product on top of a primitive unlocks

A fleet of autonomous shuttles, experienced as a resort-wide metro.

01
A frictionless guest transit experience

Presented to visitors as a coherent metro rather than a fleet of vehicles.

02
Reduced wait times and simpler navigation

Real-time scheduling and route optimisation, not fixed timetables.

03
Operational autonomy for resort staff

New lines, stations and announcements ship in minutes, without developer involvement.

04
A scalable product foundation

More shuttles, stations and routes drop into the same model as the resort grows.

Let's build your product

Tell us what you're building. We'll tell you how we'd approach it, what it takes, and how fast we can move.

We'll tell you honestly if we're the right fit. And if we're not, we'll point you to someone who is.

Delivered end-to-end by Rush Labs
Product scoping, UX design, full-stack development, and production infrastructure — one team, one handover.
Stack
  • BackendNestJS · GraphQL · Prisma · Postgres · Redis
  • FrontendNext.js · Vite · React · Tailwind · Mapbox GL
  • Real-timegraphql-ws · RxJS · CQRS · Turf · geolib
Real-time layer
  • Authenticated WebSocket telemetry
  • RxJS dedup · throttling · per-vehicle streams
  • CQRS event bus · DataLoaders
  • Geospatial overlap analysis
Roles
  • ProductScoping · UX · Content model
  • EngineeringBackend · Three front-ends
  • HandoffLive operations with resort staff
© Rush Labs · Case study 03 / 12Terhills × EasyMile · 2023 — 2025