Refactor monorepo structure and replace hardcoded colors

Add TypeScript project references, update ESLint configs to support
ESM modules, and introduce brand semantic color tokens across the web
app. Add comprehensive documentation for architecture, API reference,
development setup, and user guide.
This commit is contained in:
2026-05-12 21:22:40 +02:00
parent 98e74ee48d
commit 3c6df95a86
20 changed files with 577 additions and 76 deletions
+64
View File
@@ -0,0 +1,64 @@
# 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()`.