Commit Graph
76 Commits
Author SHA1 Message Date
MrAlders0n 9bbf8efee5 release: v2.0.4 (#217)
* perf(routes): batch cross-IATA and hash route search (#216)

One search fired a /routes/cross request per IATA pair (138k on 2026-10-08). Route search now takes an optional iatas list and runs a fixed number of index-backed queries. /info advertises built-in minimum client versions.

* chore: bump version to 2.0.4
2026-10-09 22:17:23 -04:00
MrAlders0n 041d9c1f45 release: v2.0.2
Release the changes on `dev` as v2.0.2: authenticated MeshMapper imports and the traffic-sorted observer directory, including rolling seven-day counts from available history. Bump the API version and regenerate Swagger.

MeshMapper integration requires an API key. Regional admins’ existing per-region or grouped-region coverage keys also work for these APIs. Deployments should set `MESHMAPPER_API_KEY` and restart Beacon.

Validation: `go build ./...`, `gofmt -l .` (empty), `go vet ./...`, `go test ./...`, `govulncheck ./...`, and race tests for MeshMapper and scopestore passed in a clean checkout. PostgreSQL integration tests require CI because Docker is unavailable locally.
2026-10-05 18:35:41 -04:00
MrAlders0n 4ad869d711 fix(db): page known routes by (last_seen, id)
The cursor was the last row's last_seen in ms, so routes sharing that
millisecond (common within one upsert batch) never came back. GET /routes
takes an optional cursorId, backed by keyset indexes; cursor alone keeps
working as before.
2026-10-02 19:03:46 -04:00
MrAlders0n 2f4f92e31e fix(db): tie-safe trace paging, atomic migrations and honest stats windows
GET /traces takes an optional cursorTag so tags sharing a millisecond survive
paging. Migrations run under an advisory lock and record each file in the
same implicit transaction, so a crash can't strand a fresh database.
Overview windowHours counts the hours it covers, hourly observer activity
fills unrolled hours from raw rows, and integration fixtures are UTC.
2026-10-02 16:53:32 -04:00
MrAlders0n 5ccb1a2ce3 fix(api): warn on untrusted proxies and tighten config validation
Warn at startup when limits are on without trusted_proxies, and once when a
request carries forwarding headers Beacon ignores. Reject short or whitespace
admin keys and negative durations. Key default-window stats by hour, return
500 for scope lookup failures, and validate IATA path params.
2026-10-02 16:53:32 -04:00
MrAlders0n 98006a9364 feat(stats): serve historical stats from hourly rollups
Stats endpoints read hourly rollup tables filled once per closed hour by one
advisory-locked task, instead of materialized views that re-scanned every
observation on each refresh. IATA-set tables give exact distinct counts for any
IATA set or region. Cleanup holds raw rows for unrolled hours (up to 24h).

Adds /stats/series; ingest keeps packet observation counts, observer last IATA,
channel message counts and trace tag summaries. 001_baseline.sql is rewritten,
so pre-release 2.0 databases must be recreated. See docs/historical-stats.md.
2026-10-02 07:43:56 -04:00
MrAlders0n 119be44c0d feat(channels): filter channel list by keyKnown
Also seed the cursor integration test with MeshMapper membership; it still
used channel_iatas after channel lists moved to region scoping.
2026-10-01 09:06:50 -04:00
MrAlders0n 2f49ffb3a3 feat(api): filter scope lists by region and catalogue membership
Region-filtered /scopes and /stats/scopes now list manual scopes configured
for the region and imported scopes whose MeshMapper catalogue includes the
IATA, instead of inferring membership from observed traffic. Filtered
/scopes returns string[] like the unfiltered call.

Manual scopes now require a region in config.
2026-09-30 22:05:04 -04:00
n30nex c448a04ea0 feat(routes): add bounded retained observation evidence 2026-09-30 07:19:03 -04:00
n30nex 5fbba24a4a fix(observers): separate packet metrics from presence updates 2026-09-30 07:19:02 -04:00
n30nex 8a3fa7e6bf feat(stats): add bounded path and hash-width analytics (#159) 2026-09-23 20:18:41 -04:00
n30nex 6107578c25 feat(stats): add bounded reception signal analytics (#157) 2026-09-23 20:16:22 -04:00
n30nex cf5ff7a974 feat(stats): compare flood packets reported by two observers (#152)
* feat(stats): compare distinct flood packets across observers

* test(stats): use the migrated observation deduplication key
2026-09-19 10:36:39 -04:00
n30nex bcdea76c26 feat(stats): filter scope counts by IATA and region (#142)
* feat(stats): filter scope counts by IATA and region

* perf(stats): aggregate region observations before counting scopes
2026-09-18 06:18:06 -04:00
MrAlders0n b66573b3b7 feat(observers): per-observer activity endpoint (#135) 2026-09-10 06:53:00 -04:00
n30nex f390086058 fix(channels): preserve timestamp ties in page cursors (#132) 2026-09-09 20:25:07 -04:00
Enot (ded) Skelly 336b734a42 feat: add stats api for new clock drift tracking
closes: #91
2026-07-24 14:01:12 -07:00
Enot (ded) Skelly 3f2506fc8b feat: add geojson for iatas
closes #66
2026-07-24 12:59:48 -07:00
MrAlders0n dff9c6cf00 perf(channels): track channel activity per IATA in its own table
The IATA filter ran a correlated EXISTS over packets/observations with
ILIKE, which skipped the iata index and took ~7s live. Keep a small
channel_iatas table at ingest (like node_iatas) and filter against it.
Also honor the iatas= param so multi-site regions stop getting the
global list. Filter now ages out with packet retention rather than
matching any retained packet.
2026-07-24 12:07:05 -07:00
Enot (ded) Skelly b33ebc007b feat: add plural value filter params
closes #76
2026-07-23 14:26:16 -07:00
Enot (ded) Skelly b38663d3a1 feat: add stats for top advertiser and talkers
closes #75
closes #74
2026-07-23 10:41:16 -07:00
Enot (ded) Skelly 0ca28cc6a8 feat: node prefix search
pubkeyPrefix takes any even length prefix string case-insensitive
and returns all matches
2026-07-23 10:14:47 -07:00
MrAlders0n 30772da2c5 perf(packets): drive IATA-filtered list from the observation index
Quiet sites probed hundreds of thousands of packets to fill a page.
Walk idx_observations_iata_heard per requested site and dedup instead.
Filtered lists now order by site-local recency; the cursor follows.
2026-07-20 09:07:05 -07:00
Enot (ded) Skelly 4e2ee62bad feat(nodes): add ?neighbors to list nodes
inlcudes neighbor IDs in node details list
2026-07-02 09:12:23 -07:00
Enot (ded) Skelly b58e5a1edc feat(api): differentiate traces and pings 2026-06-11 14:52:31 -07:00
Enot (ded) Skelly 205eaafbe9 feat(stats): add node type breakdown
/stats/node-types w/ filters for iata/region

closes #55
2026-06-10 13:18:26 -07:00
Enot (ded) Skelly a9b0025b1d fix(stats): support multiple IATAs and region filtering on all stats endpoints
closes: #53 and #54
2026-06-10 09:52:02 -07:00
Enot (ded) Skelly cda4905815 docs: update SPDX license lines 2026-06-08 16:08:39 -07:00
Enot (ded) Skelly 14cb9e6e2d docs: add APGL3 license 2026-06-08 15:46:01 -07:00
Enot (ded) Skelly 4147a93e8b feat(observers): add telemetry bucketing to rest api
closes #37
2026-06-08 12:32:22 -07:00
Enot (ded) Skelly fef8c8d7b6 docs: improve reader interface comment readability 2026-06-08 11:47:38 -07:00
Enot (ded) Skelly 149452f066 feat(routes): add resolved hop nodes to known routes API
closes #44
2026-06-08 11:30:26 -07:00
Enot (ded) Skelly 32e6e9939a feat: cross iata routes
adds cross iata route finding

closes #42
2026-06-08 10:30:49 -07:00
Enot (ded) Skelly 7d25b8480f feat: node neighbors
limited to repeaters and room servers

stores high confidence matches from the nodes advert
packet path first hops
2026-06-08 09:36:20 -07:00
Enot (ded) Skelly c792029d3d fix: routes pagination cursor
closes #41
2026-06-06 11:14:13 -07:00
Enot (ded) Skelly 65cb8c9d61 add routes api
any route observer where all hops are high confidence
are now stored and available at /routes

you can also search for a src dest route and it will
return any recored route subset that can link the src
and dest hash
2026-06-05 15:57:08 -07:00
Enot (ded) Skelly f0c57fde45 add traces endpoint 2026-06-05 15:20:53 -07:00
Enot (ded) Skelly ae14d948d0 add scopes api 2026-06-05 12:31:35 -07:00
Enot (ded) Skelly 588b3705c9 add packet and message backfill api
/packets/backfill, /messages/backfill

both take afterId and limit. the id is the message or
packet observation last received to backfill after
2026-06-05 12:05:24 -07:00
Enot (ded) Skelly a943660778 rename to beacon 2026-06-05 08:10:43 -07:00
Enot (ded) Skelly a9fc1ac147 refactor api package 2026-06-04 14:10:49 -07:00
Enot (ded) Skelly ec7cf67a10 add trace route resolution
packet details now includes resolved route
2026-06-04 11:58:45 -07:00
Enot (ded) Skelly 594cd7281e add scope stats api endpoint 2026-06-04 11:17:58 -07:00
Enot (ded) Skelly 1e5ccc6e50 add filter by scope to messages
also adds the multi iata filter from other endpoints
for messages now on both routes
2026-06-04 11:07:54 -07:00
Enot (ded) Skelly fcc7bb1b23 add transport scopes
new config for transport scope keys seeded to db

new transport keystore to lookup matching keys and tag
- packets with scope key
- nodes with default scope
- observers with all supported scopes it forwards

allow filtering by region scope key on: packets, nodes, observers
2026-06-04 10:32:03 -07:00
Enot (ded) Skelly cba1690470 add region filter to observers 2026-06-03 15:07:36 -07:00
Enot (ded) Skelly 67e60de76f add region filter to nodes 2026-06-03 14:59:26 -07:00
Enot (ded) Skelly a49c64b4b5 add region filtering to packets 2026-06-03 14:37:18 -07:00
Enot (ded) Skelly 8c71277de8 add radio-presets stats 2026-06-03 13:56:31 -07:00
Enot (ded) Skelly 984a49deb1 feat: propagation time 2026-06-03 11:38:38 -07:00