Commit graph

56 commits

Author SHA1 Message Date
jedarden
c817e96802 feat: implement repeated-setting change detection with guided calibration
Detects when user changes same config setting 3+ times within 24 hours.
Shows non-intrusive prompt offering help with guided calibration flow.

Guided calibration features:
- Test for false positives (walk around room)
- Test for missed motion (sit still)
- Suggest optimal value based on diurnal baseline SNR and link health
- Apply suggested value button

Files:
- dashboard/js/proactive.js: Complete implementation with localStorage tracking

Acceptance:
- Help prompt fires after 3+ changes in 24h
- Calibration flow tests both directions
- Suggests value based on system data
- Apply button works
2026-04-11 00:18:19 -04:00
jedarden
d81d1cb82c feat: implement ambient dashboard mode with Canvas 2D renderer
- Added /ambient route serving ambient.html for wall-mounted tablet display
- Canvas 2D renderer at 2Hz with lerp interpolation for smooth person movement
- Time-of-day palette with 30-minute transitions (morning/day/evening/night)
- Auto-dim: reduces brightness to 40% after 60s of no presence
- Alert mode: pulsing red background for fall/security alerts
- Morning briefing overlay: 15-second overlay on first detection after 6am
- Unified alerts API for fall, anomaly, and node_offline events
- Jest test setup mocking Canvas 2D context for jsdom

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 23:16:52 -04:00
jedarden
eaad8f789a feat: implement home automation integration (MQTT and webhooks)
Implemented comprehensive home automation integration with MQTT support for
Home Assistant auto-discovery and a system-wide webhook for delivering all
Spaxel events.

MQTT Client (mothership/internal/mqtt/client.go):
- Extended MQTT client with proper Home Assistant auto-discovery payloads
- Added support for person presence binary sensors with device discovery
- Added zone occupancy sensors (count + binary occupied sensors)
- Added fall detection binary sensor with safety device class
- Added system health and system mode (select) entities
- Implemented retained message support for presence and occupancy states
- Added Last Will and Testament for availability topic
- Added exponential backoff reconnection (5s to 2min cap)
- Added discovery config cleanup (empty payload) on entity deletion

MQTT Event Publisher (mothership/internal/mqtt/publisher.go):
- Subscribes to internal event bus and publishes relevant events to MQTT
- Publishes zone entry/exit events updating person presence
- Publishes fall detection events with person/zone/timestamp info
- Publishes periodic system health updates (node count, quality, mode)
- Provides zone and person mapping for proper entity naming

System Webhook Integration (mothership/internal/webhook/publisher.go):
- System-wide webhook delivering ALL spaxel events to configured URL
- Event payload includes event_type, timestamp, zone, person, blob_id, severity
- Includes X-Spaxel-Event header with event type for routing
- Implements retry policy (one retry after 30s on 5xx errors)
- Supports concurrent event publishing with goroutine safety
- Provides TestWebhook method for configuration verification

Integration Settings API (mothership/internal/api/integrations.go):
- GET/POST /api/settings/integration for MQTT and webhook configuration
- MQTT settings: broker URL, username, password, TLS, discovery prefix
- Webhook settings: URL, enabled flag
- POST /api/settings/integration/test to test connections
- Returns connection status for MQTT (connected boolean)
- Validates URL formats and required fields

Tests:
- mothership/internal/mqtt/client_test.go: MQTT client tests including
  * Client creation with validation
  * Home Assistant discovery config format verification
  * MQTT topic generation and payload format validation
  * Retained message behavior tests
  * Broker URL parsing tests
- mothership/internal/webhook/publisher_test.go: Webhook tests including
  * Publisher creation and config updates
  * Event publishing with schema validation
  * Retry on 5xx server errors
  * Concurrent event publishing safety
  * All event type coverage
  * Test webhook delivery

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 21:17:07 -04:00
jedarden
4a4e8a114a feat: implement guided troubleshooting with proactive contextual help
Implements Component 36: Guided Troubleshooting system with proactive
contextual help and post-feedback explanations.

Backend (mothership/internal/guidedtroubleshoot/):
- Manager: Coordinates all guided troubleshooting features
- EditTracker: Monitors repeated settings edits (3 in 60min triggers hint)
- ZoneQualityTracker: Detects quality degradation (<60% for >24h)
- DiscoveryTracker: First-time feature discovery tooltips
- FleetNotifier: Node offline event handling with 2min grace period

API (mothership/internal/api/guided.go):
- GET /api/guided/issues - List active troubleshooting issues
- POST /api/guided/issues/quality/{zoneId}/dismiss - Dismiss quality banner
- POST /api/guided/feedback/response - Inline feedback response
- POST /api/guided/calibration/complete - Calibration reinforcement
- GET /api/guided/node/{mac}/troubleshoot - Node troubleshooting steps
- GET /api/guided/tooltip/{featureId} - Feature discovery tooltips
- POST /api/guided/tooltip/{featureId}/dismiss - Dismiss tooltip

Frontend:
- troubleshoot.js: Node offline cards, quality banners, calibration reinforcement
- guided-help.js: Step-by-step guides for common troubleshooting scenarios
- tooltips.js: First-time feature discovery with localStorage persistence
- feedback.js: Thumbs-up/down feedback with inline responses

Integration:
- Settings edit tracking via SetEditTracker on settingsHandler
- WebSocket events for quality_drop, repeated_edit, calibration_complete
- Hub broadcasts node status changes for FleetNotifier
- Main.go initializes guidedMgr with zones and fleet callbacks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 04:25:31 -04:00
jedarden
7969920eb2 feat: complete morning briefing feature with provider adapters and API fixes
- Wire up briefing providers (zone, person, prediction, health) in main.go
- Add notification service integration for briefing push notifications
- Fix API endpoint URLs in dashboard (simple.js and ambient.js)
- Complete settings persistence and validation for briefing configuration
- Add test notification endpoint with notify service integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 04:25:31 -04:00
jedarden
1a52dde111 feat: implement morning briefing feature
Add daily summary card with push notification option.

- Add briefings table with person and sections_json columns (migration 013)
- Implement briefing generator with sections for alerts, sleep, people, anomalies, health, predictions, and learning
- Add briefing scheduler for automatic daily generation at configurable time
- Add push notification support via notify adapter
- Add API endpoints: GET/POST /api/briefing, /api/briefing/latest, /api/briefing/settings
- Add frontend briefing card with sections styled by type
- Add briefing settings panel for configuration (time, push notifications, auto-generate)
- Add briefing indicator icon when dismissed but available
- Integrate briefing scheduler into main.go with providers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 00:25:33 -04:00
jedarden
cdd9c64800 feat: complete pre-deployment simulator implementation
Implements comprehensive pre-deployment simulator for WiFi CSI-based
positioning that allows users to predict detection quality before
purchasing hardware.

Components:
- Virtual space definition with rooms, walls, and material properties
- Virtual nodes with configurable roles (TX/RX/TX_RX/PASSIVE/IDLE)
- Synthetic walkers (random walk, path-following, node-to-node)
- GDOP overlay for coverage quality visualization
- Signal propagation model with path loss and wall attenuation
- Fresnel zone accumulation for blob detection
- REST API endpoints for simulator control
- Dashboard integration with space/node/walker management
- Coverage optimization recommendations

The simulator produces realistic synthetic CSI data matching
real-world conditions by using the same propagation models and
localization algorithms as the live system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 21:30:47 -04:00
jedarden
a70e3e433d feat: implement GDOP overlay for simulator visualization
- Add GET /api/simulator/gdop/heatmap endpoint in both simulator handlers
- Fix viz3d.js to call correct endpoint (GET instead of POST)
- Update response format handling to parse gdop_map and grid_dimensions
- Generate colors from GDOP values using quality thresholds
- Position overlay correctly in 3D scene

The GDOP overlay now visualizes accuracy metrics across the virtual space
with color-coded quality indicators (green=excellent, yellow=good, orange=fair, red=poor).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 21:30:47 -04:00
jedarden
6d975f472b feat: implement time-travel debugging and CSI replay
This commit implements the replay feature that allows users to pause the
live 3D view, scrub through a 48-hour recording buffer, and replay the 3D
scene exactly as it was at any historical moment.

Key components:
- Recording buffer with SeekToTimestamp for time-travel navigation
- Replay engine with session management (start, stop, seek, play, pause)
- Replay signal processing pipeline with tunable parameters
- REST API endpoints for replay control
- Dashboard UI with timeline scrubber, playback controls, and tuning panel
- Comprehensive test coverage for all replay functionality

Acceptance criteria met:
- Seek to any point in 48-hour window completes in < 1 second
- Replay produces identical blob positions to original live processing
- Parameter sliders re-process in < 3 seconds
- "Apply to Live" correctly writes parameter changes
- Timeline scrubber event markers correctly align
- "Back to Live" correctly resumes live detection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 19:27:42 -04:00
jedarden
245bbe89bb docs: verify REST API implementation completeness
All required REST API endpoints have been verified as implemented:

- Settings (GET/POST /api/settings): SQLite-backed with cache
- Zones & Portals (CRUD): WebSocket broadcast for live 3D view
- Automation Triggers (CRUD + test): VolumeTriggersHandler with webhook/MQTT/Ntfy
- Notifications (config + test): Inline handlers with quiet-hours support
- Replay/Time-Travel (sessions, start, stop, seek, tune): CSI recording buffer
- BLE Devices (list, update): Device registry with person assignment

All handlers include OpenAPI-style godoc comments and proper error handling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 18:18:42 -04:00
jedarden
1995b06820 feat: add anomaly_detected and sleep_session_end to valid event types
- Update isValidEventType to include anomaly_detected and sleep_session_end
- These event types were already supported in simple mode filtering
- Ensures consistency between type validation and mode filtering
2026-04-09 15:30:45 -04:00
jedarden
a48fc8134b feat: implement POST /api/events/{id}/feedback endpoint
- Add missing encoding/json import to events.go
- Add EventID field to FeedbackRequest struct
- Implement postEventFeedback handler that:
  - Returns 404 for non-existent event IDs
  - Validates feedback type (correct, incorrect, missed)
  - Delegates to feedback handler via SubmitFeedback interface
  - Falls back to logging feedback event if no handler set
- Add comprehensive tests for POST /api/events/{id}/feedback endpoint:
  - Valid feedback (correct, incorrect, missed)
  - Event not found (404)
  - Invalid event ID (400)
  - Invalid feedback type (400)
  - Invalid request body (400)
  - Feedback handler delegation with mock

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:17:47 -04:00
jedarden
2810bfec1c test: add tests for GET /api/events/{id} endpoint
- TestGetEvent_NotFound: verifies 404 for non-existent event IDs
- TestGetEvent_InvalidID: verifies 400 for invalid ID format
- TestGetEvent_HTTPHandler_Found: verifies 200 with full event details

Acceptance criteria met:
- Returns 404 for non-existent event IDs
- Returns full event details for valid IDs
2026-04-09 15:09:01 -04:00
jedarden
1a31fe658d feat: implement GET /api/events list endpoint with full query support
Implement the GET /api/events endpoint with comprehensive query parameters:
- since, until: time-range filtering (ISO8601 format)
- type: filter by event type
- person_id, zone_id: filter by person/zone (with aliases)
- limit: pagination (max 500 per page)
- mode: simple/expert mode (filters system events in simple mode)

Acceptance criteria met:
- Filtered queries use indexed columns (idx_events_time, idx_events_type, idx_events_zone, idx_events_person)
- Time-range filtering returns correct subsets with since/until parameters
- Person and zone filters return correct subsets with person_id/zone_id aliases
- Mode parameter filters system events in simple mode (excludes: node_online, node_offline, ota_update, baseline_changed, system)
- Pagination works correctly with before cursor and limit parameter

Added comprehensive tests for:
- Mode parameter (simple vs expert mode)
- person_id and zone_id parameter aliases
- Combined filters with mode parameter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 15:02:31 -04:00
jedarden
d879e2268b feat: add search and filter to timeline with category checkboxes
Implement comprehensive filter bar with:
- Type filter checkboxes for event categories (Presence, Zones, Alerts, System, Learning)
- Person and zone dropdowns for filtering
- Date range selector with preset options (Today/Last 7 days/Last 30 days/Custom)
- Text search input for fuzzy matching on descriptions
- Client-side filtering for loaded events (instant feedback)
- Server-side filtering for date-range queries
- Load more pagination works for 500+ results

Backend changes:
- Add support for 'since'/'until' date range parameters in /api/events
- Add zone_id and person_id query parameter aliases
- Add POST /api/events/{id}/feedback endpoint for feedback submission

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 14:33:33 -04:00
jedarden
54cab1e89d wip: various improvements
- Visualization improvements in 3D view
- Event API enhancements
- Replay system refinements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 13:52:10 -04:00
jedarden
2115b002d7 feat(replay): complete time-travel debugging implementation
Add time-based querying to recording store via ScanRange(), enabling
timeline scrubbing through historical CSI data. Refactor fusion engine
to interface for better testability and decoupling.

Changes:
- store.go: Add ScanRange(fromNS, toNS) for time-range queries
- worker.go: Change fusionEngine from *localization.Engine to interface
- api/replay.go: Add SetFusionEngine() method for dependency injection

Acceptance criteria met:
- Pause live mode: Dashboard Pause button + pauseLiveMode()
- Timeline scrubbing: Replay scrubber + seek API + ScanRange
- Replay 3D: BroadcastReplayBlobs() + updateReplayBlobs()
- 24h buffer: 360MB default in RecordingStore (configurable)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 13:32:48 -04:00
jedarden
38f3f311c8 feat: implement CSI simulator CLI with GDOP overlay
Implemented Go CLI tool for virtual node generation and synthetic CSI
binary frame output. Key features:

- Virtual nodes positioned at space corners/edges with mixed heights
- Synthetic CSI frames with Fresnel zone modulation and path loss
- Random walk simulation for person movement
- WebSocket connections to mothership with hello/health/BLE messages
- Authentication token support (X-Spaxel-Token header)
- Configurable space dimensions, node count, walkers, rate, and duration
- Infinite run mode (--duration 0) for manual testing
- Comprehensive test coverage for frame structure, RSSI calculation,
  Fresnel modulation, and walker position updates
- Makefile with build targets for multiple platforms
- Full documentation in README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 12:31:13 -04:00
jedarden
56c13335c3 feat: implement pre-deployment simulator with GDOP overlay
Implemented Component 17 of the Spaxel plan - a pre-deployment simulator
that allows users to define virtual spaces, place virtual nodes, and
simulate walkers to predict detection quality before purchasing hardware.

Key features:
- Virtual space definition with rooms and wall segments
- Virtual node placement with corner positioning suggestions
- Synthetic walkers (random walk and path-following modes)
- GDOP (Geometric Dilution of Precision) computation for coverage quality
- Two-ray RF propagation model (direct + first-order reflection)
- Wall penetration loss by material type (drywall, brick, concrete, glass, metal)
- Fresnel zone computation and zone decay
- Shopping list generation with hardware recommendations
- REST API endpoints for simulation control and results

Files added:
- internal/simulator/space.go - Virtual space and room definitions
- internal/simulator/node.go - Virtual node management
- internal/simulator/walker.go - Synthetic walker simulation
- internal/simulator/gdop.go - GDOP computation and coverage analysis
- internal/simulator/propagation.go - RF propagation model
- internal/simulator/engine.go - Simulation engine (bug fixes)
- internal/simulator/handler.go - HTTP API handlers
- internal/api/simulator.go - REST API endpoints
- internal/simulator/simulator_test.go - Comprehensive tests
- internal/simulator/space_test.go - Space definition tests

Integration:
- Simulator API registered in main mothership server at /api/simulator/*
- Endpoints for space, nodes, walkers, GDOP computation, and simulation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 12:10:53 -04:00
jedarden
eb6e479bea feat: implement detection explainability system
Add X-ray overlay showing contributing links to detections with confidence breakdown.

- Users can click "Why?" on any blob to see detailed explanation
- Contributing links are highlighted with Fresnel zone visualization
- Per-link contribution breakdown shows deltaRMS, zone number, weight
- BLE identity match details displayed when available
- Confidence gauge shows overall detection certainty

Explainability is accessible via:
- Right-click context menu on blob figures
- "Why?" button in blob hover tooltip
- Click directly on humanoid blob figures
- Timeline event "Why?" buttons

Accepts: Users can see exactly why a detection was triggered with visual overlays and confidence metrics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:48:55 -04:00
jedarden
0cb2353a08 feat: implement activity timeline with tap-to-jump and inline feedback
Phase 8 implementation: Activity Timeline (Component 27)

- Tap-to-jump navigation: Click any event to create replay session and seek to that moment
- Inline feedback display: Thumbs up/down buttons on each event for detection feedback
- Replay API integration: Creates replay window around event timestamp (±5 seconds)
- Feedback API: New /api/feedback endpoint for correct/incorrect/missed detection reports
- Event loading improvements: Real-time WebSocket event insertion with animation
- Filter UI: Type, zone, person, time range, and search filters
- Load more pagination: Keyset cursor-based pagination for large event sets

Acceptance criteria met:
- Users can view all system events chronologically
- Tap any event to jump to that moment in time via replay mode
- Inline feedback buttons allow marking detections correct/incorrect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 11:07:16 -04:00
jedarden
af8800caef feat: add self-improving localization REST API
Implement REST API endpoints for managing learned weights and tracking
improvement in the self-improving localization system.

- Add LocalizationHandler with endpoints for:
  - GET /api/localization/weights - get all learned link weights
  - GET /api/localization/weights/{linkID} - get specific link weight
  - POST /api/localization/weights/reset - reset all weights to default
  - GET /api/localization/spatial-weights - get spatial weights per zone
  - GET /api/localization/groundtruth/* - ground truth sample management
  - GET /api/localization/accuracy/* - position accuracy tracking
  - GET /api/localization/learning/* - learning progress and history

- Integrate spatial weight learner into fusion engine:
  - Add AddLinkInfluenceWithSpatialWeights to grid.go for per-cell weight application
  - Update Fuse() in fusion.go to use spatial weight functions when available
  - Apply both sigma adjustments and spatial weights for Fresnel zone computation

- Add comprehensive table-driven tests for all API endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 10:06:06 -04:00
jedarden
ef75a823fc feat: implement presence prediction REST API endpoints
Implemented prediction API handler with comprehensive REST endpoints:

- GET /api/predictions - Get all predictions (optional filter by person/horizon)
- GET /api/predictions/stats - Get prediction statistics and data age
- POST /api/predictions/recompute - Force probability recomputation
- GET /api/predictions/accuracy - Get accuracy stats for all people
- GET /api/predictions/accuracy/overall - Get overall system accuracy
- GET /api/predictions/accuracy/{personID} - Get person-specific accuracy
- GET /api/predictions/pending - Get pending prediction count
- GET /api/predictions/patterns/zones - Get zone occupancy patterns
- GET /api/predictions/patterns/zones/{zoneID} - Get pattern for specific zone
- POST /api/predictions/patterns/compute - Compute zone occupancy patterns
- GET /api/predictions/horizon - Get Monte Carlo horizon predictions
- GET /api/predictions/horizon/{personID} - Get horizon prediction for person

The implementation includes:
- Proper error handling with appropriate HTTP status codes
- Query parameter support for filtering (person, horizon)
- JSON responses for all endpoints
- Helper function for logging prediction accuracy
- Table-driven tests for all endpoints

HA sensor exposure for predictions was already implemented in the MQTT
client via PublishPredictionSensors() and UpdatePredictionState() methods.

Accepts the 75% accuracy target at 15-minute horizon per specification.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 09:59:42 -04:00
jedarden
15c491ffea feat: implement anomaly detection and security mode
Implements comprehensive anomaly detection system that learns normal household
patterns over 7+ days and alerts on deviations. Transforms spaxel into a basic
home security system.

Core features:
- Normal behaviour model: statistical tracking of occupancy patterns per
  (hour_of_week, zone_id) slot with expected occupancy, typical person count,
  and typical BLE devices
- Four anomaly types: unusual hour presence, unknown BLE device, motion during
  away mode, unusual dwell duration
- Security mode: lowered thresholds, immediate alerts, bypasses quiet hours
- Auto-away/disarm: automatic security mode activation based on BLE device
  presence (15min absence, auto-disarm on device return)
- Alert chain: staged notifications (dashboard → push → webhook → escalation)
- WebSocket integration: real-time anomaly broadcasts to dashboard

API endpoints:
- GET/POST /api/mode: system mode control (home/away/sleep)
- GET /api/security/status: current security state

Tests cover all anomaly types, alert chain timing, security mode thresholds,
auto-away/disarm, acknowledgement flow, and cooldown deduplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 09:48:44 -04:00
jedarden
50856415b3 feat: add diurnal baseline REST API endpoints
Add REST API for diurnal baseline data:
- GET /api/diurnal/status - learning status for all links
- GET /api/diurnal/slots/{linkID} - slot data for specific link

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 08:53:31 -04:00
jedarden
636f3efba2 feat: complete anomaly detection & security mode dashboard UI
- Add anomaly.css and sleep.css to dashboard includes
- Add sleep.js for sleep quality monitoring
- Implement analytics API handler (flow, dwell, corridors)
- Add tracks API and tests for time-based data queries
- Add sleep monitor tests
- AnomalyDetector initialized and running in main()
- Anomaly events broadcast via WebSocket to dashboard
- Security mode arm/disarm persists across restarts (learning_state table)
- Learning progress tracking and display
- Alert banner with acknowledge functionality
- All API endpoints wired: /api/anomalies, /api/security/*, /api/analytics/*

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-09 05:59:54 -04:00
jedarden
b1c2218146 feat: wire anomaly detection & security mode API endpoints
AnomalyDetector initialized in main() with periodic model updates.
Anomaly events broadcast to dashboard WS as 'alert' messages via
BroadcastAlert. GET /api/anomalies?since=24h lists recent events.
POST /api/security/arm and /api/security/disarm manage security mode.
GET /api/security/status returns armed state, learning progress, and
24h anomaly count. Arm/disarm state persisted to learning_state table
and restored on restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 15:09:34 -04:00
jedarden
6a1ae97324 feat: verify zones CRUD REST endpoints with full test coverage
Zones CRUD (GET/POST/PUT/DELETE /api/zones) and portals CRUD already
implemented with OpenAPI godoc comments, WebSocket broadcasting via
ZoneChangeBroadcaster for live 3D view updates, and 31 table-driven
tests covering all endpoints, edge cases, and broadcast behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 15:00:32 -04:00
jedarden
45f00e184a feat: add missing name-required validation test for zone creation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 15:00:32 -04:00
jedarden
aca74c05c4 feat: wire anomaly detection & security mode API endpoints
Confirm AnomalyDetector initialization in main(), wire anomaly event
broadcasts to dashboard WS as alert messages, and verify all security
mode endpoints (arm/disarm/status) return correct JSON with persistent
state across restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 14:47:44 -04:00
jedarden
bf40673b72 feat: wire anomaly detection & security mode API endpoints
AnomalyDetector is initialized in main() with periodic model updates.
Anomaly events are pushed to dashboard WS as 'alert' messages via
BroadcastAlert callback. Security mode arm/disarm state persists
across restarts via SQLite learning_state table.

Endpoints:
- GET /api/anomalies?since=24h — list recent anomaly events
- POST /api/security/arm — enable security mode
- POST /api/security/disarm — disable security mode
- GET /api/security/status — armed, learning_until, anomaly_count_24h

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 14:36:59 -04:00
jedarden
008d3caa60 feat: fix floorplan table schema and create /data/floorplan directory
- Fix migration 001 floorplan schema: use distance_m instead of cal_distance_m,
  and rotation_deg instead of room_bounds_json
- Update migration 010 to ALTER existing floorplan tables for databases
  that already ran migration 001
- Create /data/floorplan directory in db.OpenDB for storing floor plan images
2026-04-07 14:20:38 -04:00
jedarden
04129addd3 feat: implement Zones CRUD REST endpoints with OpenAPI docs
- GET/POST /api/zones - list and create zones with JSON responses
- PUT /api/zones/{id} - update existing zone
- DELETE /api/zones/{id} - delete zone
- All endpoints return JSON with proper HTTP status codes
- OpenAPI/Swagger annotations present (@Summary, @Description, @Tags, @Router, etc.)
- Table-driven tests for all CRUD operations

Acceptance criteria met:
- Endpoints respond correctly to HTTP requests
- Godoc annotations present for API documentation
2026-04-07 14:13:08 -04:00
jedarden
98c43b3734 feat: wire NTP client into firmware build and initialization 2026-04-07 13:38:13 -04:00
jedarden
f851ede69e feat: wire anomaly detection & security mode API endpoints
- AnomalyDetector initialized and running in main() with periodic updates
- Anomaly events pushed to dashboard WS feed as 'alert' messages
- GET /api/anomalies?since=24h lists recent anomaly events
- POST /api/security/arm + /api/security/disarm endpoints
- GET /api/security/status returns armed, learning_until, anomaly_count_24h
- Arm/disarm state persists via learning_state SQLite table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 13:20:54 -04:00
jedarden
31659a5ccc fix: resolve TestTimeoutDoesNotDisable hang in trigger tests
Replace httptest.Server with raw net.Listen to avoid Close() blocking
on active connections after a timeout, which caused the test to hang
indefinitely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 12:34:35 -04:00
jedarden
0377426926 fix: wire anomaly detection & security mode API endpoints
- Add missing CountAnomaliesSince method to mockDetectorProvider
  in security_test.go to satisfy the DetectorProvider interface
- Fix variable shadowing bug in anomaly.go QueryAnomalyEvents
  where incomplete rename from 'events' to 'result' caused
  append(events, &e) to reference the package instead of the slice

All security mode endpoints verified:
- GET /api/anomalies?since=24h — lists recent anomaly events
- POST /api/security/arm + /api/security/disarm — arm/disarm
- GET /api/security/status — {armed, learning_until, anomaly_count_24h}
- Anomaly events push to dashboard WS as 'alert' messages
- Arm/disarm state persists across restarts via learning_state table

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 12:10:01 -04:00
jedarden
5db3110a2a feat: implement automation triggers CRUD REST endpoints
Add full CRUD endpoints for triggers with OpenAPI-style godoc comments:
- GET/POST /api/triggers (list all, create new)
- PUT/DELETE /api/triggers/{id} (update, delete)
- POST /api/triggers/{id}/test (fire trigger once for testing)

Both TriggersHandler (simple) and VolumeTriggersHandler (3D geometry)
implement all endpoints with table-driven tests covering validation,
persistence, and round-trip lifecycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 11:38:34 -04:00
jedarden
e44dd345f6 feat: implement comprehensive /healthz endpoint
Add complete health check implementation for Docker HEALTHCHECK and
Traefik health routing with:

Response fields:
- status: "ok" or "degraded"
- uptime_s: seconds since mothership boot
- version: mothership version string
- nodes_online: count of connected nodes
- db: "ok" or "failing" (SELECT 1 with 100ms timeout)
- load_level: 0-3 from load shedding state
- reason: human-readable explanation (only when degraded)

HTTP status codes:
- 200 for healthy (status="ok")
- 503 for degraded (status="degraded")

Degraded conditions:
- Database unreachable
- Load level 3 sustained for >60 seconds
- No nodes connected after 5 minutes uptime

Docker HEALTHCHECK updated to verify status="ok" response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 11:09:36 -04:00
jedarden
9f53218f16 fix: correct no-op trigger update test expectation
The "no-op update returns current" test case was missing wantEnable: true,
causing a false negative since the seeded trigger has Enabled: true.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 10:21:02 -04:00
jedarden
3d3cb41d25 feat: add security mode persistence and tracker blob lifecycle events
- Add GetArmedAt() method to persist armed timestamp across restarts
- Add blob appear/disappear callbacks to tracker for security events
- Add security handler for arm/disarm API endpoints
- Update /api/security endpoint to return armed_at timestamp
- Add tracker tests for blob lifecycle callbacks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 10:14:51 -04:00
jedarden
01547269cc feat: verify dashboard WebSocket feed supports events, alerts, BLE, triggers, health
All 5 new message types (event, alert, ble_scan, trigger_state,
system_health) were already implemented in hub.go with broadcast methods,
called from main.go/ingestion/volume_triggers/events, and handled in
app.js. Also includes security mode persistence from anomaly DB and
OpenAPI docs for triggers endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:54:14 -04:00
jedarden
fe68bb5fdc feat: implement BLE Devices REST endpoints with OpenAPI docs
- GET /api/ble/devices: list all BLE devices with filtering
- PUT /api/ble/devices/{mac}: update device label and assign to person
- Added comprehensive OpenAPI-style godoc comments
- Supports filtering by registered/discovered/archived status
- Includes device history and aliases endpoints
2026-04-07 09:36:32 -04:00
jedarden
56c28bce63 feat: implement BLE Devices REST endpoints with OpenAPI docs
- Add GET /api/ble/devices to list known devices with filtering
- Add PUT /api/ble/devices/{mac} to set label and assign to person
- Add comprehensive OpenAPI-style godoc comments for all BLE endpoints
- Add table-driven tests for BLE handler endpoints

Endpoints support:
  - Filtering by registration status (registered/discovered)
  - Time window filtering (hours parameter)
  - Device labels and person assignment
  - Sighting history per device

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:30:55 -04:00
jedarden
a873663cfc feat: implement Replay/Time-Travel REST endpoints
Add OpenAPI-style godoc comments and comprehensive table-driven tests
for replay endpoints:
- GET /api/replay/sessions - list recording sessions and replay store info
- POST /api/replay/start - start replay at timestamp (speed 1/2/5)
- POST /api/replay/stop - stop replay, return to live
- POST /api/replay/seek - seek within session
- POST /api/replay/tune - update pipeline parameters mid-replay

Improvements:
- Fix writeJSON calls to use proper 3-argument signature
- Add detailed request/response type documentation
- Add mockRecordingStore for isolated unit testing
- Add 12 table-driven test cases covering all endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:19:36 -04:00
jedarden
86a373debb feat: implement Notifications REST endpoints
- GET /api/notifications/config to get all delivery channel settings
- POST /api/notifications/config to set channel configurations
- POST /api/notifications/test to send test notifications
- Support for ntfy, pushover, gotify, webhook, and mqtt channel types
- Config validation for each channel type
- Table-driven tests for all endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:11:01 -04:00
jedarden
72b340d03a feat: implement Settings REST endpoints
Implement GET and POST/PATCH /api/settings endpoints with:

- GET /api/settings: Returns all configurable settings as JSON with
  default values merged in for any settings not explicitly set

- POST/PATCH /api/settings: Partial update with merge semantics,
  only updating the keys provided in the request body

- SQLite persistence: Settings stored in settings table with
  JSON-encoded values, loaded on startup

- Comprehensive validation: All known settings validated with
  proper range checks (fusion_rate_hz, grid_cell_m, delta_rms_threshold,
  tau_s, fresnel_decay, n_subcarriers, breathing_sensitivity,
  motion_threshold, dwell_seconds, vacant_seconds, max_tracked_blobs,
  replay_retention_hours, replay_max_mb, security_mode,
  events_archive_days)

- OpenAPI-style godoc comments: Documentation for all endpoints
  using swagger annotations

- Table-driven tests: Comprehensive test coverage for all
  functionality including GET, POST, PATCH, validation,
  persistence, and error cases

- Helper utilities: Extracted writeJSON, writeJSONError,
  writeJSONData to utils.go for reuse

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 09:04:55 -04:00
jedarden
5b24192186 feat: add trigger_state WebSocket message type to /ws/dashboard feed
Broadcasts { type: 'trigger_state', trigger: { id, name, last_fired, enabled } }
on trigger fire, enable, and disable events. Handled in app.js onmessage
and forwarded to window.Automations.updateTriggerState().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 08:41:17 -04:00
jedarden
b99599c403 fix: resolve Phase 6 build integration issues
- Fix unclosed brace in main.go (if zonesMgr block swallowed 1831 lines)
- Add missing resolveBlobIdentity helper function
- Apply worker changes to zones, automation, sleep, briefing, ingestion, localization, db

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 02:31:02 -04:00
jedarden
ad1e17ddf2 feat: implement SQLite Online Backup API streaming endpoint
Use modernc.org/sqlite's Online Backup API (NewBackup/Step/Commit)
with in-memory destination and Serialize for consistent hot backups
without temp files. Streams zip directly to HTTP response.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 02:15:51 -04:00