How pauligwe/ubermaps works
1. Overall shape
- This is a two-tier Node/React app with a thin browser frontend and a backend orchestration API.
- The backend owns all routing, geographic calculations, and third-party API calls; the frontend is mainly a UI for inputs, map display, and result rendering.
- There is no persistent database or long-lived domain store; each route search is a request-driven computation.
2. Frontend boundary
- frontend/ is a Vite-built React application.
- App.jsx is the main UI composition point: city selector, origin/destination/budget/departure inputs, map, and results panel.
- The frontend submits a route-planning request to the backend and renders the returned hybrid/full-transit options and map geometry.
3. Backend entrypoint
- backend/index.js starts the Express server.
- It applies security-related middleware and serves the compiled frontend assets in production, so the backend is also the web server.
- This means the deployed system is typically a single origin: browser UI plus API from one Node process.
4. API boundary
- backend/routes/route.js exposes the main application endpoint, POST /api/route.
- This route is responsible for request validation and then dispatching into the route-planning pipeline.
- The API contract is centered around trip planning inputs: origin, destination, budget, departure time, and city context.
5. City and pricing model
- backend/services/cities.js defines supported cities and their local configuration, including geographic center, timezone, and fare rates.
- backend/services/fareEstimate.js converts budget into an approximate Uber reach using the city’s pricing model and surge multiplier.
- This pricing layer is central to the architecture because it determines the search radius and whether a candidate handoff stop is even feasible.
6. Candidate discovery
- backend/services/places.js queries Google Places for transit stops within the budget-derived search area.
- This is the first external lookup in the pipeline and is used to generate candidate handoff points rather than relying on preloaded station data.
- The result is a dynamic set of possible switch points between ride-share and transit.
7. Baseline transit comparison
- backend/services/google.js uses Google Directions in transit mode to compute the full public-transit baseline and later validate candidate hybrid routes.
- The baseline route is important because the app only prefers a hybrid option if it arrives meaningfully earlier than full transit.
- This service is also the source of the transit legs returned to the UI for map display.
8. Road-distance filtering
- backend/services/osrm.js uses OSRM for driving/road distance and duration, plus route geometry/polyline data.
- OSRM acts as a fast filter before more expensive transit validation: candidates that would exceed budget or are effectively walkable from the destination are removed.
- This creates a clear computational boundary: road-network estimation first, then transit confirmation.
9. Orchestration pipeline
- backend/services/pipeline.js coordinates the full algorithm and enforces the overall timeout.
- The pipeline follows the sequence described in the README: radius calculation, stop discovery, OSRM filtering, Google transit validation, and winner selection.
- It is the main business-logic boundary in the repository, and most architecture diagrams should treat it as the core engine.
10. Selection logic and output
- The winner is the hybrid route with the earliest arrival time that beats the full-transit baseline by at least five minutes.
- If no candidate wins, the system falls back to the full-transit route and reports that transit is faster.
- The response includes the chosen handoff stop, estimated Uber fare, comparison against the baseline, and route geometry for visualization.
11. External services
- The backend depends on Google Maps APIs for Places and Directions.
- It also depends on OSRM for routing calculations and Mapbox for frontend map tiles/rendering, based on the required token.
- These integrations are the main external architecture dependencies and should be shown explicitly in any diagram.
12. Execution model
- The system is synchronous from the user’s perspective, but internally it fans out across external services and candidate evaluations.
- The computational bottleneck is in the backend pipeline, not in the frontend.
- Because there is no database, caching layer, or message queue in the repo, all state is transient per request.
13. What to draw in an architecture diagram
- A browser client sends trip-planning inputs to an Express API.
- The API invokes a route-planning pipeline that reads city config, computes budget/radius, queries Google Places, filters with OSRM, validates with Google Directions, and returns the best route.
- The same backend also serves the built React frontend assets to the browser.
Main entry points: pipeline.js Planner · App.jsx App UI · index.js Express server · google.js Google adapter
Components 17
Frontend
Browser UI and map rendering
- Browser · User-facing entry point
- App UI · Main trip-planning interface
frontend/src/App.jsx
Backend
Express API and route-planning engine
- Express server · Hosts API and serves built frontend
backend/index.js - Route API · Main planning endpoint
backend/routes/route.js - Planner · Coordinates the route-selection workflow
backend/services/pipeline.js - Cities · Supported cities and local pricing context
backend/services/cities.js - Fare estimate · Budget to ride-share reach calculation
backend/services/fareEstimate.js - Place search · Finds transit stops near the search area
backend/services/places.js - Road filter · Driving distance, duration, and geometry
backend/services/osrm.js - Google adapter · Transit baseline and validation calls
backend/services/google.js - Transit baseline · Full public-transit route used as benchmark
- Winner selection · Chooses hybrid route or falls back to transit
- Route result · Chosen handoff, fare, comparison, and geometry
External services
Third-party APIs and routing engines
- Mapbox · Map rendering and tiles
- Google Places · Transit stop discovery
- Google Directions · Transit routing and validation
- OSRM · Road-network routing service
Connections 20
- Browser → App UI: opens · Loads the trip-planning interface
- App UI → Express server: POST /api/route · Sends trip inputs to the backend
- Express server → Route API: routes · Express dispatches the planning request
- Route API → Planner: invokes · Hands off validated request parameters
- Express server → App UI: serves build · Returns compiled frontend assets in production
- App UI → Mapbox: renders map · Displays route geometry and map layers
- Planner → Cities: reads · Loads city center, timezone, and fare rates
- Planner → Fare estimate: computes radius · Converts budget into ride-share reach
- Fare estimate → Cities: uses pricing · Applies city-specific fare model
- Planner → Place search: discovers stops · Finds candidate handoff points
- Place search → Google Places: queries · Searches Google Places for transit stops
- Planner → Road filter: filters candidates · Removes infeasible or walkable options
- Road filter → OSRM: routes · Requests driving distance, duration, and geometry
- Planner → Google adapter: validates · Checks candidate routes against transit travel time
- Google adapter → Google Directions: transit mode · Computes public-transit directions
- Google adapter → Transit baseline: returns baseline · Produces the full-transit comparison route
- Planner → Winner selection: selects · Chooses earliest hybrid that beats transit by threshold
- Winner selection → Route result: formats · Builds the final response payload
- Route result → App UI: renders · UI shows results and map geometry
- Route result → Browser: delivers · User receives the planned route outcome