# Fase 10 — Eventos ONVIF (opcional ao MVP)

**Status:** concluída neste ambiente de desenvolvimento  
**Data:** 2026-08-19  
**Serviço:** `ipcam-events.service`

## Contexto de desenvolvimento

Ainda **não há câmeras reais**. O poller ONVIF **não** alcança 192.168.20.x.  
Validação no lab: `php artisan ipcam:demo-event` (evento interno no Simulador lavfi).

## Princípio

Gravação **não depende** de eventos. Câmera “só vídeo” é cidadã de primeira classe.  
O poller é systemd separado — **não** spawna FFmpeg e **não** liga/desliga o Recorder.

Modelo genérico `camera_events` (`type`, `source=onvif|internal|adapter`, payload JSONB).  
Classificação pelo **tópico ONVIF padrão** (`Motion`, `DigitalInput`, `LineDetector`…), sem `if fabricante`.

## O que foi entregue

- Tabela `camera_events` + `EventIngestor` (idempotente, redige senha)
- `OnvifEventClient` PullPoint (CreatePullPoint → PullMessages → Unsubscribe)
- `ipcam:events` / `ipcam-events.service` — ignora lavfi / câmera sem Events
- `ipcam:demo-event` para o simulador
- Timeline: marcadores rosa (movimento) + lista curta no player
- Descoberta ONVIF passa a gravar `events_url` quando a câmera anunciar Events

## Aceite

| Critério | Resultado |
|---|---|
| Movimento na timeline (lab/demo) | OK |
| Sem afetar gravação | OK (poller não toca FFmpeg / `recording_enabled`) |
| Sem `if fabricante` | OK |
| Simulador sem ONVIF não quebra o poller | OK (skip) |
| JSON da timeline sem path/senha | OK |

## Fora desta fase

Carga 60 simuladas (Fase 11 — concluída neste lab com teto de FFmpeg), PoC reencode (Fase 12 — **NO-GO** neste lab), cutover, WebRTC.
