Role
Discovery lead · Product strategist · Solution architect
Year
2026

Operations platform for a mobility business

Scope discovery, multi-role architecture, and gated mocks for a regional mobility operator that needed to unify fleet operations, B2B contracts, and B2C ticketing in one platform.

  • PWA (Next.js 16 proposed)
  • Supabase (Postgres, Realtime, RLS)
  • Multi-tenant from day one
  • Mobile-first across three roles

At a glance

A regional mobility operator wanted a platform to run its business: tracking the fleet, managing corporate contracts, selling tickets to consumers, and giving drivers a working tool that does not require six apps. What started as a conversation about “an app for our drivers” turned into a three-sided product after we mapped the actual operation.

I led the post-discovery scoping that expanded the brief honestly (with the client’s agreement), produced gated screen mocks across three roles, and proposed an architecture that ships in phases without committing the operator to all three sides on day one.

This work is at the active proposal stage. Mocks are gated to a Tier 1 minimum; Tier 2 unlocks once a meeting confirms budget and timeline.

The context

The operator runs a regional mobility business with three groups of users it serves simultaneously:

  1. Internal operations. A fleet of vehicles, drivers on rotating shifts, dispatch decisions made on the phone and a whiteboard, and a finance lead who needs revenue reconciled across both B2B and B2C streams.
  2. B2B clients. Companies that contract the operator for employee transport, with their own headcount, schedules, and billing cadence. These contracts represent the predictable, high-margin part of the business.
  3. B2C riders. Individual passengers who buy tickets per trip. Lower per-transaction value, higher volume, and a different surface area entirely (public-facing booking, payments, push notifications).

Before discovery, the operator described what they wanted as “an app for our drivers, mostly.” After mapping the actual flows, the driver app is one of three surfaces, and not the one with the biggest leverage.

Discovery

The starting input was a recorded audio summary from a previous conversation. I transcribed and analyzed it, then ran one structured session with the operator to validate the picture and identify gaps. Three findings shaped the eventual scope:

The dispatcher is the chokepoint, not the driver. Drivers can do their job with what they have. Dispatchers cannot. The most valuable single surface is the dispatcher’s: a real-time view of where each vehicle is, which trip it is on, who the next passengers are, and which corporate contract or B2C ticket each seat belongs to.

B2B and B2C are not the same product. The B2B side is contract-based: predictable schedules, billing by invoice, employee identities tied to the client company. The B2C side is transaction-based: public booking, immediate payment, anonymous-until-paid passengers. Building them as a single feature would make both worse. Building them as two independently scoped surfaces, sharing the same fleet and dispatcher, made the architecture honest.

The technical decision was bigger than expected. The operator initially assumed a simple “GPS tracking” feature. After discovery, the question was: PWA-only for now, or invest in hardware (dedicated tablets per vehicle, GPS modules)? Each path has different cost, complexity, and unlock timing. We agreed to defer the hardware decision and ship the PWA path first, validating the operational pattern before committing capital to devices.

Architecture

The proposed system is a multi-tenant PWA on Next.js 16 with Supabase for data, auth, and realtime. Multi-tenant from day one (one operator now, room for more later without rewriting).

Three role-scoped surfaces, one codebase. The dispatcher, driver, and rider apps are routes within the same Next.js application, gated by authenticated role. Shared components live in a design system. Role-specific surfaces are kept lean (drivers do not need to see the dispatcher’s full board; riders do not need to know there is a dispatcher).

Realtime where it earns its keep. Vehicle positions, dispatcher view of active trips, and driver assignment updates use Supabase Realtime. Lower-frequency data (B2B contract terms, financial reconciliation) sits on standard server actions. Realtime is a budget; we spend it where the operator actually needs sub-second updates and not elsewhere.

B2B and B2C separated by data model, unified by fleet. Corporate contracts and consumer tickets are different tables with different lifecycles. They share a trips table where the actual movement happens; each trip carries either contract or ticket identifiers, never both. The dispatcher sees the unified view; the billing logic sees the separated streams.

PWA first, hardware later. Phase 1 ships as a PWA across the three roles, installed on whatever phones the drivers already carry and on the dispatcher’s desktop. If operational volume and budget justify it, Phase 2 considers dedicated in-vehicle tablets and GPS modules. The PWA does not block the hardware path; it de-risks it.

Design direction

The gated mocks were produced under deliberate scope discipline. Mock Tier 1 covers the surfaces that have to look right for the proposal to land: dispatcher home, driver assignment, rider booking flow. Mock Tier 2 (contract management, finance reconciliation, admin) only ships if the budget conversation confirms it. The pattern is documented in my workflow: never commit to five screens without knowing the budget supports them.

The visual direction leans operational, not consumer-cute:

  • Dispatcher first. The most-used surface is the dispatcher’s board. It is designed for someone scanning information density on a desk monitor, not for someone on the bus to work. Information is dense without being noisy.
  • Driver surface is a tool. Drivers see one trip at a time, with the next assignment queued. Large tap targets. High contrast. Works one-handed.
  • Rider surface is the consumer face. This is where the brand expression lives. Simpler, friendlier, faster to interact with, branded.
  • Mobile-first across all three. Even the dispatcher’s primary surface is responsive; emergencies happen when the dispatcher is not at the desk.

What I took from this

Discovery is a scope expansion tool, not just a clarification tool. Used well, it can turn “an app for our drivers” into a three-sided platform that the client recognizes as the real problem. Used badly, it can also do the opposite, by anchoring on what they originally said.

Real-time is a budget. Treating realtime as a finite spend (not a default) keeps both the architecture and the operating cost honest.

Hardware decisions are usually upstream of the software decision. Asking “do we ship a PWA or invest in tablets” before any line of code keeps the proposal from collapsing six months in.

Gated mocks protect the budget conversation. Tier 1 mocks land the proposal. Tier 2 mocks unlock when budget is confirmed. This is not a sales tactic; it is honest scope discipline. The mocks themselves are work I do not do for free.

Stack

Next.js 16 App Router as a PWA, deployed on Vercel. Supabase for Postgres, authentication, RLS, and Realtime. Multi-tenant from day one (businesses table with RLS enforcing tenant isolation, even though one tenant is currently in scope). TailwindCSS for the design system. Sentry for observability. Push notifications via web-push standards, no native app required.

← All projects