ligbox-ops-platform/specs/009-ops-audit-overview/spec.md
Ligbox Spec Hub 3a2c64834b Initial import: ligbox-ops-platform + specs + LAPTOP + obsidian merge (CT130)
Source: VM122 /opt + obsidian-infra + LAPTOP
Hub: CT130 spec-hub 10.10.10.130
2026-06-19 17:26:41 +00:00

158 lines
7 KiB
Markdown

# Feature Specification: Audit Overview Dashboard (009)
**Feature Branch**: `009-ops-audit-overview`
**Created**: 2026-06-08
**Status**: Draft
**Input**: Dashboard estilo Cloudflare Ops — health e scorecard por tenant/EmailServer (~10 nós), com 8 checks read-only alinhados ao portal onboarding. Primeira entrega do Track A (AUD-1, AUD-2, AUD-3).
**Depends on**: MVP Ops VM122 (API, worker, tenants table); VM112 como primeiro tenant auditado
## User Scenarios & Testing *(mandatory)*
### User Story 1 — Overview multi-tenant (Priority: P1)
A equipa ops abre `/ops/overview` (ou tab Infra expandida) e vê cards por tenant registado com estado global: OK / Atenção / Crítico.
**Why this priority**: Core da visão "painel cheio de informação" — saúde de todos os nós num ecrã.
**Independent Test**: Com VM112 registada, overview mostra card com score 6/8 checks OK.
**Acceptance Scenarios**:
1. **Given** tenant VM112 com todos checks verdes, **When** overview carrega, **Then** card mostra `healthy` e score `8/8`.
2. **Given** check DKIM falhou, **When** overview carrega, **Then** card mostra `degraded` e lista check falhado.
3. **Given** tenant API inacessível, **When** collector falha, **Then** card mostra `unknown` com timestamp última tentativa.
---
### User Story 2 — Scorecard 8 checks por domínio (Priority: P1)
Por tenant, a equipa vê detalhe dos 8 checks alinhados ao wizard portal: Carbonio, nginx/vhost, certificado LE, MX, SPF, DKIM, DMARC, webmail HTTP.
**Why this priority**: Diagnóstico actionable — sabe exactamente o que corrigir sem SSH manual.
**Independent Test**: Abrir scorecard VM112 para `diarissima.com` (ou domínio activo) e ver 8 linhas com pass/fail.
**Acceptance Scenarios**:
1. **Given** domínio com SPF correcto, **When** scorecard renderiza, **Then** check `spf` = pass com valor detectado.
2. **Given** certificado expira em < 14 dias, **When** scorecard renderiza, **Then** check `cert` = warn.
3. **Given** webmail responde HTTP 200, **When** check `webmail`, **Then** pass com URL testada.
---
### User Story 3 — Collectors automáticos (Priority: P1)
Worker Ops executa collectors read-only periodicamente (sem alterar sistemas remotos) e persiste snapshots.
**Why this priority**: Dados frescos sem refresh manual; base para alertas futuros.
**Independent Test**: Após ciclo worker (≤ 15 min), `GET /api/v1/audit/overview` reflecte dados novos.
**Acceptance Scenarios**:
1. **Given** worker activo, **When** passam 10 minutos, **Then** `last_audit_at` actualiza.
2. **Given** collector DNS timeout, **When** falha, **Then** check marcado `error` com mensagem; outros checks continuam.
---
### User Story 4 — Domínios monitorizados (Priority: P2)
Cada tenant pode ter 1+ domínios monitorizados (inicialmente domínios vistos em eventos onboarding ou lista manual).
**Why this priority**: EmailServers multi-domínio; MVP pode começar com domínio principal do tenant.
**Independent Test**: Domínio de evento `account.created` aparece automaticamente em scorecard.
**Acceptance Scenarios**:
1. **Given** evento `account.created` para `foo.com`, **When** próximo audit cycle, **Then** `foo.com` entra em domínios monitorizados do tenant VM112.
---
### Edge Cases
- Tenant sem domínios conhecidos: scorecard vazio com hint "aguardar onboarding".
- Check intermitente (DNS): último resultado + contagem falhas consecutivas.
- VM112 portal down: checks locais Carbonio via API read-only falham gracefully.
- Múltiplos tenants (futuro 10 nós): overview pagina ou scroll; MVP suporta 3.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: Ops DEVE expor `GET /api/v1/audit/overview` lista tenants com status agregado e score.
- **FR-002**: Ops DEVE expor `GET /api/v1/audit/tenants/{id}/scorecard?domain=` 8 checks detalhados.
- **FR-003**: Worker DEVE executar collectors a cada `AUDIT_INTERVAL_SEC` (default 600s).
- **FR-004**: Collectors DEVEM ser read-only sem zmprov write, sem alterar DNS/Traefik.
- **FR-005**: Os 8 checks MVP: `carbonio`, `nginx_vhost`, `cert_le`, `dns_mx`, `dns_spf`, `dns_dkim`, `dns_dmarc`, `webmail_http`.
- **FR-006**: Resultado por check: `pass` | `warn` | `fail` | `error` | `skip` + `message` + `checked_at`.
- **FR-007**: Persistência em SQLite: tabelas `audit_domains`, `audit_checks` (último snapshot por tenant+domain+check).
- **FR-008**: UI DEVE ter view **Overview** (ou expandir Infra) com grid de cards tenant.
- **FR-009**: UI DEVE permitir drill-down scorecard por tenant/domínio.
- **FR-010**: Domínios auto-registados a partir de eventos webhook `account.created` / `onboarding.completed`.
- **FR-011**: VM112 primeiro tenant: collectors usam API portal read-only (`/onboarding/infrastructure/status/{domain}`, `/dns/verify/{domain}`) + HTTP externo DNS/webmail.
### Key Entities
- **Audit Domain**: tenant_id, domain, source (`onboarding` | `manual`), added_at.
- **Audit Check**: check_id, status, message, evidence (JSON), checked_at.
- **Tenant Health**: aggregated from worst check status.
### Status aggregation rules
| Pior check | Tenant status |
|------------|---------------|
| fail | critical |
| error | critical |
| warn | degraded |
| pass/skip | healthy |
## Success Criteria *(mandatory)*
- **SC-001**: Overview carrega em < 2s com 3 tenants e 5 domínios.
- **SC-002**: 8/8 checks executados para domínio activo VM112 em ciclo worker.
- **SC-003**: Equipa identifica problema deliverability (SPF/DKIM/DMARC) via scorecard sem SSH.
- **SC-004**: Dados actualizados automaticamente 15 min (configurável).
- **SC-005**: Zero writes em sistemas remotos durante audit (verificável por logs).
## Assumptions
- VM112 portal API acessível na LAN `:8090` ( usado por `vm112/status`).
- Checks DNS via resolver público (8.8.8.8) ou biblioteca dns.resolver read-only.
- Webmail check: HEAD/GET `https://mail.{domain}/` timeout 10s.
- Cert check: expiry via portal infra status ou TLS handshake directo.
- Postgres não necessário SQLite suficiente para MVP.
- Agentes IA (AUD-4) fora de scope collectors determinísticos.
## Dependencies
- Constitution v1.0.0
- Tenant registry (tabela `tenants` existente)
- Worker Redis container existente em VM122
- Feature 004 opcional (auto-domínios) pode usar `account.created` events existentes
## Out of Scope
- Agentes IA A1/A2/A3 (AUD-4, AUD-5)
- Alterações automáticas / remediation
- Poll Wazuh API
- Auth RBAC (003)
- Alertas email/ntfy por check fail
- 10 tenants hardcoded registo manual OK para MVP além de VM112
## The 8 Checks (aligned portal)
| ID | Check | Fonte read-only |
|----|-------|-----------------|
| 1 | carbonio | Portal ou zmprov read via API VM112 |
| 2 | nginx_vhost | `infrastructure/status` carbonio_nginx_vhost |
| 3 | cert_le | infra status cert expiry |
| 4 | dns_mx | DNS lookup MX mail.{domain} |
| 5 | dns_spf | DNS TXT SPF |
| 6 | dns_dkim | DNS TXT default._domainkey |
| 7 | dns_dmarc | DNS TXT _dmarc |
| 8 | webmail_http | HTTPS mail.{domain} status code |