9.1 KiB
Feature Specification: Migração E-mail Legado — Execução VM122 (019)
Criado: 2026-06-16
Solicitado por: Roger
Status: 📋 Aprovado para planeamento / implementação
Prioridade: P0
Depende de: Spec 013 (modelo completo), Spec 010 (tickets), Spec 018 (Serviços MOSP)
Wizard cliente: permanece na VM112 — não executa migração legada
Resumo executivo
| Onde | O quê |
|---|---|
| VM112 | Wizard onboarding — criar domínio/conta Carbonio, DNS só após gate |
| VM122 | Orquestração OPS — migrar e-mail do servidor anterior/legado → Carbonio VM112 |
Regra de ouro (Roger):
Migrar → validar → aprovar gate → só depois virar DNS (MX).
O cliente não vê imapsync nem PST no wizard. O técnico sénior opera no Desk VM122 (vista Email Migration + ticket).
Porquê VM122 e não VM112?
| Critério | VM112 (wizard) | VM122 (Desk) |
|---|---|---|
| Público | Cliente final | Técnico OPS |
| Duração | minutos | horas / dias |
| Credenciais servidor antigo | ❌ nunca | ✅ vault encriptado |
| Ferramentas pesadas (imapsync, PST) | ❌ | ✅ worker/host |
| Auditoria / ticket | parcial | completa |
| Gate antes DNS | consulta API | controla e aprova |
Ferramentas GitHub (rápidas e seguras)
| Ferramenta | Repositório | Uso | Maturidade |
|---|---|---|---|
| imapsync | imapsync/imapsync | IMAP → IMAP (cPanel, Zimbra, O365, Gmail…) | ⭐ ~4k — padrão indústria |
| imap-upload | rgladwell/imap-upload | mbox → IMAP (pós readpst) | Complemento PST |
| readpst | pst-utils (Debian) |
Extrair PST Outlook | Sistema |
| zmmailbox TGZ | Carbonio nativo | Zimbra/Carbonio → Carbonio | Oficial Zextras |
| oauth2_imap | imapsync.lamiral.info | O365 / Gmail moderno | Obrigatório se Basic Auth off |
Não recomendado MVP: ferramentas comerciais fechadas, scripts aleatórios sem logs, migração manual sem gate.
Boas práticas imapsync (oficial)
--justlogin+--dry+--justfoldersantes do sync real- Credenciais em ficheiro 600, nunca na linha de comando
- Presync (bulk) com MX ainda no servidor antigo
- Delta sync agendado (6/6h)
- Sync final na janela de cutover
--maxbytespersecondse origem limitar rate- O365: OAuth2, não password básica
Fontes: FAQ Migration Plan, FAQ Massive
Arquitectura VM122
┌─────────────────────────────────────────────────────────────┐
│ Desk VM122 (ligbox-ops-platform) │
│ UI: Email Migration │ API /api/v1/migration/* │
│ Worker + ferramentas │ Gate DNS → bloqueia wizard VM112 │
└────────────┬───────────────────────────────┬────────────────┘
│ imapsync / PST pipeline │ GET /migration/gate
▼ ▼
Servidor LEGADO (host1) VM112 Carbonio (host2)
cPanel / Zimbra / O365 mail.{dominio}
Onde correm as ferramentas
| Fase piloto | Host |
|---|---|
| Agora | VM122 host ou container worker (fora da API) |
| Produção volume | VM123 dedicada ligbox-migration (Spec 013 infrastructure.md) |
Nunca dentro do container API FastAPI (bloqueia event loop, sem ferramentas).
Fluxo operacional (técnico sénior)
sequenceDiagram
participant T as Técnico Desk
participant V122 as VM122 API/Worker
participant LEG as Servidor legado
participant V112 as Carbonio VM112
participant W as Wizard VM112
T->>V122: Criar job migração (domínio, mailboxes)
T->>V122: Preflight (--justlogin)
V122->>LEG: Teste IMAP origem
V122->>V112: Teste IMAP destino
T->>V122: Sync initial (MX ainda no legado)
V122->>LEG: imapsync bulk
V122->>V112: grava mensagens
loop Delta
T->>V122: Sync delta
end
T->>V122: Verify ≥99%
T->>V122: Approve gate (ops_lead)
W->>V122: GET /migration/gate?domain=
V122-->>W: ready_for_dns
T->>W: Cutover DNS (ou assist)
T->>V122: Sync final
T->>V122: Close job + relatório ticket
Integração com wizard VM112
| Momento | VM112 | VM122 |
|---|---|---|
| Cliente cria conta | ✅ wizard | job discovered manual ou webhook |
| Contas destino Carbonio | ✅ zmprov via wizard | preflight confirma |
| Aplicar MX Cloudflare | ⚠️ bloqueado se gate ≠ ready_for_dns |
gate API |
| Override emergência | — | super_admin + motivo auditado |
Implementação gate (Fase B):
GET /api/v1/migration/gate?domain= — VM112 chama antes de dns.applied final.
Fases e critérios (resumo Spec 013)
| Fase | DNS virado? | Acção |
|---|---|---|
| discovered | Não | Inventário mailboxes |
| preflight | Não | Testes login + mapeamento pastas |
| initial_sync | Não | imapsync bulk |
| delta_sync | Não | incrementais |
| cutover_ready | Não | verify ≥99%, aprovação ops_lead |
| dns_cutover | Sim | MX → VM112 |
| final_sync | Sim | última delta |
| verified / closed | Sim | relatório ticket |
Matriz de risco (Roger)
| Risco | Nível | Impacto | Mitigação |
|---|---|---|---|
| Virar MX antes da migração | 🔴 Crítico | Perda de e-mail novo + antigo separados | Gate API + procedimento OPS |
| PST corrompido | 🟠 Alto | Gaps silenciosos | readpst + quarentena + verify |
| O365 Basic Auth bloqueado | 🟠 Alto | Sync falha | OAuth2 (oauth2_imap) |
| Duplicatas em re-sync | 🟡 Médio | Inbox duplicado | imapsync Message-Id; não misturar PST+imap mesma pasta |
| Rate limit servidor origem | 🟡 Médio | IP banido | --maxbytespersecond, horários off-peak |
| Mailbox gigante (50GB+) | 🟡 Médio | Timeout | sync por pasta; worker 24h retomável |
| Credenciais em log | 🔴 Crítico | Compromisso contas | vault Fernet; passfile 600 |
| Carga VM122 | 🟡 Médio | Desk lento | worker separado / VM123 futuro |
| Cliente envia mail durante cutover | 🟡 Médio | Algumas msgs no legado | sync final + TTL MX baixo pré-cutover |
Nível global da etapa: 🟠 ALTO — dados de produção irreversíveis se mal executado.
Com Spec 013 + gate + presync: 🟡 MÉDIO controlável para técnico sénior com runbook.
Plano de implementação (como vamos proceder)
Fase A — Fundação (VM122, ~1 sprint)
- Schema SQLite (
migration_jobs,mailboxes,runs,credentials) — Spec 013 data-model install-migration-tools.shna VM122 (imapsync, pst-utils, imap-upload)- API CRUD jobs + preflight
--justlogin - Worker
migration_runner.py— 1 mailbox imapsync - UI Desk mínima: lista jobs + log
Fase B — Gate DNS (~½ sprint)
gate.py— ratio 99%, estados blocked/warning/readyGET /migration/gate?domain=para VM112- Integração ticket + notas por
migration_run
Fase C — PST + verify (~1 sprint)
- Upload PST multipart
- Pipeline readpst → imap-upload
- Relatório verify + approve-gate
Fase D — VM112 hook (~½ sprint)
- VM112: antes DNS final, consultar gate
- Override auditado super_admin
Piloto obrigatório
- 1 domínio teste (não produção crítica)
- Origem: cPanel ou Zimbra conhecido
- Destino: Carbonio VM112 tenant teste
- Só depois: cliente real com legado
API (referência — Spec 013)
| Método | Path |
|---|---|
| POST | /api/v1/migration/jobs |
| POST | /api/v1/migration/jobs/{id}/preflight |
| POST | /api/v1/migration/jobs/{id}/sync |
| GET | /api/v1/migration/jobs/{id}/verify |
| GET | /api/v1/migration/gate?domain= |
| POST | /api/v1/migration/jobs/{id}/approve-gate |
Fora de escopo desta spec
- Migração no wizard Hero VM112
- Calendário/contactos CardDAV (só e-mail)
- VM123 provisionamento (até volume exigir)
Documentos relacionados
specs/013-email-server-migration/spec.md— spec completaspecs/013-email-server-migration/research.md— ferramentas GitHubspecs/013-email-server-migration/plan.md— ficheiros códigospecs/013-email-server-migration/quickstart.md— runbook técnicospecs/013-email-server-migration/tasks.md— checklist T001–T040
Critérios de aceite execução VM122
- imapsync instalado e
--justloginOK VM122 → legado + Carbonio - Job piloto cPanel/Zimbra → Carbonio sem perda Inbox/Sent
- Gate bloqueia DNS com sync < 99%
- Gate libera com aprovação ops_lead + relatório
- Wizard VM112 respeita gate (ou override auditado)
- Zero credenciais origem em logs Desk