The IPAWS civil-alert adapter shipped backend-complete but frontend-partial:
it rendered only in the generic adapter-config page and the Advanced (raw)
Data Feeds tab, and the `emergency` family was absent from the curated Data
Feeds panel, the family-settings toggles, and the MeshCore routing matrix.
Adapter (ipaws), benchmarked against firms/nws:
- Environment.tsx: add `ipaws` to AdapterKey union, EnvConfig interface,
META (native-only, keyless), a new `emergency` FAMILIES group, PANEL_META_KEY
(LLM toggle), and a hand-written renderSettings panel exposing base_url,
user_agent, tick_seconds, state_fips, same_codes, exclude_weather,
status_actual_only — with coverage-scope handling like the other adapters.
- Environment.tsx: IPAWS_DEFAULT backfill so pre-ipaws GET payloads don't crash.
- Dashboard.tsx: SOURCE_ICONS entry (Siren/IPAWS) so ipaws events aren't a slug.
- ActivityLog.tsx: TABLE_LABELS + CATEGORIES + text-hint so ipaws_alerts rows
show labeled "Emergency" and honor the category filter.
- dispatcher.py: _SOURCE_TO_TABLE fallback ipaws -> ipaws_alerts so region-routed
emergency sends land labeled in the audit feed (not NULL).
Family (emergency), benchmarked against fire:
- Notifications.tsx: add `emergency` to TOGGLE_FAMILY_META (Siren icon). This
cascades to Family Settings, the Meshtastic delivery matrix, and the MeshCore
routing matrix (the last was hardcoded to the static list and previously
omitted emergency entirely). Backend VALID_TOGGLES/gating/categories were
already complete — no backend family change needed.
Tests: update the _SOURCE_TO_TABLE exact-match guard and add an ipaws audit-row
parity test. Full suite 2407 passed / 6 pre-existing unrelated failures.
Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Backend: add _SOURCE_TO_TABLE class constant in Dispatcher mapping event.source
("nws", "nifc", "wzdx", "traffic", "511") to canonical audit table names.
_post_broadcast_commit now falls back to this map when _broadcast_audit is
absent/None, so native env adapter sends (nws.py, fires.py, wzdx.py,
roads511.py, traffic.py) write a non-NULL source_event_table instead of NULL.
Existing _broadcast_audit paths (Central handlers, scheduled broadcasts) are
unchanged.
Frontend: replace naive familyLabel() string transform with explicit
TABLE_LABELS lookup (10 known tables → friendly names) plus a TEXT_HINTS
emoji-prefix heuristic for legacy NULL-source rows, so historical orphan rows
still display a meaningful label before/after backfill.
Tests: three new unit tests in test_dispatcher_persistence.py covering the
fallback path (nws→nws_alerts), the full _SOURCE_TO_TABLE map, and that
explicit _broadcast_audit is never overridden by the fallback.
Co-authored-by: Matt Johnson <mj@k7zvx.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move all application source (meshai/, dashboard-frontend/, tests/,
config/, docs/, Dockerfile, etc.) into work/ directory
- Add Node.js multi-stage build to Dockerfile for frontend compilation;
remove compiled static assets from git tracking
- Fix satpass missing time windows: consolidation was splitting wire on
newline and only putting line 1 in event.title, dropping the time
window line that the composer uses for precomposed broadcasts
- Fix satpass burst flooding: stagger consolidation timers (+60s per
pending pass) so Central batch publishes don't blast the mesh
- Update CI workflow build context to work/
- Anchor lib/ and data/ gitignore patterns to repo root to prevent
false matches on nested directories
- Add dashboard-frontend/node_modules/ to .dockerignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>