ligbox-ops-platform/specs/037-dns-multi-cloudflare-orchestration/client-cf-account-lifecycle.md
Ligbox Spec Hub 038fb8f7ce feat(dns): Spec 037 DNS Viewer — Desk, Console e patches Wizard V4
Entrega read-only de apontamentos DNS (Cloudflare, OpenPanel BIND, público)
no Desk e Console /admin/dominio, com spec, scripts de rollback e patches
VM112 para painel lateral no passo DNS do onboarding (deploy wizard pendente).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-25 16:36:25 +00:00

149 lines
5.6 KiB
Markdown

# Anexo 037-B — Conta Cloudflare por cliente (e-mail proj + handoff gestor)
**Parent:** [spec.md](./spec.md) · Spec **037**
**Solicitado por:** Roger · **2026-06-22**
**Status:** 📋 Regra definida — implementação Fase 2
---
## Regra de negócio (Roger)
Novos clientes que escolhem **vir para Cloudflare gerenciada pela Ligbox** recebem uma **conta Cloudflare dedicada** (não zona partilhada nas contas mãe ligit/itecnologys/ibytera a longo prazo).
### Fase A — Onboarding (conta sob controlo Ligbox)
| Campo | Valor |
|-------|--------|
| **E-mail titular / membro inicial** | `proj_{id}@ligbox.com.br` (ex.: `proj_005@ligbox.com.br`) |
| **Nome da conta CF** | Dados do **domínio do cliente** (ex.: `Empresa XYZ — empresa.com.br`) |
| **Zona DNS** | `cliente.com.br` criada **nesta** conta |
| **Gestão** | Ligbox opera via API token / membro admin Ligbox |
O `proj_{id}` vem do **ID de projeto/onboarding** (sequencial ou UUID curto no wizard / Ops Desk).
### Fase B — Handoff (conta estável)
Quando a conta estiver **setada e a funcionar** (DNS verificado + conta email Carbonio criada + infra OK):
1. **Convidar** `admin@{dominio_cliente}` (ou e-mail indicado no wizard) como **gestor** na conta Cloudflare.
2. Role sugerida: **Administrator** (ou custom com Zone DNS + Read mínimo se preferirem).
3. Manter `proj_{id}@ligbox.com.br` como membro técnico Ligbox (não remover até handoff confirmado).
4. Registar em `domain_registry`: `cf_account_id`, `cf_member_client_email`, `handoff_status`.
Opcional futuro: **promover** e-mail do cliente a owner principal e rebaixar `proj_*` a read-only — depende da política Cloudflare Tenant.
---
## Fluxo wizard (alvo Fase 2)
```mermaid
sequenceDiagram
participant W as Wizard VM112
participant CF as Cloudflare API
participant M as Mail ligbox.com.br
participant C as Cliente
W->>W: Gera project_id (ex. 005)
W->>M: Cria proj_005@ligbox.com.br + senha
W->>C: Entrega credenciais projeto (wizard)
W->>CF: POST /accounts (name=cliente.com.br)
Note over CF: Membro inicial proj_005@ligbox.com.br
W->>CF: POST /zones (account_id novo)
W->>CF: upsert MX/SPF/DMARC
W->>C: NS no registrador
C->>C: Propaga DNS
W->>W: dns/verify OK + account/create OK
W->>CF: POST /accounts/{id}/members (admin@cliente.com.br)
CF->>C: Convite gestor
W->>M: Notifica ops + cliente
```
---
## Relação com Fase 1 (actual)
| Fase 1 (hoje) | Fase 2 (regra Roger) |
|---------------|----------------------|
| Zona nova em conta partilhada `ibytera` | Conta CF **nova por cliente** |
| Token único conta mãe | Token scoped por `cf_account_id` cliente |
| Sem `proj_*@ligbox.com.br` | E-mail projeto Ligbox como membro inicial |
| Sem handoff gestor | Convite `admin@dominio` pós-go-live |
**Transição:** Fase 1 mantém-se até Tenant API / tokens prontos; novos clientes premium ou flag `dedicated_cf_account: true` usam Fase 2.
---
## Pré-requisitos técnicos
### 1. E-mails `proj_*@ligbox.com.br`
- O **agente Ligbox cria caixa real** no Carbonio (`ligbox.com.br`) via `project_identity.provision_project_email()`.
- Entrega **senha** ao cliente no wizard (uma vez) — ver [project-email-identity.md](./project-email-identity.md).
- Padrão: `proj_{project_id:03d}@ligbox.com.br`.
- Referenciado em: CF member, `domain_registry`, webhooks DNS, `activity_log`.
### 2. API Cloudflare
| Operação | Endpoint | Permissão |
|----------|----------|-----------|
| Criar conta | `POST /accounts` | **Tenant admin** (organização Ligbox) |
| Criar zona | `POST /zones` | Account Zone Edit na conta nova |
| Convidar gestor | `POST /accounts/{id}/members` | Account User Management |
| Abuse contact | `settings.abuse_contact_email` | Pode ser `admin@cliente.com.br` desde Fase A |
> `POST /accounts` está limitado a **tenant admins**. Se Ligbox ainda não tiver Tenant, alternativa interina: zonas na conta mãe (Fase 1) até activar Tenant.
### 3. Registo interno (VM112)
Ficheiro ou DB por domínio (`/var/lib/ligbox-wizard/cf_client_accounts/{domain}.json`):
```json
{
"domain": "empresa.com.br",
"project_id": "005",
"ligbox_email": "proj_005@ligbox.com.br",
"cloudflare_account_id": "…",
"cloudflare_account_name": "Empresa XYZ — empresa.com.br",
"zone_id": "…",
"client_manager_email": null,
"handoff_status": "pending",
"created_at": "2026-06-22T12:00:00Z",
"handoff_at": null
}
```
### 4. Gatilho handoff
Automático quando **todos** verdadeiros:
- `GET /dns/verify/{domain}``ready: true`
- `POST /account/create` → sucesso
- `infrastructure.ready` (se aplicável)
Então: `POST /dns/cloudflare/handoff-manager` com `{ domain, manager_email: "admin@empresa.com.br" }`.
---
## Endpoints planeados (Fase 2)
| Método | Path | Descrição |
|--------|------|-----------|
| POST | `/dns/cloudflare/provision-client-account` | Cria conta CF + zona + registo `proj_*` |
| POST | `/dns/cloudflare/handoff-manager` | Convida gestor do domínio cliente |
| GET | `/dns/cloudflare/client-account/{domain}` | Estado handoff (ops) |
---
## Critérios de aceitação (Fase 2)
1. Cliente novo → conta CF com nome do domínio e membro `proj_{id}@ligbox.com.br`.
2. Zona + apontamentos mail na **conta do cliente**, não na mãe ibytera.
3. Após go-live → convite `admin@cliente.com.br` enviado e registado.
4. `proj_*` permanece acessível à Ligbox para suporte.
5. BYO / registrador **não** passam por este fluxo.
---
## Pergunta em aberto (Roger)
**Formato do `project_id`:** sequencial `005` (`proj_005@`) ou slug do domínio (`proj_empresa-com-br@`)? Recomendação: **sequencial numérico** — mais limpo e alinhado ao exemplo.