The App Shell owns routing, theme and dependency lifetime, while Presentation composes maps, panels, search and itinerary views. iOS Glass and Android Material 3 diverge in Adaptive UI. Views do not call service implementations or Mapbox directly. Supabase authentication and storage sit behind adapters so remote sessions remain separate from view state.
2. City-data normalization
Data/Models converts Seoul Open Data subway, weather and closure responses plus OSM GeoJSON rails into common models. Station, line and coordinate contracts join live responses to static geometry. When an API is empty or rate-limited, demo fixtures provide the same service interface and preserve the presentation path.
3. Train position and rendering path
TrainSimulator combines low-frequency positions, schedules and rail segments. TrainInterpolator estimates progress between updates. The result becomes source and layer updates through IMapController, and the Mapbox adapter renders GeoJSON and markers per frame. Separating refresh cadence from render cadence avoids displaying five-minute input as discontinuous jumps.
4. AI place and itinerary path
Gemini Vision structures social images and text into place candidates and evidence. Geocoding turns valid candidates into coordinates and rejects malformed or out-of-Seoul results. A Dijkstra-based planner orders the route and returns markers, polylines and itinerary cards to Presentation.
5. Trust and failure boundaries
Seoul APIs, Gemini, Mapbox and Supabase are independent external boundaries. Adapters normalize loading, empty, error and demo states, while the map contract limits engine-specific changes. AI places and routes remain suggestions and do not replace official safety or real-time operating information.
6. State and data ownership
The app bundle owns static GeoJSON and transit constants, the presentation layer owns search and map viewport state, and Supabase owns rooms, members, votes and shared location. Keeping recent local searches separate leaves readable city information available during a network outage.
Rendering many lines, stations and POIs makes map-source updates and widget rebuilds likely bottlenecks. Viewport-based layer limits, throttled location publishing, per-service timeouts and caches require validation; the last static transit data is the external-API fallback.
8. Security, observability and debt
A debug path that prints the map token in main.dart should be removed. Supabase RLS, owner RPCs and notification functions form trust boundaries, but unified tracing and external-service SLOs are missing. Map FPS and battery cost have not been measured.