# TimeToLeave Architecture This document outlines the architectural decisions, directory structure, and data flow of the TimeToLeave application. ## 🏗️ Monorepo Structure TimeToLeave uses an **npm Workspaces Monorepo** to manage its interconnected components. This allows for seamless code sharing and dependency management between the Web dashboard, the Mobile client, and the shared packages. ```text TimeToLeave/ ├── apps/ │ ├── web/ # Next.js 16 Web Dashboard & Backend Proxy │ └── mobile/ # React Native 0.81 / Expo 54 Mobile Client ├── packages/ │ ├── api-client/ # Unified API Client for Backend Proxies │ └── core/ # Shared Domain Types, Logic, and Utilities ├── docs/ # Comprehensive Documentation └── package.json # Root Workspace Configuration ``` ## 🧩 Component Overview ### 1. Web Application (`apps/web`) - **Role:** Primary dashboard for desktop users and the **Backend Proxy** for HAFAS/Geocoding APIs. - **Framework:** Next.js 16 (App Router) with React 19. - **Styling:** Tailwind CSS 4. - **State Management:** React Context (`EventsProvider`, `ReminderSettingsProvider`). - **Backend Proxy:** The Next.js API routes (`/api/*`) act as a server-side proxy. This is crucial because the HAFAS protocol and various geocoding APIs require server-side execution to protect API keys, handle CORS, and manage protocol-specific payloads. ### 2. Mobile Application (`apps/mobile`) - **Role:** On-the-go companion app for real-time status checks and native device integration. - **Framework:** React Native 0.81 via Expo 54. - **Navigation:** React Navigation 7 (Native Stack Navigator). - **Native APIs:** - `expo-location`: Geolocation for finding nearby stations and calculating local transit (bike/walk) to the station. - `expo-calendar`: Native integration to read local calendar events directly on the device. - `expo-notifications`: Push notifications to alert the user when it's time to leave. - `@react-native-async-storage/async-storage`: Persisting user settings (buffers, toggles) and cached events locally. ### 3. Core Package (`packages/core`) - **Role:** The single source of truth for domain logic and TypeScript types across the entire monorepo. - **Key Modules:** - **Types:** Defines `Event`, `Journey`, `Station`, `BikeRoute`, `CountdownInfo`, and `WienerLinien` specific types. - **HAFAS Time Parsing:** Specialized utilities to parse Vienna-centric (CET/CEST) timestamps. Handles Daylight Saving Time (DST) transitions accurately using `Intl.DateTimeFormat`. - **Countdown & Status Logic:** Algorithms to translate raw journey data into human-readable statuses like *"Leave now"*, *"On time"*, or *"Delayed +12 min"*. - **Formatting:** Standardized formatting for dates, times, distances, and durations. ### 4. API Client Package (`packages/api-client`) - **Role:** A lightweight HTTP client that wraps the Web App's API routes. - **Usage:** Used by both the Web frontend (for server/client data sync) and the Mobile client to communicate with the backend proxy. - **Features:** Handles URL building, query parameters, and JSON serialization for HAFAS requests, calendar fetching, and routing requests. ## 🔄 Data Flow 1. **Calendar Sync:** The user provides an `.ics` URL or uploads a file. The `ApiClient` sends this to the Web App's `/api/calendar` route, which parses the events and returns standardized `CalendarEvent` objects. 2. **Station Search:** The user searches for a station. The `ApiClient` triggers a HAFAS `LocMatch` request via `/api/hafas`. 3. **Journey Calculation:** Using the station `extId` and the event time, the `ApiClient` sends a `TripSearch` request to `/api/hafas`. The backend returns real-time journey data (`Journey[]`). 4. **Local Routing:** Using `expo-location` (mobile) or browser geolocation (web), the app calculates the bike/walk route from the user's home/location to the departure station via `/api/bike-route` or `/api/walk-route`. 5. **Real-Time Status:** The `packages/core` logic continuously compares the `Journey.rD` (real departure) against the current time and local travel duration to update the Leave Status dynamically. ## ⚠️ Technical Constraints & Guidelines - **Next.js Version:** The project uses **Next.js 16.2+**, which includes breaking changes compared to previous versions. Always refer to `node_modules/next/dist/docs/` when modifying Web routing or API conventions. - **HAFAS Timezone:** HAFAS timestamps are strictly tied to `Europe/Vienna`. The `hafas-time.ts` module handles the bi-directional conversion between UTC `Date` objects and Vienna-local HAFAS strings. Never use standard `Date` methods for HAFAS times; always use `parseHafasTime()` and `hafasDateTime()`.