feat(reservations): native booking-confirmation import via KDE KItinerary (#1102)

* feat(reservations): native booking-confirmation import via KDE KItinerary

Adds a two-step preview → confirm flow for importing booking emails,
PDFs, PKPass and HTML confirmations. The server invokes the KDE
kitinerary-extractor binary, maps JSON-LD schema.org output to TREK
reservation shapes, and persists via the existing createReservation
pipeline (accommodations, budget, places, WebSocket broadcasts).

- NestJS BookingImportModule: preview + confirm endpoints under
  /api/trips/:tripId/reservations/import/booking{,/confirm}
- KitineraryExtractorService: spawns the binary, filters stderr noise,
  handles QDateTime (@value) timezone-aware datetimes
- kitinerary-mapper: FlightReservation, TrainReservation, BusReservation,
  BoatReservation, LodgingReservation, FoodEstablishmentReservation,
  RentalCarReservation, EventReservation → typed preview items
- BookingImportService: auto-creates place rows; geocodes venues without
  coordinates via Nominatim (name+address → address → name fallback);
  resolves day IDs for accommodation linking
- BookingImportModal: drag-and-drop multi-file upload, preview cards
  with type icons, per-item exclude toggle, confirm step
- Shared Zod contracts: BookingImportPreviewItem, PreviewResponse,
  ConfirmRequest, ConfirmResponse — consumed by controller, service,
  API client and modal
- Dockerfile: node:24-trixie-slim runtime; amd64 downloads KDE static
  binary + locales; arm64 installs libkitinerary-bin + symlinks to
  fixed path; ENV KITINERARY_EXTRACTOR_PATH set for both arches
- /api/health/features exposes { bookingImport: boolean } so the UI
  hides the Import button when the binary is absent
- i18n keys (English), wiki docs, API.md, README one-liner

* i18n: add booking import translations for all 19 non-English locales

Adds 17 reservations.import.* keys and undo.importBooking to ar, br, cs,
de, es, fr, gr, hu, id, it, ja, ko, nl, pl, ru, tr, uk, zh, zh-TW.

* chore: enforce i18n parity

* docs(wiki): add KItinerary local setup instructions to dev environment guide
This commit is contained in:
jubnl
2026-06-04 20:40:57 +02:00
committed by GitHub
parent abe1c549bd
commit 6ef3c7ae6b
64 changed files with 1851 additions and 31 deletions
+43 -2
View File
@@ -84,7 +84,48 @@ npm i
---
## 6. Available Scripts
## 6. Optional: KItinerary (Booking Import)
The booking-confirmation import feature uses [KDE KItinerary](https://apps.kde.org/itinerary/) to parse travel documents. The server works without it, but the import endpoint will be non-functional.
### Linux — amd64
Download the static binary from the KDE CDN and verify the checksum:
```bash
wget -qO /tmp/ki.tgz https://cdn.kde.org/ci-builds/pim/kitinerary/release-26.04/linux/kitinerary-extractor-x86_64-26.04.0.tgz
echo "b7058d98990053c7b61847fef0c21e02d59b60e323e2b171ca210b682334e801 /tmp/ki.tgz" | sha256sum -c
sudo tar -xz -C /usr/local -f /tmp/ki.tgz bin/kitinerary-extractor share/locale
rm /tmp/ki.tgz
```
### Linux — arm64
```bash
sudo apt-get install -y libkitinerary-bin
sudo ln -sf "$(find /usr/lib -name kitinerary-extractor -type f | head -1)" /usr/local/bin/kitinerary-extractor
```
### Environment variables
Add these to your local `.env` (or export them before starting the server):
```bash
# Required: path to the extractor binary
KITINERARY_EXTRACTOR_PATH=/usr/local/bin/kitinerary-extractor
# Prevent Qt from probing for a display in headless/server environments
QT_QPA_PLATFORM=offscreen
# KDE cache directory (avoids writing to $HOME)
XDG_CACHE_HOME=/tmp/kf6-cache
```
You can override `KITINERARY_EXTRACTOR_PATH` if you installed the binary to a different location.
---
## 7. Available Scripts
### Server (`/server`)
@@ -114,7 +155,7 @@ npm i
---
## 7. Commit & Push Your Changes
## 8. Commit & Push Your Changes
```bash
git add .
+10
View File
@@ -137,6 +137,16 @@ For setup instructions, see [MCP-Overview](MCP-Overview).
---
## Booking Import (KDE Itinerary)
| Variable | Description | Default |
|---|---|---|
| `KITINERARY_EXTRACTOR_PATH` | Full path to the `kitinerary-extractor` binary. When unset, TREK searches `/usr/lib/*/libexec/kf6/kitinerary-extractor` and then `PATH`. Set this if you install the binary to a non-standard location. | auto-detected |
The official TREK Docker image bundles the binary automatically: on amd64 it downloads the static release from `https://cdn.kde.org/ci-builds/pim/kitinerary/`; on arm64 it installs `libkitinerary-bin` via apt (Debian trixie). When running TREK from source, install `libkitinerary-bin` (Debian trixie / Ubuntu 25.04+) or download the static binary directly and place it anywhere on `PATH`. The `GET /api/health/features` endpoint returns `{ "bookingImport": true }` when the binary is found, and the Import button in the Reservations panel is hidden when it is not.
---
## Other
| Variable | Description | Default |
+41
View File
@@ -76,6 +76,47 @@ Click **Add** (or the + button) in the Reservations panel. Fill in the form:
<!-- TODO: screenshot: Create Reservation modal -->
## Import from booking confirmation
TREK can parse booking confirmation emails, PDFs, and pass files and create reservations automatically using [KDE Itinerary](https://apps.kde.org/itinerary/).
### Supported formats
| Format | Extension |
|--------|-----------|
| Booking confirmation email | `.eml` |
| PDF ticket or confirmation | `.pdf` |
| Apple Wallet pass | `.pkpass` |
| HTML confirmation page | `.html`, `.htm` |
| Plain-text email | `.txt` |
Up to 5 files, 10 MB each, per import.
### How to import
1. Open the **Reservations** tab.
2. Click the **Import** (download) button in the toolbar — the button is only shown when the extractor is available on your server.
3. Drag and drop your files onto the upload area, or click to browse.
4. TREK parses each file and shows a **preview list** of the detected reservations with type, title, dates, endpoints, and confirmation number.
5. Deselect any items you do not want to import by clicking the × on their card.
6. Click **Confirm** to create the selected reservations.
All created reservations appear immediately in the panel and are broadcast to all connected trip members in real time.
### What gets created automatically
- **Hotels** — a reservation *and* a linked accommodation row in the day plan (check-in/check-out dates are read from the confirmation).
- **Hotels / Restaurants / Events** — the venue is auto-created as a place with coordinates when the extractor returns location data.
- **All types** — a budget entry is created if the Budget addon is enabled and a price is present.
### When the button is not visible
The Import button is hidden when the `kitinerary-extractor` binary is not available. The binary ships inside the official TREK Docker image. If you run TREK from source, install the `libkitinerary-bin` package (Debian trixie / Ubuntu 25.04+) or set `KITINERARY_EXTRACTOR_PATH` to the binary's full path. See [Environment-Variables](Environment-Variables).
### Needs review flag
Items that the extractor could only partially parse are flagged **Needs review** — an amber badge on the card. Review these reservations after import and fill in any missing fields manually.
## Editing and deleting
Each card has a pencil icon to open the edit form and a trash icon to delete. Deleting requires confirmation in a dialog before the record is removed.
+4
View File
@@ -81,4 +81,8 @@ See [Day-Plans-and-Notes](Day-Plans-and-Notes) for details.
---
> **Faster: import the confirmation** — If you have a booking confirmation email or PDF, you can skip the form entirely. See [Import from booking confirmation](Reservations-and-Bookings#import-from-booking-confirmation) in the Reservations guide.
---
**See also:** [Reservations-and-Bookings](Reservations-and-Bookings) · [Accommodations](Accommodations) · [Map-Features](Map-Features) · [Day-Plans-and-Notes](Day-Plans-and-Notes)