Commit Graph

352 Commits

Author SHA1 Message Date
l5y bb95b0792d web: fix chat (#800)
* chore: add guardrails

* docs: fix meshcore badge

* web: life chat message cap at 1000 in frontend

* web: honor protocol in chat

* web: deprioritize test channels

* fix ci
2026-06-19 16:37:41 +02:00
l5y 512b4f157b Fix regression where Meshcore chat senders show as Meshtastic (#794)
* Fix regression where Meshcore chat senders show as Meshtastic

* Address review feedback for protocol misclassification fix

- ingest.rb: exclude wrapper ``protocol`` key from /api/nodes batch-limit
  count so the documented 1000-node maximum still applies after the
  Python ingestor started stamping protocol at the wrapper level.
- Drop plan-file references from production and test comments per the
  repo guidelines; the why is already explained inline.

* Address protocol-fallback review feedback

- Neighbor placeholder now inherits the source node's protocol from the
  surrounding /api/neighbors entry, so the badge tracks the radio the
  peer lives on instead of collapsing to the neutral "Unknown" label
  (review item #1).
- resolve_record_protocol logs one warn_log line when an explicit
  protocol stamp is rejected as malformed, making misbehaving custom
  protocol adapters visible in the operator log instead of silently
  falling back (review item #3).

* Extract buildNodePlaceholder helper for testability

The neighbor placeholder logic in main.js lives inside an untested
closure, so codecov reported the protocol-propagation lines as
uncovered.  Extract the small placeholder builder into long-link-router
so it can be unit tested directly; the closure-internal call site stays
trivial (one factory call + one fallback call).
2026-05-24 09:49:45 +02:00
l5y d2fe4f8223 web: add node opt-out marker and data retention policies (#793)
* web: add node opt-out marker and data retention policies

* web: address review comments

* web: address review comments
2026-05-20 21:02:59 +02:00
l5y 8a89185fbe fix sentinel position data (#792)
* fix sentinel position data

* address review comments
2026-05-18 21:27:47 +02:00
l5y c32da2c541 chore: bump to 0.6.4 (#785) 2026-05-03 17:01:28 +02:00
l5y 73e161f432 web: fix liveliness of api data hydration bug (#783)
* web: fix liveliness of api data hydration bug

* web: address review comments
2026-05-03 13:05:37 +02:00
l5y 7b38f92b2d web: refactor 6/7 node page (#777)
* web: refactor 6/7 node page

* web: address node-page refactor review and close coverage gaps

Fix the concurrency cap in fetchNodeDetailsIntoIndex so it actually
limits in-flight requests.  The previous implementation built each
fetch as an immediately-invoked async IIFE, so all N fetches started
the moment the loop ran; the slicing-then-Promise.all step only
changed when settlement was observed, not when work began.  Replace
the IIFE-then-batch pattern with a worker pool: a fixed-size set of
worker promises iterates a shared queue and only pulls the next
identifier once the previous fetch settles.

Reduce cross-module coupling around the role-aware short-name badge
by extracting renderRoleAwareBadge into a new badge.js module that
single-node-table, messages, detail-html, and traces import directly,
so the neighbour module is no longer pulled in by four non-neighbour
callers.  Tighten applyDetails in role-index.js by hoisting the
ternary into a single key binding and dropping the redundant
instanceof Map guard.

Close the patch-coverage gap reported by Codecov: add tests for
parameter-validation paths in bootstrap (parseReferencePayload,
normalizeNodeReference, fetchNodeDetailHtml, initializeNodeDetailPage),
the worker-pool branches in role-index (no-fetch, empty queue, 404,
non-success responses, and an explicit concurrency-cap assertion),
the badge fallback path, the nested-neighbor seedNeighborRoleIndex
branches, the renderNeighborBadge metadata-merge and short-name
fallback paths, the empty-trace and empty-chart short-circuits, and
single-node-table validation.  All ten node-page submodules now
report 100% line coverage.
2026-05-02 23:05:36 +02:00
l5y e04fab5b19 web: refactor 7/7 main js (#778)
* web: refactor 7/7 main js

* web: refactor 7/7 main js

* web: address review feedback on 7/7 main.js refactor

* Consolidate the duplicate ./main/format-utils.js import block in
  main.js so all symbols come from a single, alphabetised import
  statement (review item: "Important — Duplicate format-utils.js
  import block").
* Replace the leftover stale JSDoc atop +createOfflineTileLayer+ with
  one clear "do not inline" DI block, and likewise expand the
  +fetchMessages+ wrapper docstring so future readers see the shim's
  purpose without hunting for the implementation (review nit:
  "thin wrappers ... worth a one-line JSDoc").
* Add per-module unit tests under
  public/assets/js/app/main/__tests__/ covering every previously-
  uncovered branch in the 9 modules codecov flagged: tile-coords,
  sort-comparators, fullscreen-helpers, format-utils, data-fetchers,
  data-merge, tooltip-html, long-link-router, and offline-tile-layer.
  This drives the codecov patch percentage on PR #778 from 78.99%
  to ~100% on the new modules and unblocks the codecov/patch gate.

JS suite: 1,114 tests, 0 failures.
2026-05-02 22:35:34 +02:00
l5y d1d0225197 web: refactor 5/7 node page charts (#776)
* web: refactor 5/7 node page charts

* web: address review feedback on node-page-charts split

* Drop the local stringOrNull/numberOrNull copies from node-page.js
  and import them from ./value-helpers.js so the shared module's
  stated dedup actually happens (review issue #1).  The two locals
  were byte-identical to the new shared module.
* Split the display-only formatters out of
  node-page-charts/format-utils.js into a sibling
  node-page-charts/display-formatters.js so format-utils.js carries
  only chart concerns (review issue #2).  The barrel
  node-page-charts.js re-exports both files so existing callers and
  tests keep working unchanged.
* Inline +fmtCurrent+ in node-page-charts/specs.js and drop the
  sideways import from short-info-telemetry.js so node-page-charts/
  no longer depends on an unrelated module (review issue #3).
* Add a dedicated value-helpers.test.js pinning the contract of
  +numberOrNull+ and +stringOrNull+ so they stop relying on
  transitive coverage from the chart suite (review issue #5).
2026-05-02 22:16:18 +02:00
l5y 0fbff32535 web: refactor 2/7 federation (#773)
* web: refactor 2/7 federation

* web: close federation coverage gaps and apply review nits

Address Codecov patch coverage feedback by adding rspec examples for
the 51 lines flagged across the new federation shards (announce,
crawl, validation, http_client, self_instance, instance_metrics,
announcer_threads, lifecycle, signature). Per-shard line coverage in
the federation directory is now 100%.

Apply two review-comment changes: rename the awkwardly-named
http_client_get.rb to instance_fetcher.rb (matching its semantic
role rather than the HTTP verb), and declare PotatoMesh::App::Federation
explicitly in the federation.rb manifest so the namespace is owned by
this file rather than implicitly created by whichever shard happens to
load first.
2026-05-02 22:12:20 +02:00
l5y 03caf391e7 web: refactor 1/7 data processing (#772)
* web: refactor 1/7 data processing

* web: close coverage gaps in data_processing submodules

Bring every file under lib/potato_mesh/application/data_processing/ to
100% line coverage so codecov/patch passes on the 1/7 refactor PR. The
gap was a relocation of pre-existing untested branches; closing them
here keeps the subsequent refactor PRs in the series unblocked.

* Add unit tests covering canonical sender/recipient overrides,
  reply_id/emoji updates on existing rows, and the rare INSERT
  ConstraintException recovery path inside +insert_message+.
* Cover the non-canonical reporter and per-neighbour resolution
  branches in +insert_neighbors+.
* Cover the SQLException rescue in +upsert_ingestor+, the
  fallback_num branch in +touch_node_last_seen+, the limit fallback
  in +read_json_body+, the unrecognised-type branch in
  +store_decrypted_payload+, the +power+ telemetry_type fallback,
  the default-coercion path in +resolve_numeric_metric+, and the
  numeric/bare-hex paths in +canonical_node_parts+ and
  +coerce_trace_node_id+.

Drop dead code surfaced while pinning behaviour:

* +clear_encrypted+ in +insert_message+ has been initialised to
  +false+ and never reassigned since #633 dropped the
  decrypted-text override; remove it and the four dependent
  branches.
* The +rescue ArgumentError; nil+ tails in
  +identity.resolve_node_num+ and +traces.coerce_trace_node_id+ are
  unreachable because every +Integer(...)+ call inside is guarded by
  a regex pre-check.

Add a comment to the +data_processing.rb+ shim explaining that the
+require_relative+ list is ordered by dependency rather than
alphabetically, addressing review nit #5.
2026-05-02 22:08:21 +02:00
l5y 09d9e7be13 chore: bump version to 0.6.3 (#779)
* chore: bump version to 0.6.3

* chore: bump version to 0.6.3
2026-04-29 22:06:29 +02:00
l5y 43a5724b7f web: add seo improvements (#771)
* web: add seo improvements

* web: address review comments

* web: address review comments
2026-04-29 10:33:33 +02:00
l5y ee98efc120 web: rework map spider-net feature (#769)
* web: rework map spider-net feature

* web: address review comments

* web: address review comments
2026-04-29 07:06:18 +02:00
l5y 161f22bf12 chore: bump version to 0.6.2 (#763)
Backfill v0.6.1 CHANGELOG entry (previously undocumented),
add v0.6.2 entry covering 9 commits since v0.6.1, and bump
the version string across data, web, matrix, and app along
with the README docker-pull examples.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 19:02:26 +02:00
l5y a4902548d3 web: fix emoji pattern render in short names (#760)
* web: fix emoji pattern render in short names

* web: address review comments
2026-04-21 13:02:36 +02:00
l5y db236d58e2 web: fix meshcore message duplication with 120s dupe protection (#758)
* web: fix meshcore message duplication with 120s dupe protection

* web: fix meshcore message duplication with 120s dupe protection

* web: address review comments

* web: address review comments
2026-04-21 10:13:39 +02:00
l5y a6cac6ced5 web: fix node duplication through message synthetization (#757)
* web: fix node duplication through message synthetization

* web: fix edge case

* web: address review comments
2026-04-21 08:53:09 +02:00
l5y f866cf8837 web: show colocated nodes (#753)
* web: show colocated nodes

* web: address review comments

* web: address review comments

* web: address review comments
2026-04-17 09:02:39 +02:00
l5y 8ac12ee2c8 fix reaction handling and classification (#750)
* fix reaction handling and classification

* fix reaction handling and classification

* web: add tests

* web: address review comments

* web: address review comments

* web: address review comments

* web: address review comments
2026-04-16 20:07:41 +02:00
l5y 580c2fb6ea web: fix federation node counts (#749)
* web: fix federation node counts

* web: fix federation node counts

* web: address review comments
2026-04-15 15:43:34 +02:00
l5y 13b2ce9067 web: fix meshcore node misclassification (#748)
* web: fix meshcore node misclassification

* web: address review comments

* web: address review comments
2026-04-15 12:38:50 +02:00
l5y 5a73e212a3 web: optimize caching (#744)
* web: optimize caching

* web: address review comments

* web: address review comments

* web: run rufo
2026-04-14 23:29:54 +02:00
l5y 07c8e85caa web: fix federation resolver issue with multi addresses (#743)
* web: fix federation resolver issue with multi addresses

* web: add tests

* web: address review comments
2026-04-14 18:55:40 +02:00
l5y c08b3f2c2d web: restore refresh and protocol buttons (#742)
* web: restore refresh and protocol buttons

* web: restore refresh and protocol buttons

* web: restore refresh and protocol buttons

* web: address review comments
2026-04-14 16:54:57 +02:00
l5y b951dbffeb web: per protocol active node counts (#735)
* web: per protocol active node counts

* web: address review comments
2026-04-13 18:26:16 +02:00
l5y aeb97477f0 chore: bump version to 0.6.1 (#726) 2026-04-09 13:14:20 +02:00
l5y 81e588e44c web: add markdown static pages (#723)
* web: add markdown static pages

* web: add tests and docker

* web: improve wording and configs

* web: add tests

* web: address review comments

* web: address review comments

* Potential fix for pull request finding 'CodeQL / Incomplete multi-character sanitization'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* web: address review comments

* web: address review comments

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-08 16:42:13 +02:00
l5y 083de6418f web: fix federation for multi protocol (#722)
* web: fix federation for multi protocol

* web: fix short name emojis

* web: address review comments

* ci: fix the codeql gap

* ci: fix the codeql gap

* ci: fix the codeql gap

* ci: remove swift
2026-04-08 14:36:43 +02:00
l5y 4d38ddd341 web: facelift (#716)
* web: facelift

* web: facelift

* web: facelift

* web: address review comments

* web: address review comments

* web: address review comments

* web: address review comments

* web: address review comments

* web: address review comments

* web: more css magic

* web: link parsing for chat contact

* web: remove one-letter fallback for shortnames

* Potential fix for pull request finding 'CodeQL / Incomplete multi-character sanitization'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* web: fix fallback for shortnames

* web: address review comments

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-07 21:38:43 +02:00
l5y 95aa1de8a8 web: sort channels by activity not index (#711)
* web: sort channels by activity not index

* web: address review comments
2026-04-06 14:04:47 +02:00
l5y d8b80c2a97 web: reference meshcore nodes in chat (#709)
* web: reference meshcore nodes in chat

* data: add adv_name to messages

* web: address review comments

* derive actual companion from name string

* derive actual companion from name string

* derive actual companion from name string

* web: address review comments

* web: address review comments
2026-04-06 13:39:00 +02:00
l5y 406fa80dd0 web: fix node disappearance role reset (#707)
* web: fix node disappearance role reset

* web: address review comments

* web: address review comments

* web: address review comments
2026-04-05 23:43:36 +02:00
l5y de1ccc5a2e release: v0.6.0 — remove deprecated env var aliases (#704)
* chore: bump version to 0.6.0 and remove deprecated env var aliases

BREAKING CHANGES:
- POTATOMESH_INSTANCE removed — use INSTANCE_DOMAIN
- PROVIDER removed — use PROTOCOL
- MESH_SERIAL removed — use CONNECTION
- PORT config alias removed — use CONNECTION

The _ConfigModule proxy class (which kept PROTOCOL/PROVIDER and
CONNECTION/PORT in sync) is deleted. docker-compose.yml now defaults
INSTANCE_DOMAIN to http://web:41447 so deployments without an explicit
value continue to work.

* tests: run black

* address review comments
2026-04-05 16:49:10 +02:00
l5y 0a479e4517 web: protect real node names from fallback (#702)
* web: protect real node names from fallback

* web: address review comments

* web: address review comments
2026-04-05 13:57:18 +02:00
l5y 3647cb125b web: define meshcore modem presets (#696)
* web: define meshcore modem presets

* web: address review comments
2026-04-05 13:37:58 +02:00
l5y 06530f36ff web: add proper short names for meshcore companions (#693)
* web: add proper short names for meshcore companions

* web: address review comments
2026-04-05 09:01:43 +02:00
l5y 3cfa0db7e6 web: distinguish meshcore from meshtastic in frontend (#688)
* web: distinguish meshcore from meshtastic in frontend

* fix mark_packet_seen bug

* web: distinguish meshcore from meshtastic in frontend

* address review comments

* address review comments

* address review comments
2026-04-04 17:14:16 +02:00
l5y d9420ff13b fix: address review comments from PRs #676 and #681 (#689)
* fix: address review comments from PRs #676 and #681

- Introduce ClosedBeforeConnectedError(ConnectionError) subclass so
  callers can distinguish a user-initiated shutdown from a hardware
  failure without string-matching the exception message (#676)
- Add test covering the close-before-connected path: asserts
  isConnected stays False and error_holder contains the typed error
- Add protocolIconPrefixHtml unit tests covering null, meshtastic,
  meshcore, and unknown protocol strings (#681)
- Add buildDisplayContext tests for protocol extraction from trace,
  node, and absent candidate sources (#681)
- Expose buildDisplayContext via _testUtils to make it directly testable
- Add meshcore icon presence assertions to createAnnouncementEntry and
  createMessageChatEntry tests (previously only checked absence of
  meshtastic icon)

* fix: address #689 review comments

- Move createMessageChatEntry meshcore icon test into its own section,
  after the createMessageChatEntry divider where it belongs
- Export ClosedBeforeConnectedError from providers/__init__.py via the
  existing lazy-load __getattr__ so callers outside the providers/
  subpackage can catch it without importing the full meshcore module

* refactor: eliminate test boilerplate to fix SonarCloud duplication gate

Introduce withApp() and innerHtml() helpers in main-protocol.test.js to
replace the 18-repeated setupApp/try/finally/cleanup pattern and the
inconsistent innerHTML extraction expression. No test logic changed.

* refactor: extract stalled-run helpers to fix SonarCloud duplication gate

The two stall-based _run_meshcore tests shared ~20 lines of identical
setup and spin-loop boilerplate. Extract _setup_stalled_run() and
_start_stalled_run() so each test contains only its distinct assertions.
2026-04-04 13:28:26 +02:00
Ben Allfree 7e0ba60a22 fix: get meshcore protocol icon displaying correctly (#681) 2026-04-04 13:00:25 +02:00
l5y 9c3dae3e7d chore: refactor codebase before meshcore release (#682)
* chore: refactor codebase before meshcore release

* data: run black

* fix: resolve SonarCloud S1244/S5796 reliability issues in test files

Replace floating-point equality comparisons with pytest.approx() to
satisfy S1244, and replace the `is` identity operator with id()-based
comparison to satisfy S5796.

* fix: remove duplicate encrypted_flag assignment in store_packet_dict

The encrypted_flag was computed identically on lines 307 and 345 with no
mutation of `encrypted` between them. Remove the dead second assignment.
2026-04-04 10:22:31 +02:00
l5y a62a068c08 feat: implement meshcore provider (#663)
* feat: add meshcore support

* fix: address PR #663 review comments

* fix: address PR #663 review comments

* address review comments
2026-03-31 13:44:05 +02:00
l5y e48c575b9d web: prepare release (#665)
* web: prepare release

* fix: address pre-release review concerns

- Emit invalid telemetry_type warning at severity=warning/always=True so
  it surfaces in production logs, not just under DEBUG=1
- Hoist VALID_TELEMETRY_TYPES to a module-level constant in DataProcessing
  to avoid per-call allocation inside insert_telemetry
- Add Python test covering the invalid-type drop path in store_telemetry_packet
- Add Ruby spec asserting that an invalid telemetry_type in a POST payload
  is discarded and metric-based inference takes over
2026-03-30 23:15:55 +02:00
l5y f638c79e13 web: fix css issues (#659)
* web: fix css issues

* chore: bump version to 0.5.12
2026-03-30 08:55:35 +02:00
l5y 874e81ab8b web: prepare frontend for multi protocol (#657)
* web: prepare frontend for multi protocol

* web: address review comments

* fix: address review feedback on multi-protocol frontend prep

- Replace iconHtml/innerHTML in renderChatTabs with iconSrc + DOM APIs;
  the img element is now built attribute-by-attribute so no innerHTML trust
  boundary exists even if iconSrc were to receive external input
- Add MESHTASTIC_ICON_SRC / MESHCORE_ICON_SRC constants to protocol-helpers;
  meshtasticIconHtml() and meshcoreIconHtml() reference these so the asset
  path has a single source of truth
- Use meshtasticIconHtml() in the map legend via a temp span to eliminate
  the 7-setAttribute duplication
- Add getRoleColors(protocol) to role-helpers, making meshcoreRoleColors
  reachable through a tested code path rather than a dead export
- Rename __test__ export in main.js to __testUtils for consistency
- Add JSDoc cross-reference on normalizeNodeNameValue vs stringOrNull


* web: address review comments

* web: address review comments

* web: address review comments
2026-03-30 08:21:39 +02:00
l5y a5d0008555 feat: split device and power-sensor telemetry charts (#643) (#656)
* feat: split device and power-sensor telemetry charts (#643)

Add telemetry_type TEXT discriminator column across the full stack so
device_metrics rows no longer mix with power_metrics in the same chart.
Python and Ruby ingestors detect the protobuf subtype at write time;
classifySnapshot() provides field-presence fallback for legacy rows.
'Power metrics' chart split into 'Device health' and 'Power sensor'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: skip typeFilter for aggregated telemetry; add air_quality coverage

- renderTelemetryChart now skips spec.typeFilter when chartOptions.isAggregated
  is true, preventing mixed-bucket aggregated snapshots from losing series data
- renderTelemetryCharts detects the aggregated vs per-packet path and sets
  isAggregated accordingly; typeFilter still applies for per-packet history
- JS tests: extract makeAggregatedNode/makeHistoryNode helpers to eliminate
  fixture duplication; add aggregated-mixed-bucket regression test; move
  type-separation tests onto the history path where filtering actually applies
- Ruby + Python: add air_quality_metrics telemetry_type tests for coverage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: reduce test duplication flagged by Sonar

Hoist CHART_NOW_MS/CHART_NOW_SECONDS constants to eliminate 14 repeated
setup lines across renderTelemetryCharts tests.  Extract
expect_stored_telemetry_type helper in app_spec to replace the four
identical with_db/SELECT/expect blocks in telemetry_type inference tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* web: address review comments

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 00:07:24 +02:00
l5y 4d0d6f8565 web: implement a 'protocol' field across systems (#655)
* web: implement a 'protocol' field across systems

* web: address review feedback on multi-protocol support

- Rebase on main (pick up coordinate-clearing bugfix from #654)
- P1: prevent cross-protocol message merges on shared packet IDs
- P2: exclude "ingestor" key when enforcing /api/nodes batch limit
- Extract append_protocol_filter helper + PROTOCOL_CLAUSE constant to
  reduce cognitive complexity and deduplicate SQL fragment in queries.rb
- Extract coerce_bool helper to reduce upsert_node cognitive complexity
- Merge nested if in insert_message protocol update path (Sonar)
- Add explicit UPDATE backfill in ensure_schema_upgrades so any pre-existing
  NULL/empty protocol rows are set to meshtastic on upgrade
- Rename migration file to 20260328_ (correct year)
- Expand protocol_spec.rb: filter tests for all 7 endpoints,
  cross-protocol non-merge test, batch limit test, Sonar constant fixes,
  ENV.fetch, P1 regression test


* web: address review comments
2026-03-29 11:48:32 +02:00
l5y 7b1d25e286 fix upsert clearing node coordinates bug (#654) 2026-03-28 21:21:13 +01:00
l5y ecce7f3504 chore: bump version to 0.5.11 (#645)
* chore: bump version to 0.5.11

* data: run black
2026-03-01 21:59:04 +01:00
l5y 17fa183c4f web: limit horizontal size of dropdown (#644)
* web: limit horizontal size of dropdown

* address review comments
2026-03-01 21:49:06 +01:00