Espelho VM130 das decisões webmail gate, contratos, VM112 e índice chat bruto. Co-authored-by: Cursor <cursoragent@cursor.com>
148 lines
5.1 KiB
Markdown
148 lines
5.1 KiB
Markdown
# Contrato — Liberação formal webmail (`company_gate`)
|
|
|
|
**Spec:** [043](../spec.md) · [023](../../023-billing-recurrence-desk-visibility/spec.md) · [035 domain-manager](../../035-ligbox-mail-bundles-foss-openpanel/domain-manager-console-ui.md)
|
|
**VM:** 112 (`company_gate.py`, `DomainAdmin.jsx`)
|
|
**Versão:** 1.0 · 2026-07-01 · Roger
|
|
**Status:** Backend ✅ · UI Painel Admin ⏳ pendente
|
|
|
|
**Chat bruto:** [CHAT_BRUTO_WEBMAIL_GATE_TICKETS_SPEC043_044_20260701.txt](../../../chat-bruto/CHAT_BRUTO_WEBMAIL_GATE_TICKETS_SPEC043_044_20260701.txt)
|
|
|
|
---
|
|
|
|
## 1. Duas camadas de «activar webmail»
|
|
|
|
| Camada | O quê | Quem | Flag / API |
|
|
|--------|-------|------|------------|
|
|
| **A — Infra** | Traefik, cert LE, SNI, HTTPS `mail.{dom}` | Sistema automático | `infrastructure.ready` |
|
|
| **B — Gate formal** | Gerente confirma empresa + libera webmail (2FA Ligbox) | Gerente domínio | `webmail_released_at` |
|
|
|
|
**Regra:** camada A não remove aviso da camada B. Login Carbonio pode funcionar antes da liberação formal — aviso é informativo.
|
|
|
|
---
|
|
|
|
## 2. Onde fica cada mensagem (decisão Roger 2026-07-01)
|
|
|
|
| Superfície | Mensagem | Tipo |
|
|
|------------|----------|------|
|
|
| **Login Carbonio** `mail.{dom}` | Rodapé: *«Aviso: ambiente operacional — aguarda activação formal pelo Gerente do Domínio no Painel Ligbox…»* | Informativo (não bloqueia) |
|
|
| **Wizard** passo Concluído | *«Conta criada — webmail em activação»* (infra pendente) | Técnico |
|
|
| **Wizard** `WebmailReleaseModal` | Confirmar empresa + liberar com 2FA | Acção gerente (onboarding) |
|
|
| **Painel Admin** `/admin` **Início** | Banner P0 + card «Activar webmail» | Acção gerente (**UI falta**) |
|
|
| **Painel Admin** Contas / Resumo | Badge `WEBMAIL ⏳` / `WEBMAIL ✓` | Estado secundário |
|
|
| **Sidebar** «Abrir Webmail» | Desactivado até `webmail_released_at` | Evita 502/confusão |
|
|
|
|
**Não colocar** a acção de liberar só no rodapé do Carbonio — utilizador final vê aviso; **gerente actua no Painel Ligbox**.
|
|
|
|
---
|
|
|
|
## 3. Fluxo backend (VM112)
|
|
|
|
```
|
|
Onboarding concluído
|
|
→ domain_registry (sem webmail_released_at)
|
|
→ sync_webmail_user_notice() → Carbonio login footer
|
|
|
|
Gerente confirma empresa
|
|
→ POST /api/domain-admin/gate/company-profile
|
|
→ company_profile_confirmed_at
|
|
→ webhook company.validated → Desk (Spec 043)
|
|
|
|
Gerente libera webmail (2FA Ligbox)
|
|
→ POST /api/domain-admin/gate/release-webmail
|
|
→ webmail_released_at
|
|
→ sync_webmail_user_notice() limpa aviso
|
|
→ webhook webmail.released → Desk
|
|
```
|
|
|
|
### Ficheiros VM112
|
|
|
|
| Ficheiro | Função |
|
|
|----------|--------|
|
|
| `backend/app/services/company_gate.py` | Gate, mensagens, webhooks |
|
|
| `backend/app/routers/domain_admin.py` | `/gate/status`, `/gate/company-profile`, `/gate/release-webmail` |
|
|
| `backend/app/services/webmail_pending_page.py` | Página pública aguardando liberação |
|
|
| `frontend/src/components/WebmailReleaseModal.jsx` | Modal wizard (onboarding) |
|
|
| `frontend/src/DomainAdmin.jsx` | Painel gerente — **falta UI gate** |
|
|
|
|
### Constantes (`company_gate.py`)
|
|
|
|
```python
|
|
PENDING_WEBMAIL_USER_DESCRIPTION = (
|
|
"Aviso: ambiente operacional — aguarda activação formal pelo Gerente do Domínio "
|
|
"no Painel Ligbox. Utilização de correio permitida."
|
|
)
|
|
```
|
|
|
|
Injectado via `carbonio.set_domain_web_ui_notice()`.
|
|
|
|
---
|
|
|
|
## 4. API Painel Admin
|
|
|
|
### `GET /api/domain-admin/gate/status`
|
|
|
|
```json
|
|
{
|
|
"domain": "dratcoin.com",
|
|
"needs_company_confirm": false,
|
|
"webmail_released": false,
|
|
"service_active": false,
|
|
"webmail_url": "https://mail.dratcoin.com/",
|
|
"ops_ticket_state": "awaiting_billing_validation",
|
|
"pending_message": "Este webmail aguarda activação pelo Administrador do domínio..."
|
|
}
|
|
```
|
|
|
|
### `POST /api/domain-admin/gate/release-webmail`
|
|
|
|
```json
|
|
{
|
|
"ligbox_login": "roger",
|
|
"totp_code": "123456",
|
|
"recovery_code": null
|
|
}
|
|
```
|
|
|
|
**Pré-requisitos:** `company_profile_confirmed_at` preenchido; 2FA portal user válido.
|
|
|
|
---
|
|
|
|
## 5. Webhooks Desk
|
|
|
|
| Evento | Quando |
|
|
|--------|--------|
|
|
| `company.validated` | Após confirmar perfil empresa |
|
|
| `webmail.released` | Após `release_webmail()` |
|
|
|
|
Desk: `FUNNEL_STAGE` rank 8 = `webmail_released` (`main.py` VM122).
|
|
|
|
---
|
|
|
|
## 6. UI pendente — Painel Admin (`DomainAdmin.jsx`)
|
|
|
|
Wireframe **Início** (`/admin`):
|
|
|
|
```
|
|
┌─ Activar webmail ─────────────────────────────────────┐
|
|
│ Empresa: ⏳ confirmar | Webmail: ⏳ aguarda liberação │
|
|
│ [ Confirmar dados empresa ] [ Activar webmail + 2FA ] │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
Reutilizar lógica de `WebmailReleaseModal.jsx` + `me.gate` da API `/me`.
|
|
|
|
---
|
|
|
|
## 7. Caso dratcoin.com (Roger 2026-07-01)
|
|
|
|
- Login `mail.dratcoin.com` mostra aviso no rodapé ✅ (esperado)
|
|
- Erro *Credentials are not valid* = senha/email incorrectos (separado do gate)
|
|
- Painel `/admin` não mostra card liberar — **gap UI**
|
|
|
|
---
|
|
|
|
## Histórico
|
|
|
|
| Versão | Data | Notas |
|
|
|--------|------|-------|
|
|
| 1.0 | 2026-07-01 | Decisão UX mensagens + mapa company_gate |
|