MultiTrain/README.md
2026-07-10 10:54:05 +02:00

65 lines
2.5 KiB
Markdown

# MultiTrain
Search train connections from **multiple start stations to multiple destination stations** in one query. Results are merged, deduplicated, and ranked; each station can carry a **penalty in minutes** (e.g. "Wien Meidling +10 because it takes me longer to get there") that is added to a journey's duration for ranking only — displayed times stay real.
Data comes from [Transitous](https://transitous.org), a community-run [MOTIS](https://github.com/motis-project/motis) instance aggregating open timetable data from many carriers (ÖBB, DB, and many more). Please respect their fair-use policy: set a `USER_AGENT` that identifies you.
## Development
```bash
nix develop # provides node 22 + npm + typescript-language-server
npm install
npm run dev # dev server on http://127.0.0.1:3000
```
Note: `tsx watch` does not detect file changes on Windows-mounted drives (`/mnt/*` in WSL) — restart manually there.
## Architecture
Lightweight hexagonal: `src/model` is the pure domain core (domain model, `JourneySource` port, search use case — fan-out over station pairs, merge, dedupe, penalty scoring). `src/adapter` holds the Fastify HTTP adapter and the Transitous adapter (the only place touching the MOTIS client libraries). `src/main.ts` wires everything by hand.
## API
- `GET /api/locations?query=wien` — station suggestions
- `POST /api/search` — body:
```json
{
"from": [{ "query": "Wien Hbf", "penalty": 0 }, { "query": "Wien Meidling", "penalty": 10 }],
"to": [{ "query": "München Hbf", "penalty": 0 }],
"departure": "2026-07-11T08:00:00Z"
}
```
`departure` and `arrival` are mutually exclusive; omit both to depart now.
## Configuration (environment)
| Variable | Default | Purpose |
|---|---|---|
| `PORT` | `3000` | HTTP port |
| `HOST` | `127.0.0.1` | Bind address |
| `USER_AGENT` | `multitrain` | Sent to the MOTIS API — please personalize |
| `MOTIS_BASE_URL` | api.transitous.org | Self-hosted MOTIS instance |
## Deployment on NixOS
```nix
# flake inputs
inputs.multitrain.url = "github:you/multitrain"; # or a path/git url
# NixOS configuration
{
imports = [ inputs.multitrain.nixosModules.default ];
services.multitrain = {
enable = true;
port = 3000;
host = "127.0.0.1";
userAgent = "multitrain (you@example.org)";
# motisBaseUrl = "https://motis.example.org";
};
}
```
`nix build` produces the server as `result/bin/multitrain`. After changing `package-lock.json`, refresh `npmDepsHash` in `flake.nix` (`nix run nixpkgs#prefetch-npm-deps -- package-lock.json`).