Commit Graph

131 Commits

Author SHA1 Message Date
Alex Vanderpot 1940f995dc Merge pull request #34 from ajvpot/neighbor-refreshable-mvs
Speed up neighbors with hourly refreshable materialized views
2026-05-29 03:03:10 -04:00
Alex Vanderpot 02623e5559 neighbors: seattle->letsmesh region + fix path-edge prefix extraction
- Point the seattle region at the letsmesh broker (wss://mqtt-us-v1.letsmesh.net:443,
  topic meshcore/SEA) where Seattle traffic now lives.
- Fix a pre-existing bug in the path-edge extraction: `path` is a hex string of
  1-byte hop prefixes, so use substring(path, 2*i-1, 2) instead of
  hex(substring(path, i, 1)) (which re-hexed a single hex char and never matched
  the 2-char repeater prefixes -> path edges were always empty). Seattle now yields
  path edges again.

Verified on a full prod snapshot: the MV-backed "show all neighbors" query drops
from ~1.6s / 145M rows / 11.8 GiB to ~1ms / 108 rows / 3.8 KiB.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 03:02:09 -04:00
Alex Vanderpot cab5d821cf neighbors: serve from hourly refreshable materialized views
The two slow neighbor queries are converted to read precomputed tables that an
hourly REFRESH EVERY 1 HOUR materialized view maintains, instead of re-aggregating
meshcore_packets per request:

- meshcore_all_neighbor_edges: the global per-region edge graph (direct path_len=0
  adverts + repeater-prefix path edges) with endpoint details. getAllNodeNeighbors
  now filters it by region + bbox + lastSeen + has_location.
- meshcore_node_direct_neighbors: per-node direct adjacency (both directions) with
  neighbor details. getMeshcoreNodeNeighbors now filters it by node_public_key.

Also add the meshcore/SEA topic to the seattle region. Validated on a clean local
stack: migration 001->003 applies, both refreshable MVs create + refresh + populate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 02:33:57 -04:00
Alex Vanderpot 49847c46af Merge pull request #33 from ajvpot/release-ingest
add ingest code: monorepo + one-command deploy
2026-05-29 01:51:20 -04:00
Alex Vanderpot 6be73b04a6 clickhouse: lift readonly read-size caps
The readonly profile's max_rows_to_read / max_bytes_to_read (500MB) is exceeded by
the map/stats views, which scan the full (growing) meshcore_packets table -> the web
app failed with TOO_MANY_BYTES. Remove the read-size caps; readonly=1, allow_ddl=0,
max_memory_usage and max_execution_time remain the guardrails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:48:56 -04:00
Alex Vanderpot 7785158934 clickhouse: cap system log growth (TTL + disable profiler)
ClickHouse's internal diagnostics grew unbounded (text_log at Trace level and the
1s query profiler -> trace_log accumulated ~160G over months). Add short TTLs to
all system *_log tables, cap text_log at warning level, and disable the query
profiler in both profiles so trace_log stays empty.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:46:04 -04:00
Alex Vanderpot c233952840 pin clickhouse to 25.6.2.5 and grafana to 12.1.1
Pin the bundled service images to known versions for reproducible releases and
safe in-place reuse of an existing data dir (matching the production deployment).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:28:01 -04:00
Alex Vanderpot e6c4200448 Provision MeshCore Grafana dashboard
Add the MeshCore dashboard (exported from prod) as a provisioned file
dashboard, with a file provider config. Pin the ClickHouse datasource
uid to "clickhouse" so the dashboard's panel datasource references
resolve at provision time.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:24:02 -04:00
Alex Vanderpot 78bf1c5855 add Grafana service with provisioned ClickHouse datasource
Bundle Grafana (127.0.0.1:3000) with the grafana-clickhouse-datasource plugin
and an auto-provisioned ClickHouse datasource using the read-only user. Adds
GRAFANA_ADMIN_PASSWORD to .env.example. Verified: datasource health returns OK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:19:42 -04:00
Alex Vanderpot 384f7f8b14 ingest: fix go module path to match repo
Module is now github.com/ajvpot/meshexplorer/ingest (the code lives under
ingest/ in the meshexplorer repo), updated from the old standalone
clickhouse-meshingest path. build/vet/test pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:19:42 -04:00
Alex Vanderpot b7bcca6bf3 release-prep: docs, migration dialect fix, drop unused UDF
- Add a deploy-focused root README; update the web app README (meshcore-only,
  point Docker usage at the unified root compose).
- Fix the migration runner: set the goose clickhouse dialect (it defaulted to
  postgres and failed to create its version table). Migrations now apply cleanly.
- Remove the unused meshcore decrypt UDF (meshcore_try_decrypt was never called
  by any view/query/code) and simplify the ClickHouse image to a single stage.

Verified end-to-end: `docker compose up` brings up clickhouse -> migrate ->
meshcoreingest + meshexplorer; live ingestion from the real MQTT brokers lands
packets in ClickHouse and the web API serves decoded meshcore nodes via the
readonly user.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:01:33 -04:00
Alex Vanderpot 6a1536410c release-prep: unified docker-compose + .env.example
Single root compose brings up the whole stack on one internal network:
clickhouse (healthchecked) -> migrate (one-shot) -> meshcoreingest + meshexplorer,
with the discord-bot behind a "bot" profile. Web app/bot connect as the readonly
ClickHouse user; ingest/migrate use the default user. Named volume replaces the
host /tank path. .env.example documents every variable with placeholders; root
.gitignore keeps real .env out of git. Drops the per-project compose files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:01:33 -04:00
Alex Vanderpot cd1a345242 release-prep: remove meshtastic from web app
Meshtastic was UI-filtering only (no meshtastic data backend). Drop it as a
node type/option, and simplify the map marker/cluster/popup rendering now that
every node is meshcore. Update product copy to MeshCore-only. The nodeTypes
query plumbing stays (the unified view's type is always 'meshcore').
Production build passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:01:33 -04:00
Alex Vanderpot 83978609f0 ingest: meshcore MQTT->ClickHouse stack
Vendor the ingest service under ingest/ and move the web app under meshexplorer/.
The ingest builds the meshcoreingest daemon and the goose migration runner,
applies the meshcore ClickHouse schema (packets, adverts, unified node view),
and loads its MQTT broker list and ClickHouse settings entirely from environment
variables (MQTT_BROKERS as a JSON array, CLICKHOUSE_*). No credentials are baked
into the source.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 01:01:33 -04:00
ajvpot 815d465566 Bump nextjs 2026-01-06 03:11:33 +01:00
ajvpot e6e74589c1 save map position, stroke width slider 2025-09-29 18:06:11 +02:00
ajvpot b173351011 path display overhaul 2025-09-23 04:04:17 +02:00
ajvpot 665b91f1fa add analyze links to PathVisualization 2025-09-23 03:13:10 +02:00
Alex Vanderpot 580c315a20 Merge pull request #24 from CoryNQ1E/main
Support Lowercase Public Keys in Node API Endpoints
2025-09-22 19:38:14 -04:00
ajvpot b12d570142 analyze link in discord bot relay 2025-09-23 01:28:47 +02:00
ajvpot add14fa37b fix concurrency in bot 2025-09-23 00:05:56 +02:00
ajvpot b296017331 Add anchors to stats pages (closes #26) 2025-09-19 17:43:00 +02:00
ajvpot a1416bcc05 handle numeric values in useQueryParams (closes #25) 2025-09-19 17:34:12 +02:00
ajvpot f34836763c min packet thresh 2025-09-18 01:58:48 +02:00
ajvpot 4faa6491c2 ui rearranging 2025-09-18 01:53:15 +02:00
ajvpot 0f1327469d hide meshcore overlay setting 2025-09-18 01:41:52 +02:00
ajvpot f3ad947b9a All neighbors, map layer settings 2025-09-18 01:40:45 +02:00
ajvpot fe6e44cc80 path magic 2025-09-17 17:46:43 +02:00
ajvpot ea32ccea77 support # channels 2025-09-15 23:03:29 +02:00
ajvpot ed9943e091 missing file 2025-09-15 22:52:25 +02:00
ajvpot 4c7e7d8e1c highlights for discord 2025-09-15 04:36:14 +02:00
ajvpot 0aac045c1b discord bot: support threads 2025-09-15 04:14:58 +02:00
ajvpot 9f1056095b all neighbors 2025-09-15 04:14:50 +02:00
ajvpot 7addbb3165 update stats and path viz to use 2 day last seen time 2025-09-14 18:26:47 +02:00
ajvpot e41dfe83d3 stuff 2025-09-14 18:25:56 +02:00
ajvpot 3ade624a51 emoji 2025-09-13 03:31:30 +02:00
ajvpot 8ac7d5eece Discord bot, profile picture endpoint, channel management ux, streaming apis, refactor region logic 2025-09-13 02:57:52 +02:00
ajvpot 2afbe80c1b fix clickhouse constructor 2025-09-11 18:29:27 +02:00
ajvpot 1dd6781113 override region for node info page with detected region info 2025-09-11 18:28:12 +02:00
ajvpot 46606abbf9 Replies/highlights 2025-09-11 17:53:13 +02:00
CoryNQ1E 170bcf394a Support Lowercase Public Keys in Node API Endpoints 2025-09-10 13:45:05 -07:00
ajvpot cdd66725ec fix build 2025-09-10 03:52:26 +02:00
ajvpot 93cfd969a8 link target for embed view 2025-09-10 03:49:39 +02:00
ajvpot fbe31eb092 create embeddable map view, finish migration to route groups 2025-09-10 03:42:31 +02:00
ajvpot 6171bf812a restructure: use app route group and replace relative imports with @ imports 2025-09-10 03:21:40 +02:00
ajvpot 6fab8a112a move stats to tanstack query, implement cancelation 2025-09-10 02:47:44 +02:00
ajvpot a5638fe924 fix search params for path vis 2025-09-10 02:17:24 +02:00
ajvpot f92895ca8f optimize neighbors, fix aggregation 2025-09-10 02:12:18 +02:00
ajvpot 83b41619ac Store map lat/lng, fix state handling 2025-09-10 01:58:26 +02:00
ajvpot e43dd51336 persist selectedtab in usequeryparams 2025-09-10 01:47:45 +02:00