5.2 KiB
5.2 KiB
Development Guide
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
Install
npm install
cp .env.example .env
The root workspace owns dependency installation. Avoid installing separately inside workspaces unless you are intentionally changing that workspace's dependency list.
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:
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:
cd apps/web
docker-compose up --build
Testing Notes
- 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 typecheckafter changing shared types because both apps consumepackages/core.
Development Rules
- Use
@timetoleave/corefor shared behavior. - Use
@timetoleave/api-clientfor 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
Datelogic; useparseHafasTime()andhafasDateTime(). - This repo uses Next.js 16. Read the relevant
node_modules/next/dist/docs/material before changing Next.js framework code.