Files
meshcore-analyzer/cmd/server
efitenandClaude Opus 5 71b892ba95 fix(#1899): scope the channel preview to the region filter (#1961)
Closes #1899.

The Channels sidebar preview (`lastMessage` / `lastSender`) ignored the
active region filter, so an operator filtering on their own region saw a
preview line from a message their observers never heard.

## Cause

`GetChannels` scoped `msg_count` and `last_activity` correctly: the
outer query joins `observations` and `observers` and filters on IATA.
The `sample_json` subquery that feeds the preview joined neither, so it
always returned the globally newest message on the channel.

## Fix

Both region-filtered branches now scope the subquery the way the outer
query does: v3 through `observations`/`observers` on `observer_idx`, v2
through the `EXISTS` on `observer_id`. The unfiltered branch is
untouched, since there is no filter for it to respect.

**One thing that is easy to get wrong here:** the subquery sits in the
SELECT list, *ahead of* the WHERE, so its placeholders bind first. The
region codes are appended twice, subquery set first, or every filtered
call binds the wrong values.

**Scope checked rather than assumed:** `GetEncryptedChannels` has the
same shape and the same `regionPlaceholder` pattern, but selects no
`sample_json`, so it does not have this bug and is left alone.

## Verification

The regression test **fails on unmodified master**, with the reported
symptom:

```
db_test.go:2465: preview sender = Bob, want Alice: SJC must not be shown Bob's
                 message, which only SFO heard
db_test.go:2469: preview message = heard in SFO, want "heard in SJC"
```

It asserts both directions, so it cannot pass by always picking the
oldest row, and it asserts the unfiltered call still shows the globally
newest message, which was never in question.

`gofmt` clean, `go vet` clean, `cmd/server` suite ok in 98.5s.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 17:04:54 +02:00
..