update documentation
This commit is contained in:
+95
-83
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user