4.7 KiB
4.7 KiB
Spec 025 — Onboarding contínuo (sem gaps)
Criado: 2026-06-17 · Roger
Sistema: Wizard VM112 + Desk VM122 + Traefik CT114 + Carbonio VM112
Prioridade: P0
Relacionado: Spec 012 (ticket/lead), Spec 017 (purge), Spec 022 (ACCOUNT_EXISTS ops)
Problema
O wizard trata cada passo como linear e «virgem». Na prática o cliente (ou um técnico) pode:
- Abandonar no meio e voltar dias depois
- Ter conta já criada no Carbonio mas portal/Traefik/DNS incompletos
- Receber
ACCOUNT_EXISTSno passo 3 e ficar bloqueado sem caminho
O Desk Spec 022 resolve o caso para técnicos; o cliente no wizard continua preso.
Princípio — «Estado real, não passo cego»
Cada etapa consulta o estado efectivo no servidor antes de mostrar UI ou falhar:
| Camada | Fonte de verdade | Acção se já feito |
|---|---|---|
| Domínio Carbonio | domain_exists |
Avançar |
| DNS mail | dns_verify |
Mostrar OK + continuar |
| Conta admin | account_exists + domain_registry |
Reconciliar (não falhar) |
| Portal admin | is_portal_admin |
Registar se em falta |
| Webmail gate | Traefik dynamic | sync_webmail_gate |
| Infra completa | infrastructure.get_status |
Painel «pendente» com checklist |
Regra de ouro: POST /account/create é idempotente — conta existente → reconciliação + passos pós-criação, HTTP 200 com reconciled: true.
Fluxo alvo (cliente)
flowchart LR
A[Domínio] --> B[DNS]
B --> C{Dados conta}
C -->|não existe| D[Confirmar + criar]
C -->|já existe| E[Continuar activação]
D --> F[Reconciliar pós-criação]
E --> F
F --> G{Infra OK?}
G -->|sim| H[Concluído — webmail]
G -->|não| I[Checklist infra + polling]
I --> H
Passo 2 (UI)
- Consultar
GET /onboarding/account/status?domain=&local_part= - Se
exists: true→ banner «Conta já existe — vamos concluir a activação» (não «NÃO existe») - Botão: «Continuar activação →» em vez de só «Rever e criar»
Passo 3 (UI)
- Se conta existe → «Continuar activação» (mesmo endpoint, reconcilia)
- Opcional: actualizar senha via
zmprov spse utilizador confirmou nova senha
Erros que não bloqueiam
| Situação | Comportamento |
|---|---|
| ACCOUNT_EXISTS | Reconciliar → 200 |
| DNS incompleto | Passo 4 com finishPendingInfra (já existe) |
| Traefik/LE pendente | Polling infra + guia no card Resumo |
| API lenta (>30s) | Timeout frontend 120s + mensagem clara (feito VM122) |
Erros que bloqueiam (com saída clara)
| Situação | Comportamento |
|---|---|
| Domínio inválido / blacklist | Mensagem + voltar passo 1 |
| Carbonio indisponível (OOM) | «Servidor ocupado — tente em 2 min» + webhook ops |
| Senha < 8 chars | Validação local |
API VM112 (novo / alterado)
GET /onboarding/account/status
{
"email": "admin@exemplo.com",
"exists": true,
"portal_admin": true,
"domain_registered": true
}
POST /onboarding/account/create (idempotente)
Resposta quando conta já existia:
{
"email": "admin@exemplo.com",
"reconciled": true,
"account_verified": true,
"needs_review": false,
"infrastructure": { "ready": false, "steps": [...] }
}
Webhook: account.reconciled (novo) ou account.created com reconciled: true.
Desk / Ops (sem duplicar Spec 022)
| Evento | Desk |
|---|---|
account.reconciled |
Nota no ticket — «Cliente retomou conta existente» |
onboarding.failed + ACCOUNT_EXISTS |
Spec 022 — só se reconciliação impossível (conta órfã de outro email) |
onboarding.completed + infra não ready |
Ticket mantém crm_track: infra_pending |
Fases de entrega
Fase 1 — P0 (esta spec, 2026-06-17)
- Spec documentada
- Backend: idempotência
create_account+GET account/status - Frontend: banners dinâmicos passos 2–3
- Deploy VM112 + smoke
exuberanti.com.br
Fase 2 — Resiliência
- Sessão wizard: ao reabrir URL,
resumeconsulta estado e salta passos feitos - VM112 RAM → 16 GB (Proxmox)
- Validação Traefik YAML (router sem
rule= build fail)
Fase 3 — Processo comercial completo
- Spec 012 abandonos → lead
- Spec 023 billing no Desk
- Wizard dedicado VM124 (Spec 018 fase 3)
Critério de aceite (exuberanti.com.br)
- Cliente com
teste001@exuberanti.com.brjá no Carbonio abre wizard no passo 2 → vê «conta já existe» - Clica «Continuar activação» → passo 4 sem erro 400
- Portal admin registado; gate Traefik sincronizado
- Ticket Desk recebe evento; Bloqueios Carbonio não aparece para este caso