update documentation

This commit is contained in:
2026-05-18 15:01:53 +02:00
parent 834025e560
commit 7018443b18
13 changed files with 756 additions and 725 deletions
+95 -83
View File
@@ -1,101 +1,113 @@
# Development Guide
This guide covers setting up the development environment, running the applications, and maintaining code quality.
## Prerequisites
## 🛠 Prerequisites
- Node.js 20 or newer
- npm 9 or newer
- Android Studio or Xcode for native mobile builds
- Expo/EAS tooling when building or submitting mobile apps
- **Node.js:** Version 20.x or higher.
- **npm:** Version 9.x or higher.
## Install
## 📥 Installation
1. **Clone the repository:**
```bash
git clone <repository-url>
cd TimeToLeave
```
2. **Install dependencies:**
```bash
npm install
```
*This installs dependencies for the root workspace as well as all apps and packages.*
3. **Environment Variables:**
- Web App: Copy `apps/web/.env.example` to `apps/web/.env` and configure your HAFAS/Geocoding API keys.
- Mobile App: Copy `apps/mobile/.env.example` to `apps/mobile/.env` and set the backend API URL.
## ▶️ Running the Applications
| Script | Command | Description |
| :--- | :--- | :--- |
| `dev` | `npm run dev` | Starts the Next.js development server (Web) on `http://localhost:3000`. |
| `dev:mobile` | `npm run dev:mobile` | Starts the Expo development server (Mobile) and opens the Expo Go simulator. |
| `build` | `npm run build` | Builds the production bundle for the Web application. |
## 🧪 Testing & Quality Assurance
The project enforces strict typing and linting across all workspaces.
| Script | Command | Description |
| :--- | :--- | :--- |
| `test` | `npm run test` | Runs **Vitest** for the Web app (using jsdom & React Testing Library) and **Jest** for the Mobile app (using jest-expo). |
| `lint` | `npm run lint` | Runs **ESLint 9** across the entire monorepo. |
| `typecheck` | `npm run typecheck` | Runs **TypeScript 5** type checking across all workspaces. |
### Testing Specific Packages
If you want to run tests for a specific workspace:
```bash
cd apps/web && npm test
cd apps/mobile && npm test
cd packages/core && npm run typecheck
npm install
cp .env.example .env
```
## 🐳 Docker Support (Web App)
The root workspace owns dependency installation. Avoid installing separately inside workspaces unless you are intentionally changing that workspace's dependency list.
The web application includes a `Dockerfile` and `docker-compose.yml` for containerized development or deployment.
## Environment
| Variable | Default | Purpose |
| --- | --- | --- |
| `PORT` | `3000` through Next dev defaults | Web server port when the runtime honors it. |
| `HAFAS_URL` | `https://fahrplan.oebb.at/bin/mgate.exe` | ÖBB HAFAS endpoint. |
| `HAFAS_TIMEOUT_MS` | `10000` | HAFAS request timeout. |
| `HAFAS_VER`, `HAFAS_LANG`, `HAFAS_AID`, `HAFAS_CLIENT_*` | ÖBB app-compatible defaults | HAFAS request envelope metadata. |
| `NOMINATIM_URL` | `https://nominatim.openstreetmap.org` | Geocoding endpoint. |
| `NOMINATIM_USER_AGENT` | `TimeToLeave/2.0` | Required Nominatim user agent. |
| `OSRM_URL` | `https://router.project-osrm.org` | Bike and foot routing base URL. |
| `WIENER_LINIEN_API_URL` | `https://api.wienerlinien.at/darwin-v2` | Wiener Linien live data base URL. |
| `OEBB_GTFS_URL` | ÖBB 2026 GTFS ZIP | Optional HAFAS response enrichment source. |
| `CORS_ALLOWED_ORIGINS` | `http://localhost:3000` fallback | Allowed browser origins for `/api/*`. |
| `API_RATE_LIMIT_MAX_REQUESTS` | `120` | Per-IP API requests per window. |
| `API_RATE_LIMIT_WINDOW_MS` | `60000` | Rate-limit window length. |
| `DEPLOYMENT_URL` | local fallback in OAuth code | Public app URL for Google OAuth redirects. |
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, `GOOGLE_REDIRECT_URI` | none | Enables Google Calendar sync. |
| `APP_VERSION` | `0.1.0` | Version returned by `/api/health`. |
| `EXPO_PUBLIC_API_BASE_URL` | empty | Mobile backend URL. Required for physical devices unless the empty base URL is intentionally proxied. |
## Commands
| Command | Description |
| --- | --- |
| `npm run dev` | Start the web app with `next dev`. |
| `npm run build` | Build the web app. |
| `npm run start` | Start the built web app. |
| `npm run dev:mobile` | Start the Expo dev server. |
| `npm run android` | Run the Expo app on Android from the root script. |
| `npm run ios` | Run the Expo app on iOS from the root script. |
| `npm run lint` | Run ESLint across web, mobile, core, and api-client. |
| `npm run typecheck` | Run TypeScript checks across all workspaces. |
| `npm run test` | Run web Vitest tests and mobile Jest tests. |
Workspace-specific examples:
```bash
npm run test -w apps/web
npm run test -w apps/mobile
npm run typecheck -w packages/core
npm run typecheck -w packages/api-client
```
## Web Routes
| Route | Description |
| --- | --- |
| `/` | Departure desk with next upcoming event, train/bike mode selector, live journeys, route sections, reminders, and nearby Wiener Linien departures. |
| `/calendar` | Calendar import/management with URL, file, Google OAuth, and batch destination editing. |
The web add/edit event flow is implemented by `apps/web/src/app/add-event/AddEventModal.tsx`, not a standalone route.
## API Routes
| Endpoint | Methods | Notes |
| --- | --- | --- |
| `/api/health` | `GET` | Returns `{ ok, ts, version }`. |
| `/api/hafas` | `GET`, `POST` | GET is a simple trip search. POST validates and forwards `TripSearch` or `LocMatch`. |
| `/api/geocode` | `GET` | Requires `name`; optional `countrycodes`. Returns the first result. |
| `/api/bike-route` | `GET` | Requires `fromLat`, `fromLng`, `toLat`, `toLng`. |
| `/api/walk-route` | `GET` | Same coordinate contract as bike route, using OSRM foot profile. |
| `/api/calendar` | `GET` | Requires an allowed remote ICS `url`; optional `days`. |
| `/api/calendar/parse` | `POST` | Parses raw ICS text from the request body. |
| `/api/calendar/google` | `GET` | Requires Google OAuth token cookie; optional day horizon. |
| `/api/auth/google` | `GET` | Starts OAuth. |
| `/api/auth/google/callback` | `GET` | Completes OAuth. |
| `/api/auth/google/status` | `GET` | Reports configuration and connection state. |
| `/api/auth/google/disconnect` | `POST` | Clears OAuth token cookie. |
| `/api/wienerlinien/stops` | `GET` | Requires `lat`, `lng`; optional `radius`, capped server-side. |
| `/api/wienerlinien/monitor` | `GET` | Accepts repeated `stopIds`, capped server-side. |
## Docker
The web app includes Docker support:
```bash
cd apps/web
docker-compose up --build
```
## 📁 Web App Routing (Next.js 16)
## Testing Notes
The web app uses the Next.js App Router. Key routes include:
- Web tests use Vitest, jsdom, and Testing Library.
- Mobile tests use Jest, jest-expo, and React Native Testing Library.
- Route, geocoding, HAFAS, calendar, routing, reminder, and UI component tests are present across the repo.
- Run `npm run typecheck` after changing shared types because both apps consume `packages/core`.
| Route | Description |
| :--- | :--- |
| `/` | **Dashboard:** Lists upcoming events and their real-time leave status. |
| `/calendar` | **Calendar Sync:** Interface to import `.ics` files or paste calendar URLs. |
| `/add-event` | **Manual Entry:** Add a new event manually without a calendar source. |
| `/event/[id]` | **Event Details:** Deep dive into a specific event, showing journey options, delays, and local routing. |
## Development Rules
### Backend API Routes
The web app acts as a proxy for external APIs. These are located in `apps/web/src/app/api/`:
| Endpoint | Method | Description |
| :--- | :--- | :--- |
| `/api/health` | `GET` | Health check for the backend proxy. |
| `/api/calendar` | `GET` | Fetch and parse remote `.ics` files. |
| `/api/calendar/parse` | `POST` | Parse raw `.ics` content. |
| `/api/hafas` | `POST` | Generic HAFAS protocol endpoint (TripSearch, LocMatch). |
| `/api/geocode` | `GET` | Forward geocoding (Nominatim). |
| `/api/geocode/reverse`| `GET` | Reverse geocoding. |
| `/api/bike-route` | `GET` | Bicycle routing between coordinates. |
| `/api/walk-route` | `GET` | Walking routing between coordinates. |
| `/api/wienerlinien/stops`| `GET` | Find nearby WienerLinien stops. |
## 📱 Mobile App Structure
The mobile app is organized into the following directories:
- `src/screens/`: UI screens (`EventListScreen`, `EventDetailScreen`, `AddEventScreen`, `CalendarImportScreen`, `SettingsScreen`).
- `src/navigation/`: React Navigation configuration (`AppNavigator.tsx`).
- `src/services/`: API integration and data fetching services.
- `src/store/`: Local state management and AsyncStorage integration.
## ⚠️ Development Notes
1. **Next.js 16 Breaking Changes:** The web app runs on Next.js 16.2+, which introduces breaking changes in routing and API conventions. Always check `node_modules/next/dist/docs/` if you encounter unexpected behavior.
2. **HAFAS Timezones:** Never parse HAFAS times using standard `Date` methods. Use `@timetoleave/core` utilities (`parseHafasTime`, `hafasDateTime`) to ensure accurate CET/CEST and DST handling.
- Use `@timetoleave/core` for shared behavior.
- Use `@timetoleave/api-client` for client-to-backend calls that are shared by web and mobile.
- Keep backend validation close to route handlers, then delegate external service behavior to `apps/web/src/lib`.
- Never parse HAFAS date/time values with ad hoc `Date` logic; use `parseHafasTime()` and `hafasDateTime()`.
- This repo uses Next.js 16. Read the relevant `node_modules/next/dist/docs/` material before changing Next.js framework code.