Every page was read against the code on dev. What changed:
- Pages that described 4.2 behaviour: satellite view on the vector maps,
the mobile journal timeline, Collab with its fifth tab, the Review badge,
clustered pins on the share page, the Leaflet preset list, the strict
guard on fe80::/10, the invite link tools and their scopes, the Public
API scope rules, the permission count in the plugin SDK.
- Features of this release that no page mentioned: videos in a journal
entry, receipts on an expense, the Google transit backend, routing
counters, the rating on a place, the navigation menu, car stops, the
manual school holiday catalogue and its MCP tools, the Dawarich panel in
the Atlas, the release notes modal, plugin frames going fullscreen, the
corridor call into the search provider hook.
- Statements that sent an admin the wrong way: DEFAULT_LANGUAGE is not in
the Helm ConfigMap, env.PORT cannot be changed on the chart alone, the
rotation script does not cover the document sync credentials, event
handlers cannot broadcast, there is no per user MFA reset in the admin
panel, the demo user can edit, an unparsable APP_URL stops the server.
- Updating gets a section for 4.3.0: the TREK Places API as the new
default, the new variables, the Overpass timeout, SSO sessions on an
OIDC only instance, the migration that puts booked nights on the drive.
A key could only ever read everything a user owns. When a second service
reads TREK on that user's behalf, that is more than it needs: Dawarich
wants trips, days and places, not notes, bookings or the wish list.
Keys can now be minted with an explicit list of areas, checked in the
guard and shown when the key is listed. Keys that existed before this
keep full read access, so nothing that works today stops working. A key
marked as limited whose list cannot be read grants nothing rather than
everything.
Homepage's customapi widget and everything shaped like it want a handful
of numbers from one request; /api/v1/trips hands out the rows, but a
widget maps fields, it cannot aggregate a list.
The figures come from AtlasService.getTravelStats, the same call behind
the dashboard's passport card, rather than from a second count. Visited
countries carries years of rules — countries reached only by a flight,
layovers that do not count, countries hidden by hand — and a second
implementation would disagree with the card next to it within a release.
That is also why the controller sits in atlas/ and not in public-api/:
PublicApiModule stays a leaf, so the route comes to the data instead.
TravelStatsController next door already does this for
/api/auth/travel-stats. ApiTokenGuard is provided locally rather than
imported with PublicApiModule — @UseGuards instantiates a guard in the
declaring controller's module, so an export would still leave its
TokenService unresolvable here.
last_trip means the most recently started trip, not the most recently
created one, and is null while every trip is still ahead.
Closes#1367
Reading the surface back against real data turned up three things it dropped
without saying so.
Places with no day were invisible, because the payload only reached places
through day_assignments. On a live instance that is half of them, and they
are the ones carrying a coordinate and no claim about when — exactly what an
integration can act on. They come back under `unplanned_places`, minus the
hotel, which is already reported as an accommodation.
Bookings with no day were dropped by the day filter. reservations.day_id is
nullable and deleting a day detaches its bookings rather than removing them,
so this is not a hypothetical.
The bucket list had no endpoint at all. It hangs off the user rather than a
trip, so it gets its own, and it answers whether or not the Atlas addon is
switched on: the addon decides what TREK shows, not what a key can read.
Also fixes ?include=notes returning the bare trip: places, notes and
reservations are reported on days, so asking for one now implies days
instead of quietly answering with nothing.
The module stays a leaf. Reaching for AtlasService pulled AuthModule and the
storage registry in behind it and broke the surface's own boot, so the one
SELECT lives here like every other query in the file.
An MCP token drives every assistant tool; an API key reads trips over HTTP.
Handing the same credential to a third-party integration gives it the whole
MCP surface, so the two are now separate kinds on `mcp_tokens` and the kind
sits in the WHERE clause — a token of the wrong kind is indistinguishable
from one that does not exist.
Also adds `travellers` to the trip payload: display name and an owner flag,
no ids and no email addresses. An integration key reads its owner's
itinerary; it is not a way to enumerate the people around them.
Documents the surface in the wiki, since integrators need something to read
that is not the source.