7 KiB
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:
- Given tenant VM112 com todos checks verdes, When overview carrega, Then card mostra
healthye score8/8. - Given check DKIM falhou, When overview carrega, Then card mostra
degradede lista check falhado. - Given tenant API inacessível, When collector falha, Then card mostra
unknowncom 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:
- Given domínio com SPF correcto, When scorecard renderiza, Then check
spf= pass com valor detectado. - Given certificado expira em < 14 dias, When scorecard renderiza, Then check
cert= warn. - 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:
- Given worker activo, When passam 10 minutos, Then
last_audit_atactualiza. - Given collector DNS timeout, When falha, Then check marcado
errorcom 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:
- Given evento
account.createdparafoo.com, When próximo audit cycle, Thenfoo.comentra 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(já usado porvm112/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 — só collectors determinísticos.
Dependencies
- Constitution v1.0.0
- Tenant registry (tabela
tenantsexistente) - Worker Redis container existente em VM122
- Feature 004 opcional (auto-domínios) — pode usar só
account.createdevents já 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 |