# Implementation Plan: Streaming Simplification (WebRTC-only) ## 0) Goal and scope ### Goal Simplify the current streaming architecture to a single production-pragmatic implementation path: - Control plane via REST + socket signaling - Media plane via WebRTC only - No JPEG frame fallback relay - Preserve security and device-role authorization ### Scope in/out - In scope: - Stream request/accept/end lifecycle - Device role and ownership checks - WebRTC signaling and connection setup/teardown - Frontend Web + Mobile stream runtime paths - API/docs updates for simplified contract - Out of scope: - Multi-party broadcast or conferencing - SFU/ingest pipeline replacement in this phase - Media provider feature parity with mock provider URLs - Full recording workflow and upload/finalization ## 1) Current-state constraints to keep - Devices use bearer tokens and role-based socket/session authentication. - Stream request is initiated by a `client` device targeting a linked `camera`. - Current schema/event names exist and are used across components. - Backend and frontends already support `stream:requested`, `stream:started`, `stream:ended`, and `webrtc:signal`. ## 2) Explicit requirements 1. Runtime complexity reduction: - Keep one media transport: WebRTC. - Remove socket JPEG fallback flow from runtime. 2. Reliability and safety: - Keep strict owner/role checks for all stream/session endpoints. - Ensure deterministic teardown when stream ends. 3. Maintainability: - Remove dead or non-critical branches. - Minimize special-case flags and dual state machines. 4. Backward compatibility strategy: - Prefer a feature flag `SIMPLE_STREAMING` for controlled rollout. ## 3) Assumptions - Existing database schema can remain (deprecating fields is acceptable for now). - Camera and client are expected to be online for primary WebRTC path; if not reachable, stream request/accept will fail gracefully. - `stream:frame` is not required for core user value in phase 1. - Recording features can be delayed or gated without blocking stream acceptance. - Existing command dispatch infrastructure can be simplified or replaced by direct request/session events without redesigning auth. ## 4) Non-goals and excluded behaviors - No immediate migration to true production-grade media server or SFU. - No auto-retry queue for offline command delivery. - No new codec/transcoding pipeline. ## 5) Target architecture ### Backend - Stream endpoints: request -> accept -> end. - Session state transitions: - `requested` -> `streaming` -> `ended` - Commands table may be retained only for audit/logging or removed later. - Gateway relays: - `webrtc:signal` only for media negotiation. - `stream:started` and `stream:ended` for lifecycle updates. ### Frontend (Web + Mobile) - Shared runtime model: - `idle` -> `connecting` -> `active` -> `ended` - On camera accept: start WebRTC offer. - On client started event: start WebRTC answer/handling. - On ended: stop peer connections, clear state. - No frame image fallback state/UI. ## 6) Phased implementation strategy ### Phase 1: Contract freeze and safety gate (Day 0) 1. Lock simplified state contract and event matrix. 2. Add/validate `SIMPLE_STREAMING` flag and default behavior. 3. Add migration notes for legacy paths. ### Phase 2: Backend control-plane simplification (Day 1) 1. Refactor stream request/accept/end handlers to only manage session lifecycle and signaling. 2. Remove/disable stream-provider-specific runtime side effects from these handlers. 3. Ensure response payloads are minimal and stable. ### Phase 3: Gateway simplification (Day 1) 1. Remove `stream:frame` event handler and related relay state. 2. Keep only validated WebRTC signaling and lifecycle event emitters. 3. Remove command retry loop if not required by flag. ### Phase 4: Web frontend simplification (Day 2) 1. Simplify stream controller into single mode. 2. Remove image fallback flow and related timers/state. 3. Keep single video render path and deterministic cleanup. ### Phase 5: Mobile frontend simplification (Day 2) 1. Remove periodic frame capture/relay code and image fallback rendering. 2. Keep camera capture + WebRTC publish path. 3. Align end/cleanup behavior with web. ### Phase 6: API/doc/ops cleanup (Day 3) 1. Update OpenAPI/event docs and internal docs. 2. Deprecate references to frame-based streaming and mock endpoints in code comments. 3. Add rollout and rollback runbook. ### Phase 7: Validation and rollout (Day 4) 1. Manual runtime smoke tests for request/accept/offer/answer/end. 2. Validate unauthorized access rejection for all endpoints. 3. Rollout in flag-off/flag-on modes and monitor. ## 7) Sequence and dependency reasoning - Backend simplification must land before frontend simplification to avoid client calling removed paths. - Gateway simplification is independent after stream endpoints are stable but should be merged before frontend hardening. - Frontend changes rely on a stable event contract (`webrtc:signal`, `stream:started`, `stream:ended`). - Docs/validation are final tasks once behavior stabilizes. ## 8) Failure handling and risk controls 1. **Rollback strategy:** feature flag switch routes behavior back to existing legacy logic. 2. **Forward progress gate:** stream accept/start should not require any media provider credential. 3. **Safety gate:** reject unknown/non-matching event payloads in gateway before forwarding. 4. **Error handling:** explicit peer connection cleanup on timeout/error and session end. 5. **Observability:** structured logs for request/accept/offer/answer/hangup/end with stream session ids. ## 9) Acceptance criteria 1. `client` -> request -> camera `accept` -> live WebRTC stream works on web and mobile. 2. No `stream:frame` event is used in runtime media path. 3. Stream teardown always emits `stream:ended`, clears peer connections, and stops capture. 4. Unauthorized role/device combinations are rejected with explicit errors. 5. OpenAPI and internal docs only advertise simplified contract by default. 6. Feature flag allows toggling between simplified and legacy behavior for quick rollback.