# System Architecture ## Recommended stack ### Apps - `apps/web`: trip planning interface. - `apps/mobile`: mobile riding/offline interface. Recommended technologies: - TypeScript. - React for web. - React Native for mobile. - MapLibre-compatible rendering. ### Backend - API service: FastAPI or equivalent. - Database: PostgreSQL + PostGIS. - Queue: Redis + worker for imports/scoring/offline-pack jobs. - Object storage: S3-compatible bucket for generated exports/offline manifests. ### Routing Routing must be accessed through a provider interface. Supported target providers: - openrouteservice for prototype/API-based routing, - GraphHopper for self-hosted or API routing, - Valhalla for self-hosted routing and isochrones, - BRouter-inspired offline routing later. ### Map display - MapLibre-compatible client. - Vector tiles from self-hosted OpenMapTiles, Protomaps/PMTiles, MapTiler, or equivalent. - Do not rely on public OSM tile servers for production app traffic. ### Data pipeline Pipeline jobs: 1. Download OSM extracts. 2. Normalize bikepacking-relevant tags. 3. Build route graph or send extract to routing engine. 4. Import POIs. 5. Attach elevation. 6. Import protected areas/rules. 7. Generate derived segment scores. 8. Build offline pack manifests. ## Services ```text Client Apps |-- Web planner |-- Mobile rider app Backend API |-- Auth/session |-- Trip planner |-- Stage planner |-- Route scorer |-- POI corridor service |-- Offline pack service |-- Export service |-- Community report service |-- Rules service Provider Layer |-- Routing provider |-- Elevation provider |-- POI provider |-- Weather provider |-- Accommodation provider |-- Device export provider Data Stores |-- PostGIS |-- Object storage |-- Cache/queue ``` ## Provider interfaces Every external dependency should be swappable. ```ts interface RoutingProvider { planRoute(request: RoutePlanRequest): Promise; reroute(request: RerouteRequest): Promise; } interface PoiProvider { searchCorridor(request: CorridorPoiRequest): Promise; } interface ElevationProvider { samplePolyline(polyline: Coordinate[]): Promise; } interface WeatherProvider { forecastAlongRoute(request: WeatherRouteRequest): Promise; } interface RulesProvider { getRuleCards(request: RuleCardRequest): Promise; } ``` ## MVP architecture simplification For first implementation: - use a hosted routing provider or mock routing fixture; - use OSM-derived POI fixtures in PostGIS; - implement stage planning and scoring locally; - render a route and stage cards; - export GPX; - define offline pack manifest without full tile download implementation.