docs(wiki): document road trip, document sync, the TREK Places API and Dawarich

The 4.3.0 features had no pages, or pages that described an earlier
state. Three new pages and a rewrite:

- Road-Trip: the addon from enabling it to the phone tab, stays and a
  stop's End as the time you leave, pinned times and the backward
  schedule, daily travel times, the three driving limits, search along
  the route, via points, other ways and what avoiding tolls needs,
  following a track, the warning layer, MCP tools and troubleshooting.
- Document-Sync: switching stores on, binding a trip, what each store
  asks for and binds, direction and delete rules, conflicts, the
  mass-delete guard, renames and restores, what needs a look, limits,
  private addresses, and the MCP tools.
- TREK-Places-API: what the index is, where TREK asks it, what leaves
  the instance, switching it off or pointing it at a copy of your own,
  and what happens when it is down.
- Dawarich: brought up to date with suggestions, the journal fold,
  recorded routes, Atlas proposals and the wish list.

Places and search, documents, the addon and admin overviews, MCP
tools, environment variables, internal network access, the sidebar and
home link the new pages, and the in-app help picks them up from the
sidebar.
This commit is contained in:
Maurice
2026-09-19 21:45:16 +02:00
parent 03d3f2f91e
commit 58f6a49f32
24 changed files with 1376 additions and 235 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ For each day between the **From** day and **To** day (inclusive), the accommodat
## On the route
Booking a night also puts its place on the check-in day, as a stop of its own. That stop
is what the map draws a line to and what the Road Trip view builds its route from, so the
is what the map draws a line to and what the [Road Trip](Road-Trip) view builds its route from, so the
hotel shows up on the drive without having to be entered a second time as an ordinary
place. It works the same way whichever way you book the night: the Day Detail panel, the
booking form under Bookings, the phone, the Road Trip view, an MCP client or a plugin.
+11 -7
View File
@@ -6,7 +6,7 @@ Addons are optional features that an admin can enable or disable for the entire
## What addons are
Each addon extends TREK with functionality beyond the core trip-planning features. Addons are managed globally — you cannot enable an addon for one user only. Once enabled, the feature becomes available to all users on the instance.
Each addon extends TREK with functionality beyond the core trip-planning features. Addons are managed globally: you cannot enable an addon for one user only. Once enabled, the feature becomes available to all users on the instance.
## Addon list
@@ -15,17 +15,19 @@ The following addons are registered in the system (defined in `server/src/db/see
| Addon ID | Type | Description |
|---|---|---|
| `mcp` | integration | Exposes TREK data and actions through the Model Context Protocol for AI assistant integrations. |
| `packing` | trip | **Lists** — packing lists and to-do tasks for your trips. See [Packing-Lists](Packing-Lists). |
| `budget` | trip | **Costs** — track and split trip expenses. See [Budget-Tracking](Budget-Tracking). |
| `documents` | trip | Document and file attachments for trips — store itineraries, visa copies, and other files. See [Documents-and-Files](Documents-and-Files). |
| `packing` | trip | **Lists**: packing lists and to-do tasks for your trips. See [Packing-Lists](Packing-Lists). |
| `budget` | trip | **Costs**: track and split trip expenses. See [Budget-Tracking](Budget-Tracking). |
| `documents` | trip | Document and file attachments for trips: itineraries, visa copies and other files. Can be kept in step with a self-hosted document store (Paperless-ngx, Papra, Nextcloud, OpenCloud, Synology). See [Documents-and-Files](Documents-and-Files) and [Document-Sync](Document-Sync). |
| `vacay` | global | Personal vacation day planner with a year calendar, holiday packs, collaborator fusion, and read-only calendar sharing. See [Vacay](Vacay). |
| `atlas` | global | Interactive world map showing countries and regions you have visited, plus a bucket list. See [Atlas](Atlas). |
| `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). |
| `roadtrip` | trip | **Road trip**: plans a trip as one continuous drive, with stops along the route, driving times and arrival times that update themselves. Off by default. See [Road-Trip](Road-Trip). |
| `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. |
| `dawarich` | integration | Read the stays and recorded routes of each user's own Dawarich instance, offered as suggestions to confirm. Read-only, nothing is written back. See [Dawarich](Dawarich). |
| `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` | integration | Import places from shared Naver Maps lists directly into a trip. |
## Enabling addons
@@ -35,3 +37,5 @@ The following addons are registered in the system (defined in `server/src/db/see
## Per-addon sub-features
Some addons expose sub-features that an admin can independently toggle. The [Real-Time-Collaboration](Real-Time-Collaboration) addon, for example, lets an admin decide which of its four sub-features (chat, notes, polls, and what's next) are active across the instance. These are configured from the [Admin-Addons](Admin-Addons) panel alongside the addon's main toggle.
The **Documents** addon carries one switch per document store: Paperless-ngx, Papra, Nextcloud, OpenCloud and Synology Drive. They are off by default and only show while Documents is on, and switching Documents off switches all of them off. The stores themselves are connected per trip, in the trip's file manager. See [Document-Sync](Document-Sync).
+25 -17
View File
@@ -1,6 +1,6 @@
# Admin — Addons
# Admin: Addons
The **Addons** tab lets you enable or disable optional features for the entire TREK instance. Toggling an addon affects all users immediately — disabling one hides its UI elements and blocks its API routes instance-wide.
The **Addons** tab lets you enable or disable optional features for the entire TREK instance. Toggling an addon affects all users immediately: disabling one hides its UI elements and blocks its API routes instance-wide.
![Addon overview](assets/Addons-Overview.png)
@@ -16,27 +16,30 @@ Addons are grouped into three categories, shown as labeled sections.
Trip addons add per-trip feature panels. They appear in every trip where the addon is enabled.
The default trip addons are: **Lists**, **Costs**, **Documents**, **Collab**, and **Naver List Import** (all enabled by default). The exact list is determined by what is registered in your TREK database.
The default trip addons are: **Lists**, **Costs**, **Documents** and **Collab** (all enabled by default), and **Road trip** (disabled by default). The exact list is determined by what is registered in your TREK database.
**Sub-toggles on trip addons:**
- **Lists** — when enabled, a nested **Bag Tracking** toggle appears. Bag Tracking lets users assign packed items to specific bags.
- **Collab** — when enabled, four sub-toggles appear for individual collaboration features:
- **Chat** — in-trip real-time chat
- **Notes** — shared trip notes
- **Polls** — trip polls
- **What's Next** — the "what's next" widget
- **Lists**: when enabled, a nested **Bag Tracking** toggle appears. Bag Tracking lets users assign packed items to specific bags.
- **Collab**: when enabled, four sub-toggles appear for individual collaboration features:
- **Chat**: in-trip real-time chat
- **Notes**: shared trip notes
- **Polls**: trip polls
- **What's Next**: the "what's next" widget
- **Documents**: when enabled, one row per document store appears underneath: **Paperless-ngx**, **Papra**, **Nextcloud**, **OpenCloud** and **Synology Drive**. All of them are off by default. Switching a store on only lets trip owners offer it; the address and credentials are entered per trip, in the trip's file manager. Switching a store off pauses the trips bound to it without touching them. Switching **Documents** itself off switches every store off, and each has to be switched on again afterwards; a store cannot be switched on while **Documents** is off. See [Document-Sync](Document-Sync).
Each sub-toggle can be disabled independently while the parent addon remains enabled.
**Road trip** plans a trip as one continuous drive: search along the route, driving limits, daily travel times, via points and avoidance of toll roads, motorways and ferries. **Disabled by default.** It needs no key: routing runs on the public OSRM and Valhalla servers until you set your own under **User Defaults** (**Own routing engine**, **Own Valhalla instance**, restart required). See [Road-Trip](Road-Trip).
### Global addons
Global addons add features that are not tied to a single trip. The default global addons are **Vacay**, **Atlas**, **Collections**, and **Journey**.
- **Vacay** — personal vacation day planner with calendar view. Enabled by default.
- **Atlas** — world map of visited countries with travel stats. Enabled by default.
- **Collections** — personal place library: save places across trips into named lists, copy them into any trip, and share them. **Disabled by default.** See [Collections](Collections).
- **Journey** — trip tracking and travel journal (check-ins, photos, daily stories). **Disabled by default.**
- **Vacay**: personal vacation day planner with calendar view. Enabled by default.
- **Atlas**: world map of visited countries with travel stats. Enabled by default.
- **Collections**: personal place library that saves places across trips into named lists, copies them into any trip, and shares them. **Disabled by default.** See [Collections](Collections).
- **Journey**: trip tracking and travel journal (check-ins, photos, daily stories). **Disabled by default.**
**Sub-items on global addons:**
@@ -44,15 +47,17 @@ Global addons add features that are not tied to a single trip. The default globa
### Integration addons
Integration addons connect TREK to external services. Most of them need additional configuration (API keys, URLs) once enabled, but not in the admin **Settings** tab — each one has its own place.
Integration addons connect TREK to external services. Most of them need additional configuration (API keys, URLs) once enabled, but not in the admin **Settings** tab: each one has its own place.
- The **MCP** addon requires `APP_URL` to be set in your environment. When enabled, the **MCP Access** tab appears in the Admin Panel. **Disabled by default.** See [MCP-Overview](MCP-Overview) for full details.
- The **Naver List Import** addon imports the places of a shared Naver Maps list into a trip. **Enabled by default.** It needs no key.
- The **AirTrail** addon syncs flights from a self-hosted AirTrail instance. **Disabled by default.** The toggle here is the instance-wide switch only; each user connects their own instance (URL + API key) in **Settings → Integrations**.
- The **Dawarich** addon reads the stays and recorded routes of a self-hosted Dawarich instance and offers them as suggestions. **Disabled by default.** The toggle here is the instance-wide switch only; each user connects their own instance (address + API key) in **Settings → Integrations**. A Dawarich on your local network also needs `ALLOW_INTERNAL_NETWORK=true`. See [Dawarich](Dawarich).
- The **AI Parsing** addon is the LLM fallback for booking imports KItinerary cannot read. **Disabled by default.** When enabled, its provider, base URL, API key, and model fields appear inline underneath the addon row. Filling them in sets the instance-wide config for all users; leaving them blank lets each user configure their own provider in **Settings → Integrations**. See [AI-Booking-Import](AI-Booking-Import).
## Enabling or disabling an addon
Click the toggle switch on any addon row. The change is applied immediately — no save button is needed. A brief success toast confirms the update.
Click the toggle switch on any addon row. The change is applied immediately; no save button is needed. A brief success toast confirms the update.
If a toggle fails (e.g., network error), it rolls back to its previous state.
@@ -60,8 +65,10 @@ If a toggle fails (e.g., network error), it rolls back to its previous state.
Some addons require credentials or environment variables before they are functional:
- **Journey** — works without any external integration. To embed photos from Immich or Synology Photos, enable the corresponding photo-provider toggle listed under Journey, then configure credentials per-user in **Settings → Integrations**. See [Photo-Providers](Photo-Providers).
- **MCP** — requires `APP_URL` to be set so OAuth redirect URIs resolve correctly.
- **Documents**: the document stores need nothing instance-wide beyond their switch. The trip owner enters a store's address and credentials in the trip's file manager. A store on your local network also needs `ALLOW_INTERNAL_NETWORK=true`. See [Document-Sync](Document-Sync) and [Internal-Network-Access](Internal-Network-Access).
- **Journey**: works without any external integration. To embed photos from Immich or Synology Photos, enable the corresponding photo-provider toggle listed under Journey, then configure credentials per-user in **Settings → Integrations**. See [Photo-Providers](Photo-Providers).
- **MCP**: requires `APP_URL` to be set so OAuth redirect URIs resolve correctly.
- **Road trip**: works out of the box on the public routing servers. To use your own OSRM or Valhalla, set **Own routing engine** or **Own Valhalla instance** under **Admin → User Defaults**, then restart the server and reload the page. See [Road-Trip](Road-Trip#routing-engines).
## Related pages
@@ -69,3 +76,4 @@ Some addons require credentials or environment variables before they are functio
- [Admin-MCP-Tokens](Admin-MCP-Tokens)
- [MCP-Overview](MCP-Overview)
- [Addons-Overview](Addons-Overview)
- [Document-Sync](Document-Sync)
+9 -9
View File
@@ -19,24 +19,24 @@ The Admin Panel is divided into tabs. Most tabs are always visible; a few appear
| **User Defaults** | Default settings applied to new users | No |
| **Addons** | Enable or disable optional features instance-wide | No |
| **Plugins** | Install, update, and manage plugins; rescan the plugins folder; view each plugin's error log. See [Admin-Plugins](Admin-Plugins) | No |
| **Storage** | Storage backends, category assignment, replication, health | Hidden on managed instances |
| **Storage** | Storage backends, category assignment, replication, health | No |
| **Settings** | Authentication methods, MFA, allowed file types, API keys, OIDC/SSO configuration, and JWT secret rotation | No |
| **Notifications** | SMTP, webhook, ntfy, and push notification channel configuration; trip reminder toggle; admin notification preferences | No |
| **Backup** | Manual and scheduled full-instance backups: database, uploads, plugin data and plugin code. See [Backups](Backups) | Hidden on managed instances |
| **Backup** | Manual and scheduled full-instance backups: database, uploads, plugin data and plugin code. See [Backups](Backups) | No |
| **Audit** | Chronological activity log | No |
| **MCP Access** | OAuth sessions and static API tokens | Only when the MCP addon is enabled |
| **GitHub** | Release timeline and support links | Hidden on managed instances |
| **GitHub** | Release timeline and support links | No |
| **Dev: Notifications** | Test notification dispatch | Only in development mode (`NODE_ENV=development`) |
![Admin panel on the User Defaults tab, setting instance-wide defaults for colour mode, temperature unit, distance unit, time format, currency and blurred booking codes](assets/AdminUserDefaults.png)
### Routing services
On desktop and mobile, **User Defaults** includes optional **Custom routing instance** and **Custom Valhalla instance** fields in the map section. Changes save when you leave the field; **reset** restores the built-in default. These fields are hidden on managed instances.
On desktop and mobile, **User Defaults** includes optional **Own routing engine** and **Own Valhalla instance** fields in the map section. Changes save when you leave the field; **reset** restores the built-in default.
With both fields empty, TREK uses public OSRM servers for routing and the public FOSSGIS Valhalla for avoiding toll roads, motorways and ferries. Configuring only a custom routing instance disables the public Valhalla fallback. After entering a custom server URL, restart TREK and reload the page.
With both fields empty, TREK uses public OSRM servers for routing and the public FOSSGIS Valhalla for avoiding toll roads, motorways and ferries. Configuring only a custom routing instance disables the public Valhalla fallback. After entering a custom server URL, restart TREK and reload the page. See [Road-Trip](Road-Trip#routing-engines).
> **AI / MCP:** These fields configure browser routing services and do not change stored trip data.
> **AI / MCP:** These fields configure the routing services the planner and the road trip MCP tools use, and do not change stored trip data.
### Linking to a tab directly
@@ -50,7 +50,7 @@ Unlike the trip planner's `tab` parameter, this one stays in the address bar and
| Tab | Id |
|-----|-----|
| Users | `users` (the default — carries no `?tab=`) |
| Users | `users` (the default, carries no `?tab=`) |
| Personalization | `config` |
| User Defaults | `defaults` |
| Addons | `addons` |
@@ -64,13 +64,13 @@ Unlike the trip planner's `tab` parameter, this one stays in the address bar and
| GitHub | `github` |
| Dev: Notifications | `dev-notifications` |
An id with no panel behind it opens **Users**, and on a managed instance the three tabs hidden there — `storage`, `github` and `backup` — fall back to **Users** as well. The other two conditional tabs behave differently: `mcp-tokens` and `dev-notifications` open their panel even when the MCP addon is off or the instance is not in development mode, with nothing highlighted in the sidebar, because the entry is missing from it.
An id with no panel behind it opens **Users**. The two conditional tabs behave differently: `mcp-tokens` and `dev-notifications` open their panel even when the MCP addon is off or the instance is not in development mode, with nothing highlighted in the sidebar, because the entry is missing from it.
## Plugin activity and audit
Plugins that are granted data-access capabilities have every host-mediated action they take recorded in a tamper-evident, hash-chained log. This log is separate from the instance **Audit** tab described above.
- **Admins** can review the per-plugin capability audit — every core-data read, broadcast, notification, and AI call a plugin made, with the acting user, the resource touched, and the outcome. It is served by `GET /api/admin/plugins/<id>/audit`; the admin plugin view itself currently surfaces only each plugin's error log (**View error log**).
- **Admins** can review the per-plugin capability audit: every core-data read, broadcast, notification, and AI call a plugin made, with the acting user, the resource touched, and the outcome. It is served by `GET /api/admin/plugins/<id>/audit`; the admin plugin view itself currently surfaces only each plugin's error log (**View error log**).
- **Every user** (not just admins) can see the plugin actions taken in their own name under **Settings → Plugins**. This is what keeps a plugin's broad read grants accountable to the person whose data was read.
See [Audit-Log](Audit-Log) for details on the hash chain and how the two logs differ.
-2
View File
@@ -3,8 +3,6 @@
The **Storage** tab (Admin Panel → Storage) controls where TREK stores each
kind of content: which storage backends exist, which content category writes
to which backend, and whether writes are replicated to additional backends.
On managed/hosted instances this tab is hidden — storage is the operator's
concern.
## Backends
+2
View File
@@ -135,6 +135,8 @@ A request for an account that can actually be reset writes **two** rows: one wit
|---|---|
| `immich.private_ip_configured` | Immich URL saved that resolves to a private IP |
| `airtrail.private_ip_configured` | AirTrail URL saved that resolves to a private IP |
| `dawarich.private_ip_configured` | Dawarich URL saved that resolves to a private IP |
| `dawarich.disconnected` | A user disconnected their Dawarich instance |
## Log columns
+181 -57
View File
@@ -1,119 +1,243 @@
# Dawarich
[Dawarich](https://dawarich.app) is a self-hosted location-history tracker — a Google Timeline replacement you run yourself. It knows exactly where you were. TREK knows what you planned and why. This addon connects the two.
[Dawarich](https://dawarich.app) is a self-hosted location history tracker, a Google Timeline replacement you run yourself. It knows where you actually were. TREK knows what you planned and why. This addon lets TREK read your Dawarich instance and offer what it finds.
The split is deliberate and it does not move: **Dawarich records, TREK plans and interprets.** TREK never starts a tracker of its own, never writes anything into Dawarich, and never keeps a copy of your GPS archive. The route drawn on a trip is fetched for the window you are looking at and thrown away again.
The split is deliberate and it does not move: **Dawarich records, TREK plans and interprets.** TREK never starts a tracker of its own, never writes anything into Dawarich, and never keeps a copy of your recorded route. Everything it finds arrives as a **suggestion** that only you can see, and nothing reaches a trip, a journal or your Atlas until you confirm it. A background check must not edit a trip three other people are planning.
> **Admin:** Enable the **Dawarich** addon in **Admin → Addons**. It is listed under **Integration** and is off by default. The toggle is the instance-wide switch only: each user connects their own instance in **Settings → Integrations**. A Dawarich on your local network also needs `ALLOW_INTERNAL_NETWORK=true` on the TREK server. See [Admin-Addons](Admin-Addons) and [Internal-Network-Access](Internal-Network-Access).
## What it does
- **Suggests entries from where you actually were.** Dawarich detects the places you stopped at; TREK lists them for review, with the date, the arrival and departure times and how long you stayed.
- **Turns a reviewed stay into a place, a journal entry, or a ticked wish** — your choice, after you have corrected anything the detector got wrong.
- **Draws the route you actually took** over a trip's map, coloured per day in your own timezone, alongside the one you planned.
- **Ticks off your wishlist.** For each entry on your Atlas bucket list with coordinates, TREK can ask your recordings whether you ever got there — and how long you stayed, so driving past does not count.
- **Offers the countries your recordings say you visited** for your Atlas, without touching what you marked by hand.
Everything arrives as a **suggestion**. Nothing reaches a trip, a journal or your Atlas until you confirm it — a background poll must not edit a trip three other people are planning.
- **Offers the stays Dawarich recorded during your trips**, for review, in the trip planner and in your journals, with the day, the arrival and departure times and how long you stayed.
- **Turns a reviewed stay into a place or a journal entry**, after you have corrected anything the detector got wrong.
- **Draws the route you actually travelled** over the trip map and the journal map, one colour per day, next to the one you planned.
- **Ticks off your bucket list** when your recordings show you spent real time at a wish, so driving past does not count.
- **Proposes countries for your Atlas** from the countries and cities your recordings cover, without touching what you marked by hand.
## Setting it up
**An administrator** enables the `dawarich` addon under **Admin → Addons**. It is off by default.
**Each reader** then connects their own instance:
1. In Dawarich, open **Account** and copy your **API key**.
2. In TREK, go to **Settings → Integrations → Dawarich**.
3. Paste your instance address (for example `https://dawarich.example.com`) and the key.
4. Press **Test connection**. TREK reports what it found and which parts of your instance it can read.
2. In TREK, open **Settings → Integrations**. The **Dawarich** card appears there once the addon is on, on the desktop and on the phone.
3. Enter the **Instance address**, for example `https://dawarich.example.com`, and paste the **API key**.
4. Press **Test connection**. On success TREK says how many stays it found in the last 30 days, shows the Dawarich version, and lists anything your version does not offer.
5. Press **Save**.
The key is stored encrypted and never shown again. Leave the field blank when changing the address later — blank means "keep the stored key", as long as the address still points at the same instance. **Moving the connection to a different host clears the key**: a key issued by one Dawarich must not be sent to another one, so retype it after a move. Fixing a typo in the path, or adding a trailing slash, keeps it.
| Field | Notes |
|---|---|
| Instance address | The address of Dawarich itself. TREK adds `/api/v1` on its own, and strips a trailing `/api` or `/api/v1` if you pasted one. |
| API key | Stored encrypted and never shown again. Leave it blank to keep the key already stored. |
| Check for new stays automatically | On by default. Off means TREK only reads Dawarich when you ask it to. |
| Allow self-signed certificate | Only needed if your instance uses a certificate your TREK server does not trust, which is common on a LAN. |
> **A self-signed certificate** on a LAN instance needs the *Allow self-signed certificate* switch. TREK still refuses addresses it cannot resolve or reach; the switch only relaxes the certificate check.
Once connected, the card shows **Connected**, a **Check now** button, a **Disconnect** button, when TREK last checked, and the reason when the last check did not fully succeed.
Each person connects their own Dawarich. Your stays and your recorded route are visible to you alone, on a trip you share with others too. A place you create from a stay is an ordinary place, which everyone on the trip sees.
### The API key
- **It is never returned.** The card shows a placeholder, and no endpoint and no MCP tool reads the key back.
- **Blank keeps the stored key.** The field is never prefilled, so leave it empty when you only change a switch. **Save** needs either a stored connection or a typed key.
- **Changing the host clears the key.** A key belongs to the instance that issued it, so pointing the connection at a different scheme, host or port drops the stored key and the card goes back to **Not connected**. Fixing a typo in the path, or adding a trailing slash, keeps it. After a move, type the key in again before you press **Test connection** or **Save**.
- **Clearing the address clears the key** as well.
- **Disconnect** removes the address, the key and the check history. Places and journal entries you already made from stays are yours and stay where they are. Disconnecting is recorded in the [Audit-Log](Audit-Log) as `dawarich.disconnected`.
### Private addresses and certificates
> **A private address** (`192.168.…`, `10.…`) is accepted with a warning, and the save is recorded in the [Audit-Log](Audit-Log) as `dawarich.private_ip_configured`. TREK reaches Dawarich through the same strict guard as Immich and AirTrail, so the server needs `ALLOW_INTERNAL_NETWORK=true` to reach a LAN instance.
>
> **A private address** (`192.168.…`, `10.…`) is accepted with a warning. Your TREK server may additionally need `ALLOW_INTERNAL_NETWORK=true` to reach it.
> **A self-signed certificate** needs **Allow self-signed certificate**. The switch only relaxes the certificate check. An address TREK cannot resolve at all is still refused with *TREK cannot use that address.*
Each person connects their own Dawarich. One user's recordings are never visible to anyone else on a shared trip.
## How TREK checks for stays
## Reviewing what was recorded
With **Check for new stays automatically** on, TREK asks Dawarich for new stays every fifteen minutes. **Check now** on the card does the same at once and reports how many new stays it found. Pressing it while a check is already running answers *A check is already running* instead of asking Dawarich twice.
TREK checks for new stays in the background every fifteen minutes, for trips that are running or recently finished. You can turn that off and pull by hand instead, and **Check now** always works.
A check covers the dates of your trips, not your whole history:
Stays appear:
- every trip you own or are a member of that has a start date, is not archived, has begun (or begins tomorrow) and ended no more than 400 days ago
- for each of them, from three days before the start to one day after the end, but never past the present moment
- in the **Places** panel of a trip, for the dates that trip covers
- in a **journal**, above its timeline
Stays outside those windows are never fetched. Dawarich's confirmed and unconfirmed visits both come in, because since Dawarich 1.12 an unconfirmed visit is the normal state of one.
Each one shows what was recorded and how sure Dawarich's detector was. Then:
**Checking again never duplicates anything.** A stay is identified by your account and its Dawarich visit id, so the tenth check over the same dates produces the same list as the first. A stay you have not acted on yet is simply updated when Dawarich changes it, and removed when Dawarich deletes it. Stays you accepted or dismissed are never rewritten; see *When Dawarich changes its mind* below.
The addon switch is read on every run, so turning the addon off stops the checks without a restart.
## Reviewing stays in the trip planner
**From Dawarich** sits at the top of the trip's **Places** panel, and at the top of the places list on a phone. It starts collapsed; its header says when TREK last checked and shows how many stays are waiting. Until you connect an instance it reads *Connect Dawarich in Settings to see your stays here.*
Opened, it lists the stays of this trip grouped by day, with each stay's name and its arrival and departure times. A gauge mark flags a stay Dawarich's own detector was unsure about. Each row has two actions:
| Action | What happens |
|---|---|
| **Write a journal entry** | Creates a dated entry in the journal you pick, prefilled with the stay's date, time, name and coordinates. Add photos to the entry afterwards, as usual. |
| **Add as a place** | Creates a place on the trip, optionally pinned to one of its days. Left off a day it joins the trip's shortlist. |
| **Not a place I visited** | Dismisses it. Reversible — dismissed stays are one click away under *Show already dealt with*. |
| **Add as a place** | Opens the review step, then creates a place on the trip. |
| **Not a place I visited** | Dismisses the stay. Reversible, see below. |
Everything is editable before it is saved. A visit detector is right most of the time and confidently wrong the rest, which is exactly why there is a review step and not an import button.
**The review step** first shows what was recorded: the arrival and departure, how long the stay lasted, whether Dawarich still marks it *Detected, unconfirmed*, and how confident its detector was. Below that, every value is editable before anything is saved: **Name**, **Arrived**, **Left**, **Day**, **Trip** and **Notes**. **Day** can stay on **Not on a day yet**, which leaves the place unplanned on the trip. **Add place** creates it with the stay's coordinates, its arrival and departure as the place's times, and the length of the stay as its duration. Everyone on the trip sees it straight away.
Wishes are not ticked off from here. A wish belongs to the Atlas, is reached once, and is confirmed there — see *Wishlist and Atlas* below.
Adding a place needs the same rights as adding one by hand: `place_edit`, and `day_edit` to put it on a day. See [Admin-Permissions](Admin-Permissions).
A place that came out of a recording carries a small Dawarich mark next to its name, so months later it is still clear where it came from. Delete that place and the stay returns to the review list: an acceptance whose result is gone is not an acceptance.
A place that came out of a recording carries a small Dawarich mark next to its name in its details (*Added from your Dawarich recordings*), so months later it is still clear where it came from.
### When Dawarich changes its mind
Dismissed and accepted stays move to **Show _n_ already dealt with** at the bottom of the list. A dismissed stay has **Put back**. An accepted stay has no undo button, because the place it produced is a thing of its own now; delete the place instead, as described below.
Dawarich can rename a stay, or delete one, after you have already written a journal entry from it. TREK notices and says so next to the entry — and does nothing else. What you wrote is yours; an integration that rewrote your journal because a detector ran again would be a bug, not a feature.
A visit detector is right most of the time and confidently wrong the rest, which is why there is a review step and not an import button.
## Reviewing stays in a journal
On the desktop, a journal folds each day's waiting stays into that day: one line at the end of the day with the Dawarich mark, *1 stay from Dawarich* or *3 stays from Dawarich*, and the span from the first arrival to the last departure. Click it to open the stays.
- A day that has stays waiting but no entry yet joins the timeline, as long as it lies within the journal's own span: the dates of its entries together with the dates of the trips linked to it.
- Nothing is drawn on a day with nothing waiting, or for someone who cannot edit the journal's entries.
Each row offers **Write a journal entry** and **Not a place I visited**. In the fold, **Write a journal entry** adds the entry to this journal straight away: dated to the stay's day, timed at its arrival, and titled and located with the stay's name and coordinates. Edit it afterwards like any other entry, and add photos to it as usual.
On a phone, a Dawarich button over the journal's map (in the timeline view) opens **From Dawarich** as a sheet listing all your waiting stays. There, **Write a journal entry** opens the review step first, with **Name**, **Date**, **Arrived**, **Left**, **Journal** and **Your story**, and **Add entry** writes it.
Writing an entry needs edit rights on the journal.
## Deleting what you accepted
Delete the place or the journal entry a stay produced, and the stay returns to the list as waiting. The same happens when a bucket list wish that was ticked off from a stay is deleted. An acceptance whose result is gone is not an acceptance, so nothing is lost and nothing is stuck.
## When Dawarich changes its mind
Dawarich can rename a stay, move it, or delete it after you have already acted on it. TREK notices on its next check and marks the stay in the **already dealt with** list:
| Mark | Meaning |
|---|---|
| **Changed in Dawarich** | An accepted stay's recording changed since you accepted it. |
| **Gone from Dawarich** | An accepted or dismissed stay no longer exists in Dawarich. |
Both come with the sentence *What you wrote in TREK is untouched*, and that is all TREK does. The place or entry you made is never rewritten or deleted because a detector ran again; that would be the integration overwriting your journal, not a feature.
## The recorded route on the map
Open a trip and press the Dawarich control on the map. The route you actually travelled is drawn dashed and coloured per day, under the planned route so the plan stays readable.
### On the trip map
It is fetched live and never stored. If there is nothing to draw, the control says which: nothing was recorded on those dates, the instance could not be reached, or the device is offline.
The Dawarich button on the trip map switches the recorded route on and off. On the desktop it sits in the bottom right corner of the map, on a phone among the map controls. It stays available in road trip mode, where the route you actually drove is the thing you most want beside the planned one.
A journal draws the same thing for its own dates, on the map it already has, when *Show trip tracks* is on.
- The route is drawn dashed, one colour per day, underneath the planned route so the plan stays readable. Days are cut at local midnight, not at midnight UTC, so an evening walk stays on the evening it happened.
- On or off is remembered per trip for the browser session.
- While it is on, TREK fetches the route for the trip's dates and refreshes it every two minutes, so a trip in progress catches up without a reload.
- Collapsing a day in the day plan, or in the road trip sidebar, takes that day's route off the map together with its places.
- The button's label says why a map has no line: *Loading the recorded route…*, *Nothing was recorded on these dates*, *The recorded route could not be loaded*, or *The recorded route needs a connection*.
## Wishlist and Atlas
The route is drawn, never applied: TREK does not correct your plan from it.
Both live in the **Atlas**, on the Dawarich panel beside the statistics:
### On a journal map
- **Wishlist** asks your recordings about each bucket-list entry that has coordinates. A match needs both closeness and time spent — within 250 m and at least 20 minutes on the spot, so driving past does not count. What it finds is a list you confirm, with the distance, the time spent and the day; entries without coordinates are named as skipped rather than silently ignored. A wish is ticked off on the day it was reached, not on the day you pressed the button, and a tick that came from a recording can be undone on the wishlist itself.
- **Countries** reads the countries and cities your recordings cover in the last year. Countries already in your Atlas are marked as such, and countries you marked by hand keep their own provenance when confirmed again.
A journal draws the same route on its own map, from the first to the last date of the trips linked to it, when **Show all trip GPX tracks** is on in the journal's **Journey Settings**.
### Nothing is stored
The route is read from Dawarich when a map asks for it and then discarded. TREK's server holds it in memory for one minute, so panning and toggling do not ask your instance again, and forgets it on a restart or when you change the connection. No position is written to TREK's database, so the route is not in backups and is not available offline.
TREK prefers the tracks Dawarich has already generated, which arrive split into segments with a travel mode. On an instance that has not generated tracks yet, it falls back to the raw points and thins them to 600 per day, so a month-long trip stays drawable.
## Bucket list and Atlas
On the desktop Atlas, a Dawarich panel sits at the bottom of the map, left of the statistics, with two buttons: **Wishlist** and **Countries**. On a phone, a **Dawarich** button sits next to **Bucket List**. Both open the same dialog. The Dawarich reads need a connection; nothing is cached for offline use.
### Wishlist
**Check wishlist** asks your recordings, entry by entry, whether you reached the places on your bucket list.
- **A match needs closeness and time.** A wish counts as reached within 250 m and after 20 minutes on the spot. Of several stays that qualify, the longest wins.
- Each match shows the distance, the time spent and the day. Matches start selected, apart from wishes already ticked off, which are marked *Already ticked off*.
- Only entries with coordinates can be checked. The others are named as skipped rather than silently ignored.
- One check looks at up to 50 entries, the ones not ticked off yet first, and says so when there were more.
**Tick off _n_** marks the selected wishes visited **on the day of the stay**, not on the day you pressed the button. On the desktop bucket list, a wish ticked off this way shows that date with a tooltip, *Ticked off from your Dawarich recordings*; click the date to undo it. A wish that was already ticked off keeps its own date.
Background checks help here too: a stay of at least 20 minutes within 250 m of a wish is linked to it, and one wish belongs to exactly one stay (the closest one, the longer one on a tie). That link is only a hint. Ticking the wish off still needs you, or an assistant you authorised through MCP.
### Countries
**Look for countries** reads the countries and cities your recordings cover in the last 12 months.
- Countries already marked visited in your Atlas, by hand or from an earlier check, are left out, so a mark you set by hand is never relabelled. The rest are listed with their flag and their cities, and start selected.
- Country names TREK cannot match to a country are listed underneath rather than dropped.
- **Add _n_ countries** marks them visited, recorded as coming from Dawarich. A country you removed from your Atlas earlier comes back when you confirm it here.
TREK asks Dawarich for the year in 30-day pieces, one after another, because Dawarich computes this answer on the spot and a whole year at once can take longer than a request may.
## MCP tools
With the [MCP](MCP-Overview) addon on as well, an assistant can review your stays for you. The tools exist only while the Dawarich addon is on. Switching the addon on or off ends open MCP sessions, so an assistant reconnects with the tools that currently apply. The connection itself (address, key, test, disconnect) is deliberately not reachable through MCP.
| Tool | What it does | Scope |
|---|---|---|
| `list_dawarich_suggestions` | Lists your stays: waiting, accepted or dismissed, optionally for one trip. 50 by default, up to 200. | `journey:read` |
| `accept_dawarich_suggestion_as_place` | Turns a stay into a place on a trip, optionally on one of its days, with a corrected name, notes or coordinates. | `places:write` |
| `accept_dawarich_suggestion_as_journal_entry` | Turns a stay into a dated journal entry, with a title, a story, a date and a time. | `journey:write` |
| `mark_bucket_list_item_visited_from_dawarich` | Ticks off the wish a stay was linked to, or another wish of yours. | `atlas:write` |
| `dismiss_dawarich_suggestion` | Dismisses a stay, or puts a dismissed one back. | `journey:write` |
| `get_dawarich_trip_track` | Summarises a trip's recorded route per day: segments, times, travel mode and distance. The line itself stays on the map. | `journey:read` |
The same rules apply as in the browser: nothing is added until a tool is called, and the permissions for adding a place are checked the same way. See [MCP-Addon-Tools](MCP-Addon-Tools) and [MCP-Scopes](MCP-Scopes).
## What TREK keeps, and what it never does
TREK keeps:
- **your connection**: the address, the encrypted key, the two switches, when it last checked and how that went, and which parts of your instance answered
- **the stays it offered you**: name, coordinates, arrival and departure, length, Dawarich's confidence, the country, and what you did with each. They belong to you and nobody else sees them.
TREK never:
- **writes to Dawarich.** Every request it makes is a read.
- **stores your route or raw positions.** They stay in Dawarich.
- **adds a place, an entry, a tick or a country on its own.** Every one of them needs a confirmation.
- **rewrites or deletes what you made** because the recording changed.
## The other direction
Dawarich can read your TREK trips through the [Public API](Public-API) — a versioned, read-only surface with a key you mint yourself and can narrow to just the sections you want it to see. Nothing is written back to TREK either.
Dawarich can read your TREK trips through the [Public API](Public-API): a versioned, read-only surface with a key you mint yourself and can narrow to just the sections you want it to see (see [What a key may read](Public-API#what-a-key-may-read)). Nothing is written back to TREK either.
## Which Dawarich versions work
TREK probes your instance when you connect and uses what it finds. A feature your version does not offer is switched off rather than broken, and the connection card names what is missing.
TREK asks your instance what it offers when you test the connection, and again after every successful check, so a Dawarich upgrade is picked up without reconnecting. A feature your version does not offer is switched off rather than broken, and the connection card names it: *This Dawarich version does not offer: …*. The integration was checked against Dawarich 1.14.4.
What TREK reads, when the instance offers it:
| Endpoint | Used for |
|---|---|
| `GET /api/v1/users/me` | the connection test |
| `GET /api/v1/users/me` | the connection test, and the version the instance reports |
| `GET /api/v1/visits` | the stays waiting for review |
| `GET /api/v1/tracks` | the recorded route on the map |
| `GET /api/v1/points` | the same, on an instance that has not generated tracks yet |
| `GET /api/v1/locations` | checking your wishlist |
| `GET /api/v1/locations` | checking your bucket list |
| `GET /api/v1/countries/visited_cities` | the Atlas countries |
Two details worth knowing, because they shape what TREK can promise:
- **A Dawarich visit carries no "last changed" timestamp.** TREK detects a change by comparing the fields it shows, which is why it can tell you a stay changed but cannot tell you exactly what.
- **Deleting a visit removes it from the API rather than marking it deleted.** TREK notices by re-reading the whole window, which is why a sync reads a date range rather than only what is new.
- **A Dawarich visit carries no "last changed" timestamp.** TREK detects a change by comparing the fields it shows, which is why it can tell you a stay changed but not exactly what.
- **Deleting a visit removes it from the API rather than marking it deleted.** TREK notices by re-reading the whole date range, which is why a check reads the trip's dates rather than only what is new.
Each request to Dawarich gives up after 15 seconds, and TREK reads at most 8 MB from one answer.
## Troubleshooting
| What you see | What it usually means |
|---|---|
| *TREK could not reach that address* | Wrong address, instance down, or your TREK server has no route to it. |
| *Dawarich rejected the API key* | The key was regenerated, or belongs to a different instance. |
| *That address answered with something that is not Dawarich* | Usually a reverse proxy or an auth portal answering instead. Enter the Dawarich address itself. |
| *This Dawarich version does not have that endpoint* | An older instance. Everything else keeps working; the connection card lists what is missing. |
| Connected, but no stays | Dawarich detects visits only with a reverse geocoder configured (Photon, Nominatim, Geoapify or LocationIQ). Check that first. |
| *some trips could not be read* | Part of the sync succeeded. Press **Check now**; if it persists, look at the reason under the connection. |
| No Dawarich card in **Settings → Integrations** | The addon is off. An admin enables it in **Admin → Addons**. |
| *TREK could not reach that address.* | Wrong address, the instance is down, or your TREK server has no route to it. A LAN instance also needs `ALLOW_INTERNAL_NETWORK=true`, and a self-signed certificate needs **Allow self-signed certificate**. **Test connection** adds the underlying reason in brackets. |
| *TREK cannot use that address.* | The address is malformed or does not resolve, so **Save** refused it. |
| *Dawarich rejected the API key.* | The key was regenerated, or belongs to a different instance. |
| *That API key is not allowed to read this.* | Dawarich refused the request for this key. |
| *That address answered with something that is not Dawarich.* | Usually a reverse proxy or a login portal answering instead. Enter the Dawarich address itself, reachable without a separate login. It also appears when one answer is larger than 8 MB. |
| *This Dawarich version does not have that endpoint.* | An older instance. Everything else keeps working; the connection card lists what is missing. |
| *Dawarich asked TREK to slow down. Try again shortly.* | Dawarich is rate limiting. Wait and press **Check now** again. |
| *some trips could not be read* | Part of a check succeeded and part did not. Press **Check now**; if it persists, read the reason on the connection card. |
| **Not connected** after changing the address | The host changed, so the key was cleared. Type it in again. |
| Connected, but no stays | TREK only reads stays inside the dates of your trips, and only the ones Dawarich's visit detection produced. Check that the stays show up in Dawarich itself for those dates. |
| *Nothing was recorded on these dates* | Dawarich has no points or tracks for the trip's dates, or the trip has no dates. |
## See also
- [Public API](Public-API) — how Dawarich reads your trips
- [Atlas](Atlas) — the bucket list and the visited-countries map
- [Journey Journal](Journey-Journal) — where accepted stays become entries
- [Addons Overview](Addons-Overview) — the full addon table
- [Public API](Public-API): how Dawarich reads your trips
- [Atlas](Atlas): the bucket list and the visited countries map
- [Journey Journal](Journey-Journal): where accepted stays become entries
- [Internal Network Access](Internal-Network-Access): reaching an instance on your LAN
- [Addons Overview](Addons-Overview): the full addon table
+1 -1
View File
@@ -104,7 +104,7 @@ Shows or hides station / airport names on the endpoint markers of booking routes
## Explore places on the map
Shows a category pill on the trip map for finding nearby restaurants, hotels and more from OpenStreetMap. Set to **On** or **Off**.
Shows a row of category buttons on the trip map for finding nearby restaurants, accommodation, sights and more. TREK's own place index answers first and OpenStreetMap fills in; see [Exploring the map by category](Places-and-Search#exploring-the-map-by-category). Set to **On** or **Off**.
## Always show booking routes
+345
View File
@@ -0,0 +1,345 @@
# Document Sync
A trip can keep its documents in step with a self-hosted document store: **Paperless-ngx**, **Papra**, **Nextcloud**, **OpenCloud** or a **Synology** NAS. What someone uploads in TREK appears in the store, and what someone files in the store appears in TREK.
Three rules shape everything else on this page:
- **The connection belongs to the trip, not to a person.** The trip owner connects the store once, TREK talks to it under that one account, and TREK's own membership decides who sees what. Every member sees the same documents, and the store never learns who is on the trip.
- **TREK keeps its own copy of every document.** A synced document is an ordinary file in the trip's [Documents-and-Files](Documents-and-Files) manager, so preview, download, trash, offline use, [PDF-Export](PDF-Export) and [Backups](Backups) work as before, and a store that is down does not empty a trip that starts tomorrow.
- **Nothing is deleted on the other side on its own.** A document removed in the store is flagged in TREK and waits for a person. A document deleted in TREK is removed in the store only when the binding is set to move it to the store's recycle bin.
> **Admin:** Each store is switched on separately under the **Documents** addon in **Admin → Addons**. They ship switched off. A store on your local network also needs `ALLOW_INTERNAL_NETWORK=true` on the TREK server. See [Admin-Addons](Admin-Addons) and [Internal-Network-Access](Internal-Network-Access).
## What each store syncs
| Store | A trip is bound to | Shown in the list as |
|---|---|---|
| Paperless-ngx | a tag | *Files by tag* |
| Papra | a tag inside one organisation | *Files by tag, inside an organisation* |
| Nextcloud | a folder | *Files in a folder* |
| OpenCloud | a space | *Files in a space* |
| Synology Drive | a folder inside a shared folder, reached through File Station | *Files in a folder on the NAS* |
Only what is inside that tag, folder or space is synced. Everything else in the store stays out of TREK.
On the TREK side, a binding covers all of the trip's documents in the file manager. Files attached to a chat message or to a collab note are left out: they belong to a conversation, not to the trip's paperwork.
## Switching stores on
An administrator switches each store on under **Admin → Addons**. The stores are rows underneath the **Documents** addon, on the desktop and on the phone, and they only show while **Documents** itself is on: **Paperless-ngx**, **Papra**, **Nextcloud**, **OpenCloud** and **Synology Drive**.
- **All five ship switched off.** The admin decides only which stores may be offered. The credentials are entered per trip, in the trip itself, never in the admin panel.
- **Switching a store off pauses** every binding that uses it, without touching the binding or its documents. The binding card then reads *Paused: an administrator has switched this provider off. Syncing resumes once it is back on.* and resumes where it stopped once the store is back on.
- **Switching the Documents addon off switches every store off** as well. When **Documents** comes back, each store has to be switched on again.
- A store cannot be switched on while **Documents** is off. The server answers *Enable the Documents addon first*.
## Binding a trip
Open the trip's **Files** tab. When a store is available, a **Document sync** button sits next to **Trash** in the toolbar; on the phone it sits between **Upload** and the trash button at the top of the Files tab. The button only shows where there is something behind it: on a trip that is already bound, for every member, and on any trip for the people who may bind it while at least one store is switched on.
**Who may bind a trip:** the trip owner, or an instance administrator. The credential a binding stores usually reaches that person's entire archive, so no other member can set one up, point it elsewhere or change its settings. Every member can open the dialog, see where the trip's documents go and press **Sync now**.
1. Open **Document sync**. Under **Connect a provider**, pick the store.
2. Fill in the form. The fields per store are listed below; optional ones are marked as such.
3. Press **Test connection**. On success the footer reads *Reached it, signed in as* followed by the account name. On failure it names the reason; see [Troubleshooting](#troubleshooting).
4. Press **Connect**.
5. TREK asks *Where should this trip live in* followed by the store's name. Either create a new tag, folder or space under **Make a new one** (the name is prefilled from the trip's title plus its id, for example `japan-2026-42`) and press **Create**, or pick an existing one under **Or use one you already have**.
The binding starts with both directions on, **Keep both copies** for deletions, **Ask me** for conflicts and **Sync automatically** on, and TREK runs it once straight away. A trip can be bound to several stores, one binding per store; each of them holds a full copy of the trip's documents. With a store bound, **Add another** lists the remaining ones.
Things worth knowing before you bind:
- **One account per store and trip.** The binding runs under the account of the person who saved the connection, and only while that person is the trip owner or a member of the trip. When they leave the trip the binding stops, so an ex-member's credential is never used again. An instance administrator who is not on the trip can set a binding up, but it stops at the next scheduled check for the same reason.
- **Documents that arrive from the store** are listed in TREK as uploaded by that person, since nobody in TREK uploaded them.
- **The credentials are stored encrypted** with the trip and never sent back to a browser. Once a trip is connected to a store, picking that store again (after **Disconnect**, for example) goes straight to the folder picker with the stored credentials; the form is not shown again.
- **Bind a new, empty tag, folder or space** rather than one that already holds this trip's documents from an earlier binding. A new binding knows nothing about earlier pairings, so it treats both sides as new: every document in the store is downloaded into TREK as a further copy, and TREK's documents are offered to the store again, which gives second copies in Paperless-ngx and failed uploads under **Needs a look** where a file name is already taken.
## Setting up each store
Every connection form ends with **Accept a self-signed certificate**, off by default: *For an instance on your own network with a self-signed certificate.* It relaxes the certificate check only; the address rules in [Stores on your own network](#stores-on-your-own-network) still apply.
### Paperless-ngx
*TREK files this trip under its own tag and never touches the rest of your archive.*
| Field | Notes |
|---|---|
| Address | The Paperless-ngx address, for example `https://paperless.example.com`. A trailing `/api` is tolerated. |
| API token | *Create one under My Profile in Paperless. It carries that account's full rights.* |
- **Scope:** a tag. The picker lists your tags; **Make a new one** creates a tag, and refuses a name that already exists rather than taking over a tag that may belong to someone else's filing. Pick an existing tag from the list instead.
- **Custom field:** a document TREK uploads carries the trip's tag and a custom field named `trek_trip_id`, holding `trek-trip-` plus the trip's id. TREK creates the field on the first upload. It is a breadcrumb for whoever tidies the archive later; TREK does not filter on it. Removing the tag from a document takes it out of the trip, whatever the field says.
- **Names:** Paperless-ngx keeps a title rather than a file name, so a document arrives in TREK as its title plus the extension of the original file. TREK downloads the original file, not the archived PDF Paperless-ngx makes from it.
- **File types:** Paperless-ngx takes PDF, JPEG, PNG, TIFF, GIF, BMP, WebP, HEIC and HEIF images, plain text, CSV and email (`.eml`) files. Word, Excel, PowerPoint, OpenDocument and RTF files only go through on an instance that runs Tika and Gotenberg; without them Paperless-ngx refuses them and TREK lists them as *Type not allowed*.
- **Instant updates:** when the token's user may add workflows, TREK creates a workflow named `TREK document sync (link n)` that calls TREK whenever a document with the trip's tag is added or updated. **Disconnect** deletes it again. See [When TREK checks](#when-trek-checks).
- **Recycle bin:** a document TREK removes goes to the Paperless-ngx trash.
- **Version:** Paperless-ngx 3 or newer.
### Papra
*Pick the organisation this trip belongs to. TREK files it under its own tag inside it.*
| Field | Notes |
|---|---|
| Address | The Papra address, for example `https://papra.example.com`. |
| API key | Starts with `ppapi_`. *Create one under API keys in Papra. Papra keys always reach every organisation you belong to.* |
| Organisation ID | *The org_… id from the Papra address bar.* It is `org_` followed by 24 lowercase letters and digits. |
- **Scope:** a tag inside that organisation. **Make a new one** creates the tag, and refuses a name that already exists.
- **Key permissions:** a key limited in Papra must still be allowed to work with the organisation's documents and tags. Papra answers a missing permission exactly like a wrong key, so TREK can only report *The credentials were refused.*
- **Duplicates:** Papra keeps one document for identical bytes, so of two identical files in TREK only the first reaches Papra; the second is listed under **Needs a look**.
- **Upload limit:** Papra's own upload limit is an instance setting TREK cannot read. A file over it is listed as *Too large*.
- **Instant updates:** none. Papra does not let an API key manage webhooks, so the binding runs on the timer.
- **Recycle bin:** a document TREK removes goes to Papra's trash.
### Nextcloud
*Use an app password, not your account password: it survives two-factor and you can revoke it on its own.*
| Field | Notes |
|---|---|
| Address | The Nextcloud address, for example `https://cloud.example.com`. |
| Username | *Your Nextcloud login name, not your email address.* |
| App password | *Settings, Security, Create new app password. Never your account password.* |
| Base folder | Optional. *Where TREK looks for trip folders.* Defaults to `/TREK`. |
- **Scope:** a folder directly under the base folder. **Make a new one** creates it there, and creates the base folder too if it does not exist yet. A folder of that name that already exists is refused; pick it from the list instead.
- **Only the top level** of the folder is synced. Sub-folders inside it are left alone, so moving a file into one takes it out of the trip.
- **Instant updates:** when the account may manage webhooks (an administrator account on an instance with the `webhook_listeners` app), TREK subscribes itself to files being created, written, deleted and renamed. Otherwise the binding runs on the timer.
- **Recycle bin:** a document TREK removes goes to Nextcloud's *Deleted files*. **On an instance without the Deleted files app, it is deleted for good.**
### OpenCloud
*TREK gets its own space for this trip, separate from everything else.*
| Field | Notes |
|---|---|
| Address | The OpenCloud address, for example `https://opencloud.example.com`. |
| Username | Your OpenCloud username. |
| App token | *Created under app tokens in OpenCloud.* |
- **Scope:** a space. The picker lists the spaces the account can reach; **Make a new one** creates a new space, which needs an account OpenCloud allows to create spaces.
- **Only the top level** of the space is synced. Sub-folders inside it are left alone.
- **Instant updates:** none. OpenCloud has no subscription API TREK could use, so the binding runs on the timer.
- **Recycle bin:** a document TREK removes goes to the space's trash.
### Synology Drive
*Best a DSM account that only reaches the shared folder this trip should use.*
| Field | Notes |
|---|---|
| Address | The DSM address. *Include the port, for example https://nas.example.com:5001* |
| Username | *Best a dedicated DSM account with access to just this shared folder.* |
| Password | The DSM password of that account. DSM has no app tokens, so this is the real account. |
| Two-factor code | Optional. *Only needed once, if the account uses two-factor authentication.* |
| Base folder | Optional. Defaults to `/trek`. |
- **File Station:** TREK talks to the NAS through the File Station API, so the account must be allowed to use File Station. If it is not, **Test connection** fails even though the login worked.
- **Scope:** a folder. The picker lists every shared folder the account can see, plus the folders directly under the base folder. DSM paths start with the name of a shared folder, so the default `/trek` only exists if there is a shared folder called `trek`; set **Base folder** to a path inside an existing shared folder, such as `/documents/trek`, or bind a shared folder directly. **Make a new one** can create folders inside a shared folder, never a shared folder itself.
- **Sub-folders** inside the bound folder are included.
- **Renames** in File Station come through even though DSM has no file ids: TREK recognises the renamed or moved file by its size and modification time.
- **Two-factor accounts:** the code is used once. DSM then hands TREK a trusted-device token, which TREK keeps encrypted with the trip's Synology connection, so it survives a restart of TREK and no new code is needed afterwards. TREK appears as **TREK** among the account's trusted devices in DSM.
- **Failed logins:** DSM blocks an address after a few failed logins. TREK does not retry a refused password for a minute, and waits fifteen minutes when DSM has already blocked it.
- **Recycle bin:** File Station's API only deletes permanently, so a document TREK removes is moved into a `.trek-trash` folder inside the bound folder instead, where anyone can take it back out in File Station. A file of the same name already in there is renamed with a timestamp rather than overwritten. TREK never lists the `.trek-trash` folder.
- **Instant updates:** none. File Station has no change feed, so the binding runs on the timer.
## The binding card
Once bound, the dialog lists the trip's stores under **This trip** and shows the selected one as a card:
- **The store's name** with a state dot, and **Paused** while **Sync automatically** is off.
- **Where and when:** the bound tag, folder or space, and the last run.
- **A notice line** when the binding needs attention, for example *Failed · The provider could not be reached.*
- **The flow bar:** TREK on one side, the store on the other, each with the number of documents it holds, and two lanes between them, **Out to the store** and **In from the store**. The trip owner switches a direction off by clicking its lane; the last lane cannot be switched off. Other members see the same bar without the switch.
- **Sync now**, for every member, and **Disconnect** for the trip owner.
**Settings**, folded away under the card, holds what the owner sets once:
| Setting | Options |
|---|---|
| When a document is deleted | **Keep both copies** (default) or **Move to recycle bin**. *What happens to the copy on the other side.* |
| When both sides changed | **Ask me** (default), **Keep the TREK copy** or **Keep the store's copy**. *Which copy survives when a document was edited in both places.* |
| Sync automatically | On by default. Off leaves the binding to **Sync now** alone. |
| Instant updates | An address for the store to call. See [When TREK checks](#when-trek-checks). |
On the phone the card opens as a sheet. The first three settings are buttons there that step through their options with each tap; the **Instant updates** address is only shown on the desktop.
**Disconnect** ends the binding and keeps every document where it is, on both sides: *Documents stay in TREK and at the store. Only the pairing between them goes.* The phone asks before it disconnects; the desktop does not. A workflow or webhook subscription TREK created for the binding is removed with it.
## How changes travel
### New documents
- **Uploaded in TREK:** goes to the store on the next run, into the bound tag, folder or space.
- **Filed in the store:** downloaded into TREK on the next run as an ordinary trip document, provided TREK accepts its type and size (see [File types and sizes](#file-types-and-sizes)).
TREK itself has no way to rename a document or replace its content, so what travels from TREK to the store is new documents and deletions.
### Changes in the store
A document whose content changed in the store is downloaded again as a new document, and the copy it replaces goes to TREK's trash. Links the old copy had to bookings, places or expenses stay with the old copy.
**Renames in the store come through.** On Nextcloud, OpenCloud and Synology the TREK copy takes the new name. On Paperless-ngx and Papra a document that came from the store arrives again as a fresh copy after a rename, and on Paperless-ngx after any edit of the document, and the old copy goes to TREK's trash without its links. A document TREK itself uploaded to Paperless-ngx or Papra is renamed in place.
### Deletions
**Deleted in the store:** TREK keeps its copy and flags it as *Missing at the provider* under **Needs a look**. Nothing is removed in TREK.
**Deleted in TREK:** the file goes to TREK's trash as usual, and the binding's **When a document is deleted** rule decides what happens in the store:
| Rule | In the store |
|---|---|
| **Keep both copies** | The store's copy stays. TREK remembers the pairing, so it is not downloaded again. |
| **Move to recycle bin** | The store's copy goes to the store's bin: the Paperless-ngx trash, Papra's trash, Nextcloud's *Deleted files*, the OpenCloud space's trash, or the `.trek-trash` folder on Synology. |
The rule is applied once, at the run that notices the deletion. Changing it later does not reach back to documents deleted before. Emptying TREK's trash or deleting a file there permanently counts as a deletion too, and the store's copy is not downloaded again afterwards.
### Restoring from TREK's trash
A document taken back out of TREK's trash syncs again, in one of three ways:
- **The store's copy is still there:** the pairing counts again, and an edit made in the store in the meantime comes down.
- **TREK had moved the store's copy to the bin:** the document goes up again as a new one.
- **Someone else deleted the store's copy:** TREK does not upload it over their deletion. It flags it as *Missing at the provider* instead.
### Conflicts
When a document changed in both places since the last run, **When both sides changed** decides. **Keep the TREK copy** and **Keep the store's copy** settle it on their own, as long as the binding still moves documents in the winner's direction; when that lane is switched off, the conflict waits as with **Ask me**.
With **Ask me**, the document waits under **Needs a look** as a *Conflict*. **Resolve** opens it with three choices: **Keep the TREK version**, **Keep the provider version**, or **Keep both**, which keeps the store's copy as a second document in TREK so nothing is lost. The trip owner or an instance administrator decides.
### The mass-delete guard
An unmounted share, a revoked share or an expired token all answer the same way: a listing far shorter than the last one. Read literally, that would flag a whole trip as deleted.
So once a binding knows **five or more** documents in the store, a run that finds **more than 40 percent** of them gone at once is thrown away without acting on any of it, not even the parts that look fine. The binding shows *Partly synced · Most documents vanished at once, so nothing was changed. Check that the folder is still mounted.* and waits until the documents are back, or until the trip is bound again. Fewer missing documents are flagged one by one as *Missing at the provider*. Deleting documents in TREK never trips the guard.
## Needs a look
The dialog lists what a person has to decide about under **Needs a look**, with a count per kind. On the phone the sheet shows conflicts; the full list is in the desktop dialog, and assistants read it through MCP.
| Shown as | What it says | What to do |
|---|---|---|
| **Conflict** | *Changed in both places. Pick which one to keep.* | Press **Resolve** and pick a side. |
| **Missing at the provider** | *Gone from the store. The TREK copy is still here.* | Put the document back in the store, for example from its recycle bin, if it went by mistake. The flag clears on the first run that finds it again. |
| **Type not allowed** | *This file type is not allowed here.* | TREK refused an incoming file, or the store refused an outgoing one. See [File types and sizes](#file-types-and-sizes). |
| **Too large** | *Bigger than the limit.* | The file is over TREK's limit or over the store's. |
| **Error** | *The transfer did not go through.* | TREK tries again after 30 seconds, 2 minutes, 10 minutes and an hour. After six failed attempts in a row the document waits; **Sync now** gives it another go. |
## File types and sizes
**Into TREK**, a document from the store goes through the same checks as an upload in the file manager:
- **The size limit** of 50 MB per file. A larger document is listed as *Too large*.
- **The blocked types**, which are always refused (HTML, SVG, XML, scripts and executables; the full list is in [Documents-and-Files](Documents-and-Files)).
- **The allowed types** an admin sets under **Admin → Settings → Allowed File Types**. A file without an extension is refused too.
A document refused for its type stays refused until it changes in the store. Widening the allowed types does not fetch it again on its own.
**Into the store**, the store's own rules apply: the Paperless-ngx type list and Papra's upload limit (see above). A store that is out of space reports *The provider is out of space.*
## When TREK checks
A binding runs **straight after it is bound**, and from then on **on a timer, every five minutes** by default. Each pass takes up to 20 bindings, the ones waiting longest first, and each run moves at most 25 documents; the rest follow on the next run, and the binding shows *Partly synced* until then.
- **Sync now** runs a binding at once. It also gives documents that stopped retrying another attempt.
- **Sync automatically** off leaves a binding to **Sync now** alone.
- **A failing binding backs off:** the next attempt waits 1, 5, 15, 30, 60 and then 120 minutes. After ten failures in a row the timer stops trying until a run started with **Sync now** succeeds.
### Instant updates
Where a store can tell TREK that something changed, it calls the binding's own address, and TREK runs the binding soon after instead of waiting for the timer. A call only ever means "look now": TREK waits five seconds so a burst of calls ends up as one run, and never reads anything from what the store sent. The timer keeps running either way, because no store reports every change: Paperless-ngx, for example, sends nothing when a document is deleted.
| Store | Instant updates |
|---|---|
| Paperless-ngx | TREK creates the workflow itself when the token's user may add workflows. |
| Nextcloud | TREK subscribes itself when the account may manage webhooks (an administrator account with the `webhook_listeners` app). Nextcloud sends these from its background jobs, so they arrive as promptly as its cron runs, and a TREK on a private address is only called when Nextcloud's `allow_local_remote_servers` is on. |
| Papra, OpenCloud, Synology | Timer only. |
- **The address TREK registers** is built from the address the person binding the trip used to open TREK at that moment, including what the reverse proxy passes in `X-Forwarded-Host` and `X-Forwarded-Proto`. Bind the trip through the address the store can reach TREK under. Behind a proxy that passes no host, no address is registered and the timer carries the binding.
- **Paperless-ngx refuses a callback address longer than 256 characters.** The binding then runs on the timer.
- **TREK only acts on a call that carries the binding's secret**, which TREK hands over itself when it subscribes. The **Instant updates** address under **Settings** is shown for every binding, but the secret is not shown anywhere, so pasting that address into a store by hand does not speed anything up. Those bindings run on the timer.
### Tuning
There is no environment variable or admin screen for the timer. Two rows in the `app_settings` table are read on every pass, so a change needs no restart:
| Key | Effect |
|---|---|
| `docsync_poll_interval_seconds` | Seconds between passes. Default `300`, kept between `60` and `3600`. |
| `docsync_sync_enabled` | `false` stops the timer and ignores store calls for every binding on the instance. **Sync now** still works. |
## Stores on your own network
TREK reaches every store through its strict outbound guard (see [Internal-Network-Access](Internal-Network-Access)):
- **A store on a private address needs `ALLOW_INTERNAL_NETWORK=true`** on the TREK server. That includes a store in another container on the same Docker network (the container name resolves to a private address), a Tailscale address (`100.64.0.0/10`) and a `.local` name.
- **Loopback is never reached**, whatever the flag says: an address such as `localhost` or `127.0.0.1` is refused. Use the host's LAN address or the container name instead.
- A private address is saved even while the flag is off, but every request to it is refused with *That address is not allowed.* **Test connection** shows the same message for a name that does not resolve at all.
- A store with a self-signed certificate needs **Accept a self-signed certificate** in its connection form.
## MCP tools
With the [MCP](MCP-Overview) addon on as well, an assistant can see where a trip's documents live and start a sync. The tools exist only while the **Documents** addon is on, and any member of the trip may use them. Connecting a store or changing a binding is deliberately not possible through MCP: it hands over a credential to someone's document archive, and that stays with the trip owner in the file manager.
| Tool | What it does | Scope |
|---|---|---|
| `get_trip_document_sync` | Shows the trip's bindings: the store, the bound tag, folder or space, the last run and its state, and how many documents are synced, waiting, in conflict or missing in the store. | `files:read` |
| `list_trip_document_sync_issues` | Lists what **Needs a look** lists: conflicts, refused types and sizes, failed transfers and documents gone from the store. Empty when everything is in step. | `files:read` |
| `sync_trip_documents` | Runs every binding of the trip now and reports what came in, what went out and what is in conflict. `full: true` compares both sides in full. A binding whose owner left the trip, or whose store an admin switched off, is reported and not run. | `files:write` |
See [MCP-Addon-Tools](MCP-Addon-Tools) and [MCP-Scopes](MCP-Scopes).
## Which versions work
- **Paperless-ngx 3 and newer.** TREK pins the Paperless-ngx API version it was written against, so a routine upgrade of Paperless-ngx does not change the answers under it.
- The integration was checked against **Paperless-ngx 3.1.3**, **Papra 26.6.2**, **Nextcloud 31.0.14** and **OpenCloud 8.0.1**.
- **Synology** follows Synology's File Station API guide and was checked against a stand-in for it. It has not yet been confirmed on real DSM hardware.
## Troubleshooting
### Binding states
| State | What it means |
|---|---|
| **Not synced yet** | Bound, first run still to come. |
| **In sync** | The last run finished with nothing left over. |
| **Partly synced** | The last run left something undone: more than 25 documents to move, documents listed under **Needs a look**, or the mass-delete guard. The notice line names which. |
| **Failed** | The store could not be used. The notice line names the reason; TREK retries with the backoff described above. |
| **Sign in again** | The store refused the stored credential while TREK was listing documents. More often a refused credential shows as **Failed** with *The credentials were refused.* The usual causes: a revoked Paperless-ngx token or Papra key, a deleted app password or app token, a changed DSM password, or TREK removed from the account's trusted devices in DSM. If the credential still exists in the store, **Sync now** tries again. The connection form only opens for a store the trip has not been connected to yet, so a replaced credential cannot be entered from the trip at the moment. |
| **Folder is gone** | The bound tag, folder or space no longer exists. TREK does not recreate it. **Disconnect**, then pick the store again under **Add another** and bind a new, empty one; TREK's documents go up into it. |
| **Owner left the trip** | The person whose account the store was connected with is no longer on the trip. The binding stopped for good and **Sync now** is refused. Documents stay where they are on both sides. Once that person is back on the trip, switching **Sync automatically** on lets it run again. |
### Messages
| Message | What it usually means |
|---|---|
| *No document providers are available* | No store is switched on. An admin switches them on under **Admin → Addons → Documents**. |
| *The provider could not be reached.* | Wrong address, the store is down, or the TREK server has no route to it. An `https://` address on a port that only speaks plain HTTP lands here too. |
| *The certificate was rejected. Allow self-signed certificates if you trust this instance.* | Turn on **Accept a self-signed certificate**. |
| *The credentials were refused.* | Wrong token, key, app password or password. On Nextcloud, check that it is an app password and not the account password. On Papra, check the key's permissions. |
| *This account is not allowed to do that.* | The account lacks a permission in the store, for example creating a space in OpenCloud or reaching a shared folder on the NAS. |
| *Not found on the provider.* | On Nextcloud during **Test connection**, the username is not the login name. Otherwise the document or folder is gone. |
| *The connected folder no longer exists.* | See **Folder is gone** above. On Synology, **Create** answers the same when **Base folder** does not start with an existing shared folder. |
| *The provider is rate limiting us. TREK will try again later.* | The store asked TREK to slow down, or DSM blocked TREK's address after failed logins. |
| *The file is larger than the provider accepts.* | The store refused the upload for its size. |
| *The provider does not accept this file type.* | The store refused the upload for its type. |
| *The provider is out of space.* | The account's quota in the store is full. |
| *The document changed on both sides.* | A conflict. Nextcloud's **Create** also answers this when a folder of that name already exists; pick it from the list instead. |
| *The transfer did not arrive intact.* | The store stored something different from what TREK sent. TREK tries again. |
| *The provider reported an error.* | The store answered with an error TREK has no closer word for. On Synology, **Test connection** also answers this when the account may not use File Station, and **Create** when DSM will not accept the folder name. |
| *The provider took too long to answer.* | The store accepted the request but did not answer in time. |
| *That address is not allowed.* | The address points at loopback or link-local, does not resolve, or is private while `ALLOW_INTERNAL_NETWORK` is off. See [Stores on your own network](#stores-on-your-own-network). |
| *Most documents vanished at once, so nothing was changed. Check that the folder is still mounted.* | The mass-delete guard. See above. |
| *Paused: an administrator has switched this provider off. Syncing resumes once it is back on.* | The store, or the whole **Documents** addon, is switched off. Nothing about the binding changed. |
| *This provider is not available on this instance.* | The store is switched on but this TREK version has no adapter for it. |
| *Something went wrong.* | Anything else, including **Sync now** on a binding whose owner left the trip. |
## See also
- [Documents and Files](Documents-and-Files): the file manager every synced document lands in
- [Internal Network Access](Internal-Network-Access): reaching a store on your LAN
- [Admin: Addons](Admin-Addons): switching the stores on
- [MCP Addon Tools](MCP-Addon-Tools): the three document sync tools
- [Trip Members and Sharing](Trip-Members-and-Sharing): who is on a trip
+11
View File
@@ -61,6 +61,16 @@ From a reservation modal, use the "link existing file" picker to attach files di
Click the download icon on any file row to download it. `.pkpass` files (Apple Wallet passes) are served with the `application/vnd.apple.pkpass` MIME type, so Safari on iOS and macOS offers to add the pass to Wallet instead of saving it as a generic download.
## Document sync
A trip's documents can be kept in step with a self-hosted document store: Paperless-ngx, Papra, Nextcloud, OpenCloud or a Synology NAS. Once a store is available, a **Document sync** button sits next to **Trash** in the toolbar; on the phone it is at the top of the Files tab. The trip owner connects the store there once, and from then on what someone uploads here appears in the store, and what someone files in the store appears here.
Synced documents are ordinary files in this manager. Preview, starring, links, trash and download work as described on this page, and a document deleted here is only removed in the store when the binding is set to do so.
See [Document-Sync](Document-Sync) for setup per store, the delete and conflict rules, and troubleshooting.
> **Admin:** Each store is switched on separately under the **Documents** addon in [Admin-Addons](Admin-Addons). They ship switched off.
## Permissions
| Permission | Controls |
@@ -72,5 +82,6 @@ Click the download icon on any file row to download it. `.pkpass` files (Apple W
## See also
- [Reservations-and-Bookings](Reservations-and-Bookings)
- [Document-Sync](Document-Sync)
- [Admin-Addons](Admin-Addons)
- [Trip-Planner-Overview](Trip-Planner-Overview)
+22 -7
View File
@@ -53,7 +53,7 @@ like `NODE_ENV=staging` still boots.
| `SESSION_DURATION` | How long a login session stays valid before re-login is required. Used when **"Remember me" is unchecked** on the login form (the default): applies to the `trek_session` JWT `exp` claim, and the cookie is issued as a **browser-session cookie** (no `maxAge`, cleared when the browser closes). Accepts `ms`-style strings: `1h`, `12h`, `7d`, `30d`, `90d`. Invalid values abort startup — see Startup Validation above. Does not affect the short-lived MFA challenge token or MCP OAuth tokens (those keep their own TTL). | `24h` |
| `SESSION_DURATION_REMEMBER` | Session length used when the user **ticks "Remember me"** on login: a longer-lived JWT `exp` claim plus a **persistent** `trek_session` cookie whose `maxAge` matches, so the session survives browser restarts. Same `ms`-style format and the same startup validation as `SESSION_DURATION`. | `30d` |
| `ALLOWED_ORIGINS` | Comma-separated origins for CORS and email notification links | same-origin |
| `ALLOW_INTERNAL_NETWORK` | Allow outbound requests to private/RFC-1918 IPs. Set `true` if Immich or other integrated services are on your local network. Loopback (`127.x`) and link-local (`169.254.x`) addresses remain blocked regardless. | `false` |
| `ALLOW_INTERNAL_NETWORK` | Allow outbound requests to private/RFC-1918 IPs. Set `true` if Immich, a document store bound through [Document-Sync](Document-Sync) or other integrated services are on your local network. Loopback (`127.x`) and link-local (`169.254.x`) addresses remain blocked regardless. | `false` |
| `APP_URL` | Public base URL (e.g. `https://trek.example.com`). Required when OIDC is enabled — must match the redirect URI registered with your IdP. Also used as the base URL for email notification links and subscribable calendar feed URLs (the `webcal://`/`https://` links the Subscribe dialog hands to Google/Apple/Outlook). | — |
| `TREK_WIKI_DIR` | Where the in-app Help pages (`/help`) read their content from. TREK ships this wiki and serves it from disk, so the docs always match the version you are running. You should not need to set this — it is an escape hatch for unusual layouts. If the directory cannot be found, Help falls back to fetching the repository's `wiki/` folder from the `main` branch on GitHub (which can be ahead of the release you are running, and needs outbound network access). | the bundled `wiki/` directory |
@@ -314,6 +314,19 @@ To get a key: create a free account at [unsplash.com/developers](https://unsplas
---
## Place Search (TREK Places API)
TREK's own place index, the [TREK Places API](TREK-Places-API), answers the suggestions and, together with OpenStreetMap, the full search in the place form, the category buttons on the trip map, the Road trip search along the drive, import geocoding and the offline download of a trip's surroundings. It needs no key, it is on by default, and there is no switch for it in the admin panel: whether searches leave the instance is set here.
| Variable | Description | Default |
|-----------------------|-------------|---------|
| `TREK_PLACES_ENABLED` | Set to `false` to stop asking the index. Search then works as it did before 4.3.0: OpenStreetMap on an install without a key, the keyed provider (Google or Amap) when one is set, the Overpass mirrors for the category buttons, and no places downloaded for offline search. Only the literal value `false` switches it off: `0`, `no`, `off` and `FALSE` pass startup validation and leave the index on, and a value that is not boolean-like aborts startup. | on |
| `TREK_PLACES_URL` | Base URL of a copy of the service you run yourself; it has to answer the same `/v1` API. Unset or blank uses the public service. A trailing slash is stripped, and a value that is not a full URL aborts startup. It is configuration rather than user input and is not run through the SSRF guard, so an address on your LAN or Docker network works without `ALLOW_INTERNAL_NETWORK`. | `https://places.liketrek.com` |
Neither variable is among the keys the Helm chart declares yet, so on Helm patch them onto the Deployment (see [How to Set Variables](#how-to-set-variables)).
---
## Place Search (Amap / 高德地图)
Google Places is unreachable from most networks inside mainland China, and OpenStreetMap's coverage of Chinese POIs
@@ -324,9 +337,9 @@ through it. There is an Amap basemap to match (see [[Map Settings|Map-Settings]]
| Variable | Description | Default |
|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|
| `AMAP_API_KEY` | Amap **Web 服务** (web service) key. When set, it takes priority over any key configured in **Admin → Settings → API Keys**, exactly like `PLACES_API_KEY` does for Google. | unset |
| `AMAP_API_KEY` | Amap **Web 服务** (web service) key. When set, it takes priority over any key configured in **Admin → Settings → API Keys**. | unset |
| `AMAP_API_SECRET` | The private secret (数字签名) of that key. Required exactly when the key was created with signing enabled: such a key rejects every unsigned request. Leave unset otherwise. | unset |
| `AMAP_API_BASE` | Send the calls somewhere other than `https://restapi.amap.com`: an egress proxy, a cache, a gateway that holds the credential. The replacement has to speak the same API. Mirrors `PLACES_API_BASE`. | `https://restapi.amap.com` |
| `AMAP_API_BASE` | Send the calls somewhere other than `https://restapi.amap.com`: an egress proxy, a cache, a gateway that holds the credential. The replacement has to speak the same API. | `https://restapi.amap.com` |
**Get a key** at [console.amap.com](https://console.amap.com/dev/key/app): create an application, then add a key of
type **Web 服务**. A **Web 端 (JS API)** key is a different kind of credential and will be rejected with
@@ -340,7 +353,7 @@ type **Web 服务**. A **Web 端 (JS API)** key is a different kind of credentia
Setting a key is not enough on its own: **Admin → Settings → API Keys → Place search provider** decides which keyed
provider answers. `Automatic`, the default, keeps Google when a Google key is configured, then takes Amap, then
nobody, so adding an Amap key never silently moves an existing install off Google. Choose **Amap** explicitly to make
it the provider. The choice is available on managed instances too, where the keys themselves come from the operator.
it the provider.
### Coordinates
@@ -396,11 +409,13 @@ next key rotation or admin reset would quietly switch the file back to WAL.
| Variable | Description | Default |
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|
| `IDEMPOTENCY_TTL_SECONDS` | How long (in seconds) stored idempotency keys are kept before garbage collection. The offline client replays queued mutations with their `X-Idempotency-Key` on reconnect, so this must exceed the longest expected offline window or a replay could create a duplicate. Invalid values abort startup. | `2592000` (30 days) |
| `NOMINATIM_URL` | Custom HTTP(S) Nominatim base URL for every geocoding call the server makes: place search, reverse lookup, place details and the Atlas region fill. When set it **replaces** the public OpenStreetMap service for all of them, with no fallback, so point it at an instance whose import covers the places your users plan and that speaks the Nominatim API (`/search`, `/reverse`, `/lookup`). Photon, Geoapify and LocationIQ are not drop-in replacements. TREK keeps its client-side spacing of roughly one request a second whichever instance answers, so this changes where the requests go, not how fast they are sent. Unset or blank uses the default. | `https://nominatim.openstreetmap.org` |
| `OVERPASS_URL` | Custom [Overpass API](https://wiki.openstreetmap.org/wiki/Overpass_API) endpoint(s) used by the map's POI "explore" search, comma-separated. When set it **replaces** the bundled public mirrors — point it at an internal or self-hosted Overpass instance when the public mirrors are unreachable from your network (e.g. firewalled/locked-down egress in a Kubernetes cluster). Entries that aren't valid `http(s)` URLs are ignored. If you don't run your own Overpass but the public mirrors throttle TREK, first make sure `APP_URL` (or `ALLOWED_ORIGINS`) is set: that alone gives outbound Overpass/Nominatim requests a unique User-Agent, which the public mirrors rate-limit far less. | bundled public mirrors |
| `OVERPASS_TIMEOUT_MS` | Per-endpoint timeout (in milliseconds) for Overpass POI requests. Endpoints race in parallel and one that hasn't answered within this window is abandoned so a faster mirror can win. Raise it if you run a slow self-hosted Overpass instance. Invalid values abort startup. | `12000` |
| `NOMINATIM_URL` | Custom HTTP(S) Nominatim base URL for every geocoding call the server makes: place search, reverse lookup, place details and the Atlas region fill. When set it **replaces** the public OpenStreetMap service for all of them, with no fallback, so point it at an instance whose import covers the places your users plan and that speaks the Nominatim API (`/search`, `/reverse`, `/lookup`). Photon, Geoapify and LocationIQ are not drop-in replacements. TREK keeps its client-side spacing of roughly one request a second whichever instance answers, so this changes where the requests go, not how fast they are sent. Unset or blank uses the default. With the TREK Places API on, suggestions while typing come from the TREK API's own OpenStreetMap layer and reach Nominatim only when the TREK API has nothing. | `https://nominatim.openstreetmap.org` |
| `OVERPASS_URL` | Custom [Overpass API](https://wiki.openstreetmap.org/wiki/Overpass_API) endpoint(s), comma-separated, for the map's category buttons, the Road trip search along the drive and the `search_pois` MCP tool whenever the TREK Places API has no answer or is switched off. When set it **replaces** the bundled public mirrors: point it at an internal or self-hosted Overpass instance when the public mirrors are unreachable from your network (e.g. firewalled/locked-down egress in a Kubernetes cluster). Entries that aren't valid `http(s)` URLs are ignored. If you don't run your own Overpass but the public mirrors throttle TREK, first make sure `APP_URL` (or `ALLOWED_ORIGINS`) is set: that alone gives outbound Overpass/Nominatim requests a unique User-Agent, which the public mirrors rate-limit far less. | bundled public mirrors |
| `OVERPASS_TIMEOUT_MS` | Per-endpoint timeout (in milliseconds) for Overpass POI requests. Endpoints race in parallel and one that hasn't answered within this window is abandoned so a faster mirror can win. The query itself gives Overpass 20 seconds of work, so a lower value hangs up on answers that were still coming; that is why the default rose from `12000` in 4.3.0. Drop any lower value you set by hand, and raise it only for a slow self-hosted Overpass instance. Invalid values abort startup. | `25000` |
| `LLM_TIMEOUT_MS` | How long (in milliseconds) one AI-parsing call may take before it is abandoned. One ceiling for every provider, applied to the abort signal and to the underlying HTTP client alike. The default is generous so heavier parsing work fits without a code change; lower it if you use a cloud provider and would rather fail fast. Invalid values abort startup. | `900000` (15 min) |
> **Routing is not set here.** The routing engines behind the planner and the [Road-Trip](Road-Trip) addon (OSRM for routes, Valhalla for avoiding toll roads, motorways and ferries) have no environment variable. An admin sets them under **Admin → User Defaults** as **Own routing engine** and **Own Valhalla instance**, and they take effect after a restart. `OVERPASS_URL` and `OVERPASS_TIMEOUT_MS` above also apply to the road trip's search along the route.
---
## Demo Mode
+1 -1
View File
@@ -2,7 +2,7 @@
## Do I need a Google Maps API key?
No. When no Google Maps key is configured, TREK automatically falls back to OpenStreetMap (Nominatim) for place search — no API key or account required. If you want richer place data (photos, ratings, opening hours), an admin can optionally add a Google Maps key in **Admin Panel → Settings** — see [Admin Panel Overview](Admin-Panel-Overview). A key saved there applies instance-wide to every member; there is no per-user field for it in the UI.
No. Place search runs on TREK's own place index, the [TREK Places API](TREK-Places-API), asked together with OpenStreetMap, with no API key, no quota and no account. A Google Maps key only answers where both come up empty, and adds ratings and photos for the places Google finds, which no open dataset has. An admin can add one in **Admin → Settings → API Keys**, see [Places and Search](Places-and-Search#with-a-google-maps-api-key). A key saved there applies instance-wide to every member; there is no per-user field for it in the UI.
## Can I use TREK offline?
+42 -39
View File
@@ -7,64 +7,67 @@ TREK is a self-hosted, real-time collaborative travel planner licensed under AGP
## Features
### Planning
- **Drag & Drop Planner** — organize places into day plans with reordering and cross-day moves
- **Interactive Map** — Leaflet map with photo markers, clustering, route visualization, and customizable tile sources
- **Place Search** — Google Places (photos, ratings, hours) or OpenStreetMap (free, no API key needed)
- **Day Notes** — timestamped, icon-tagged notes per day
- **Route Optimization** — auto-optimize place order and export to Google Maps
- **Weather Forecasts** — 16-day forecasts via Open-Meteo (no API key required), historical climate averages as fallback
- **Drag & Drop Planner**: organize places into day plans with reordering and cross-day moves
- **Interactive Map**: Leaflet map with photo markers, clustering, route visualization, and customizable tile sources
- **Place Search**: TREK's own place index and OpenStreetMap, asked together, with no API key and no quota; Google or Amap answer only where both come up empty (see [TREK Places API](TREK-Places-API))
- **Day Notes**: timestamped, icon-tagged notes per day
- **Route Optimization**: auto-optimize place order and export to Google Maps
- **Weather Forecasts**: 16-day forecasts via Open-Meteo (no API key required), historical climate averages as fallback
### Travel Management
- **Reservations & Bookings** — track flights, accommodations, restaurants with confirmation numbers and file attachments
- **Budget Tracking** — category-based expenses with pie chart, per-person/per-day splitting, multi-currency support (see [Currencies](Currencies))
- **Packing Lists** — category-based checklists with user assignment, templates, and progress tracking
- **Document Manager** — attach documents, tickets, and PDFs to trips, places, or reservations (up to 50 MB per file)
- **PDF Export** — export complete trip plans as PDF with cover page, images, and notes
- **Reservations & Bookings**: track flights, accommodations, restaurants with confirmation numbers and file attachments
- **Budget Tracking**: category-based expenses with pie chart, per-person/per-day splitting, multi-currency support (see [Currencies](Currencies))
- **Packing Lists**: category-based checklists with user assignment, templates, and progress tracking
- **Document Manager**: attach documents, tickets, and PDFs to trips, places, or reservations (up to 50 MB per file)
- **Document Sync** _(admin-enabled)_: keep a trip's documents in step with a self-hosted Paperless-ngx, Papra, Nextcloud, OpenCloud or Synology NAS, in both directions, under one connection the trip owner sets up for every member (see [Document Sync](Document-Sync))
- **PDF Export**: export complete trip plans as PDF with cover page, images, and notes
### Collaboration
- **Real-Time Sync** — WebSocket-based live sync; changes appear instantly for all connected users
- **Multi-User** — invite members with role-based access
- **Invite Links** — registration links with configurable max uses (1–5 or unlimited) and expiry
- **OIDC SSO** — sign in with Google, Apple, Authentik, Keycloak, or any OIDC provider
- **Two-Factor Authentication** — TOTP-based 2FA with QR code setup
- **Passkeys** _(admin-enabled)_ — passwordless WebAuthn sign-in with Touch ID, Windows Hello, Android screen lock, or a hardware key; owning one also satisfies the require-2FA policy (see [Passkeys](Passkeys))
- **Public Share Links** — share a read-only view of any trip
- **Real-Time Sync**: WebSocket-based live sync; changes appear instantly for all connected users
- **Multi-User**: invite members with role-based access
- **Invite Links**: registration links with configurable max uses (1 to 5, or unlimited) and expiry
- **OIDC SSO**: sign in with Google, Apple, Authentik, Keycloak, or any OIDC provider
- **Two-Factor Authentication**: TOTP-based 2FA with QR code setup
- **Passkeys** _(admin-enabled)_: passwordless WebAuthn sign-in with Touch ID, Windows Hello, Android screen lock, or a hardware key; owning one also satisfies the require-2FA policy (see [Passkeys](Passkeys))
- **Public Share Links**: share a read-only view of any trip
### Addons _(admin-toggleable)_
- **Lists** — packing lists and to-dos with templates, member assignments, optional bag tracking
- **Costs** — expense tracker with category breakdown, splits, multi-currency
- **Documents** — file manager for trips, places, and reservations
- **Collab** — group chat, shared notes, polls, day-by-day attendance
- **Vacay** — personal vacation day planner with calendar view, public holidays, and carry-over tracking
- **Atlas** — interactive world map, bucket list, travel stats, continent breakdown
- **Collections** — personal place library: save places across trips into named lists, copy them into any trip, share with per-member roles (see [Collections](Collections))
- **Journey** — magazine-style travel journal with entries, photos (via Immich/Synology Photos), maps, and moods
- **Naver List Import** — import places from shared Naver Maps lists
- **MCP** — expose TREK to AI assistants via the Model Context Protocol (OAuth 2.1)
- **AirTrail** — sync flights from your self-hosted AirTrail instance into trips
- **AI Parsing** — LLM fallback that extracts bookings from confirmation files KDE Itinerary cannot read (see [AI-Booking-Import](AI-Booking-Import))
- **Lists**: packing lists and to-dos with templates, member assignments, optional bag tracking
- **Costs**: expense tracker with category breakdown, splits, multi-currency
- **Documents**: file manager for trips, places, and reservations
- **Collab**: group chat, shared notes, polls, day-by-day attendance
- **Road trip**: plan a trip as one continuous drive, with search along the route, driving limits, daily travel times and avoidance of toll roads, motorways and ferries (see [Road Trip](Road-Trip))
- **Vacay**: personal vacation day planner with calendar view, public holidays, and carry-over tracking
- **Atlas**: interactive world map, bucket list, travel stats, continent breakdown
- **Collections**: a personal place library that saves places across trips into named lists, copies them into any trip, and shares them with per-member roles (see [Collections](Collections))
- **Journey**: magazine-style travel journal with entries, photos (via Immich/Synology Photos), maps, and moods
- **Naver List Import**: import places from shared Naver Maps lists
- **MCP**: expose TREK to AI assistants via the Model Context Protocol (OAuth 2.1)
- **AirTrail**: sync flights from your self-hosted AirTrail instance into trips
- **Dawarich**: read the stays and routes your self-hosted Dawarich instance recorded, offered as suggestions you confirm; nothing is written back (see [Dawarich](Dawarich))
- **AI Parsing**: LLM fallback that extracts bookings from confirmation files KDE Itinerary cannot read (see [AI-Booking-Import](AI-Booking-Import))
> Dashboard widgets (currency converter and timezone clock) are per-user preferences, not an admin-toggleable addon — see [Dashboard-Widgets](Dashboard-Widgets).
> Dashboard widgets (currency converter and timezone clock) are per-user preferences, not an admin-toggleable addon; see [Dashboard-Widgets](Dashboard-Widgets).
>
> The full addon table, with type and per-addon notes, lives in [Addons-Overview](Addons-Overview).
### Plugins
- **Sandboxed Plugin Runtime** — third-party plugins run in a forked child process with permission-gated RPC, install-time manifest and signature checks, and an egress allowlist (see [Plugins](Plugins))
- **Plugin SDK** — build and publish plugins with the `trek-plugin-sdk` npm package: dev server, preflight, signing, submit (see [Plugin-Development](Plugin-Development))
- **Sandboxed Plugin Runtime**: third-party plugins run in a forked child process with permission-gated RPC, install-time manifest and signature checks, and an egress allowlist (see [Plugins](Plugins))
- **Plugin SDK**: build and publish plugins with the `trek-plugin-sdk` npm package, with dev server, preflight, signing and submit (see [Plugin-Development](Plugin-Development))
### AI / MCP Integration
- **MCP Server** — built-in Model Context Protocol server with OAuth 2.1 authentication
- **150+ Tools** — create trips, plan itineraries, manage budgets, send messages, and more
- **30 Resources** — read-only `trek://` URIs for trips, days, places, budget, packing, journeys, and more
- **29 OAuth Scopes** — granular permissions across 14 permission groups
- **Pre-built Prompts** — `trip-summary`, `packing-list`, and `budget-overview` context loaders
- **MCP Server**: built-in Model Context Protocol server with OAuth 2.1 authentication
- **150+ Tools**: create trips, plan itineraries, manage budgets, send messages, and more
- **30 Resources**: read-only `trek://` URIs for trips, days, places, budget, packing, journeys, and more
- **29 OAuth Scopes**: granular permissions across 14 permission groups
- **Pre-built Prompts**: `trip-summary`, `packing-list`, and `budget-overview` context loaders
### Admin
- User management, invite links, packing templates, global categories
- Addon management, API key storage, scheduled auto-backups
- System notices for onboarding and announcements
> **Admin:** Most configuration lives in the Admin Panel. On first boot TREK seeds an admin account automatically — credentials come from `ADMIN_EMAIL` / `ADMIN_PASSWORD` if set, otherwise a random password is printed to the container log.
> **Admin:** Most configuration lives in the Admin Panel. On first boot TREK seeds an admin account automatically: credentials come from `ADMIN_EMAIL` / `ADMIN_PASSWORD` if set, otherwise a random password is printed to the container log.
## Get Started
+14 -8
View File
@@ -6,9 +6,11 @@ TREK makes outbound HTTP requests when you configure integrations such as Immich
TREK has two SSRF guards, both in `ssrfGuard.ts`. Which one applies depends on the call site, not on who configured the URL.
**The strict guard** (`safeFetch` / `safeFetchFollow`, built on `checkSsrf`) covers most outbound traffic — Immich, Synology Photos, AirTrail, notification webhooks, ntfy, Unsplash, and place lookups. It resolves the hostname to an IP address before allowing the connection and blocks loopback, link-local and private ranges. Only the private ranges open up, and only with `ALLOW_INTERNAL_NETWORK=true`. The two tables below describe this guard.
**The strict guard** (`safeFetch` / `safeFetchFollow`, built on `checkSsrf`) covers most outbound traffic: Immich, Synology Photos, AirTrail, Dawarich, the document stores behind [Document-Sync](Document-Sync) (Paperless-ngx, Papra, Nextcloud, OpenCloud and Synology), notification webhooks, ntfy, Unsplash, and place lookups. It resolves the hostname to an IP address before allowing the connection and blocks loopback, link-local and private ranges. Only the private ranges open up, and only with `ALLOW_INTERNAL_NETWORK=true`. The two tables below describe this guard.
**The relaxed guard** (`safeFetchAdminConfigured`, also exported as `safeFetchLlm`) covers endpoints that are expected to live on your own network: OIDC (discovery, token, userinfo, JWKS), the LLM providers behind the AI Parsing addon (a local Ollama or any OpenAI-compatible endpoint), and plugin OAuth token exchanges. It deliberately permits loopback and LAN targets, so a model server on `localhost` or an identity provider on your LAN works **without** `ALLOW_INTERNAL_NETWORK`. It still resolves every hostname, re-checks every redirect hop, and always blocks link-local and cloud-metadata addresses (`169.254.0.0/16`, the full `fe80::/10`, and the AWS and Alibaba metadata addresses).
**The relaxed guard** (`safeFetchAdminConfigured`, also exported as `safeFetchLlm`) covers endpoints that are expected to live on your own network: OIDC (discovery, token, userinfo, JWKS), the LLM providers behind the AI Parsing addon (a local Ollama or any OpenAI-compatible endpoint), and plugin OAuth token exchanges. The self-hosted routing engines an admin sets for the [Road-Trip](Road-Trip) addon (**Own routing engine**, **Own Valhalla instance**) go through it too when the server asks them itself, which it does for the MCP road trip tools. The planner asks them from the browser, so they must also be reachable from your users' devices. It deliberately permits loopback and LAN targets, so a model server on `localhost` or an identity provider on your LAN works **without** `ALLOW_INTERNAL_NETWORK`. It still resolves every hostname, re-checks every redirect hop, and always blocks link-local and cloud-metadata addresses (`169.254.0.0/16`, the full `fe80::/10`, and the AWS and Alibaba metadata addresses).
**No guard** applies to the addresses an admin sets in the environment for place search: `TREK_PLACES_URL`, `NOMINATIM_URL` and `OVERPASS_URL`. They are configuration rather than user input, so a self-run copy of the [TREK Places API](TREK-Places-API), a Nominatim or an Overpass instance on your LAN or in the same Docker network is reached without `ALLOW_INTERNAL_NETWORK`.
## Always blocked (no override possible)
@@ -21,7 +23,7 @@ Under the strict guard, these ranges are blocked regardless of any setting:
| `169.254.0.0/16`, `fe80::/16` | Link-local / cloud metadata endpoints |
| `::ffff:127.x.x.x`, `::ffff:169.254.x.x` | IPv4-mapped loopback and link-local |
The IPv6 link-local rule here matches the `fe80:` hextet only, which is narrower than the nominal `fe80::/10` prefix (`fe80:`–`febf:`). In practice that is the same set of addresses, since RFC 4291 link-local addresses are always `fe80::/64`. The relaxed guard covers the whole `/10`.
The IPv6 link-local rule here matches the `fe80:` hextet only, which is narrower than the nominal `fe80::/10` prefix (`fe80:` to `febf:`). In practice that is the same set of addresses, since RFC 4291 link-local addresses are always `fe80::/64`. The relaxed guard covers the whole `/10`.
## Blocked unless `ALLOW_INTERNAL_NETWORK=true`
@@ -35,17 +37,19 @@ The IPv6 link-local rule here matches the `fe80:` hextet only, which is narrower
| IPv4-mapped RFC-1918 variants | e.g. `::ffff:10.x`, `::ffff:192.168.x` |
| `*.local`, `*.internal`, `localhost` hostnames | mDNS / internal DNS suffixes (e.g. Docker service names, LAN hosts) and the literal `localhost` |
The hostname `localhost` is matched at the hostname stage too, but it normally resolves to a loopback address (`127.0.0.1` or `::1`), which the always-blocked loopback rule catches first — so under the strict guard it is blocked no matter how `ALLOW_INTERNAL_NETWORK` is set. On a host that maps `localhost` somewhere else, the hostname rule still applies and it stays blocked unless `ALLOW_INTERNAL_NETWORK=true`. The relaxed guard allows `localhost` outright, which is what makes a local Ollama the supported default for AI Parsing.
The hostname `localhost` is matched at the hostname stage too, but it normally resolves to a loopback address (`127.0.0.1` or `::1`), which the always-blocked loopback rule catches first, so under the strict guard it is blocked no matter how `ALLOW_INTERNAL_NETWORK` is set. On a host that maps `localhost` somewhere else, the hostname rule still applies and it stays blocked unless `ALLOW_INTERNAL_NETWORK=true`. The relaxed guard allows `localhost` outright, which is what makes a local Ollama the supported default for AI Parsing.
`*.local` and `*.internal` hostnames are permitted when `ALLOW_INTERNAL_NETWORK=true` — the guard still resolves them to an IP and enforces all IP-level rules, so any such hostname that resolves to a loopback or link-local address remains blocked regardless.
`*.local` and `*.internal` hostnames are permitted when `ALLOW_INTERNAL_NETWORK=true`: the guard still resolves them to an IP and enforces all IP-level rules, so any such hostname that resolves to a loopback or link-local address remains blocked regardless.
## When to enable
Set `ALLOW_INTERNAL_NETWORK=true` when a service reached through the strict guard — Immich, Synology Photos, AirTrail, or a notification webhook — is hosted on your local network and you need TREK to reach it. You do **not** need it for a local or LAN Ollama, an OpenAI-compatible endpoint, an OIDC provider on your LAN, or plugin OAuth; those go through the relaxed guard and already work. Leave the flag off if only those need internal access, since turning it on widens the surface for every strict-guard integration at once.
Set `ALLOW_INTERNAL_NETWORK=true` when a service reached through the strict guard (Immich, Synology Photos, AirTrail, Dawarich, a document store bound through [Document-Sync](Document-Sync), or a notification webhook) is hosted on your local network and you need TREK to reach it. You do **not** need it for a local or LAN Ollama, an OpenAI-compatible endpoint, an OIDC provider on your LAN, your own OSRM or Valhalla, or plugin OAuth; those go through the relaxed guard and already work. Nor do you need it for your own TREK Places API, Nominatim or Overpass, which are not guarded at all. Leave the flag off if only those need internal access, since turning it on widens the surface for every strict-guard integration at once.
A service in another container on the same Docker network counts as internal too, because its container name resolves to a private address; so do a Tailscale address (`100.64.0.0/10`) and a `.local` name. A service on loopback (`localhost`, `127.0.0.1`) is never reached through the strict guard, whatever the flag says: use the host's LAN address or the container name instead.
See [Environment-Variables](Environment-Variables) for how to set environment variables.
> **Admin:** Set `ALLOW_INTERNAL_NETWORK=true` in [Environment-Variables](Environment-Variables) before configuring Immich or Synology on a LAN.
> **Admin:** Set `ALLOW_INTERNAL_NETWORK=true` in [Environment-Variables](Environment-Variables) before configuring Immich, Synology Photos, AirTrail, Dawarich or a document store on a LAN.
## DNS rebinding protection
@@ -53,11 +57,13 @@ Even with `ALLOW_INTERNAL_NETWORK=true`, TREK pins the DNS resolution to prevent
## Audit log
When a user saves an Immich URL that resolves to a private IP, TREK records an `immich.private_ip_configured` entry in the [Audit-Log](Audit-Log) including the URL and the resolved IP address. AirTrail does the same with `airtrail.private_ip_configured`. Synology Photos does not emit an equivalent event.
When a user saves an Immich URL that resolves to a private IP, TREK records an `immich.private_ip_configured` entry in the [Audit-Log](Audit-Log) including the URL and the resolved IP address. AirTrail does the same with `airtrail.private_ip_configured`, and Dawarich with `dawarich.private_ip_configured`. Synology Photos does not emit an equivalent event, and neither does document sync.
## See also
- [Photo-Providers](Photo-Providers)
- [Dawarich](Dawarich)
- [Document-Sync](Document-Sync)
- [User-Settings](User-Settings)
- [Environment-Variables](Environment-Variables)
- [Security-Hardening](Security-Hardening)
+53 -21
View File
@@ -183,20 +183,50 @@ Requires `journey:read` or `journey:write` scope.
| `create_journey_share_link` | Create or update the public share link for a journey. Requires `journey:share`. |
| `delete_journey_share_link` | Revoke the public share link for a journey. Requires `journey:share`. |
---
### Dawarich _(Dawarich addon required)_
### Roadtrip
The Roadtrip addon must be enabled. These tools work without an open browser. The external assistant chooses places based on the traveller's interests, uses the existing trip, day, place and assignment tools to save them, and recalculates to check the result.
Each tool asks for the scope of what it writes, so the scopes differ per tool. The connection itself (address, API key, test, disconnect) has no MCP tool. See [Dawarich](Dawarich).
| Tool | Purpose | Scope |
|---|---|---|
| `get_roadtrip_context` | Saved days, visits, coordinates, stays, pinned times, vehicle preferences, route profiles, vias, tracks and manual boundaries | trips:read |
| `calculate_roadtrip` | Calculated days, arrivals, departures, automatic pauses, driving warnings and range warnings; optional geometry | trips:read |
| `get_roadtrip_settings` | Shared driving preferences for the specified trip | trips:read |
| `update_roadtrip_settings` | Patch shared trip driving preferences, preserving other settings | trips:write |
| `search_roadtrip_corridor` | Fuel, charging, rest areas, campsites, food, sights or hotels along a day | trips:read |
| `update_route_via` | Move an existing routing handle and optionally change its outgoing leg | trips:write |
| `list_dawarich_suggestions` | List the stays TREK pulled from the caller's Dawarich for review, optionally for one trip or one state (`new`, `accepted`, `dismissed`); 50 by default, up to 200 | `journey:read` |
| `accept_dawarich_suggestion_as_place` | Turn a stay into a place on a trip, optionally on one of its days, with a corrected name, notes or coordinates | `places:write` |
| `accept_dawarich_suggestion_as_journal_entry` | Turn a stay into a dated journal entry with a title, story, date and time | `journey:write` |
| `mark_bucket_list_item_visited_from_dawarich` | Tick off the bucket list wish a stay was matched to, or another wish of the caller's | `atlas:write` |
| `dismiss_dawarich_suggestion` | Dismiss a stay, or put a dismissed one back | `journey:write` |
| `get_dawarich_trip_track` | Summary of a trip's recorded route per local day: segments, times, travel mode, distance and point counts, without the geometry. Read live from Dawarich, nothing stored | `journey:read` |
### Document sync _(Documents addon required)_
`get_trip_document_sync` and `list_trip_document_sync_issues` require `files:read`; `sync_trip_documents` requires `files:write`. Any member of the trip may call them. No tool connects a store or changes a binding: that hands TREK a credential to someone's document archive, and it stays with the trip owner in the file manager. See [Document-Sync](Document-Sync).
| Tool | Description |
|---|---|
| `get_trip_document_sync` | Show whether the trip's documents are synced with a document store (Paperless-ngx, Papra, Nextcloud, OpenCloud or a Synology NAS), which tag, folder or space they are bound to, when the last run happened and how it went, and how many documents are synced, waiting, in conflict or missing in the store. |
| `list_trip_document_sync_issues` | List the documents that need a person: conflicts, documents refused for their type or size, transfers that failed, and documents gone from the store. Returns `configured: false` for a trip that is not bound, and an empty list when everything is in step. |
| `sync_trip_documents` | Run every binding of the trip now instead of waiting for the next scheduled check, and report how many documents came in, went out and are in conflict. Pass `full: true` to compare both sides in full. A binding whose owner left the trip, or whose store an admin switched off, is reported and not run. Safe to call repeatedly: a run already in progress is not started twice. |
### Road trip _(Road trip addon required)_
These tools work without an open browser. The external assistant chooses places based on the traveller's interests, uses the existing trip, day, place and assignment tools to save them, and recalculates to check the result. What each tool corresponds to in the planner is described on [Road-Trip](Road-Trip#mcp-tools).
| Tool | Purpose | Scope |
|---|---|---|
| `get_roadtrip_context` | Saved days, visits, coordinates, stays, pinned times, vehicle preferences, route profiles, vias, tracks and manual boundaries | `trips:read` |
| `calculate_roadtrip` | Calculated days, arrivals, departures, automatic pauses, driving warnings and range warnings; optional geometry | `trips:read` |
| `get_roadtrip_settings` | Shared driving preferences for the specified trip | `trips:read` |
| `update_roadtrip_settings` | Patch shared trip driving preferences, preserving other settings | `trips:write` |
| `search_roadtrip_corridor` | Fuel, charging, rest areas, campsites, food, sights or hotels along a day | `trips:read` |
| `update_route_via` | Move an existing routing handle and optionally change its outgoing leg | `trips:write` |
| `list_route_vias` | A day's via points, or the whole trip's together with its followed tracks | `trips:read` |
| `add_route_via`, `add_route_vias` | Add one via point, or a whole chain on one day | `trips:write` |
| `reanchor_route_vias` | Re-pin a day's via points after its stops changed | `trips:write` |
| `remove_route_via` | Remove a via point so the leg drives direct again | `trips:write` |
| `list_day_boundaries`, `set_day_boundary` | Read or set dragged day endings; null restores the automatic ending | `trips:read` / `trips:write` |
| `get_roadtrip_hazards` | Current DWD and GDACS notices with geometry, timestamps and source availability | `trips:read` |
| `get_roadtrip_charging_info`, `lookup_roadtrip_charging_info` | Availability and published tariffs for a saved charging stop, or for a station by coordinate and name | `trips:read` |
| `preview_google_maps_route` | Read the ordered stops of a Google Maps directions link; nothing is saved | `trips:read` |
| `import_google_maps_route` | Append the reviewed stops to a day as places and visits | `places:write` |
Driving preferences include daily times, day-ending mode, leg/day driving limits, fuel or electric vehicle specifications, fallback range, fill percentage, avoidance and route display. They belong to the specified trip and apply equally to all its travellers. Both settings tools require tripId. Changing driving preferences requires day-edit permission, as do changes to visits, vias and endings. Fixed visit times retain priority over automatic times. Turning daily travel times off preserves saved endings but stops applying them.
@@ -204,7 +234,19 @@ Calculation distances are metres, route durations seconds, and stays minutes. Se
Corridor results include source attribution, distance along/from the route, failed areas and truncated areas. Follow `nextOffset` for remaining search rectangles. Filters include name or brand, socket type, minimum known charging power and `fromKm`/`toKm`. Unknown charging power remains unknown. Search never adds places automatically. Use the returned place information with `create_and_assign_place`, then move or reorder the assignment and re-anchor vias as needed. Recalculate after editing.
Existing `list_route_vias`, `add_route_via`, `add_route_vias`, `reanchor_route_vias` and `remove_route_via` manage scenic detours and followed tracks. `list_day_boundaries`, `set_day_boundary` and `set_assignment_end_day` manage manual endings. The Places tool `import_trip_gpx` accepts GPX XML up to one million characters, uses the standard importer and requires places:write. It imports waypoints, routes and tracks without assigning them to days; `export_trip_gpx` exports the trip. Stay durations and place-level time defaults can be cleared with null through `update_place`.
Corridor searches include installed search-provider plugins. Providers receive the category and search bounds, and the host filters hits to the route. The response lists successful and failed sources; a failed provider does not discard the remaining results.
The via tools manage scenic detours and followed tracks. `list_day_boundaries`, `set_day_boundary` and `set_assignment_end_day` manage manual endings; `set_assignment_end_day` is a general assignment tool and is registered whether or not the addon is on. The Places tool `import_trip_gpx` accepts GPX XML up to one million characters, uses the standard importer and requires places:write. It imports waypoints, routes and tracks without assigning them to days; `export_trip_gpx` exports the trip. Stay durations and place-level time defaults can be cleared with null through `update_place`.
`get_roadtrip_hazards` takes `tripId`. It does not reroute the trip. The shared `roadtrip_show_hazards` setting controls the online map overlay.
Google Maps directions links can be reviewed with `preview_google_maps_route` and saved with `import_google_maps_route`. Import creates places and visits together in the supplied order, with trip access and place/day permission checks. Unresolved stops must be omitted from the confirmed input. The Google road geometry is not copied.
`get_roadtrip_charging_info` accepts tripId and placeId. It requires trip access and the Road trip addon. It reports matching failures, unavailable feeds, freshness, known free capacity and unknown status counts separately. Published tariff components include currency, tax handling and conditions; they do not estimate a user's roaming price. Data source: [MobiData BW OCPDB](https://api.mobidata-bw.de/), with per-source attribution from its public source registry.
`lookup_roadtrip_charging_info` answers the same question for a station that is not on the trip, by coordinate and name rather than by place id, which is what a hit found along the route has. It takes tripId, lat, lng and name, requires the same trip access and the same addon, and returns the same fields with the same caveats. The trip is there for the access check only and does not narrow the search. One station per call: it shares its cache with the saved-stop tool, and the registry behind it is public infrastructure. It carries no power rating and no socket count; those are OpenStreetMap tag data and travel with the corridor search result instead.
---
## Addon-gated resources
@@ -235,19 +277,9 @@ Resources provide read-only access via `trek://` URIs. The following resources r
---
Roadtrip also exposes `get_roadtrip_hazards` (`tripId`, trips read scope). It returns current DWD/GDACS notices with geometry, source timestamps and availability. This does not reroute the trip. The shared `roadtrip_show_hazards` setting controls the online map overlay.
## Related
- [MCP-Tools-and-Resources](MCP-Tools-and-Resources)
- [MCP-Scopes](MCP-Scopes)
- [MCP-Prompts](MCP-Prompts)
- [MCP-Setup](MCP-Setup)
Roadtrip corridor searches include installed search-provider plugins. Providers receive the category and search bounds, and the host filters hits to the route. The response lists successful and failed sources; a failed provider does not discard the remaining results.
Google Maps directions links can be reviewed with preview_google_maps_route and saved with import_google_maps_route. Import creates places and visits together in the supplied order, with trip access and place/day permission checks. Unresolved stops must be omitted from the confirmed input. The Google road geometry is not copied.
get_roadtrip_charging_info accepts tripId and placeId. It requires trip access and the Roadtrip addon. It reports matching failures, unavailable feeds, freshness, known free capacity and unknown status counts separately. Published tariff components include currency, tax handling and conditions; they do not estimate a user's roaming price. Data source: [MobiData BW OCPDB](https://api.mobidata-bw.de/), with per-source attribution from its public source registry.
lookup_roadtrip_charging_info answers the same question for a station that is not on the trip, by coordinate and name rather than by place id, which is what a hit found along the route has. It takes tripId, lat, lng and name, requires the same trip access and the same addon, and returns the same fields with the same caveats. The trip is there for the access check only and does not narrow the search. One station per call: it shares its cache with the saved-stop tool, and the registry behind it is public infrastructure. It carries no power rating and no socket count; those are OpenStreetMap tag data and travel with the corridor search result instead.
+4 -3
View File
@@ -2,7 +2,7 @@
TREK exposes **tools** (read and write actions) and **resources** (read-only `trek://` URIs). Tools are registered per-session based on OAuth scopes and enabled addons.
For addon-gated tools (Packing, To-Dos, Atlas, Collab, Collections, Vacay, Journey) and their resources, see [MCP-Addon-Tools](MCP-Addon-Tools).
For addon-gated tools (Packing, To-Dos, Atlas, Collab, Collections, Vacay, Journey, Dawarich, Document sync, Road trip) and their resources, see [MCP-Addon-Tools](MCP-Addon-Tools).
## Tools
@@ -61,7 +61,7 @@ Requires `places:read` or `places:write` scope.
| `bulk_delete_places` | Delete multiple places by ID. Removes all day assignments. Cannot be undone. |
| `import_places_from_url` | Import all places from a publicly shared Google Maps or Naver Maps list URL. |
| `list_categories` | List all available place categories with id, name, icon, and color. |
| `search_place` | Search for a place by name or address. Returns `osm_id` and `google_place_id` for use in `create_place`. |
| `search_place` | Search for a place by name or address, the way the full search in the app does: TREK's own place index and OpenStreetMap together, and Google or Amap only when both are empty. Returns `osm_id` (and `google_place_id` / `google_ftid` when Google answered) for use in `create_place`. Takes an optional `locationBias` to rank results around the trip's destination. |
### Day Planning
@@ -169,7 +169,8 @@ Requires `places:read` or `places:write` scope.
|---|---|---|
| `get_place_details` | `geo:read` | Fetch detailed information (hours, photos, ratings) about a place by its Google Place ID. |
| `reverse_geocode` | `geo:read` | Get a human-readable address for given coordinates. |
| `resolve_maps_url` | `geo:read` | Resolve a Google Maps share URL to coordinates and place name. |
| `resolve_maps_url` | `geo:read` | Resolve a Google Maps or Amap (高德地图) share URL to coordinates and place name. |
| `search_pois` | `geo:read` | List places of one or more categories inside a map rectangle, the MCP side of the category buttons on the trip map. Answers from TREK's place index where it can and from OpenStreetMap (Overpass) otherwise, names the source of each result, and never calls Google. |
| `search_airports` | `geo:read` | Search for airports by name, city, or IATA code. Returns IATA code, name, city, country, timezone. |
| `get_airport` | `geo:read` | Look up an airport by IATA code (e.g. `"ZRH"`, `"CDG"`). |
| `get_weather` | `weather:read` | Get a weather forecast for a location and date. |
+1 -1
View File
@@ -44,7 +44,7 @@ A card above the button lists the days: each one by its title, or by its number
The total is real routed distance summed over every leg — road geometry from the router, not straight lines between stops — which is what makes it worth building a fuel estimate on. It arrives a few legs at a time: while they are still coming in the total is followed by an ellipsis to say it is a partial sum, and it settles once every leg has answered. A leg the router refuses keeps its straight line on the map and contributes nothing to the total, so a trip with an unroutable hop reads low rather than wrong. Days with fewer than two located stops have no route and are left out of the list entirely.
Road trip mode already draws the whole trip its own way, so the button is not offered while it is on.
[Road trip mode](Road-Trip) already draws the whole trip its own way, so the button is not offered while it is on.
## GPX tracks
+1
View File
@@ -46,6 +46,7 @@ On login, when the browser comes back online, and when you lift **Force offline
- Trips, days, places, packing items, to-dos, budget items, reservations, accommodations, trip members, tags, and categories.
- File attachments that are neither photos nor videos (PDFs, documents, etc.) are downloaded and stored as blobs in IndexedDB. Videos are deliberately skipped — a single clip can be hundreds of megabytes and would evict the trip's real documents.
- Map tiles are pre-fetched into the service-worker `map-tiles` cache for zoom levels 10–16 across each trip's bounding box, stopping at the zoom level that would push the total past 12 288 tiles (roughly 180 MB).
- The places around each trip, up to 3000 from the [TREK Places API](TREK-Places-API) in one request (about a megabyte for a city), so place search and suggestions still answer offline. They are downloaded whether or not **Store map tiles offline** is on, refreshed only when the trip's area changes, and removed with the trip. See [Searching offline](Places-and-Search#searching-offline).
> **Note:** A WebSocket reconnect does *not* run this sync. It replays your queued changes and then re-reads the trip you currently have open — days, places, packing items, to-dos, budget items, reservations and files — which refreshes that one trip's cached rows. It never re-downloads the bundles for your other trips, the file blobs or the map tiles; skipping the full sync there is deliberate, so a dropped socket on an otherwise online device doesn't run into the server's rate limiter.
+122 -58
View File
@@ -1,106 +1,170 @@
# Places and Search
Places are the building blocks of your trip. You can add them by searching, pasting a URL, entering coordinates, or importing a file.
Places are the building blocks of your trip. You can add them by searching, pasting a map link, entering coordinates, or importing a file.
![Places sidebar](assets/PlaceAutocomplete.png)
## Adding a place
Click **+ Add Place** at the top of the Places sidebar to open the Place form. You can also **right-click anywhere on the map** to create a place at that exact location — the address is reverse-geocoded and pre-filled automatically.
Click **Add Place/Activity** at the top of the Places sidebar to open the place form. While a day is open the button splits in two: **New place** adds the place to the trip, and **To day** (*Add to the open day*) puts it straight onto that day. In a narrow sidebar both drop to their icons.
You can also **right-click anywhere on the map** to create a place at that exact spot. The address is filled in by reverse geocoding through OpenStreetMap, or through Amap inside mainland China when Amap holds the keyed slot (see [Which provider answers](#which-provider-answers)).
## Searching for a place
Type in the search box at the top of the form. After 2 or more characters, with a 300 ms debounce, suggestions appear in a dropdown.
Place search needs no API key. Two sources answer it together: the **TREK API**, TREK's own index of 73.6 million places, and **OpenStreetMap**. The index is strongest on businesses such as restaurants, shops and hotels; OpenStreetMap is where the temples, bridges, viewpoints and stations are. What the index is, where its data comes from and what TREK sends to it is on its own page: [TREK Places API](TREK-Places-API).
- Use **↑ / ↓** to navigate results, **Enter** to select, **Esc** to dismiss.
- Search results are biased toward the geographic center of your existing trip places. When those places span more than ~500 km, the bias is skipped.
### Suggestions while you type
After 2 or more characters, and a 300 ms pause, suggestions appear in a dropdown under the search box.
- Use **↑ / ↓** to move through them, **Enter** to pick one, **Esc** to close the list.
- Suggestions come from the TREK API, from its index and from an OpenStreetMap layer it keeps. A suggestion from that layer shows the name that matched what you typed, with the name used on the spot underneath when the two differ.
- Only when the TREK API has nothing does TREK ask the keyed provider (Google or Amap), or, without one, OpenStreetMap's own search service.
### The full search
Press **Enter** without picking a suggestion, or click the search button, to run a full search. It asks the TREK API and OpenStreetMap at the same time and interleaves their answers, TREK first, up to ten results. A place both of them know (within 60 metres, with a matching name) is listed once.
A Google or Amap key does not change this. The keyed provider is asked only when the TREK API and OpenStreetMap both come back empty; see [Google and Amap](#google-and-amap).
Installed [search plugins](Plugin-Cookbook#answer-place-searches-from-your-own-index) add their results below the core list, on the full search only.
### Where each result came from
On the desktop every row, in the suggestions and in the search results, carries a small mark naming its source: **TREK**, **OpenStreetMap**, **Google** or **Amap** (高德地图, or 高德地圖 in traditional Chinese). On the phone the suggestions carry it. A list that mixes the TREK API and OpenStreetMap stays readable that way. Results from the offline cache carry no mark; see [Searching offline](#searching-offline).
### The open day steers the search
Every search is hinted with the area you are planning, so "Hase-dera" finds the temple beside your hotel in Kamakura rather than the one of the same name in Nara. The hint is taken from:
1. the places on the day you have open, or, with no day open or an empty one,
2. all of the trip's places.
A hint that reaches further than about 60 km from its centre is dropped instead of sent. The middle of a round trip sits in open country between the cities, and pointing the search there ranks worse than no hint at all. Measured over 126 places of a real trip, the day hint put the right place among the first five results 70.6 percent of the time, against 54.8 percent with no hint and 57.1 percent with a hint around the whole trip.
Without any hint, the TREK API turns down a single common word such as `bar` as too broad, and OpenStreetMap answers that search on its own. Once the trip has a place or two, the index joins in.
The place form on the desktop and the search sheet on the phone use the same hint.
## Google and Amap
### With a Google Maps API key
> **Admin:** The Google Maps API key is instance-wide, set in **Admin → Settings → API Keys**. It is stored encrypted at rest and used for every member of the instance; on managed instances the operator supplies it and the panel is hidden.
> **Admin:** The Google Maps API key is instance-wide, set in **Admin → Settings → API Keys → Google Maps API Key**. It is stored encrypted at rest and used for every member of the instance.
When a key is present, the autocomplete uses the Google Places API, which can return ratings, opening hours, photos, and phone numbers from Google's database.
A key does not buy a different search. Google fills the slot that answers once the TREK API and OpenStreetMap both have nothing, and it adds what only a commercial provider has: ratings and photos. No open dataset carries either of those for ordinary businesses. A place found through Google keeps its Google id, so its details, rating and photos keep coming from Google.
> **API key restrictions:** TREK calls the Google Places API from the server, not the browser. If you apply **HTTP referrers** restrictions to your key in Google Cloud Console, you must also set `APP_URL` in your environment — TREK sends it as the `Referer` header on every outbound Google API request. Without it, Google will reject all server-side calls with `REQUEST_DENIED`. For server-side deployments, **IP address** restrictions are simpler and require no extra configuration. See [Troubleshooting](Troubleshooting) if photos are missing after adding a key.
The key's block carries four switches under **What the key may be used for**:
### Without a Google Maps API key
| Switch | What it covers |
|---|---|
| **Place Photos** | Google photos. Wikimedia pictures are unaffected. |
| **Place Autocomplete** | The suggestions while you type. |
| **Place Details** | The details of a place: hours, rating, website. |
| **Place Enrichment** | The **Place details** column in the place form, see [below](#place-details-while-searching). |
Search still works, and it needs no key. Two sources answer every search together: the TREK Places index, a dataset of businesses and sights that TREK maintains itself, and OpenStreetMap, which is where the temples, bridges and viewpoints are. Each row in the result list carries a small mark naming where it came from (TREK, OpenStreetMap, Google or Amap), so a list that mixes sources stays readable. Results include name, address and coordinates.
> **Place Autocomplete and Place Details act on every provider**, not only on Google. Switched off, the suggestion dropdown stays empty and details lookups stop for the TREK API and OpenStreetMap too; the full search keeps working. Leave both on unless that is what you want.
A key does not buy a different search. It fills the slot that answers once the index and OpenStreetMap have nothing, and it adds what only a commercial provider has: ratings, opening hours and, with Google, photos.
> **API key restrictions:** TREK calls the Google Places API from the server, not the browser. If you apply **HTTP referrers** restrictions to your key in Google Cloud Console, you must also set `APP_URL` in your environment: TREK sends it as the `Referer` header on every outbound Google API request, and without it Google rejects every server-side call with `REQUEST_DENIED`. For server-side deployments, **IP address** restrictions are simpler and need no extra configuration. See [Troubleshooting](Troubleshooting) if photos are missing after adding a key.
### With an Amap (高德地图) API key
> **Admin:** Set the key in **Admin → Settings → API Keys → Amap (高德地图) API Key**, then pick **Amap** under **Place search
> provider** in the same card. It needs a **Web 服务** (web service) key from
> [console.amap.com](https://console.amap.com/dev/key/app); a JS API key is a different credential and is rejected.
> **Admin:** Set the key in **Admin → Settings → API Keys → Amap (高德地图) API Key**, then pick **Amap (高德地图)** under **Place search provider** in the same card. It needs a **Web 服务** (web service) key from [console.amap.com](https://console.amap.com/dev/key/app); a JS API key is a different credential and is rejected.
Google Places is unreachable from most networks inside mainland China, and OpenStreetMap knows very little about
Chinese restaurants, shops and shopping centres. With Amap selected it takes the slot Google otherwise holds: the index
and OpenStreetMap are still asked first, and Amap answers when they have nothing, in Chinese, with ratings, phone
numbers and opening hours where Amap has them. Autocomplete, place details and the reverse geocoding behind
right-click-to-add-a-place go through Amap as well. Rows that came from Amap carry an Amap mark like every other
source.
Google Places is unreachable from most networks inside mainland China, and OpenStreetMap knows very little about Chinese restaurants, shops and shopping centres. With Amap selected it takes the slot Google otherwise holds: the TREK API and OpenStreetMap are still asked first, and Amap answers when they have nothing, in Chinese, with ratings, phone numbers and opening hours where Amap has them. Suggestions, place details and the reverse geocoding behind right-click-to-add-a-place go through Amap as well. Rows that came from Amap carry an Amap mark like every other source.
Amap does not supply place photos here. Its images come with no licence statement TREK could show next to them, so an
Amap place gets its picture from Wikimedia Commons like any other, with the credit and licence attached.
Amap does not supply place photos here. Its images come with no licence statement TREK could show next to them, so an Amap place gets its picture from Wikimedia Commons like any other, with the credit and licence attached.
A place remembers where it came from. One picked from Amap keeps its Amap id, one picked from Google keeps its Google
id, and each keeps opening against the provider that knows it, whichever provider the admin selects later.
A place remembers where it came from. One picked from Amap keeps its Amap id, one picked from Google keeps its Google id, and each keeps opening against the provider that knows it, whichever provider the admin selects later.
You can also paste an Amap link into the search box, the same way a Google Maps URL works below, as long as the link
carries a coordinate: a `uri.amap.com/marker?position=…` share link does, a map URL with the coordinate in the address
does, and a `surl.amap.com` short link does when it resolves to one of those. A bare `amap.com/place/…` POI page is an
id and nothing else, and TREK answers that one with an error rather than guessing where it is.
Amap links can be pasted into the search box too; see [Pasting a map URL](#pasting-a-map-url).
### Which provider answers
**Admin → Settings → API Keys → Place search provider** decides only who fills the keyed slot beside the index and
OpenStreetMap. Those two are asked either way. The choice is available on managed instances too, where the keys
themselves come from the operator.
**Admin → Settings → API Keys → Place search provider** decides only who fills the keyed slot beside the TREK API and OpenStreetMap. Those two are asked either way.
| Setting | Who fills the keyed slot |
|------------------|-------------------------------------------------------------------------------|
| `Automatic` | Google when a Google key is set, otherwise Amap when an Amap key is, otherwise nobody. The default, and what every install had before Amap existed: adding an Amap key never moves an install off Google on its own. |
| `Google Places` | Google. With no Google key the slot stays empty rather than falling to Amap. |
| `Amap (高德地图)` | Amap. With no Amap key the slot stays empty. |
| `OpenStreetMap` | Nobody, whatever keys are configured. Search runs on the index and OpenStreetMap alone. |
| Setting | Who fills the keyed slot |
|---|---|
| `Automatic` | Google when a Google key is set, otherwise Amap when an Amap key is, otherwise nobody. The default, and what every install had before Amap existed: adding an Amap key never moves an install off Google on its own. |
| `Google Places` | Google. With no Google key the slot stays empty rather than falling to Amap. |
| `Amap (高德地图)` | Amap. With no Amap key the slot stays empty. |
| `OpenStreetMap` | Nobody, whatever keys are configured. Search runs on the TREK API and OpenStreetMap alone. |
When the selected provider has no key, the card says so: place search is then answered by the TREK index and OpenStreetMap alone.
To keep searches from reaching the TREK API at all, set `TREK_PLACES_ENABLED=false` on the server; see [Switching it off](TREK-Places-API#switching-it-off).
## Place details while searching
On desktop the Place form carries a **Place details** column to the left of the form. Pick a search result and it fills in on its own — no extra click, and nothing changes about the usual add-a-place flow of searching, picking and saving. If you already know the place, ignore the column and save as before.
On desktop the place form carries a **Place details** column to the left of the form. Pick a search result and it fills in on its own, with no extra click, and nothing changes about the usual flow of searching, picking and saving. If you already know the place, ignore the column and save as before.
The column shows:
The column shows what it can find:
- **Pictures** near or of the place. Click one to make it that place's thumbnail; click it again to clear the choice. The picture then appears everywhere the place does — list, map marker, itinerary, PDF export and shared trips — exactly like a [custom place image](#custom-place-image).
- **A description**, when one is available. It is *not* written into the place automatically. Use **Use this text** to copy it into the description field; the button is disabled while you already have a description of your own, so nothing you wrote gets overwritten.
- **Pictures** near or of the place. Click one to make it that place's thumbnail; click it again to clear the choice. The picture then appears everywhere the place does (list, map marker, itinerary, PDF export and shared trips), exactly like a [custom place image](#custom-place-image).
- **A rating**, for a place that came from Google or Amap.
- **Opening Hours**: today's hours up front and the whole week a click away, with an open or closed badge worked out in the place's own time zone. When the hours cannot be read reliably there is no badge rather than a wrong one.
- **Good to know**: facts such as cuisine, outdoor seating, takeaway, step-free access, Wi-Fi or a menu link, where OpenStreetMap carries them.
- **A description**, when one is available. It is *not* written into the place automatically. Use **Use this text** to copy it into the description field; the button is disabled with *Clear the description field first* while you have a description of your own, so nothing you wrote gets overwritten.
One credit line sits under the picture grid, and it belongs to the picture in play: the tile you are hovering, or failing that the one you picked, or the first picture before you have done either. It names the author, links that name to the source page, and adds the licence with a link to its terms. The other tiles carry author and licence as a tooltip only, without the links. Google's pictures get an author line and nothing else, because Google grants no reusable licence for them. Most Wikimedia Commons pictures are CC BY or CC BY-SA, which means the credit has to travel with the picture, so once you pick one, the credit stays visible under the thumbnail in the place's detail panel too.
### Where the information comes from
Wikipedia and OpenStreetMap are always used and need no configuration:
**Pictures** come from Wikimedia Commons, resolved from the place's own tags first: the Wikidata image, the lead image of its Wikipedia article, its Commons category. Only when those turn up too few does TREK look for pictures taken nearby, within 60 metres, and never for shops, restaurants, cafés and other everyday businesses. Two percent of those have a picture on Wikimedia, against 70 percent of churches, so a picture taken nearby is almost always of the building across the square. A missing picture is the honest answer there.
- Pictures from **Wikimedia Commons**, resolved from the place's own tags first — the Wikidata image, the lead image of its Wikipedia article, its Commons category — and falling back to a search by coordinate only when those turn up too few.
- Descriptions from the OpenStreetMap `description` tag, or from the Wikipedia article the place is tagged with. TREK resolves the article from that tag rather than guessing it from the name, so an ambiguous name never pulls in the wrong article. A place with no such tag simply gets no description.
**Descriptions** come from the first source that has one:
With a Google Maps API key, and only if the matching admin switches are on, up to three **Google Places** photos and Google's editorial summary are added on top.
1. The OpenStreetMap `description` tag, for a place from OpenStreetMap.
2. The Wikivoyage article, then the Wikipedia article, that the place is tagged with, in your language where one exists. TREK resolves the article from the tag rather than guessing it from the name, so an ambiguous name never pulls in the wrong article.
3. The place's own website, for a place from the TREK API: the summary the site publishes for machines, credited with the site's host name and linked back. This is what gives restaurants, shops and hotels a description at all. Your server never opens the website itself; the TREK API has read it once for everyone.
4. Google's editorial summary, with a Google key and **Place Details** on.
5. The article about the chain a branch belongs to, headed **About the chain** with the note *This describes the chain, not this branch.*
Pictures are copied to your own server and served from there — nothing is loaded directly from Google or Wikimedia while you browse, so no visitor's address leaves your instance.
**Opening hours** come from OpenStreetMap first, because an OpenStreetMap entry describes that exact building where a chain's website often carries one set of hours for every branch. After that come the hours a place from the TREK API publishes on its own site, and for a place found through Google, Google's hours.
> **Admin:** the column is controlled by **Place Enrichment** in Admin → Settings → API Keys, and it is on by default. The Google half additionally follows **Place Photos** and **Place Details**. Turning Place Enrichment off leaves the column with a short note and makes no outbound calls.
Pictures are copied to your own server and served from there. Nothing is loaded directly from Google or Wikimedia while you browse, so no visitor's address leaves your instance.
The column is desktop-only; the mobile place sheet is unchanged.
> **Admin:** the column is controlled by **Place Enrichment**, under **What the key may be used for** in the Google Maps API Key block of **Admin → Settings → API Keys**, and it is on by default. Wikipedia and OpenStreetMap are always used; the Google half additionally follows **Place Photos** and **Place Details**. Turning Place Enrichment off leaves the column with a short note and makes no outbound calls.
The column is desktop-only.
## Exploring the map by category
With **Explore places on the map** switched on in [Display Settings](Display-Settings#explore-places-on-the-map), the trip map carries a row of category buttons: **Restaurants**, **Cafés**, **Bars & nightlife**, **Accommodation**, **Sights**, **Museums & culture**, **Nature & parks** and **Activities**. Tap one to show that kind of place around the part of the map you are looking at. After you move the map, **Search this area** runs it again for the new view.
The TREK API answers these first, from the map centre out to a radius that covers the view, at most 20 km. When it has nothing for the area, or cannot be reached, the public Overpass mirrors of OpenStreetMap answer instead, narrowed to a window of half a degree around the centre; `OVERPASS_URL` and `OVERPASS_TIMEOUT_MS` on [Environment Variables](Environment-Variables) steer those. Results from the TREK API come with address, website, phone and opening hours where the index has them, under the names used on the spot rather than translations. The [Road trip](Road-Trip#search-along-the-route) search along the drive asks the same two sources.
## Searching offline
When a trip is kept for offline use, TREK also downloads the places around it from the TREK API: one request of up to 3000 places, in a box around the trip's places with some margin, at most 1.5 degrees a side (a trip spread wider gets its centre). For a city the size of Rostock that is about a megabyte. The download is repeated only when the trip's area changes, and it happens whether or not **Store map tiles offline** is on: the tiles are the big part, the places are not.
With no network, or with **Force offline mode** on, suggestions and the full search then answer from that cache: places whose name starts with or contains what you typed, ignoring case and accents, across every trip you keep offline. Picking one fills in its name, address, coordinates, website and phone from the cache. Answers from the cache carry no source mark, because they are not a live answer from anyone, and they are never written to the [Place Search Log](#place-search-log).
Switching a trip's offline storage off removes its cached places with the rest of its data, and **Clear cache** in **Settings → Offline** removes them all. With the TREK API switched off nothing is downloaded, and offline search has nothing to answer from. See [Offline Mode and PWA](Offline-Mode-and-PWA).
## Place Search Log
> **Admin:** switch it on under **Admin → Settings → API Keys → Place Search Log**, on the desktop or the phone. It is off by default.
With the log on, every time somebody picks a place from a list of search results or suggestions, TREK writes one row: what was typed, the language TREK was set to, the hint coordinate, which source answered, where in the list the picked place stood and how long the list was, and the picked place's name, id and coordinate. Coordinates are rounded to three decimals, about 100 metres. A row holds no user, no trip and no session, and a search nobody picked from leaves no row at all.
It exists so a different place index can be measured against real searches later: how often was the place people actually wanted among the first five results.
- **Nothing leaves the instance.** The log lives in your database, and only an admin can read it.
- **Retention:** rows older than 180 days are deleted every night, whether the log is on or off, so switching it off also lets what it collected age out.
- **Reading and wiping:** there is no screen for it. Signed in as an admin, `GET /api/place-shadow/summary` returns the row count, the counts per source and how often the pick was the first result or among the first five. `GET /api/place-shadow/export` returns the rows oldest first, 2000 per page; pass the `nextAfter` value back as `?after=` for the next page. `DELETE /api/place-shadow` deletes every row.
- Switching the log on or off is recorded in the [Audit Log](Audit-Log) as `admin.place_shadow`.
## Pasting a map URL
Paste a `maps.app.goo.gl/…`, `goo.gl/maps/…`, or `maps.google.*/…` URL directly into the search box and press the search button. TREK resolves it server-side and populates the name, address, and coordinates.
Paste a `maps.app.goo.gl/…`, `goo.gl/maps/…`, or `maps.google.*/…` URL directly into the search box and press the search button. TREK resolves it server-side and fills in the name, address, and coordinates.
Amap links work the same way, as long as the link carries a coordinate: `uri.amap.com/marker?position=…` share links, map URLs with the coordinate in the address, and `surl.amap.com` short links that resolve to one of those. A bare `amap.com/place/…` POI page is an id and nothing else, and TREK answers it with an error. Coordinates are converted from GCJ-02 to WGS-84 on the way in, so the place lands where it belongs on every other map.
Amap links work the same way, as long as the link carries a coordinate: `uri.amap.com/marker?position=…` share links, map URLs with the coordinate in the address, and `surl.amap.com` short links that resolve to one of those. A bare `amap.com/place/…` POI page is an id and nothing else, and TREK answers it with an error rather than guessing where it is. Coordinates are converted from GCJ-02 to WGS-84 on the way in, so the place lands where it belongs on every other map.
## Entering coordinates manually
**Paste** a `lat, lng` pair (e.g. `48.8566, 2.3522`) into the **Latitude** field — comma, semicolon or space separated. TREK detects the pair and fills both coordinate fields at once. This works on paste only: the coordinate fields accept digits, a decimal point and a leading minus, so typing a pair by hand drops the separator and leaves a single invalid number (`48.85662.3522`) behind. Type the two values into their own fields instead.
**Paste** a `lat, lng` pair (e.g. `48.8566, 2.3522`) into the **Latitude** field, comma, semicolon or space separated. TREK detects the pair and fills both coordinate fields at once. This works on paste only: the coordinate fields accept digits, a decimal point and a leading minus, so typing a pair by hand drops the separator and leaves a single invalid number (`48.85662.3522`) behind. Type the two values into their own fields instead.
## Place fields
@@ -116,13 +180,13 @@ Amap links work the same way, as long as the link carries a coordinate: `uri.ama
| Category | Pick an existing category or type a new name to create one inline (default color `#6366f1`, icon `MapPin`) |
| Start time / End time | Shown only when editing an existing place |
| Website | URL |
| File attachments | Click the Paperclip icon to attach a file, or paste an image or PDF from the clipboard. The Paperclip takes anything on the instance's **Allowed File Types** list — by default jpg, jpeg, png, gif, webp, heic, pdf, doc, docx, xls, xlsx, txt, csv, pkpass, pkpasses, md and markdown — plus video, which is exempt from that list. See [Documents-and-Files](Documents-and-Files) |
| File attachments | Click the Paperclip icon to attach a file, or paste an image or PDF from the clipboard. The Paperclip takes anything on the instance's **Allowed File Types** list (by default jpg, jpeg, png, gif, webp, heic, pdf, doc, docx, xls, xlsx, txt, csv, pkpass, pkpasses, md and markdown), plus video, which is exempt from that list. See [Documents-and-Files](Documents-and-Files) |
Two inline warnings are shown when editing times: one if the end time is set to a value before or equal to the start time, and one if the times overlap with another place already assigned to the same day.
## Costs for a place
With the [Costs/Budget addon](Budget-Tracking) enabled, the place form carries the same **Costs** block that bookings and transports have. **Create expense** saves the place and then opens the Costs editor for a new expense linked to it — the museum ticket, the guided tour, the entry fee. Once linked, the block shows that expense with edit and remove actions.
With the [Costs/Budget addon](Budget-Tracking) enabled, the place form carries the same **Costs** block that bookings and transports have. **Create expense** saves the place and then opens the Costs editor for a new expense linked to it: the museum ticket, the guided tour, the entry fee. Once linked, the block shows that expense with edit and remove actions.
The expense belongs to the **place**, not to a day. Putting the same place on several days does not multiply it: you bought the ticket once. If you really pay each time, add a second expense from the Costs tab.
@@ -130,18 +194,18 @@ Deleting the place deletes its linked expense too, the same way deleting a booki
## Custom place image
By default a place's thumbnail is fetched automatically (from Google/OpenStreetMap when the place was imported or matched, otherwise a category icon). To use your own photo instead, open the place's detail panel and click its round thumbnail — pick an image and it becomes that place's thumbnail everywhere (list, map marker, itinerary, PDF export and shared trips). A small remove button on the thumbnail clears the custom image and restores the automatic default. Accepted formats are JPG, PNG, GIF and WebP (HEIC is converted automatically), up to 20 MB.
By default a place's thumbnail is fetched automatically (from Google or Wikimedia when the place was imported or matched, otherwise a category icon). To use your own photo instead, open the place's detail panel and click its round thumbnail. Pick an image and it becomes that place's thumbnail everywhere (list, map marker, itinerary, PDF export and shared trips). A small remove button on the thumbnail clears the custom image and restores the automatic default. Accepted formats are JPG, PNG, GIF and WebP (HEIC is converted automatically), up to 20 MB.
The same control is available on saved places in [Collections](Collections#place-detail).
## Importing multiple places
Drag a `.gpx`, `.kml`, or `.kmz` file onto the Places sidebar to import all waypoints or features at once. You can also import a saved-list share URL using the **Import list** button in the sidebar header — both Google Maps and Naver Maps list URLs are supported.
Drag a `.gpx`, `.kml`, or `.kmz` file onto the Places sidebar to import all waypoints or features at once. You can also import a shared list with the **List Import** button in the sidebar header (it reads **Google List** when Google is the only list source): both Google Maps and Naver Maps list URLs are supported, and a shared Google Maps route works too, its stops becoming places in driving order. Stops a route gives only by name are looked up through the TREK API first.
Imported tracks each get their own line colour so multiple routes stay apart on the map; you can override it per track from the place details. See [Map Features](Map-Features) for the details.
Importing the same list again does not duplicate what is already in the trip. A place is recognised by the provider id it was imported with (Google place id, Google feature id, or OSM id) before its name or its coordinates are considered, so renaming a place in TREK — or moving its pin — does not make it come back as a second copy on the next import.
Importing the same list again does not duplicate what is already in the trip. A place is recognised by the provider id it was imported with (Google place id, Google feature id, or OSM id) before its name or its coordinates are considered, so renaming a place in TREK, or moving its pin, does not make it come back as a second copy on the next import.
> **Admin:** The Google Maps API key is set instance-wide in **Admin → Settings → API Keys**. Without it, OSM search is used automatically.
> **Admin:** with a Google Maps API key in **Admin → Settings → API Keys**, the list import offers **Enrich places via Google**, which looks up each imported place to fill in photos, address and contact details, one Google lookup per place. Without a key the import works the same, just without that option.
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Map-Features](Map-Features) · [Tags-and-Categories](Tags-and-Categories)
**See also:** [TREK Places API](TREK-Places-API) · [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Map-Features](Map-Features) · [Offline-Mode-and-PWA](Offline-Mode-and-PWA) · [Tags-and-Categories](Tags-and-Categories)
+378
View File
@@ -0,0 +1,378 @@
# Road Trip
Road trip mode plans a trip as one continuous drive. The same days and the same places you plan under **Days** are read as a chain of stops with the driving between them: how far each leg is, how long it takes, when you arrive and when you set off again. Change a stay, pin a time or move a stop, and every arrival after it moves with it.
It is a second way of looking at a trip, not a second trip. Nothing is copied: switch back to **Days** and the plan is where you left it.
> **Admin:** Enable the **Road trip** addon in **Admin → Addons**. It is listed under **Trip** and is off by default. It needs no key and no account: routing runs on the public OpenStreetMap routing servers until you point it at your own, see [Routing engines](#routing-engines). See [Admin-Addons](Admin-Addons).
## What it does
- **Shows the whole drive.** Trip distance, driving time and stop count at the top, then one card per day with every leg and every arrival.
- **Keeps your times.** A time you pin on a stop is never moved. The schedule is worked out forwards and backwards from it, and a stop you would reach late says by how much.
- **Knows how long you stay.** Each stop carries its own stay, up to a full day, and a stay that runs past midnight carries the drive into the next morning.
- **Caps a day.** Daily travel times end each day at the hour you choose, along the route or at the last place, and the rest of the drive continues on extra calculated days.
- **Watches your limits.** The longest drive in one go, the driving per day, and the range on one tank or charge. Legs and days over them are marked, and so is the point where the tank runs dry.
- **Searches along the road you actually drive** for fuel, charging, rest areas, campsites, accommodation, food and sights, within 2, 5 or 10 km of it.
- **Lets you shape the route** with via points, offers **Other ways** to drive a leg, and avoids toll roads, motorways and ferries where possible.
- **Follows a scenic route** from an imported GPX or KML track.
- **Shows weather warnings and disaster alerts** on the map when you ask for them. They never change the route.
- Works on the phone as its own **Road trip** tab, and through [MCP](#mcp-tools) without an open browser.
## Switching to Road trip
With the addon on, a **Days** / **Road trip** switch sits at the top of the planner's left column on the desktop. The choice is remembered per trip for as long as the browser tab stays open.
In **Road trip** the planner changes shape:
| Where | Days | Road trip |
|---|---|---|
| Left column | the day plan | the drive: a summary of **Distance**, **Driving time** and **Stops**, then one card per day |
| Map | the selected day | every day of the trip. **Fold** on a day card takes that day off the map as well |
| Right column | the places list | **Along the route** (the search, see below) and the **Driving settings** card |
The map's category pills still work, so you can look around what is in view as well as along the drive; a place both searches find is drawn once. **Show whole trip** is not offered, because this view already draws the whole trip.
The drive is built from the places planned on each day. Plan the places the trip is for under **Days** as usual, or import them (see [Importing a Google Maps route](#importing-a-google-maps-route)). A day is routed once it has two places with coordinates; a day with fewer shows an empty card you can drop a stop onto, and a place without coordinates is left out of the drive. In the rail, drag a stop to reorder its day or to move it to another day, or focus it with the keyboard and press Alt with the up or down arrow.
While the legs are still being routed, the summary says *Still working out the rest of the drive*, because until then every total is a partial sum.
### A day card
The header of each card carries the day's number, its date, its driving (for example *412 km in 5 h 10 min*) and its number of stops. It also shows how far the day runs over your driving limit, which road classes it could not avoid, and a **Track** badge for [following a track](#following-a-gpx-or-kml-track).
Below it, the day is a chain:
- **Numbered stops** are the places the day is for. The numbers match the markers on the map.
- **Stops on the way** (fuel, charging, a rest area and the other kinds below) sit on the dashed line with the icon of their kind instead of a number. They are not counted as stops, so a day with a charger between four places is still a four-stop day.
- **Drive bands** between the stops show each leg as distance and time. Click one for [Other ways](#other-ways-and-avoidance).
- **Arrival times** stand at the right edge. A time you set is printed a little stronger than one worked out from the drive; hover one to see which it is (*Time you set* or *Calculated from the drive*). A small *+1* means the next day.
- A stop the road does not quite reach, such as a viewpoint up a footpath, shows the gap as a dashed spur on the map, and the rail prints *{distance} from the road* once it is 250 m or more.
- A charging or rest halt a routing plugin adds to a leg is listed as *Stop on the way*. It is the plugin's, so it is shown but cannot be edited.
A stop reached after midnight moves to the card of the day it is reached on, under a **From day _n_** band that names the day it came from and when the drive left. Nothing is written for this: the stop still belongs to the day you planned it on, and a shorter stay the evening before puts it back.
## Stops on the way
Any stop can be a **destination**, the numbered kind, or a **stop on the way**. The kinds are:
| Kind of stop | Stay it starts with | Notes |
|---|---|---|
| **Fuel** | 10 min | Refills the range, unless the vehicle is set to **Electric**. |
| **Charging** | 30 min | Refills the range, unless the vehicle is set to **Petrol**. Shows [availability and tariffs](#charger-availability-and-tariffs). |
| **Rest area** | 20 min | |
| **Campsite** | 60 min | Can also be booked as a night. |
| **Accommodation** | 30 min | Added from the search as a night by default, see [Booked nights on the drive](#booked-nights-on-the-drive). |
| **Food** | 45 min | |
| **Sights** | 30 min | |
The stay is only a starting point. Change it on the stop, see [How long you stay](#how-long-you-stay).
- **Make it a stop on the way:** click the number of a numbered stop and pick a kind. The number turns into the kind's icon and the stops below it are renumbered.
- **Change what kind of stop this is:** click the icon of a stop on the way. **Back to a destination** gives it its number again.
- A fuel or charging stop that refills your vehicle carries a fill badge (see [Driving limits and range](#driving-limits-and-range)). Click it to set how full this particular stop fills, or **Use my default**.
Stops on the way also show under **Days** and on the day's route there. To keep them in Road trip only, switch off **Show in Days too** under **Service stops** in the **Driving settings**. The switch is on by default, belongs to the trip, and applies to every stop on the way, including existing ones. A stop that a booked night put on the drive is always hidden under **Days**, whatever the switch says, because the day already shows that booking.
### Adding a stop from the search
**Add** on a search result opens **Add as a stop**. It says where the stop lands, for example *Day 2, as stop 4*: at the point of the day where the drive really passes it. It warns when the same place is already on the trip. Pick the **Kind of stop** and the **Time at this stop** (5, 10, 20, 30, 45 or 60 minutes), then **Add**. **More details** opens the full place form instead.
For accommodation and campsites the dialog asks **Pause** or **Overnight**. Accommodation starts on **Overnight** (its button in the result list already reads **Add as an overnight stay**), a campsite on **Pause**. An overnight stay asks only for the **Check-in** time, prefilled from the calculated arrival, and shows the place's website and phone where known. **Find accommodation** opens trivago and CHECK24 for a hotel, or PiNCAMP and Pitchup for a campsite, in a new tab, with the place and your dates where the portal accepts them. Nothing is booked and no stop is added by opening a portal. CHECK24 needs a manual search.
## How long you stay
Every stop has a **Stay** badge. Click it to open **Time at this stop**:
- The length is the big number in the middle. Set it with the slider, the minus and plus buttons (5 minutes at a time), or one of the presets from 15 minutes to 12 hours. The slider reaches a full day.
- Below it, **Arrive** and **Leave** show what the stay does to the day while you change it.
- **No stay** clears it.
**The stay belongs to the place, not to one visit.** A place planned on two days has the same stay on both.
A stay may run past midnight. The clock carries into the next morning together with the drive from there, and the next stop moves to the card of the day it is actually reached on. With daily travel times set, the hours between one day's end time and the next day's start time count towards the stay, so a twelve hour night that begins at 20:00 is over at 08:00 the next morning.
A booked night is answered the same way: its length is its stay. The drive never reads a check-out, because a check-out is the latest the room has to be handed back, not the time anybody drives on. The booking keeps its check-out as a booking detail under **Days**.
## Leaving at a set time
A visit's **End** is the time the drive leaves it. Set it in the place form, where the **End** field says so in Road trip mode: *On the road trip, the drive leaves at this time.*
- The stop is stood at from whenever the drive gets there until that time. Its **Stay** badge shows the stay that results together with the time, for example *2 h until 14:00*. That length is worked out, never written into the place, so it is right again the moment an arrival moves.
- If the drive gets there after the End, the badge warns *Arrives 25 min after the time you set to leave*, and the drive leaves on arrival.
- If the daily travel times close the day before the End comes, the stop is where that day ends: *The travel day ends before 14:00, so the drive goes on the next morning.*
- Clicking the **Stay** badge of such a stop opens the End instead of the slider, with **Remove end time**. After that the stay is yours to choose again. The button is missing when you may not edit the stop, and when the End is stored on the place itself and another visit of the same place relies on it: removing it there would change that visit too.
The End belongs to one visit; the stay belongs to the place. Older trips can carry an End on the place, which then applies to its visits that have none of their own.
## Pinned times and the schedule
Give a visit a **Start** in the place form and the chain restarts from it. That time is never moved.
- With nothing to count from (no pinned time, no check-in and no daily travel times), the rail shows driving times but no clock times.
- **The schedule works backwards too.** Pin 10:00 on the second stop and the first one says when to set off, worked out from the drive and the stay. It stops at a leg that has not routed rather than inventing a duration.
- A stop reached later than the time you set says so: *Arrives 15 min after the time you set*. The same warning appears on a fuel or charging halt that carries a time.
- The **Check-in** of a booked night is not an appointment. Arriving before it means waiting for it, and it starts the day when nothing before it decides the hour. Arriving after it is simply arriving.
## Daily travel times and day endings
In **Driving settings → Daily travel times**, set a **Day start time** and a **Day end time**. Both are needed; clear either to turn the feature off. Manual times take priority.
Driving then stops at the end time and continues from the same point at the next day's start time. How the day ends is chosen under **End the day**:
| Choice | What happens |
|---|---|
| **Along the route** (default) | The day pauses on the road wherever the drive has got to at the end time. |
| **At the last place** | The day stops at the last place before the next drive would pass the end time. A drive too long for any single day asks you to add a place along the way or to pause along the route. |
- Whatever does not fit continues on **extra calculated days**, beyond the trip's own days if needed. These are arranged for the road trip view only; your days and their places are not changed.
- The rail shows each ending as an **End of day** row with **Show on map**. The map marks it with a moon and the day number, hidden once you zoom out below level 6.
- **End the day here**, in a stop's place details, ends the day after that visit and its stay even before the end time. It belongs to that one visit.
- While online you can drag an end-of-day marker on the map along the route or onto a visit. Right-click it to restore the automatic ending, or use **Restore automatic day endings** in the Driving settings. A focused marker also takes the arrow keys and Delete.
- If a time you pinned cannot be reached together with the daily breaks, the planner says so and pauses automatic scheduling rather than moving your time.
- Turning daily travel times off keeps every **End the day here** and every dragged ending, but stops applying them until the times are back.
- With daily travel times set, the days are always connected: the drive from one day's last stop to the next day's first is routed and counted.
## Driving settings
The **Driving settings** card sits under the search in the right column. Its badges show what is set without opening it. The settings belong to the trip, so everyone on it plans with the same car, the same limits and the same daily times. Changing them needs the permission *Edit days, notes & assignments* (see [Admin-Permissions](Admin-Permissions)). Trips that existed before took their owner's earlier values once.
| Section | Settings |
|---|---|
| **Driving** | **Longest drive at once**, **Driving per day**, both in minutes. Empty means off. |
| **Daily travel times** | **Day start time**, **Day end time**, **End the day**, **Restore automatic day endings** |
| **Avoid where possible** | **Toll roads**, **Motorways**, **Ferries** |
| **Service stops** | **Show in Days too** |
| **Vehicle** | What you drive (**Either**, **Petrol**, **Electric**), the range, **Fill up to**, and **Work it out from the car** |
| **Route line** | **Connect the days**, **A colour per day** |
| **Current warnings** | **Show hazard areas** |
**Connect the days** routes the drive from one day's last stop to the next day's first and counts it towards the day it arrives on. It is off by default, and always on while daily travel times are set. **A colour per day** draws each day in its own colour and tints its card to match.
## Driving limits and range
All three limits are yours to set, and nothing is assumed about the vehicle: with no limit set, nothing is flagged.
- **Longest drive at once:** a leg over it gets a warning badge, *1 h 10 min over your longest drive*.
- **Driving per day:** a day over it says so in its header. Both limits count driving only, not stays and not overnight legs.
- **Range on one tank** (or **Range on one charge** for an electric car), in your distance unit. Instead of typing it, open **Work it out from the car** and enter **Tank size** and **Consumption**, or for an electric car **Battery**, **Consumption** and **Battery wear**. Once those add up, the range is worked out from them and cannot be typed over.
- **Fill up to** says how full a stop fills, because nobody charges to 100 % on the road. Each fuel or charging stop can override it.
The range counts from the last fuel or charging stop, across days. **What you drive** decides which stops count: **Petrol** refills only at fuel stops, **Electric** only at charging stops, **Either** at both.
Where the range runs out, the rail draws a band across the leg: **Tank runs out here** or **Battery runs out here**, *after 64 km*. **Find fuel** or **Find charging** searches the road before that point and offers up to three stations the car can still reach, keeping 10 km in reserve and counting the detour twice. Each shows how much range it leaves to spare, and **Add {name} as a fuel stop** (or **as a charging stop**) puts it on the right leg. This works across day boundaries too, and needs a connection.
## Search along the route
The **Along the route** panel searches the road actually driven, not the straight line between stops. That is the difference between one petrol station and forty.
1. Pick the **Day** at the top of the panel.
2. Under **Looking for**, pick one or more of **Fuel**, **Charging**, **Rest area**, **Campsite**, **Accommodation**, **Food** and **Sights**. It opens on **Charging** when the trip's vehicle is electric, and on **Fuel** otherwise.
3. Under **Within**, pick 2, 5 or 10 km either side of the road.
4. Press **Search**.
Results are grouped by kind and listed in the order you pass them, each with how far along the day it is (*after 120 km*) and how far off the route. Click a result to bring it into view on the map, which is how you tell which side of the road it is on. **Add** puts it on the drive, see [Adding a stop from the search](#adding-a-stop-from-the-search).
To narrow the results afterwards:
- **Filter by name**, for example a brand.
- Limit the list to one stretch: **The whole day**, around one stop, or around the middle of a leg (*Halfway, Lyon to Avignon*), within 25, 50 or 100 km. A break on a five hour drive belongs in the middle of it.
- For charging: **Any plug** or one plug family, and **Any power** or a minimum of 11, 22, 50 or 150 kW. These filters work where OpenStreetMap states them. A station that states neither stays in the list, because most stations state no power at all.
**Clear results** empties the list, its pins on the map and the filters.
The search asks TREK's place index and OpenStreetMap, and any installed place-search plugin, whose hits show their source. A source that fails is named beside the results that did arrive, and a search cut short says so rather than claiming the stretch was checked. The search only runs when you press **Search**, and needs a connection.
### Add manually
The search does not know every charger or pump: a good share of the chargers at a motorway junction are missing from OpenStreetMap. **Add manually**, beside **Search**, is for those.
- Look the place up by name.
- TREK works out which leg of which day it belongs on, measured against the drawn route. **Add between** lists every leg of every routed day, if the guess is wrong.
- A place well away from the route is accepted, with a note: *12 km from the route, so check which leg it belongs on.*
- The dialog opens on the kind you are searching for, with that kind's usual stay.
### Charger availability and tariffs
A charging stop shows how many connectors are free and the published price, compactly in the rail and in full in its place details, with the source, the time of the data and the tariff conditions. The same panel appears in **Add as a stop** when the kind is **Charging**, so you can read it before the stop exists.
The data comes from the public [MobiData BW OCPDB](https://api.mobidata-bw.de/), which aggregates participating operators, without a key or an account. Coverage varies by region and operator. *No reliable data available* and *Status outdated* mean exactly that; neither means the charger is free. The prices are **Published tariffs**, not what your own charging card pays. The data is refreshed every minute while it is shown and is not available offline.
## Via points
A via point bends a day's drive without adding a stop: no number, no stay, no arrival.
- **Click the route** on the map to drop one. It is attached to the leg you clicked, between the two stops it lies between.
- **Drag** it to move it. The route is redrawn through the new spot.
- **Right-click** it to remove it, and the leg drives the direct way again.
The handles show once you zoom in far enough to aim at a road (zoom level 9). A via remembers which stop it follows, so reordering a day re-pins it instead of letting the drive snap back. Placing and moving vias needs the permission *Edit days, notes & assignments* and a connection; without either, the route cannot be clicked and the handles cannot be moved.
## Other ways and avoidance
Click a drive band in the rail to see **Ways to drive this leg**. TREK asks the router for alternatives and lists them: the **Fastest**, how much slower or quicker each other one is, and on a leg you already reshaped, the road you are on as **Current**. Hover an entry to light it up on the map, click it to drive that way. Choosing a different road places a via on the leg, replacing any the leg already had; choosing the router's own road removes them.
The list can also offer **No motorway**, **No tolls** and **No ferry**. These come from the second routing engine (see below), which prices roads with its own speed model, so they are marked *Timed by the avoidance router, not the main one* and are not compared with the others. When the router knows only one way, the list says *Only one sensible way to drive this one.*
To avoid road classes for the whole trip, switch them on under **Avoid where possible** in the Driving settings: **Toll roads**, **Motorways**, **Ferries**. This is a preference, not a ban. A day with no way round still uses the road, and says so in its header (*Toll roads unavoidable*) instead of pretending. Days that could avoid what was asked still do.
When the instance has its own OSRM but no Valhalla, the switches are unavailable and say *Your routing provider does not support avoidance.*
## Routing engines
Routing needs two engines, and both have public defaults, so the addon works without any setup:
| Engine | Used for | Public default | Own instance |
|---|---|---|---|
| **OSRM** | every road route TREK draws: the road trip, the day plan, the routed booking lines | the FOSSGIS servers at `routing.openstreetmap.de` | **Own routing engine** |
| **Valhalla** | driving around toll roads, motorways and ferries, and the **No motorway**, **No tolls** and **No ferry** offers | the FOSSGIS Valhalla at `valhalla1.openstreetmap.de` | **Own Valhalla instance** |
The public OSRM servers allow roughly one request a second. That is enough for a day plan and tight for a road trip, which routes every leg of every day: TREK spaces its requests and retries a refused one, but a long trip takes a while to fill in. An instance with many road trippers is better off with its own.
> **Admin:** Set your own engines under **Admin → User Defaults**, in the **Map** section, on the desktop or the phone: **Own routing engine** for OSRM, **Own Valhalla instance** for Valhalla. A value saves when you leave the field, and **reset** restores the public default. Then **restart the server and reload the page.** Only an admin can set them; they apply to everyone.
Why a restart: routes are calculated in the browser, and the browser only talks to addresses the server names in its security policy, which it builds once at start. An address the policy does not name is blocked by the browser without an error TREK could report.
What the combinations do:
| Own routing engine | Own Valhalla instance | Result |
|---|---|---|
| empty | empty | Public OSRM for routes, public Valhalla for avoidance. |
| set | empty | Your OSRM for routes. **The public Valhalla is not used**, because an instance that runs its own router has chosen against public hosts. The avoid switches are unavailable, and **Other ways** can still offer routes without motorways or tolls if your OSRM supports excluding them. |
| empty or set | set | Your Valhalla for avoidance. |
Requirements for your own instances:
- **OSRM** must serve the standard layout, `<address>/route/v1/<profile>/…`, which `osrm-routed` does out of the box. It answers every route in TREK, not only road trips. The public servers refuse to exclude road classes; an OSRM of your own built through the MLD pipeline, with a profile that has those classes, can answer **No motorway** and **No tolls** in **Other ways** by itself.
- **Reachable from the browser.** The browser calls the engine directly, so the address has to work from the devices your travellers plan on, not only from the TREK server. `http://localhost:5000` means the traveller's own computer to a browser. When TREK is served over HTTPS, the engine has to be HTTPS too, or the browser blocks it as mixed content.
- **Reachable from the TREK server** for the [MCP tools](#mcp-tools), which calculate on the server. An address on your local network is accepted there without `ALLOW_INTERNAL_NETWORK`, because only an admin can set it.
There is no environment variable for either engine. See also [Admin-Panel-Overview](Admin-Panel-Overview) and [Route-Optimization](Route-Optimization).
## Following a GPX or KML track
Scenic routes are usually published as a track. A day can follow one that is already imported into the trip:
1. Import the file under **Days** with **Import file** in the places panel, with its tracks (GPX) or paths (KML) selected. See [Places-and-Search](Places-and-Search#importing-multiple-places).
2. In Road trip, click the **Track** badge in the day's header.
3. Pick the track. The list shows each track's colour, length and how far it lies from this day, nearest first.
4. Press **Follow this track**.
TREK then places via points where the road strays furthest from the track and routes again, round after round, until the drive is close enough. It reports the result: *6 via points placed. The drive stays within 300 m of the track.* Via points already on those legs are replaced. On the public routing servers this can take half a minute for a long route.
The badge is then tinted, and its tooltip names the track the day follows. **Drop _n_ via points** in the same dialog undoes it.
## Weather warnings and disaster alerts
Switch on **Show hazard areas** under **Current warnings** in the Driving settings. It is off by default and shared by the trip.
- **DWD** weather warnings cover Germany. **GDACS** reports disasters worldwide; up to twelve flood, wildfire or cyclone events are drawn with their affected area.
- Click an area or an event for the source report and when it was last updated, and for GDACS its alert score. An event given only as a point says *Location only; affected area unknown.*
- The feeds are refreshed every ten minutes, and a source that is incomplete or unreachable is labelled as such. Offline, live warnings are unavailable.
- **Warnings are not road closures. Routes stay unchanged.** They are current notices, not forecasts for your travel dates, and the coverage is not exhaustive.
## Booked nights on the drive
A night booked anywhere, whether in the day panel, the booking form, on the phone, in Road trip, through MCP or by a plugin, puts its place on the check-in day as an **Accommodation** stop on the way. The hotel is on the drive without being entered twice.
- **Days** shows the night in the day header as always, and hides the stop so the hotel is not listed twice.
- Moving the booking to another day moves its stop along; deleting the booking removes the stop it created. A stop you placed yourself is left standing.
- The drive uses the booking's **Check-in** as the earliest arrival and the place's stay as its length. The check-out stays a booking detail.
- **Add as an overnight stay** from the search books the night and adds the stop in one go. The night runs to the next day; change the dates under **Days**. On the phone, booking a night works in the desktop planner only.
See [Accommodations](Accommodations#on-the-route) for the details.
## Car bookings with stops
A **Car** booking can carry the stops of its drive between pick-up and return, the way a flight carries its layovers. In the booking form, **Stops along the way** lists them, each with a place and a time; **Add stop** adds one and the arrows put them in order. The booking's line on the map runs through them in that order. This works on the desktop and on the phone, and does not need the addon. See [Transport-Flights-Trains-Cars](Transport-Flights-Trains-Cars).
## Importing a Google Maps route
A route planned in Google Maps can become the stops of a day:
1. In Road trip, open the **…** menu next to the day picker in **Along the route** and choose **Import Google Maps route**.
2. Paste the directions link. Long links, short `maps.app.goo.gl` links and Google's URL-builder links work. The link needs 2 to 30 stops.
3. Check the stops in the preview and choose the **Day**. A stop TREK could not place is marked *Location unresolved; this stop will be skipped.*
4. Import. The stops are appended to that day in their order.
TREK calculates its own route between them; Google's road is not copied. The import needs a connection and permission to edit both places and days. The **List Import** button in the places panel under **Days** (it reads **Google List** when Google is the only list source) accepts the same kind of link.
## On the phone
On a phone the addon adds a **Road trip** tab next to **Plan**. The tab bar holds five sections, so with the other trip addons on, the lists tab moves into **More** while the road trip addon is on, and comes back when it is off. A desktop window made narrower than 768 px switches to this phone layout too.
The tab shows the open day as a chain: where it starts and where it ends, each stop with its stay, the times you set next to the ones worked out, the band where the tank or battery runs out, and the stops a night drive carries into the next morning. On the day you are actually driving, **Up Next** is measured against the clock, with a countdown that turns into *15 min behind plan* once the planned time has passed. The map half of the tab draws that day alone.
- **Tap a stop** for a sheet that writes out what the badges mean, with navigation, a longer or shorter stay, and **End the day here**.
- **Tap a stop's number or icon** to change its kind, the same seven kinds as on the desktop.
- **Tap a leg** for other ways to drive it. They light up on the map before anything is saved.
- **Search along the drive** is two choices: what you are **Looking for**, and **How far**, either *50 km ahead* or **The whole day**. On the day you are driving, *ahead* starts at your next stop; otherwise it starts at the beginning of the day. Fuel and charging offers show the detour and the range they leave, with a button that puts one on the day. Search needs a connection.
Planning is done on the desktop: the Driving settings, reordering and deleting stops, following a track and booking a night. The phone reads the plan and handles what a passenger decides on the road.
## MCP tools
With the [MCP](MCP-Overview) addon on as well, an assistant can plan and check a road trip without an open browser. The server uses the same scheduling, range and day-ending rules as the planner. The road trip tools exist only while the addon is on (`set_assignment_end_day` and `import_trip_gpx` are general tools and always there), and each write needs the same permission as in the browser.
| Tool | What it does | Scope |
|---|---|---|
| `get_roadtrip_context` | Reads the saved days, visits, pinned times, End times, stays, kinds of stop, vias, followed tracks and day endings. | `trips:read` |
| `calculate_roadtrip` | Works out arrivals, departures, day splits, driving limit and range warnings. Missing coordinates and routing failures are reported, not hidden. | `trips:read` |
| `get_roadtrip_settings`, `update_roadtrip_settings` | Read or change the trip's shared driving settings. | `trips:read`, `trips:write` |
| `search_roadtrip_corridor` | Searches along a calculated day, with the same kinds, filters and sources as the panel. It never adds anything. | `trips:read` |
| `list_route_vias`, `add_route_via`, `add_route_vias`, `update_route_via`, `reanchor_route_vias`, `remove_route_via` | List, add, move, re-pin and remove via points. | `trips:read`, `trips:write` |
| `list_day_boundaries`, `set_day_boundary` | Read or set dragged day endings. | `trips:read`, `trips:write` |
| `set_assignment_end_day` | **End the day here** for one visit. | `places:write` |
| `get_roadtrip_hazards` | Reads the current DWD and GDACS notices. | `trips:read` |
| `get_roadtrip_charging_info`, `lookup_roadtrip_charging_info` | Availability and published tariffs, for a charging stop on the trip or for any station by position. | `trips:read` |
| `preview_google_maps_route`, `import_google_maps_route` | Reads a Google Maps directions link, then appends the reviewed stops to a day. | `trips:read`, `places:write` |
| `import_trip_gpx` | Imports a GPX file's waypoints, routes and tracks into the trip. | `places:write` |
Units, limits and the exact fields are on [MCP-Addon-Tools](MCP-Addon-Tools). See also [MCP-Scopes](MCP-Scopes).
## What needs a connection
Road trip planning is online. Routing, the search along the route, via points, dragging day endings, **Find fuel**, charger data, hazard areas and the Google Maps import all need a connection, and the controls say so rather than accepting a change they cannot send.
What TREK contacts, and from where:
| Service | Asked by | When | To change it |
|---|---|---|---|
| OSRM (`routing.openstreetmap.de` by default) | the browser, and the TREK server for MCP | every route | **Own routing engine** |
| Valhalla (`valhalla1.openstreetmap.de` by default) | the browser, and the TREK server for MCP | only when avoiding road classes or offering **No motorway**, **No tolls**, **No ferry** | **Own Valhalla instance**, or not at all once only **Own routing engine** is set |
| TREK's place index and OpenStreetMap | the TREK server | the search along the route (OpenStreetMap through Overpass), and the place lookups of **Add manually** and the Google import (the usual place search) | see [TREK-Places-API](TREK-Places-API) and [Places-and-Search](Places-and-Search), and `OVERPASS_URL` and `NOMINATIM_URL` in [Environment-Variables](Environment-Variables) |
| MobiData BW OCPDB | the TREK server | when a charging stop's data is shown | |
| DWD and GDACS | the TREK server | only with **Show hazard areas** on | switch it off |
| Google short links (`maps.app.goo.gl`) | the TREK server | only to unfold a short link during the Google import | |
## Troubleshooting
| What you see | What it usually means |
|---|---|
| No **Days** / **Road trip** switch | The addon is off. An admin enables it in **Admin → Addons**. On a phone, look for the **Road trip** tab instead. |
| *No route yet* | The trip has no days with places yet. Add places under **Days**, or give a place its coordinates. |
| **No route** on a leg | The routing server did not answer that leg: usually the public servers' limit of about one request a second, sometimes a place the road network cannot reach. TREK retries and asks a refused day one leg at a time; reload later, or set your own engine. |
| *Still working out the rest of the drive* for a long time | A long trip on the public routing servers. Every leg is a request, spaced a second apart. |
| *Daily breaks cannot be calculated until all connecting routes are available.* | A leg is missing. The day endings appear once every leg has routed. |
| *A fixed time conflicts with the drive and daily breaks.* | A time you pinned cannot be reached with the daily travel times. Your time is kept; move it, or change the daily times. |
| *A drive exceeds the daily travel window.* | With **At the last place**, one leg is longer than a whole travel day. Add a place along the way, or choose **Along the route**. |
| A stop you pinned or gave an End shows a late warning | The drive cannot get there in time. The warning says by how many minutes. |
| *Toll roads unavoidable* (or motorways, ferries) on a day | There is no way round on that day. The day uses the road; the other days still avoid it. |
| *Your routing provider does not support avoidance.* | Your own OSRM is set without a Valhalla. Set **Own Valhalla instance** too. |
| Routes stay straight lines after setting your own engine | The server was not restarted, the page was not reloaded, or the browser cannot reach the address (see [Routing engines](#routing-engines)). The browser's developer console shows the blocked request. |
| The search finds nothing where you know there is a charger | It is probably missing from the open data the search reads. Use **Add manually**. |
| *The place search is not answering right now.* or stretches that *could not be searched* | The place index or the OpenStreetMap mirrors did not answer. Search again, or narrow the stretch. |
| *Use a Google Maps directions link.* | The link is not a Google Maps directions link, for example a single place. |
| *The link must contain between 2 and 30 readable stops.* | Too few or too many stops in the link. Split a longer route into days. |
| Via handles do not appear or do not move | Zoom in further. Otherwise you are offline, or you may not edit days on this trip. |
## See also
- [Accommodations](Accommodations): how a booked night becomes a stop on the drive
- [Route Optimization](Route-Optimization): route modes and the day plan's routing
- [Map Features](Map-Features): the planner map
- [Places and Search](Places-and-Search): importing GPX and KML files and Google Maps lists
- [Transport: Flights, Trains, Cars](Transport-Flights-Trains-Cars): car bookings with stops
- [MCP Addon Tools](MCP-Addon-Tools): the road trip tools in detail
- [Admin: Addons](Admin-Addons): switching the addon on
- [Addons Overview](Addons-Overview): the full addon table
+6 -2
View File
@@ -6,7 +6,7 @@ TREK calculates walking and driving times between your places and can reorder th
## Route calculation
TREK uses **OSRM** (Open Source Routing Machine) to calculate routes between consecutive places in the selected day. No API key is required.
TREK uses **OSRM** (Open Source Routing Machine) to calculate routes between consecutive places in the selected day. No API key is required. By default that is the public FOSSGIS OSRM, which allows about one request a second. An admin can point TREK at an OSRM of their own under **Admin → User Defaults** (**Own routing engine**, restart required); see [Road-Trip](Road-Trip#routing-engines).
The route toggle in the day-plan footer offers a **Driving** and a **Walking** profile (each routed on the matching OSRM network). Installed plugins can add further profiles: a plugin with the `routeProvider` hook — for example an e-mobility plugin that plans charging stops — appears as an extra mode next to Driving/Walking. When such a profile is selected, that plugin computes the day's route: its geometry is drawn on the map, planned stops (e.g. chargers) appear as small dots on the line, and the leg connectors show the plugin's travel times plus any note it attaches ("25 min charge"). If the plugin fails or times out, TREK falls back to straight lines exactly as it does on an OSRM outage.
@@ -44,4 +44,8 @@ Two icon buttons in the day's route tools hand the current day to an external ma
Both buttons are on mobile as well, in the day sheet.
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Map-Features](Map-Features) · [Display-Settings](Display-Settings)
## Planning a whole drive
For a trip that is one long drive, the [Road-Trip](Road-Trip) addon adds a **Road trip** view beside **Days**: the whole trip as one chain of legs with arrival times, daily travel times, driving limits, search along the route, via points and avoidance of toll roads, motorways and ferries.
**See also:** [Day-Plans-and-Notes](Day-Plans-and-Notes) · [Map-Features](Map-Features) · [Display-Settings](Display-Settings) · [Road-Trip](Road-Trip)
+139
View File
@@ -0,0 +1,139 @@
# TREK Places API
The TREK Places API is TREK's own place index. It answers place search, the suggestions under the search box, the details of a place picked from it, the category buttons on the map and the geocoding behind imports, with no API key, no quota and no account. In the app it is called the **TREK API**, and a result that came from it carries a **TREK** mark.
It does not replace OpenStreetMap. A search asks both and shows their results together, because each is good at what the other lacks: the index is strongest on businesses such as restaurants, shops and hotels, and OpenStreetMap is where the temples, bridges, viewpoints and stations are. How the two meet in the search box is described in [Places and Search](Places-and-Search).
> **Admin:** there is nothing to set up. The index is on by default on every install and has no switch in the admin panel: whether searches leave the instance is a property of the deployment, so it is decided with environment variables (see [Switching it off](#switching-it-off) and [Running your own copy](#running-your-own-copy)), where a second admin cannot flip it from a browser. **Admin → Settings → API Keys** opens with its card, marked **Recommended default**, and **What is in it** on that card lists the fields and sources described below.
## What it is
The index is built from the places dataset of the [Overture Maps Foundation](https://overturemaps.org), rebuilt monthly, and holds 73.6 million places worldwide. The TREK project serves it from `https://places.liketrek.com`, which is where every install asks unless it is pointed at another copy.
Beside the places themselves, the service keeps what the dataset does not have:
- **Opening hours**, from a layer of 5.7 million objects taken from OpenStreetMap, and after that from the hours a place publishes on its own website for machines to read.
- **Descriptions**, quoted from a place's own website, credited with the site's host name and linked back. About 43 percent of the places in the index carry a website address. The service reads each page once and every instance reads the result from there: your TREK server never opens a business's website itself.
- **An OpenStreetMap layer for suggestions.** It carries the stations, temples and bridges the index lacks, and every name a place is known under, so a suggestion shows the name that matched what you typed, with the name used on the spot underneath when the two differ.
### What it includes and what it does not
| Included | Not included |
|---|---|
| Name, coordinates, category, address, phone, email, website, description, opening hours, a stable id | Ratings, photos of ordinary businesses |
No open dataset has ratings or photos of ordinary businesses, at any price. A Google Maps API key stays the only way to those two; see [With a Google Maps API key](Places-and-Search#with-a-google-maps-api-key).
Names are the ones the index has, which are the names used on the spot. The index has no translations, so the category buttons over Tokyo show Japanese names whatever language TREK is set to.
## Where TREK uses it
| Where | What the TREK API does | When it has no answer or cannot be reached |
|---|---|---|
| Suggestions while typing | Answers on its own, from the index and its OpenStreetMap layer | Google or Amap when one holds the keyed slot, otherwise OpenStreetMap's search service (Nominatim) |
| Full search (search button or **Enter**) | Asked together with OpenStreetMap; the two lists are interleaved, TREK first | OpenStreetMap's answer on its own; the keyed provider only when both are empty |
| Opening a place picked from it | Address, contact details, opening hours and description | The place keeps what was saved with it |
| Category buttons on the trip map | Places of that category around the map centre | The public Overpass mirrors of OpenStreetMap |
| The [Road trip](Road-Trip#search-along-the-route) addon's search along the drive | Fuel, charging, rest areas, campsites and the other kinds it looks for | The public Overpass mirrors |
| Booking imports, and stops given only by name in an imported Google Maps route | The coordinate of a venue, found by its name | OpenStreetMap's search service, which also resolves street addresses |
| Preparing a trip for offline use | Up to 3000 places around the trip, in one request | Nothing is cached, and offline search has nothing to answer from |
| MCP: `search_place` and `search_pois` | The same as the full search and the category buttons | The same fallbacks |
Right-click reverse geocoding on the map does not use it: that is OpenStreetMap's (or Amap's inside mainland China, when Amap holds the keyed slot).
### Why two sources
Measured over 128 places of a real trip, every one of them first found through the old search, the right place was among the first five results 50.0 percent of the time with OpenStreetMap alone, 51.6 percent with the index alone and 72.7 percent with both together. The gain comes from two sources answering instead of one, not from the index on its own. The first result alone is 5.5 points worse than OpenStreetMap alone, because the index always opens the list.
## Licences
What the index returns may be kept. That is what lets TREK store a place you pick from it and copy a trip's surroundings onto your device for offline search, which Google's terms rule out for Google's own results.
| Data | Source | Licence |
|---|---|---|
| Places | Overture Maps Foundation | CDLA-Permissive-2.0; the Foursquare share Apache-2.0, the AllThePlaces share CC0-1.0 |
| Opening hours, and the OpenStreetMap rows in suggestions | © OpenStreetMap contributors | ODbL-1.0 |
| Descriptions | The place's own website | Quoted and linked back, no licence claimed |
The OpenStreetMap layers are kept apart from the place rows and are joined only when an answer is put together, so the share-alike terms of the ODbL stay with the OpenStreetMap data and do not spread to the rest of the index. The service lists all of this at `/v1/attribution`. The name TREK Places API describes the interface, not the origin of the data, and it is not endorsed by the Overture Maps Foundation or the OpenStreetMap Foundation.
## What leaves your instance
Every request goes out from your TREK server, never from a browser, so the service sees your server's address and nobody else's.
| Sent | When |
|---|---|
| The words typed or searched | Suggestions and full search |
| One coordinate to rank results around: the centre of the open day's places, or of the trip's (see [The open day steers the search](Places-and-Search#the-open-day-steers-the-search)) | Suggestions and full search, when there is a hint |
| The map centre, a radius and the categories asked for | Category buttons and the Road trip search |
| The trip's area as a box | Preparing a trip for offline use |
| The index id of one place | Opening a place picked from the index |
| A venue name | Booking imports and route imports |
| An `X-TREK-Instance` header | Every request |
The header carries an opaque token derived from your instance's own address, so the service can rate-limit each instance on its own instead of everyone behind one IP. Set `APP_URL` (or `ALLOWED_ORIGINS`): without either, the token is derived from the port alone, and two unconfigured installs on the same port share one rate-limit bucket.
Who is searching never goes along. No user, account, session, cookie or trip id is sent, and neither is the language TREK is set to. The service's own front page states that queries are not logged, that requests are counted per rate-limit bucket and nothing else, and that the instance token is not stored.
The requests use Node's default HTTP client, so an outbound proxy set with `HTTPS_PROXY` applies to them; see [Environment Variables](Environment-Variables#outbound-https-proxy).
The instance's own [Place Search Log](Places-and-Search#place-search-log) is a different thing: it is off by default, lives in your database and never leaves the instance.
## Switching it off
```yaml
services:
app:
environment:
- TREK_PLACES_ENABLED=false
```
Only the value `false` switches the index off. `0`, `no`, `off` and `FALSE` pass the startup check and leave it on; a value that is not boolean-like at all aborts startup.
With the index off, TREK stops asking it for suggestions, searches, category buttons, the Road trip search, import geocoding and offline downloads, and place search works the way it did before 4.3.0:
- **Full search** goes to OpenStreetMap on an install without a key. With a Google key, Google answers every search, and with Amap selected, Amap does; OpenStreetMap is then no longer asked beside them.
- **Suggestions** come from Google or Amap when one holds the keyed slot, otherwise from OpenStreetMap's public search service. That service's usage policy does not allow autocomplete, so on a keyless install consider pointing `NOMINATIM_URL` at a Nominatim of your own.
- **Category buttons** and the **Road trip search** are answered by the Overpass mirrors.
- **Imports** geocode through OpenStreetMap's search service.
- **Offline search** has nothing to answer from, because no places are downloaded.
The card in **Admin → Settings → API Keys** stays either way: it describes the index and has no switch.
## Running your own copy
`TREK_PLACES_URL` points an instance at a copy of the service you run yourself. It has to answer the same `/v1` API the public service does. Unset or blank means the public service; a trailing slash is stripped, and a value that is not a full URL aborts startup.
The address is read from your own configuration and is not a URL a user can type, so it does not go through the SSRF guard: a copy on your LAN or in the same Docker network works without `ALLOW_INTERNAL_NETWORK`.
> **Helm:** the chart passes only the variables its ConfigMap declares, and `TREK_PLACES_ENABLED` and `TREK_PLACES_URL` are not among them yet. Patch them onto the Deployment; see [How to Set Variables](Environment-Variables#how-to-set-variables).
### Related variables
| Variable | What it steers |
|---|---|
| `TREK_PLACES_ENABLED` | Whether the index is asked at all |
| `TREK_PLACES_URL` | Which copy of the index is asked |
| `NOMINATIM_URL` | The OpenStreetMap half of the full search, right-click reverse geocoding, OpenStreetMap place details and import geocoding |
| `OVERPASS_URL`, `OVERPASS_TIMEOUT_MS` | The Overpass mirrors behind the category buttons and the Road trip search when the index has no answer |
Defaults and details for each are on [Environment Variables](Environment-Variables).
## When the service cannot be reached
Nothing breaks. Every call has a short deadline, 3.5 seconds for anything somebody is waiting on and 20 seconds for an offline download, and every call site falls back to what TREK did before the index existed. After four calls in a row that got no answer or a server error, TREK stops asking for a minute and takes the fallback straight away, so an instance that cannot reach the service does not pay the deadline on every keystroke. The first call after that minute tries again, and one answer resets the count.
| What you see | What it usually means |
|---|---|
| A search lists only **OpenStreetMap** results | The index had nothing for it, or turned down a single common word because there was no location hint to narrow it. Add a place or two to the trip, or open a day, and the index joins in. |
| `TREK Places search failed, falling back: …` in the server log | The same, or the service could not be reached. The text after the colon says which. |
| `TREK Places API unreachable, not retrying yet` in the server log | Four calls in a row got no answer and TREK is waiting out the minute. Check that the server can reach `places.liketrek.com` (or your `TREK_PLACES_URL`) and your proxy settings. |
| `TREK Places area lookup failed: …` in the server log | A trip's surroundings could not be downloaded for offline use. The trip itself still syncs. |
| The category buttons take seconds | They are being answered by Overpass, because the index had nothing for that area or is switched off. |
## See also
- [Places and Search](Places-and-Search): how the index, OpenStreetMap, Google and Amap meet in the search box
- [Offline Mode and PWA](Offline-Mode-and-PWA): keeping a trip on the device
- [Environment Variables](Environment-Variables): every variable named on this page
- [Plugin Cookbook](Plugin-Cookbook#answer-place-searches-from-your-own-index): adding a third index of your own to the search
+3 -1
View File
@@ -47,9 +47,11 @@ The active tab is saved in `sessionStorage` per trip, so switching between trips
## Roadtrip daily start and end times
> The road trip addon has its own page: [Road-Trip](Road-Trip).
Nearby station search results group into count badges when zoomed out. Click a badge to zoom into its stations. Stations that still overlap at close zoom appear in a selectable list. Planned stops, including photo markers, also group into count badges when zoomed out. Day endings remain separate. This works with all supported map providers in Roadtrip mode.
In the Roadtrip view, open **Driving settings** and enter a **Day start** and **Day end** in HH:mm format. Both values enable automatic daily scheduling and connect the drives between days. Clear either field to return to the existing schedule. These preferences belong to the trip. All travellers see the same daily schedule, vehicle settings and driving limits. Members with permission to edit days can change them. Existing trips inherit their owner's previous values once; later changes affect only that trip.
In the Roadtrip view, open **Driving settings** and enter a **Day start time** and **Day end time** in HH:mm format. Both values enable automatic daily scheduling and connect the drives between days. Clear either field to return to the existing schedule. These preferences belong to the trip. All travellers see the same daily schedule, vehicle settings and driving limits. Members with permission to edit days can change them. Existing trips inherit their owner's previous values once; later changes affect only that trip.
Driving pauses at the end time and resumes from the same location at the next day's start time. Stops and visit durations determine where each pause falls. Editing, adding or removing stops recalculates the pauses and subsequent arrivals. If a visit crosses the end time, the remaining visit continues there the next morning before driving resumes.
+4
View File
@@ -31,6 +31,7 @@
- [[Trip Members and Sharing|Trip-Members-and-Sharing]]
- [[Trip Planner Overview|Trip-Planner-Overview]]
- [[Places and Search|Places-and-Search]]
- [[TREK Places API|TREK-Places-API]]
- [[Day Plans and Notes|Day-Plans-and-Notes]]
- [[Map Features|Map-Features]]
- [[Route Optimization|Route-Optimization]]
@@ -47,6 +48,7 @@
- [[Packing Templates|Packing-Templates]]
- [[Todos and Tasks|Todos-and-Tasks]]
- [[Documents and Files|Documents-and-Files]]
- [[Document Sync|Document-Sync]]
- [[Tags and Categories|Tags-and-Categories]]
- [[Calendar Feeds|Calendar-Feeds]]
@@ -69,6 +71,7 @@
- [[Atlas]]
- [[Journey Journal|Journey-Journal]]
- [[Collections]]
- [[Road Trip|Road-Trip]]
- [[Dashboard Widgets|Dashboard-Widgets]]
## Plugins
@@ -80,6 +83,7 @@
## Integrations
- [[Public API|Public-API]]
- [[Dawarich]]
## AI / MCP
- [[MCP Overview|MCP-Overview]]