Files
mc-webui/tests
MarekWoandClaude Opus 5 77f6a70b97 feat(repeaters): move a region in the hierarchy
Adds "Move to another region" to the per-region menu. Until now the only
way to re-parent was to delete the region and add it again under a new
parent. `region put <name> <parent>` on an existing name already
re-parents it (RegionMap::putRegion), so the command was there; what was
missing was doing it safely.

Two firmware behaviours make a blind put unsafe, both confirmed live on
MarWoj Mobile Observer, and both settled by the one tree read the move
now does up front:

- The only cycle check is `region->id == parent_id`. Moving a region into
  one of its own descendants is accepted, and detaches that branch from
  the wildcard root: it disappears from the `region` listing entirely
  (printChildRegions recurses down from the root) while still holding
  table slots. Verified — after `region put zza zzb`, both vanished from
  the tree while `region get zza` still answered ` zza (zzb) F`. Nothing
  in the UI could then show them, let alone fix them. Forwarding is not
  at risk: findMatch scans the flat array and never walks parents.
- The put branch sets `region->flags = 0`, so moving a flood-denied
  region silently re-allows flood, and the reply says
  `OK - (flood allowed)` without hinting anything changed. Verified: zzb
  was denied before the move and came back allowed.

So the move reads `region` first, refuses self/descendant/wildcard
targets, then puts, then re-applies `denyf` when the region was denied.
A lost restore is surfaced rather than swallowed — the region has moved
but is forwarding traffic it was set to drop. The picker filters the same
descendant set client-side, so the guard is not a surprise at the end.

Moving a region carries its nested regions with it, which is the point:
verified moving zzc (holding zzb) under zza.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 11:20:43 +02:00
..