8.6 KiB
Feature Specification: Domínios VM112 — Purge & Histórico (017)
Criado: 2026-06-16
Actualizado: 2026-06-16 (v2 — histórico de purges)
Solicitado por: Roger
Status: v1 + v2 concluídos · Fase 3 VM112 pendente
Prioridade: P1 (testes E2E + padrão de limpeza)
Sistema: Desk VM122 + Wizard VM112
Módulo: vm112-domains
UI purge: página Serviços (Spec 018)
UI histórico: Eventos → Histórico de purges
Resumo
Técnicos Admin (super_admin, ops_lead) executam purge completo de domínios VM112 (Carbonio, site, portal, Cloudflare, Traefik/SNI, registos Desk) a partir da página Serviços, com timeline ao vivo no drawer lateral.
v2 (2026-06-16): cada purge fica persistido em SQLite e consultável em Eventos → Histórico de purges — lista clicável + modal com timeline, utilizador e serviços removidos.
Uso inicial: limpar domínios de teste para reentrarem no wizard. Futuro: padrão de limpeza de dados por domínio.
Módulo Desk (Spec 015)
| Campo | Valor |
|---|---|
id |
vm112-domains |
label |
Domínios VM112 |
default_enabled |
true |
nav_views |
(vazio — purge na página Serviços, histórico em Eventos) |
RBAC
| Acção | Perfis |
|---|---|
| Executar purge (Serviços) | super_admin, ops_lead + senha Root |
| Ver histórico de purges (Eventos) | super_admin, ops_lead |
| Listar / detalhe job purge | super_admin, ops_lead |
Técnicos technician e noc não acedem.
UI — Serviços (Spec 018)
Tile E-mail Tenant → modal purge
- Resumo — domínio, mail host, admin portal, contas Carbonio, zona CF
- Infra — passos
get_status()(Carbonio, DNS, SNI, Traefik) - Contas — lista e-mails Carbonio
- Zona perigosa — Purge (Admin only)
- Aviso irreversível
- Confirmação: digitar domínio exacto
- Campo senha Root (Desk)
- Botão «Apagar domínio e todos os dados»
- Drawer lateral
vm112-purge-drawer— timeline em tempo real durante execução
API Desk (VM122)
| Método | Path | Descrição |
|---|---|---|
| GET | /api/v1/vm112/domains?q= |
Lista domínios orquestrados (proxy VM112) |
| GET | /api/v1/vm112/domains/{domain} |
Detalhe + infra status |
| POST | /api/v1/vm112/domains/{domain}/purge/jobs |
Recomendado — purge async + polling |
| GET | /api/v1/vm112/purge/jobs/{job_id} |
Estado / timeline do job |
| POST | /api/v1/vm112/purge/jobs/{job_id}/recover |
Recuperar job após timeout UI |
| GET | /api/v1/vm112/purge/jobs?limit=&offset= |
v2 — lista histórico persistido |
| POST | /api/v1/vm112/domains/{domain}/purge/stream |
Purge SSE (legado Traefik) |
| POST | /api/v1/vm112/domains/{domain}/purge |
Purge síncrono (legado) |
Body purge:
{
"confirm_domain": "iofficebooks.com",
"root_password": "********"
}
Validações purge:
user.role∈ {super_admin, ops_lead}verify_password(root_password, hash do user root)confirm_domain=== domínio (case-insensitive)- Domínio ∉ blocklist (
ligbox.com.br, etc.) - Proxy VM112
POST /api/admin/domains/{domain}/purgecomX-Api-Key
Pós-purge Desk: apagar audit_domains, webhook_events, tickets, assist_sessions, audit_checks com referência ao domínio.
API VM112
| Método | Path | Auth |
|---|---|---|
| GET | /api/admin/domains |
X-Api-Key |
| GET | /api/admin/domains/{domain} |
X-Api-Key |
| POST | /api/admin/domains/{domain}/purge |
X-Api-Key |
| GET | /api/admin/domains/purge-jobs/{job_id} |
X-Api-Key (memória, efémero) |
Purge VM112 (ordem):
- Apagar contas Carbonio (
zmprov da) - Apagar domínio Carbonio (
zmprov dd) - Remover portal users com
planned_corporate_emailno domínio - Apagar
/opt/ligbox-sites/domains/{domain}/ - Apagar zona Cloudflare (se existir na conta Ibytera)
- Remover
mail.{domain}do SNI + routers Traefik (CT114) - Apagar logs sessão JSONL com referência ao domínio
Fase 2 — Jobs async + polling (implementado)
POST /api/v1/vm112/domains/{domain}/purge/jobs inicia thread em background.
UI faz polling GET /api/v1/vm112/purge/jobs/{id} a cada 2s.
Motivo: SSE longo falhava via Traefik (504 / Failed to fetch ~60–79s).
Fix nginx Desk: proxy_read_timeout 600s em frontend/nginx.conf.
Persistência SQLite (vm112_purge_jobs) criada nesta fase — base para v2.
Fase 2 — SSE (implementado, legado)
POST /api/v1/vm112/domains/{domain}/purge/stream · text/event-stream
| type | Conteúdo |
|---|---|
step |
{ label, at, status, detail } |
heartbeat |
{ elapsed } — cada 5s |
error |
purge falhou |
done |
{ desk, vm112, domain } |
Ordem: validação → VM112 (heartbeat) → passos VM112 → passos Desk → concluído.
v2 — Histórico de purges (implementado 2026-06-16)
Problema resolvido
| Antes | Depois |
|---|---|
| Timeline só ao vivo no drawer | Histórico persistente no Desk |
| Dados em SQLite sem UI | Lista + modal de detalhe |
| VM112 jobs em memória (efémero) | Fonte de verdade: VM122 ops.db |
| Purges «desapareciam» ao fechar modal | Consulta por domínio, data, utilizador |
Nota: purges antes da persistência (ex.: betinsport.com) não aparecem no histórico.
UI — Eventos
- Aba Webhooks (existente)
- Aba Histórico de purges (Admin only)
- Lista: Job ID, domínio, status, utilizador, resumo Desk, data, duração VM112
- Clique na linha → modal com:
- Cabeçalho (domínio, status, utilizador, data, job id)
- Removido no Desk — webhook_events, tickets, audit_domains, assist_sessions, audit_checks
- Removido na VM112 — Carbonio, portal, site, Cloudflare, Traefik
- Timeline completa (
timeline_json)
Persistência
| Campo | Valor |
|---|---|
| Base | /var/lib/ligbox-ops-platform/ops.db (Docker: /data/ops.db) |
| Tabela | vm112_purge_jobs |
| Colunas | timeline_json, desk_json, vm112_json, by_user, status, created_at |
Ficheiros v2
| Ficheiro | Alteração |
|---|---|
api/app/vm112_purge_jobs.py |
list_jobs(), schema, persistência |
api/app/vm112_domains_routes.py |
GET /purge/jobs |
frontend/assets/app.js |
renderPurgeHistory(), modal, aba Eventos |
frontend/index.html |
Toolbar Eventos + purge-history-modal |
frontend/assets/styles.css |
Estilos lista/modal |
Critérios de aceitação v2
- Admin vê aba «Histórico de purges» em Eventos.
- Lista mostra purges com status, utilizador, data e resumo Desk.
- Clique abre modal com timeline completa e contagens por serviço.
- Badges correctos:
done,error,running,queued. technician/nocnão vêem a aba.
Consulta manual (SSH VM122)
sqlite3 /var/lib/ligbox-ops-platform/ops.db \
"SELECT id, domain, status, by_user, created_at FROM vm112_purge_jobs ORDER BY created_at DESC;"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://desk.ligbox.com.br/api/v1/vm112/purge/jobs/57845ca1c5c64b53"
Fase 3 — VM112 passos em tempo real (pendente)
VM112 (/opt/ligbox-wizard) emitir passos individuais durante execução (Carbonio, CF, Traefik) em vez de bloco único + heartbeat. Alterações no wizard, não só no Desk.
Critérios de aceitação (v1)
- Admin executa purge a partir de Serviços.
- Purge com senha root errada → erro na timeline.
- Purge com domínio confirmado errado → HTTP 400.
- Após purge, domínio ausente em Carbonio, ligbox-sites e Desk.
- Drawer mostra progresso ao vivo; job persiste em SQLite.
Fora de escopo
- Purge parcial (só contas, só DNS)
- Scheduler de limpeza automática
- Export CSV/PDF do histórico
- Filtro por domínio/data na lista de histórico
- Retenção automática / purge de jobs antigos
- Link directo Serviços → histórico do domínio
Conclusão (2026-06-16)
A Spec 017 cobre o ciclo completo de purge de domínio VM112:
| Fase | Entrega | Estado |
|---|---|---|
| v1 | Purge completo via Serviços + validação Root | ✅ |
| Fase 2 | Jobs async, polling, persistência SQLite | ✅ |
| Fase 2 SSE | Timeline drawer (legado) | ✅ |
| v2 | Histórico em Eventos — lista + modal audit trail | ✅ |
| Fase 3 | Passos VM112 em tempo real no wizard | ⏳ |
Purges registados (exemplo): myvexx.com, diarissima.com, ibytera.com — visíveis em Eventos → Histórico de purges.
Próximo passo natural: Fase 3 no wizard VM112; depois filtros/export no histórico se necessário.