meshai/dashboard-frontend
Matt Johnson (via Claude) f89e9c11fb feat(v0.6-tail-3): enforce OR-not-AND continuously -- close USGS direct-lookup leak + flag environmental config changes as restart-required
Gap 1 -- env_routes.lookup_usgs_site no longer creates a temporary
USGSStreamsAdapter to hit USGS.gov directly. When the env_store has no
native usgs adapter (because usgs.feed_source != native), the endpoint
returns HTTP 404 with a body that says "site lookup unavailable in
central-feed mode; values must be entered manually or sourced from
Central". This closes the AND-mode anti-pattern Central's v0.10.2
report flagged: meshai was in central-feed mode for usgs but the
lookup helper would still call USGS.gov directly the first time the
dashboard opened the Add-Gauge form.

Gap 2 -- config_routes.RESTART_REQUIRED_SECTIONS gains "environmental"
and the PUT handler now diffs the section before/after, returning
{saved, restart_required, changed_keys}. restart_required is true only
when there are actual changes AND the section is in the restart-required
set, so a no-op PUT to environmental never raises a false alarm.

Frontend wiring:
- New RestartBanner component (yellow top-of-main banner) listens to a
  meshai:restart-required CustomEvent + cross-tab storage event,
  persists across navigations via localStorage, shows changed_keys
  preview + Restart-now button (POSTs /api/system/restart) + dismiss.
- Layout.tsx mounts <RestartBanner /> above {children} so it surfaces
  on every page.
- Config.tsx saveSection() now calls notifyRestartRequired(changed_keys)
  alongside its existing setRestartRequired(true) when the API flags
  the section.
- GaugeSites.tsx probes /api/config/environmental at mount and shows a
  "USGS lookup" button next to the site_id input. The button is
  disabled with an explanatory tooltip when usgs.feed_source != native,
  and gracefully renders the 404 detail when the API returns 404 in
  central-feed mode -- enter-manually UX, no silent fallback.

Tests -- tests/test_or_arch_continuous.py (11 cases, all passing):
- USGS lookup 404 with no env_store / no native usgs adapter
- 502 on native-adapter exception
- 200 + payload on native-adapter happy path
- environmental in RESTART_REQUIRED_SECTIONS
- PUT environmental with changed feed_source -> restart_required:true
  + changed_keys list including foo.feed_source dotted path
- PUT bot (non-restart section) -> restart_required:false
- No-op PUT to bot / environmental -> restart_required:false, empty
  changed_keys
- _diff_keys helper unit tests (nested dicts, list-element changes)

Why this matters: per the Spokane post-mortem and Central's v0.10.2
response, both sides need belt-and-suspenders against transient
AND-modes. meshai's static OR enforcement at env_store boot is the
runtime guard; this commit makes the GUI honor it continuously --
the lookup helper can't sneak past it any more, and the user is told
explicitly that an environmental config change does not take effect
until the container restarts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-06 03:51:10 +00:00
..
src feat(v0.6-tail-3): enforce OR-not-AND continuously -- close USGS direct-lookup leak + flag environmental config changes as restart-required 2026-06-06 03:51:10 +00:00
index.html feat(dashboard): React frontend scaffold with overview page 2026-05-12 10:28:12 -06:00
package.json fix(dashboard): rewrite topology graph for performance at scale 2026-05-12 12:47:42 -06:00
postcss.config.js feat(dashboard): React frontend scaffold with overview page 2026-05-12 10:28:12 -06:00
tailwind.config.ts feat(dashboard): React frontend scaffold with overview page 2026-05-12 10:28:12 -06:00
tsconfig.json feat(dashboard): React frontend scaffold with overview page 2026-05-12 10:28:12 -06:00
tsconfig.node.json feat(dashboard): React frontend scaffold with overview page 2026-05-12 10:28:12 -06:00
vite.config.ts feat(dashboard): React frontend scaffold with overview page 2026-05-12 10:28:12 -06:00