← All projects

Expo Driver Dispatch

expoA real-time driver coordination web app built for the Huntsville Comic & Pop Culture Expo. Coordinators get a live map of every active driver, dispatchers assign and track trips, and drivers self-report status and share GPS location — all from a phone browser, no app install required.

---

The Problem



Running VIP guest transport at a convention means juggling airport pickups, hotel runs, and venue shuttles across a team of volunteer drivers with no shared tooling. Walkie-talkies and group texts don't give you a map. Spreadsheets don't update in real time. The goal was a lightweight, purpose-built tool the whole team could use from whatever device they had in their pocket.

---

What It Does



For coordinators and dispatchers:
  • Live Leaflet map showing every driver's GPS position, updated every 15 seconds

  • Driver sidebar with name, current status, and on-shift filter

  • Full dispatch panel to create and assign trips (airport, hotel, venue, or custom pickup)

  • Guest roster with hotel assignments, linked agent/manager records, and real-time location tracking

  • Flight tracking — scheduled vs. actual arrivals surfaced per guest

  • Guest schedule management (panels, photo ops, autographs, meet & greets)

  • Broadcast announcements pushed instantly to all connected drivers via Socket.IO

  • Admin panel for user management and global app settings

For drivers:
  • One-tap status updates across 12 operational states (heading to airport, guest picked up, on break, etc.)

  • Optional GPS sharing toggle — location streams to the coordinator map while enabled

  • Active trip card with pickup/dropoff details, accept/decline flow

  • Live announcement feed

For handlers:
  • Guest location tracking and status updates scoped to their assigned guests

---

Tech Stack



  • Framework: Next.js 14 (App Router) + custom Node/Express server

  • Real-time: Socket.IO — bidirectional events for location updates, status changes, and announcements

  • Database: PostgreSQL via Prisma ORM

  • Auth: Phone number + OTP (Twilio SMS), JWT sessions stored as hashed tokens

  • Maps: Leaflet / React Leaflet (SSR-disabled, client-only render)

  • Storage: MinIO (S3-compatible) for avatar uploads

  • Deployment: Docker Compose on homelab Proxmox, NGINX Proxy Manager for SSL via Let's Encrypt

---

Data Model Highlights



The schema covers the full operational picture of a convention weekend:

  • Users carry one or more roles (Driver, Coordinator, Admin, Handler) and an onShift flag

  • DriverPresence stores the latest GPS coordinates, heading, speed, and accuracy per driver

  • DriverStatusEvent gives coordinators a full status history, not just the current state

  • Guests link to their hotel, handler, agent, manager, arrival/departure flights, and a running GuestLocationEvent log

  • Trips track the full lifecycle from PENDINGASSIGNEDIN_PROGRESSCOMPLETED, with optional multi-guest support via TripGuest

  • Flights cache live airline data (scheduled vs. actual departure/arrival, delay minutes) to surface at-a-glance for coordinators managing pickups

---

Key Takeaways



Designing auth around phone numbers instead of email worked well for a volunteer driver pool — no password resets, no forgotten accounts, just a text message. The OTP flow with Twilio added maybe two hours of work and removed a whole category of support headaches.

Socket.IO's room-based model made it straightforward to scope broadcasts — driver location events go to coordinators only, announcements fan out to everyone. Keeping that separation clean from the start was worth it.

Disabling SSR on the Leaflet map component is the move. Trying to render Leaflet server-side is a fight you will not win.

---

Next Steps



  • Push notifications for new trip assignments (currently handled via Socket.IO only — requires the app to be open)

  • Flight status polling automation via a background job

  • Post-event reporting: trip summaries, driver activity logs, guest movement timeline