Files
meshcore-analyzer/internal
dborupandClaude Sonnet 5 e9f5b13b70 feat: Ping Scores — global highscore board and leaderboards
New feature: every "ping" channel message gets recorded and scored,
producing records (farthest reach, most hops, widest simultaneous
spread, fastest full spread, most airtime-efficient) plus leaderboards
(top relay nodes, top first-hearer observers). Global, not scoped by
region/area, per dborup's request.

Architecture:
- Ingestor writes a lightweight ping_triggers row (tx_id, hash,
  channel_hash, sender, first_seen) at ingest time when a new CHAN
  transmission matches the same isPingTrigger logic the pong-reply
  feature already uses (mirrored, kept in sync by hand -- now a 3rd
  copy alongside public/channels.js and cmd/server/db.go).
- Server periodically (every 2 min) joins ping_triggers with the same
  GetPacketPath + LoRa-airtime-estimate logic behind View Path,
  computing the full snapshot in memory (no write access needed from
  the read-only server) and caching it, matching the steady-state
  recomputer pattern used throughout cmd/server.
- New GET /api/ping-scores endpoint + Ping Scores page (linked from
  Tools and from every pong reply bubble in Channels).

Schema change follows the dbschema.go INVARIANT from #1321 exactly:
migration in Apply() (ingestor-only), assertion in AssertReady()
(server fatal-exits if ping_triggers is missing rather than silently
degrading) -- the same pattern #1865/#1867's configured_scope should
have used but didn't fully wire up (see the ping_scores.go doc
comment and today's earlier startup-race fix for the story).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 15:01:21 +02:00
..