Files
meshcore-analyzer/public
45680a22cf fix(#2191): apply the channel filter to live WebSocket packets (#2192)
Fixes #2191.

## Problem

On the Packets page the channel filter only applies to the initial load
(`/api/packets?channel=` → server-side `transmissions.channel_hash`
match). The WebSocket handler re-checks time window, type, observer,
region and node, but not `filters.channel`, and the channel filter is
not re-applied at render time. With a channel selected, every new live
packet is appended regardless of its channel.

## Fix

- New pure helper `packetMatchesChannel(p, channel)` in
`public/packets.js`, exported as `window._packetsMatchesChannelForTest`
(same pattern as `_packetsBuildChannelOptionsForTest`).
- It derives the value the server filters on from `decoded_json`,
because WS packets don't carry `channel_hash`:
  - `channel` when the server decrypted the `GRP_TXT`,
  - otherwise `'enc_' + channelHashHex.toUpperCase()`.
- Only `payload_type === 5` can match, mirroring the server (the column
is only set for `GRP_TXT`). If a packet ever does carry `channel_hash`,
that wins.
- The WS filter calls it: `if (filters.channel &&
!packetMatchesChannel(p, filters.channel)) return false;`

Checked the derivation against a production DB (live.saarmesh.de): it
equals `channel_hash` for all 3,193 `GRP_TXT` rows of the last two days,
0 mismatches.

## Performance

WS hot path, but the new check runs only while a channel filter is
active, and for non-`GRP_TXT` packets it returns before any parsing. For
`GRP_TXT` it is one `JSON.parse` of the already-received `decoded_json`
string, O(1) per packet. WS messages are already debounced/coalesced by
`debouncedOnWS`, so at typical rates (a few packets per second) this is
negligible. No new state, no allocations beyond the parse, no API calls.

## Tests

New `tests/unit/test-packets-live-channel-filter.js` (registered in
`test-all.sh`), 10 cases:

- no filter accepts everything
- decrypted name match / mismatch
- non-`GRP_TXT` rejected while a channel filter is active
- `enc_<HH>` match incl. hex case normalisation and `enc_00`
- `channel_hash` passthrough takes precedence
- already-parsed `decoded_json` object
- malformed / missing `decoded_json` doesn't throw and doesn't match
- source check that the WS filter block actually applies the helper

Without the `packets.js` change the new test fails; with it all pass.
Existing `test-packets.js` (117), `test-packets-local-channels.js` (14),
`test-packet-filter.js` (99) and `test-frontend-helpers.js` still pass.

## Browser validation

The same change is deployed on live.saarmesh.de (hot-patched
`packets.js`, server restarted so `__BUST__` refreshed; the served file
contains the fix). I have not taken a screenshot of the filtered live
table myself, so treat the in-browser check as pending until a reviewer
or operator confirms.

No config or customizer implications.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01HJcbiRjQC5cSmydVFXbPbR

Co-authored-by: SaarMesh-Bot <300107934+SaarMesh-Bot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-10-12 15:25:59 +02:00
..