mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-07-18 19:36:02 +00:00
docs(wiki): document AI booking import, guest members and packing sharing
Fill the gaps left after the 3.2.0 feature work: - add an AI Booking Import page for the AI Parsing addon (providers, admin/per-user config, model pull, the review-before-save flow) and link it from Reservations & Bookings and the sidebar - document guest members on Trip Members and Sharing (owner-only, what they can be assigned to, and the sign-in/notification/visibility limits) - document the three packing sharing tiers and co-bringing on Packing Lists - add TRANSIT_API_URL and the plugin variables to Environment Variables, and correct the language list to 22 (add Swedish and Vietnamese) - list the airtrail and llm_parsing addons in the Addons overview
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# AI Booking Import
|
||||
|
||||
The **AI Parsing** addon adds a large-language-model fallback to TREK's booking import. When [KDE Itinerary](Reservations-and-Bookings#import-from-booking-confirmation) can't read a confirmation — a plain-text email, an unusual PDF layout, a vendor whose format it doesn't recognise — TREK can hand the document to an AI model and turn it into a reservation you review before saving.
|
||||
|
||||
It is an **opt-in addon, disabled by default**, and it works with a self-hosted local model, so no booking data has to leave your server.
|
||||
|
||||
> **Admin:** Enable **AI Parsing** in [Admin-Addons](Admin-Addons) (it sits in the *Integration* group). Booking import itself still requires the `kitinerary-extractor` binary — see [Reservations-and-Bookings](Reservations-and-Bookings#when-the-button-is-not-visible).
|
||||
|
||||
## How it fits with normal import
|
||||
|
||||
AI parsing does not replace [KDE Itinerary](Reservations-and-Bookings) — it backs it up:
|
||||
|
||||
1. Every uploaded file is parsed by KDE Itinerary first.
|
||||
2. Only files that Itinerary returns **nothing** for are sent to the AI model.
|
||||
3. Every reservation the AI produces is flagged **Review** so you can confirm it before (or after) saving.
|
||||
|
||||
So structured tickets keep being parsed the fast, deterministic way; the AI only steps in for the documents that would otherwise fail. If the addon is disabled, import behaves exactly as before.
|
||||
|
||||
## Choosing a provider
|
||||
|
||||
The addon supports three providers:
|
||||
|
||||
| Provider | Runs where | Notes |
|
||||
|----------|-----------|-------|
|
||||
| **Local (Ollama)** | Your own hardware | No booking data leaves your network. Recommended for privacy; works on CPU. |
|
||||
| **OpenAI** | OpenAI's API, or any **OpenAI-compatible** endpoint via a custom base URL | Needs an API key. |
|
||||
| **Anthropic** | Anthropic's API | Needs an API key. **Reads PDFs — including scans — natively.** |
|
||||
|
||||
> **Scanned PDFs:** Local and OpenAI-compatible models receive the document's *extracted text*. A scanned or image-only PDF has no text layer, so those providers return nothing for it. Only **Anthropic** ingests the raw PDF and can read scans.
|
||||
|
||||
## Admin: instance-wide configuration
|
||||
|
||||
When you enable the addon, a configuration panel appears directly under it in [Admin-Addons](Admin-Addons):
|
||||
|
||||
> *Set instance-wide config (applies to all users). Leave blank to let each user configure their own provider.*
|
||||
|
||||
- **Provider** — Local · OpenAI-compatible, OpenAI, or Anthropic.
|
||||
- **Base URL** — shown for every provider except Anthropic. Defaults to `http://localhost:11434/v1` for a local Ollama server, or `https://api.openai.com/v1` for OpenAI. Point it at any OpenAI-compatible endpoint here.
|
||||
- **API key** — optional for a local server (`(often not required)`), required for the cloud providers. Stored **encrypted**; it is shown masked (`••••••••`) once saved, and leaving it unchanged keeps the stored key.
|
||||
- **Model** — the model id (e.g. `qwen3:8b`, `gpt-4o`, `claude-opus-4-8`).
|
||||
|
||||
If you set a provider and model here, it applies to **all users** and overrides their personal settings. Leave the panel blank to let each user bring their own model (see below).
|
||||
|
||||
### Pulling a local model
|
||||
|
||||
With the **Local** provider selected, the panel manages your Ollama server directly:
|
||||
|
||||
- **Installed on the server** lists the models Ollama already has, with a **Refresh** button. Click a model to select it.
|
||||
- **Pull a recommended model** downloads a model with a live progress bar. The one recommended model is **Qwen3 — 8B** (`qwen3:8b`) — *best extraction quality & speed on CPU (thinking auto-disabled) · Apache-2.0*. Once the pull finishes it is selected automatically.
|
||||
|
||||
You can also select any other model already installed on the server, or type a model id by hand.
|
||||
|
||||
## Per-user configuration
|
||||
|
||||
If an admin leaves the instance config blank, each user can configure their own model under **Settings → Integrations → AI parsing** (the section only appears when the addon is enabled):
|
||||
|
||||
> *Use your own AI model to extract bookings from uploaded files. This applies only when your administrator has not configured a model for the whole instance.*
|
||||
|
||||
The fields mirror the admin panel — provider, model, base URL (for local / OpenAI), and an API key that is *stored encrypted* (leave blank to keep the current key). There is also a **Send documents as images** toggle for vision-capable models.
|
||||
|
||||
> **Precedence:** an admin instance model always wins. Personal settings only take effect when no instance-wide model is configured.
|
||||
|
||||
## Importing a booking with AI
|
||||
|
||||
The upload flow is the normal booking import — the AI simply runs behind it:
|
||||
|
||||
1. In the trip planner, open the **Reservations** tab and click **Import from file**.
|
||||
2. Drop your files (EML, PDF, PKPass, HTML, TXT — up to 5 files, 10 MB each) onto the upload area.
|
||||
3. The upload dialog closes right away and a **background widget** (bottom-right) shows *Parsing files…* with a running count. You can keep navigating TREK while it works; the widget survives a page reload and even follows you to other pages.
|
||||
4. When parsing finishes, click the widget's **Import** button to start the review.
|
||||
5. Each parsed booking opens **pre-filled in the normal reservation (or transport) editor**, one at a time. Nothing is saved until you confirm each one.
|
||||
|
||||
### What gets filled in and created
|
||||
|
||||
The model is asked to capture the full booking — including **every leg of a multi-segment flight** — and, on save, TREK wires each item into the trip:
|
||||
|
||||
- **Fields** — booking/confirmation code, dates and times, and per type: seat, class, platform, total price and currency; hotels bring their address, rental cars their company, restaurants and events their venue with phone and website.
|
||||
- **Places** — hotel, restaurant and event venues (and un-geocoded transport stops) are geocoded and added as trip places, so the map pin appears.
|
||||
- **Accommodations** — a hotel booking creates the accommodation on the matching check-in/check-out days.
|
||||
- **Linked cost** — if the [Costs/Budget addon](Budget-Tracking) is enabled and the booking has a price, a linked expense is created. Without that addon, the price stays on the reservation only.
|
||||
- **Source document** — the uploaded file is attached to the reservation's files.
|
||||
|
||||
## Good to know
|
||||
|
||||
- **No new environment variables and no manual migration** — the addon is configured entirely in the UI.
|
||||
- **Local inference can be slow.** On a CPU-only host a single booking can take tens of seconds to a couple of minutes; TREK allows local models up to 5 minutes per document. Uploads are parsed **one at a time** per user, so several files queue rather than run in parallel.
|
||||
- **Parse jobs are kept for about 10 minutes** after they finish. Start the review within that window.
|
||||
- **Privacy** — with the Local provider nothing leaves your network. With OpenAI or Anthropic, the document's text (or, for Anthropic, the PDF itself) is sent to that provider for extraction.
|
||||
- **API keys are never returned in plaintext** — they are encrypted at rest and only ever shown masked.
|
||||
|
||||
## Related pages
|
||||
|
||||
- [Reservations-and-Bookings](Reservations-and-Bookings) — the booking import flow this extends
|
||||
- [Admin-Addons](Admin-Addons) — enabling the addon
|
||||
- [Budget-Tracking](Budget-Tracking) — linked costs from imported bookings
|
||||
- [Transport: Flights, Trains, Cars](Transport-Flights-Trains-Cars)
|
||||
@@ -23,6 +23,8 @@ The following addons are registered in the system (defined in `server/src/db/see
|
||||
| `collab` | trip | Notes, polls, and live chat for trip collaboration. See [Real-Time-Collaboration](Real-Time-Collaboration). |
|
||||
| `journey` | global | Trip tracking and travel journal — check-ins, photos, and daily stories. See [Journey-Journal](Journey-Journal). |
|
||||
| `collections` | global | A personal, server-wide library of saved places in named lists, with idea/want/visited status, categories, and fusion sharing with per-member roles. See [Collections](Collections). |
|
||||
| `airtrail` | integration | Sync flights from your self-hosted AirTrail instance into trips. |
|
||||
| `llm_parsing` | integration | AI Parsing — an LLM fallback that extracts bookings from confirmation files KDE Itinerary can't read. See [AI-Booking-Import](AI-Booking-Import). |
|
||||
| `naver_list_import` | trip | Import places from shared Naver Maps lists directly into a trip. |
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Setting `ENCRYPTION_KEY` explicitly is recommended so you can back it up indepen
|
||||
|
||||
### `DEFAULT_LANGUAGE` — Supported Codes
|
||||
|
||||
You can set `DEFAULT_LANGUAGE` to any of the 20 languages TREK ships. The currently supported codes are:
|
||||
You can set `DEFAULT_LANGUAGE` to any of the 22 languages TREK ships. The currently supported codes are:
|
||||
|
||||
| Code | Language |
|
||||
|---------|--------------------|
|
||||
@@ -88,6 +88,8 @@ You can set `DEFAULT_LANGUAGE` to any of the 20 languages TREK ships. The curren
|
||||
| `ko` | 한국어 |
|
||||
| `uk` | Українська |
|
||||
| `gr` | Ελληνικά |
|
||||
| `sv` | Svenska |
|
||||
| `vi` | Tiếng Việt |
|
||||
|
||||
If you set a code that isn't supported, TREK falls back to English (`en`). This list grows as new
|
||||
translations are added to TREK.
|
||||
@@ -198,6 +200,20 @@ running TREK from source, install `libkitinerary-bin` (Debian trixie / Ubuntu 25
|
||||
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.
|
||||
|
||||
Booking import can also fall back to an AI model for documents KDE Itinerary can't read. That feature (the **AI Parsing** addon) is configured entirely in the UI and needs no environment variables — see [AI-Booking-Import](AI-Booking-Import).
|
||||
|
||||
---
|
||||
|
||||
## Public Transit (Transitous)
|
||||
|
||||
Public-transit routing in the planner is powered by [Transitous](https://transitous.org/), a free community MOTIS service — no API key is required. See [Transport: Flights, Trains, Cars](Transport-Flights-Trains-Cars) for the feature itself.
|
||||
|
||||
| Variable | Description | Default |
|
||||
|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|
|
||||
| `TRANSIT_API_URL` | Base URL of the transit routing API. TREK's server proxies requests to it. Point this at your own self-hosted [MOTIS](https://github.com/motis-project/motis) instance if you want zero third-party egress. A trailing slash is stripped. | `https://api.transitous.org` |
|
||||
|
||||
When left at the default, using the transit feature makes the TREK **server** send outbound HTTPS requests to `api.transitous.org` (with an identifying User-Agent, as the Transitous usage policy asks). No transit request is made until a user actually searches for a journey.
|
||||
|
||||
---
|
||||
|
||||
## Storage & Paths
|
||||
@@ -235,6 +251,24 @@ seeded.
|
||||
|
||||
---
|
||||
|
||||
## Plugins
|
||||
|
||||
The plugin runtime is **off unless you opt in**. It only starts when `TREK_PLUGINS_ENABLED` is exactly `true`; otherwise the Admin → Plugins panel shows a disabled banner and no plugin code runs. See [Plugins](Plugins) for the full system and [Plugin-Permissions](Plugin-Permissions) for the isolation model.
|
||||
|
||||
| Variable | Description | Default |
|
||||
|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|
|
||||
| `TREK_PLUGINS_ENABLED` | Master switch for the plugin runtime. Must be exactly `true` (case-insensitive) to enable. Setting it back to `false` is a kill switch — installed plugins stay on disk but nothing runs. | `false` |
|
||||
| `TREK_PLUGINS_DIR` | Directory where installed plugin **code** is stored. Persist it as a volume if you use plugins. | `<data>/plugins` |
|
||||
| `TREK_PLUGINS_DATA_DIR` | Directory for each plugin's own **data** (its private SQLite file). Kept separate from the code tree; persist it as a volume too. | `<data>/plugins-data` |
|
||||
| `TREK_PLUGIN_REGISTRY_URL` | Override the plugin registry index the *Discover* tab browses. Point it at your own fork or mirror of the registry. | `https://raw.githubusercontent.com/mauriceboe/TREK-Plugins/main/dist/index.json` |
|
||||
| `TREK_PLUGIN_MAX_RSS_MB` | Per-plugin memory ceiling in MB. A plugin process that exceeds it is stopped. | `300` |
|
||||
| `TREK_PLUGIN_PERMISSIONS` | Set to `off` to opt **out** of the Node.js OS-level permission sandbox for plugin child processes (not recommended). Any other value keeps the sandbox on. | `on` |
|
||||
| `TREK_PLUGIN_ALLOW_PRIVATE_EGRESS`| Set to `on` to let a plugin's declared outbound hosts resolve to private/internal addresses (e.g. a service on your LAN). By default connections to private, loopback, link-local and metadata addresses are refused. | off (private egress blocked) |
|
||||
|
||||
All of these are optional — the defaults are safe, and only `TREK_PLUGINS_ENABLED` is needed to turn the system on.
|
||||
|
||||
---
|
||||
|
||||
## Related Pages
|
||||
|
||||
- [Reverse-Proxy](Reverse-Proxy) — HTTPS proxy setup and the `FORCE_HTTPS` / `TRUST_PROXY` / `COOKIE_SECURE` trio
|
||||
|
||||
@@ -50,6 +50,44 @@ Each item row contains:
|
||||
|
||||
Hovering over an item reveals a **category picker** (colored dot), a **rename** button (pencil icon), and a **delete** button. Add new items using the inline "add item" row at the bottom of each category.
|
||||
|
||||
## Sharing packing items
|
||||
|
||||
Every packing item has a sharing tier that controls who sees it and who is bringing it. By default everything sits in the shared group pool, exactly as before — the tiers are opt-in per item.
|
||||
|
||||
### The two views
|
||||
|
||||
Two pills at the top of the list switch what you're looking at:
|
||||
|
||||
- **Shared** — the group pool: items everyone on the trip can see.
|
||||
- **My list** — your own items: your personal items, things you've been asked to bring, and things you shared with specific people.
|
||||
|
||||
Each pill shows a count of the items in it.
|
||||
|
||||
### The three tiers
|
||||
|
||||
Open an item's **Sharing** control (the share icon on the row) to move it between tiers:
|
||||
|
||||
- **Shared** — *In the group pool, visible to everyone.* This is where every item starts.
|
||||
- **Personal** — *Private — only you can see it.*
|
||||
- **Shared with…** — pick specific trip members below the two tier options. The item then shows only on your list and on theirs. (If you're the only one on the trip, this reads *No one else on this trip yet*.)
|
||||
|
||||
New items inherit the view you add them in: adding an item while in **My list** makes it Personal, adding it in **Shared** makes it Common. To share an item with specific people, add it first, then open its Sharing control and choose them.
|
||||
|
||||
Only the item's owner (the person bringing it) can change its sharing. Someone you shared an item *with* just sees it on their **My list** with a **by {name}** badge and can tick it off — they don't manage who else it's shared with.
|
||||
|
||||
### Who's bringing what
|
||||
|
||||
Every item in the **Shared** pool shows who is bringing it. For an item someone else added, other members see two quick actions instead of the Sharing control:
|
||||
|
||||
- **I can bring that too** — pledge to co-bring it. The item's badge then shows a **+1** next to the original bringer. Tap again (*I'm not bringing it*) to withdraw.
|
||||
- **Copy to my list** — clone the item onto your own personal list as a separate private copy, leaving the shared one untouched.
|
||||
|
||||
> Items created before this feature have no assigned bringer, so they show no "brought by" badge until someone edits their sharing.
|
||||
|
||||
> **Note:** this per-item sharing is separate from assigning **members to a category** (above). Category assignments only send a packing notification — they don't change who can see an item.
|
||||
|
||||
All of this is still gated by the `packing_edit` permission; there is no extra addon or admin toggle.
|
||||
|
||||
## Bag tracking
|
||||
|
||||
Bag tracking is only available when an admin has enabled it.
|
||||
|
||||
@@ -117,6 +117,10 @@ The Import button is hidden when the `kitinerary-extractor` binary is not availa
|
||||
|
||||
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.
|
||||
|
||||
### AI fallback for hard-to-read files
|
||||
|
||||
KDE Itinerary only recognises structured tickets. For confirmations it can't read — plain-text emails, unusual PDF layouts, vendors it doesn't know — TREK can optionally hand the file to an AI model instead. The optional **AI Parsing** addon runs only for the files Itinerary returns nothing for, parses them in the background, and flags every result for review before you save it. It works with a self-hosted local model, so booking data need not leave your server. See **[AI-Booking-Import](AI-Booking-Import)**.
|
||||
|
||||
## 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.
|
||||
|
||||
@@ -31,6 +31,50 @@ If you click the remove icon next to **your own** name, the action is labeled **
|
||||
|
||||
The trip owner cannot be removed through this panel.
|
||||
|
||||
## Guest Members
|
||||
|
||||
Not everyone on a trip has — or wants — a TREK account. **Guests** let you add travel companions by name only, so you can assign them to costs, packing and tasks just like a real member, without creating a login for them.
|
||||
|
||||
Guests appear in their own **Guests** section below the members list, each with a **Guest** badge:
|
||||
|
||||
> People without an account. They can be assigned to costs, packing and tasks, but cannot sign in.
|
||||
|
||||
### Adding a guest
|
||||
|
||||
Only the **trip owner** can manage guests (this is stricter than inviting members, which uses the `member_manage` permission). In the owner's view, the Guests section has a **Guest name** field and an **Add guest** button — type a name and click Add. A guest has a display name only: no email, no password, and no way to sign in.
|
||||
|
||||
Other members see the Guests section too (when guests exist) but cannot add, rename or remove them.
|
||||
|
||||
> If two guests share a name, TREK keeps them distinct internally (the second "Anna" becomes "Anna 2"), so assignments never get confused.
|
||||
|
||||
### What a guest can be assigned to
|
||||
|
||||
Once added, a guest can be picked anywhere a member can:
|
||||
|
||||
- **Costs** — added to expense splits (see [Budget-Tracking](Budget-Tracking)).
|
||||
- **Packing** — assigned to packing items and categories (see [Packing-Lists](Packing-Lists)).
|
||||
- **To-dos** — set as a task assignee.
|
||||
- **Day plan** — added as a participant on activities and places.
|
||||
|
||||
### What a guest can never do
|
||||
|
||||
Guests are firmly scoped to the one trip. A guest can **never**:
|
||||
|
||||
- sign in (they have no credentials — password, SSO and password-reset all ignore guest accounts);
|
||||
- receive notifications (no email and no in-app notifications are ever sent to a guest);
|
||||
- appear anywhere outside the trip (they are excluded from the global user directory, the admin user list, invite pickers, and search);
|
||||
- be made the trip owner.
|
||||
|
||||
These limits are enforced on the server, not just hidden in the UI.
|
||||
|
||||
### Renaming and removing
|
||||
|
||||
In the owner's Guests section, each guest row has a **Rename** (pencil) and a **Remove access** (trash) button. Removing a guest is **destructive and cascading**:
|
||||
|
||||
> Remove this guest? Their assignments and cost shares will be removed too.
|
||||
|
||||
There is no limit on the number of guests per trip.
|
||||
|
||||
## Public Share Link
|
||||
|
||||
The right column is only visible to users with the `share_manage` permission (default: trip owner).
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
## Travel Management
|
||||
- [[Reservations and Bookings|Reservations-and-Bookings]]
|
||||
- [[AI Booking Import|AI-Booking-Import]]
|
||||
- [[Transport: Flights, Trains, Cars|Transport-Flights-Trains-Cars]]
|
||||
- [[Accommodations]]
|
||||
- [[Budget Tracking|Budget-Tracking]]
|
||||
|
||||
Reference in New Issue
Block a user