docs: document web.min_web_version, batched route search and merge-commit releases (#20)

This commit is contained in:
MrAlders0n authored and GitHub committed 2026-10-09 23:05:49 -04:00
1 parent fd5f4bdae3
commit 182010dbc6
5 files changed
+37 -20

No files matched your search

+9 -6
View File
@@ -271,13 +271,16 @@ websocket:
#observers:
# delete_after: 720h # opt in to 30 days unseen
# BEACON Mobile settings, published unauthenticated at GET /api/v1/info.
# min_app_version: oldest app release allowed to use this server. Older apps
# show an "update required" screen for this server. Strict X.Y.Z (digits only,
# no "v" prefix or -beta suffix); any other value prevents startup.
# Omitted or empty (default) means no requirement. Takes effect on restart.
# Minimum client versions, published unauthenticated at GET /api/v1/info.
# Older clients show an "update required" screen for this server. Each server
# release has a built-in floor; these settings can raise it, never lower it.
# Strict X.Y.Z (digits only, no "v" prefix or -beta suffix); any other value
# prevents startup. Omitted or empty (default) means the built-in floor only.
# Takes effect on restart.
#mobile:
# min_app_version: "0.1.1" # default: "" (no requirement)
# min_app_version: "0.1.1" # BEACON Mobile; built-in floor: none
#web:
# min_web_version: "2.0.3" # Beacon Web; built-in floor: 2.0.3
# CORS configuration.
# Controls which origins, methods and headers are allowed for cross-origin requests.
+16 -9
View File
@@ -430,8 +430,8 @@ Known routes are fully resolved multi-hop paths distilled from packet history.
| Endpoint | Notes |
|---|---|
| `GET /routes` | Plain array, newest `lastSeen` first. Params: `iata`, `hopCount`, `cursor` (last item's `lastSeen`, epoch ms), `cursorId` (last item's `id`), `limit` (default 50). |
| `GET /routes/search?iata=&from=&to=` | Routes in one IATA between two node hash prefixes (hex). All required. |
| `GET /routes/cross?fromIata=&fromHash=&toIata=&toHash=` | Routes that cross IATA boundaries. All required. |
| `GET /routes/search?from=&to=[&iatas=]` | Routes within one IATA between two node hash prefixes. `from`, `to` required (hex, 1–4 bytes; widths may differ). `iatas` optional: comma list, at most 100, omitted = every IATA; the single `iata` is still accepted. At most 500 results, shortest first. `hops` is trimmed to source…destination and `hopCount` = `hops.length`. |
| `GET /routes/cross?fromHash=&toHash=[&iatas=]` | Routes that cross from one IATA into another. `fromHash`, `toHash` required. `iatas` optional: 2–100 codes, omitted = every IATA. The legacy `fromIata`+`toIata` pair is still accepted, but not together with `iatas`. At most 500 results, sorted by `totalHops`, then `crossHop.lastSeen` newest first. |
| `GET /routes/{iata}/{pathKey}/observations` | Retained reports that match a saved route exactly. `pathKey` comes from a route response. Window: `range` (default `24h`, max `720h`) or `since`+`until` (max 30 days); `pageCursor` for the next page; `limit` default 50. |
To page `/routes`, send the last item's `lastSeen` as `cursor` and its `id` as `cursorId`. Routes share a millisecond often (one batch of upserts), and `cursorId` returns the ones that didn't fit on the previous page. `cursor` alone still works but can skip those ties. `cursorId` must be a positive integer and requires `cursor`; otherwise `400`.
@@ -451,7 +451,9 @@ To page `/routes`, send the last item's `lastSeen` as `cursor` and its `id` as `
}
```
`/routes/cross` returns `[{ sourceSegment, crossHop, targetSegment, totalHops }]`, where the segments are hop arrays as above and `crossHop` is `{ fromNode, toNode, fromIata, toIata, lastSeen }`.
`/routes/cross` returns `[{ sourceSegment, crossHop, targetSegment, totalHops }]`, where the segments are hop arrays as above and `crossHop` is `{ fromNode, toNode, fromIata, toIata, lastSeen }`. `sourceSegment` runs from the source node to the boundary node and `targetSegment` from its neighbor across the boundary to the destination node; `fromNode`/`toNode` are that boundary pair (the last and first hops of the segments). `totalHops` is the two segment lengths combined.
Both searches return `400` for bad input, and also `hash matches too many areas; use a longer hash or fewer iatas` when a short hash resolves in too many IATAs; show that message to the user. A search that hits the 15s timeout returns `503`.
The observations endpoint returns `{ items, hasMore, nextPageCursor, route, windowStart, windowEnd, generatedAt, matchType, matchAvailable, hashSize, pathBytes }`. Each item is `{ id, packetHash, observerId, observerName, heardAt, payloadType, payloadTypeName, rssi, snr }`. It matches on the route's full path bytes, hash size and hop count within its IATA; `limit` is capped at 200. Evidence expires with raw packets, so a route can outlive every observation that produced it.
@@ -600,22 +602,27 @@ GET /api/v1/info
Public, no key. Counts against the normal rate limit and is sent with `Cache-Control: no-cache`.
```json
{ "minAppVersion": "0.1.1", "serverVersion": "2.0.3" }
{ "minAppVersion": "0.1.1", "minWebVersion": "2.0.3", "serverVersion": "2.0.4" }
```
`minAppVersion` is the server's `mobile.min_app_version`: the oldest BEACON Mobile release
allowed to use this server, as a strict `X.Y.Z` string, or `null` when the operator has not set
one. `serverVersion` is the server's API version (`X.Y.Z`, no `v`), the same value Swagger shows. Servers
older than this endpoint return `404`. See
`minAppVersion` and `minWebVersion` are the oldest BEACON Mobile and Beacon Web releases allowed
to use this server, as strict `X.Y.Z` strings, or `null` when there is no requirement. Each is the
higher of the server's built-in floor and the operator's `mobile.min_app_version` /
`web.min_web_version`. `serverVersion` is the server's API version (`X.Y.Z`, no `v`), the same value
Swagger shows. Servers older than this endpoint return `404`. See
[Mobile-specific concerns](#mobile-specific-concerns) for how the app uses it.
Beacon Web calls `/info` on load and again when the tab regains focus (at most once a minute). When
its own version is lower than `minWebVersion` it shows a full-screen "reload" screen instead of the
app. A `404`, a `null` or malformed value, and network errors never block.
### Admin
All under `/api/v1/admin/`, bearer key required (see [Auth](#auth)).
| Endpoint | Notes |
|---|---|
| `GET /admin/config` | Running CORS settings with defaults applied, `auth.configured`, and `ingest.broker_count` (configured broker workers, not connection status), and `mobile.min_app_version` (read-only; `""` when unset). No credentials, broker addresses, channel material or database settings. |
| `GET /admin/config` | Running CORS settings with defaults applied, `auth.configured`, `ingest.broker_count` (configured broker workers, not connection status), `mobile.min_app_version` and `web.min_web_version` (read-only effective floors; `""` when there is none). No credentials, broker addresses, channel material or database settings. |
| `PUT /admin/config` | Replaces `cors.allowed_origins` until the next restart. JSON body up to 16 KiB. |
| `GET /admin/accounts`, `POST /admin/accounts` | List or create operator account records (name only; not logins). |
| `GET /admin/accounts/{id}`, `DELETE /admin/accounts/{id}` | Fetch or deactivate one. |
+2 -1
View File
@@ -84,6 +84,7 @@ which ones to read.
| `nodes` | When a node is marked stale, when it is deleted, the clock-drift threshold, and the optional foreign repeater flag. | You want `possiblyForeign` on repeaters. |
| `observers` | Optional deletion of observers not seen for a long time. Off by default. | Rarely. |
| `mobile` | `min_app_version`: the oldest BEACON Mobile release allowed to use this server. Older apps show an update screen. Unset by default. | You need users on a newer app release. |
| `web` | `min_web_version`: the oldest Beacon Web release allowed to use this server. Older web builds show a blocking "reload" screen. The server has a built-in floor (2.0.3 today); this can raise it, not lower it. | Your web container lags the server and you want stale browsers to reload. |
| `cors` | Browser cross-origin rules for REST. Default allows any origin, read-only methods. | You are building an admin UI on another origin. |
| `cache` | Redis TTLs per response category. | Rarely. |
| `ingest` | Only store packets from observers in listed countries or continents. | You run a regional instance and want to ignore the rest of the world. |
@@ -103,7 +104,7 @@ cannot honour. These are the ones people hit:
- A `borderFile` that is missing or not a valid GeoJSON Polygon or MultiPolygon Feature, or
`nodes.mark_foreign: true` with no border source at all.
- `log.level` or `log.format` set to anything other than the listed values.
- `mobile.min_app_version` that is not a plain `X.Y.Z` release (`v1.2.3` and `1.2.3-beta` are rejected).
- `mobile.min_app_version` or `web.min_web_version` that is not a plain `X.Y.Z` release (`v1.2.3` and `1.2.3-beta` are rejected).
- An admin key under 16 characters or containing whitespace.
- A negative `ratelimit.requests_per_minute`, `ratelimit.burst` or `websocket.max_connects_per_minute`.
A negative `websocket.max_connections_per_ip` is not caught at startup and rejects every
+6 -4
View File
@@ -39,12 +39,14 @@ signed. The flow is the same in both repos; only the version bump differs.
- beacon-web: `version` in `package.json`.
Commit as `chore: bump version to vX.Y.Z`.
3. Fast-forward `main` to `dev`: `git checkout main && git merge --ff-only dev`.
4. Tag and push: `git tag vX.Y.Z && git push origin main --tags`.
3. Open a PR from `dev` into `main` titled `Release vX.Y.Z` and merge it with **Create a merge
commit**. `main` only accepts merge commits, so `dev`'s own commits land on `main` and the next
release PR lists only what is new.
4. Tag the merge commit and push it: `git tag -a vX.Y.Z origin/main -m "vX.Y.Z" && git push origin vX.Y.Z`.
5. The tag builds and publishes the container image in both repos. In beacon-server it also
builds binaries for every supported platform and attaches them to a draft GitHub release.
Open the draft, paste the release notes and publish it.
6. Rebase `dev` on `main` so the histories stay in sync: `git checkout dev && git rebase main`.
Open the draft (or create the release in beacon-web), paste the release notes and publish it.
6. Fast-forward `dev` to `main` so the branches match: `git push origin origin/main:dev`.
## Where to find release notes
+4
View File
@@ -93,6 +93,10 @@ docker compose up -d
Database migrations run when the server starts. Read the release notes first; a release that
needs a config change says so there. Keep server and web on the same `X.Y`.
Since server 2.0.4, a server can require a minimum Beacon Web version (`minWebVersion` at
`GET /api/v1/info`; see `web.min_web_version` in [Configuration](configuration.md)). An older web
build shows a "reload" screen instead of the app, so pull the web image together with the server.
## MeshMapper API authentication rollout
When upgrading to a Beacon build with MeshMapper API authentication, configure the key