meshai/tests
Matt Johnson (via Claude) 42b3106e97 feat(v0.6-3c): adapter_config REST API + dashboard editor
Closes the audit-doc Section A keystone (the GUI editor). Together with
v0.6-3a foundation, v0.6-3a.1 trim, and v0.6-3b handler wiring, every
Rule-17 CONFIG knob from the audit is now editable in the dashboard
without a container restart.

API (meshai/dashboard/api/adapter_config_routes.py):
  GET  /api/adapter-config              -- {adapter: [{key, value, default,
                                            type, description}]}
  GET  /api/adapter-config/<adapter>    -- one adapter list
  GET  /api/adapter-config/<adapter>/<key> -- single row
  PUT  /api/adapter-config/<adapter>/<key> body {value} -- typed validation
       int: int or whole-number float; rejects bool, fractional float, str
       float: int or float; rejects bool
       str: str only
       bool: bool only
       json: any JSON-serializable value
       Every PUT calls invalidate_cache() so the next handler accessor
       read sees the new value -- no container restart needed.
  POST /api/adapter-config/<adapter>/<key>/reset -- value_json = default_json,
       cache invalidated
  GET  /api/adapter-meta                -- {adapter: {display_name,
                                            include_in_llm_context, description}}
  PUT  /api/adapter-meta/<adapter> partial-update body, fields:
       include_in_llm_context: bool, display_name: non-empty str

Dashboard (dashboard-frontend/src/pages/AdapterConfig.tsx):
  - Per-adapter cards. Header row shows display_name, the include_in_llm_context
    toggle, and an expand chevron. Adapters with zero config keys (e.g. itd_511)
    still render so users can toggle their LLM-context inclusion.
  - Expanded body lists each key with a type-aware widget:
      bool  -> checkbox, commit-on-change
      int/float -> number input, commit-on-blur (or Enter)
      str   -> text input, commit-on-blur
      json  -> textarea, commit-on-blur (JSON.parse with inline error)
    Each row shows the key name, type tag, description, "edited" badge when
    value != default, a per-key Reset button, and a save badge (spinner,
    check, error tooltip, or a small amber dot for unsaved local changes).
  - Auto-save semantics: every blur/change/reset triggers PUT immediately;
    no explicit Save button needed. Reset is one-click per key.

Wiring:
  - meshai/dashboard/server.py registers the new router with prefix /api.
  - dashboard-frontend/src/App.tsx adds the /adapter-config route.
  - dashboard-frontend/src/components/Layout.tsx adds the left-nav entry
    (Sliders icon, label "Adapter Config", after Reference).
  - Vite build produces a fresh meshai/dashboard/static bundle. The
    Dockerfile copies meshai/ so the new bundle ships with the container
    image at next rebuild.

Tests (tests/test_adapter_config_api.py, 30 cases):
  - GET grouped, per-adapter, single key
  - GET per-adapter returns [] for adapters with zero keys (itd_511)
  - PUT updates value, GET shows new value, accessor returns new value
    (proves cache invalidation propagates to the in-process accessor)
  - PUT type validation per (int, float, str, bool, json) incl. edge cases:
    int rejects str + fractional float + bool but accepts whole-number float;
    float accepts int + float, rejects bool; bool rejects int; str rejects
    other types; json accepts list / dict / None
  - PUT 404 on unknown key, 400 on missing value field
  - POST reset restores default + invalidates cache
  - GET /api/adapter-meta: include_in_llm_context defaults match registry
    (central / geocoder false, rest true)
  - PUT meta partial update: only provided fields change
  - PUT meta rejects non-bool include_in_llm_context, empty display_name,
    unknown adapter

Test count: 731 -> 761 (+30 API cases, 0 regressions).

Refs audit doc v0.6-phase1-audit.md Section A keystone + finding #4.
2026-06-05 18:50:30 +00:00
..
fixtures/central_envelopes feat(content): v0.5.8-state_511_atis -- central_normalizer with Photon nearest_town + composer bypass + SB->S route normalization 2026-06-04 21:38:40 +00:00
conftest.py feat(v0.6-3a): adapter_config foundation -- migration + defaults registry + typed accessor 2026-06-05 17:06:51 +00:00
test_adapter_avalanche.py feat(notifications): Phase 2.10 avalanche adapter pipeline integration 2026-05-27 23:08:24 +00:00
test_adapter_config_api.py feat(v0.6-3c): adapter_config REST API + dashboard editor 2026-06-05 18:50:30 +00:00
test_adapter_config_foundation.py feat(v0.6-3b): wire every handler to adapter_config + v7.sql firms dedup_key column 2026-06-05 18:38:21 +00:00
test_adapter_ducting.py feat(notifications): Phase 2.13 ducting adapter threshold-crossing emission (severity-tiered, Option C) 2026-05-28 00:01:40 +00:00
test_adapter_fires.py feat(notifications): Phase 2.11 NIFC fires adapter pipeline integration 2026-05-27 23:33:48 +00:00
test_adapter_firms.py fix(fire): v0.5.7-fire -- FIRMS NATS pattern + WFIGS tombstone dedup + remove fire_proximity + categories audit 2026-06-04 06:25:42 +00:00
test_adapter_nws.py feat(notifications): Phase 2.6 NWS adapter pipeline integration 2026-05-15 04:47:31 +00:00
test_adapter_roads511.py feat(notifications): Phase 2.8 roads511 adapter pipeline integration 2026-05-27 21:18:21 +00:00
test_adapter_swpc.py feat(notifications): Phase 2.12 SWPC space weather adapter + dedup fix 2026-05-27 23:41:30 +00:00
test_adapter_traffic.py feat(notifications): Phase 2.7 traffic adapter pipeline integration 2026-05-27 19:17:27 +00:00
test_adapter_usgs.py feat(notifications): Phase 2.9 usgs water adapter pipeline integration 2026-05-27 21:58:13 +00:00
test_adapter_usgs_quake.py feat(notifications): Phase 2.14 USGS earthquake adapter (new) -- closes Rule 16 Seismic standalone path 2026-05-28 00:10:39 +00:00
test_avalanche_v057.py fix(avalanche): v0.5.7-avalanche -- Central avalanche check + categories audit 2026-06-04 06:55:27 +00:00
test_band_conditions.py feat(v0.5.11): band conditions scheduled broadcaster (3x/day HF propagation) 2026-06-05 07:38:51 +00:00
test_central_consumer.py feat(v0.5.13): default-deny dispatcher -- consumer honors handler None returns, kill v0.5.7 regression at the root 2026-06-05 14:17:41 +00:00
test_central_envelope_to_wire_v057.py feat(v0.5.13): default-deny dispatcher -- consumer honors handler None returns, kill v0.5.7 regression at the root 2026-06-05 14:17:41 +00:00
test_central_normalizer.py feat(v0.5.9): unified incident pipeline + state_511_atis Idaho cutover + two-sided freshness gate 2026-06-05 06:41:21 +00:00
test_central_region_routing.py fix(water): v0.5.7-water -- USGS NWIS hydro NATS pattern + categories audit 2026-06-04 06:42:06 +00:00
test_central_sub_adapter_routing.py feat(v0.5.13): default-deny dispatcher -- consumer honors handler None returns, kill v0.5.7 regression at the root 2026-06-05 14:17:41 +00:00
test_channel_rendering.py feat(notifications): Phase 2.5b per-channel-type renderers 2026-05-15 04:25:44 +00:00
test_cold_start_grace.py feat(v0.5.8b): persistence foundation + WFIGS handler + universal cold-start grace 2026-06-05 03:54:04 +00:00
test_config_loader.py fix(notifications): Phase 2.16.1 unblock pipeline -- grouper flush + rules coercion + toggle warning 2026-05-28 00:36:13 +00:00
test_config_source_field.py feat(central): v0.4 C.1 Central connector backend (no-op until adapter source flipped) 2026-05-28 02:28:19 +00:00
test_consumer_default_deny.py feat(v0.6-1): FIRMS handler -- storage-only, closes silent-drop on central.fire.hotspot.> 2026-06-05 15:50:33 +00:00
test_dashboard_config_save.py fix(dashboard): v0.4 C.2.1 -- route PUT /config to multi-file save_section (Rule 17 persistence unblocked) 2026-05-28 03:17:30 +00:00
test_dispatcher_persistence.py feat(v0.6-2): dispatcher state persistence -- cold-start, cooldowns, dedup LRU to SQLite 2026-06-05 16:35:40 +00:00
test_fire_v057.py feat(v0.5.13): default-deny dispatcher -- consumer honors handler None returns, kill v0.5.7 regression at the root 2026-06-05 14:17:41 +00:00
test_firms_handler.py feat(v0.6-1): FIRMS handler -- storage-only, closes silent-drop on central.fire.hotspot.> 2026-06-05 15:50:33 +00:00
test_incident_handler.py feat(v0.5.9): unified incident pipeline + state_511_atis Idaho cutover + two-sided freshness gate 2026-06-05 06:41:21 +00:00
test_itd_511_work_zone.py feat(v0.5.9): unified incident pipeline + state_511_atis Idaho cutover + two-sided freshness gate 2026-06-05 06:41:21 +00:00
test_notification_toggles.py feat(v0.6-2): dispatcher state persistence -- cold-start, cooldowns, dedup LRU to SQLite 2026-06-05 16:35:40 +00:00
test_nwis_handler.py feat(v0.5.12): usgs_nwis with minimal Idaho threshold curation (9 starter sites) 2026-06-05 07:47:35 +00:00
test_nws_handler.py feat(v0.5.10): nws + usgs_quake + swpc handlers 2026-06-05 07:27:01 +00:00
test_persistence.py feat(v0.5.8b): persistence foundation + WFIGS handler + universal cold-start grace 2026-06-05 03:54:04 +00:00
test_pipeline_digest.py fix(fire): v0.5.7-fire -- FIRMS NATS pattern + WFIGS tombstone dedup + remove fire_proximity + categories audit 2026-06-04 06:25:42 +00:00
test_pipeline_grouper.py fix(notifications): Phase 2.16.1 unblock pipeline -- grouper flush + rules coercion + toggle warning 2026-05-28 00:36:13 +00:00
test_pipeline_inhibitor_grouper.py fix(notifications): Phase 2.16.1 unblock pipeline -- grouper flush + rules coercion + toggle warning 2026-05-28 00:36:13 +00:00
test_pipeline_scheduler.py feat(notifications): Phase 2.5a channel interface unification 2026-05-15 03:45:27 +00:00
test_pipeline_skeleton.py chore(meshai): v0.5.5 -- cleanup bundle (gitignore env anchor, ducting health event_count, mesh_sources secret stripping, delete unused SeverityRouter) 2026-06-04 02:50:45 +00:00
test_pipeline_toggle_filter.py fix(fire): v0.5.7-fire -- FIRMS NATS pattern + WFIGS tombstone dedup + remove fire_proximity + categories audit 2026-06-04 06:25:42 +00:00
test_quake_handler.py feat(v0.5.10): nws + usgs_quake + swpc handlers 2026-06-05 07:27:01 +00:00
test_renderers.py fix(notifications): v0.5.7-regression -- consumer title fallback uses registry name, mesh renderer drops [Family] prefix 2026-06-04 16:06:47 +00:00
test_rf_v057.py feat(v0.5.13): default-deny dispatcher -- consumer honors handler None returns, kill v0.5.7 regression at the root 2026-06-05 14:17:41 +00:00
test_save_section_secret_preserve.py chore(meshai): v0.5.5 -- cleanup bundle (gitignore env anchor, ducting health event_count, mesh_sources secret stripping, delete unused SeverityRouter) 2026-06-04 02:50:45 +00:00
test_seismic_v057.py fix(seismic): v0.5.7-seismic -- USGS quake NATS pattern + severity=5 great-quake clamp + categories audit 2026-06-04 06:33:31 +00:00
test_swpc_handler.py feat(v0.5.10): nws + usgs_quake + swpc handlers 2026-06-05 07:27:01 +00:00
test_tracking_v057.py fix(tracking): v0.5.7-tracking -- Central tracking check + categories audit 2026-06-04 07:00:22 +00:00
test_traffic_v057.py fix(traffic): v0.5.7-traffic -- NATS pattern fix + itd_511 sub-adapter routing + categories audit 2026-06-04 06:10:12 +00:00
test_v052_dispatcher.py feat(v0.5.8b): persistence foundation + WFIGS handler + universal cold-start grace 2026-06-05 03:54:04 +00:00
test_water_v057.py fix(water): v0.5.7-water -- USGS NWIS hydro NATS pattern + categories audit 2026-06-04 06:42:06 +00:00
test_weather_v057.py fix(weather): v0.5.7-weather -- NWS HTML strip + ALERT_CATEGORIES audit (NATS pattern already valid) 2026-06-04 06:00:10 +00:00
test_wfigs_handler.py feat(v0.5.8b): persistence foundation + WFIGS handler + universal cold-start grace 2026-06-05 03:54:04 +00:00
test_work_zone_renderer.py feat(content): v0.5.8-state_511_atis -- central_normalizer with Photon nearest_town + composer bypass + SB->S route normalization 2026-06-04 21:38:40 +00:00