Real-time vehicle tracking system. Simulates GPS-equipped vehicles moving across Lagos road network and streams their positions to a live map dashboard.
flowchart LR
Sim["Simulator\n(BFS + haversine)"]
API["Backend API"]
DB[("PostgreSQL")]
WS["WebSocket Hub"]
Dash["Dashboard\n(Mapbox)"]
Sim -->|"POST /gps-points"| API
API --> DB
API --> WS
WS -->|"lat, lng, bearing, timestamp"| Dash
Dash -->|"GET /gps (initial load)"| API
- Backend seeds the database and exposes a REST API for vehicles, GPS devices, and GPS points.
- Simulator fetches all registered GPS devices, builds a road graph from Lagos OSM data, and moves each vehicle independently along BFS-computed paths. Sends the vehicle's new position, bearing, and timestamp to the API. New GPS devices are detected and picked up automatically using Server-Sent Events.
- API saves each GPS point and broadcasts it over WebSocket.
- Dashboard renders vehicle markers on a Mapbox map. Markers appear on first REST load (if a last coordinate exists) or on first WebSocket ping. Each marker rotates to face its direction of travel and holds the correct bearing as the map is rotated. Clicking a marker loads its GPS history and draws the route on the map; the route grows in real time as the vehicle moves.
| Layer | Tech |
|---|---|
| Backend | Go, net/http, go-chi/chi, gorilla/websocket, PostgreSQL, Huma |
| Simulator | Go, BFS pathfinding, paulmach/osm (OSM PBF parsing) |
| Dashboard | SolidJS, Vite, Mapbox GL JS, TanStack Query, Axios, openapi-generator client |
- Go 1.21+
- Node.js 18+
- PostgreSQL
- Mapbox access token
- Task (optional, for running all services at once)
Create a .env file in backend/:
PORT=8080
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=yourpassword
DB_NAME=beaconCreate a .env file in dashboard/:
VITE_API_BASE_URL=http://localhost:8080
VITE_WS_URL=ws://localhost:8080/ws
VITE_MAPBOX_ACCESS_TOKEN=your_mapbox_tokenAlso requires the Lagos OSM PBF file at backend/cmd/simulator/map_data/lagos.osm.pbf.
Starts the API, simulator, and dashboard in parallel. The simulator waits for the API to be healthy before starting.
task devIndividual services:
task api-service # backend with live reload (air)
task simulator # GPS simulator
task dashboard # frontend dev server# Backend
cd backend && go run cmd/api/main.go
# Simulator (in a separate terminal)
cd backend && go run cmd/simulator/main.go
# Dashboard (in a separate terminal)
cd dashboard && npm install && npm run devFull interactive docs available at http://localhost:8080/swagger/ when the backend is running.
OpenAPI JSON schema is served at /openapi.json and is used to generate the typed dashboard client via openapi-generator.
WebSocket endpoint /ws streams { gps_id, latitude, longitude, bearing, timestamp } for every position update.
SSE endpoint /api/v1/gps-devices/events streams newly registered GPS devices so the simulator picks them up automatically without polling.