Sync contratos, runbooks VM112/VM123, código wizard e VM112.md com deploy validado. Co-authored-by: Cursor <cursoragent@cursor.com>
336 lines
13 KiB
Markdown
336 lines
13 KiB
Markdown
# Contrato — Mapeamento de campos: Ativação cliente (Wizard → Desk → FOSS → OpenPanel → Odoo)
|
||
|
||
**Spec:** [043](../spec.md)
|
||
**Versão:** 1.0 · 2026-07-01 · Roger
|
||
**Status:** Fonte única de verdade para sincronização de painéis
|
||
|
||
---
|
||
|
||
## 1. Visão geral do fluxo
|
||
|
||
| Fase | Actor | Evento / acção | Persistência |
|
||
|------|-------|----------------|--------------|
|
||
| A | Cliente VM112 | Preenche card empresa + confirma | Sessão wizard |
|
||
| B | Wizard VM112 | Emite `company.validated` | — |
|
||
| C | Desk VM122 | Upsert `billing_accounts` | SQLite VM122 |
|
||
| D | Staff Desk | Clica **Activar conta** | Audit log |
|
||
| E | Desk → FOSS | `client/create` + `order/create` + activate | FOSS DB |
|
||
| F | FOSS → OpenPanel | Módulo OpenPanel ou bridge `POST /api/users` | OpenPanel |
|
||
| G | Desk → Odoo | `res.partner` create/update | Odoo DB `ligbox` |
|
||
| H | Desk → Wizard | `POST /api/internal/provision/mail-bundle` | Carbonio VM112 |
|
||
|
||
**Specs de origem:** [023](../../023-billing-recurrence-desk-visibility/spec.md) · [024 PROVISIONING_CLIENT_CARD](../../024-openpanel-fossbilling/PROVISIONING_CLIENT_CARD.md) · [035](../../035-ligbox-mail-bundles-foss-openpanel/spec.md) · [028 bridge](../../028-openpanel-ce-ligbox-reengineering/contracts/foss-bridge-api.md) · **[mail-bundle-api](./mail-bundle-api.md)**
|
||
|
||
---
|
||
|
||
## 2. Card wizard — «Dados da empresa e cobrança»
|
||
|
||
**Onde:** VM112 wizard, gate `company_gate` (após conta/domínio).
|
||
**Spec:** [023 § Gatilho](../../023-billing-recurrence-desk-visibility/spec.md)
|
||
|
||
### 2.1 Campos do formulário (UI wizard)
|
||
|
||
| ID campo wizard | Label UI (referência) | Tipo | Obrigatório | Notas |
|
||
|-----------------|----------------------|------|-------------|-------|
|
||
| `trade_name` | Nome fantasia | text | sim | Nome comercial |
|
||
| `legal_name` | Razão social | text | sim | NF / contrato |
|
||
| `tax_id_type` | Tipo documento | enum | sim | `cnpj` \| `cpf` |
|
||
| `tax_id` | CNPJ / CPF | text | sim | Só dígitos ou formatado |
|
||
| `email_billing` | E-mail de cobrança | email | sim | Pode ≠ admin@dom |
|
||
| `payment_method` | Forma de pagamento | select | não | Fase 2 (boleto/PIX) |
|
||
| `address.country` | País | text | sim | Default `BR` |
|
||
| `address.city` | Cidade | text | sim | |
|
||
| `address.postal_code` | CEP | text | sim | |
|
||
| `address.street` | Endereço | text | não | Se existir no wizard |
|
||
| `address.state` | UF | text | não | |
|
||
| `phone_landline` | Telefone fixo | tel | não | Mascarado NOC no Desk |
|
||
| `phone_mobile` | Celular | tel | não | |
|
||
| `contact_phone` | Telefone contacto | tel | não | Alias legacy |
|
||
| `email_legal` | E-mail jurídico | email | não | Se distinto do billing |
|
||
| `confirm_billing` | Aceito política de cobrança | bool | sim | Gate submit |
|
||
| `confirm_accurate` | Dados correctos | bool | sim | Gate submit |
|
||
|
||
### 2.2 Campos do gerente / responsável (conta admin)
|
||
|
||
**Specs:** [035 §5.1](../../035-ligbox-mail-bundles-foss-openpanel/spec.md) · wizard `account.create`
|
||
|
||
| ID campo | Origem | Exemplo | Notas |
|
||
|----------|--------|---------|-------|
|
||
| `domain` | Validação domínio | `ligbox.com.br` | Chave única `billing_accounts` |
|
||
| `manager_email` | Conta admin criada | `admin@ligbox.com.br` | = email Carbonio gerente |
|
||
| `manager_name` | Card responsável / display name | João Silva | Nome pessoa responsável |
|
||
| `admin_password` | Wizard (não replicar em logs) | — | Só FOSS/OP se gerada para hub |
|
||
|
||
### 2.3 Payload webhook `company.validated`
|
||
|
||
```json
|
||
{
|
||
"event": "company.validated",
|
||
"domain": "empresa.com.br",
|
||
"session_id": "<uuid>",
|
||
"data": {
|
||
"billing_state": "awaiting_billing_validation",
|
||
"company_profile": {
|
||
"trade_name": "Empresa LTDA",
|
||
"legal_name": "Empresa Serviços LTDA",
|
||
"tax_id_type": "cnpj",
|
||
"tax_id": "00000000000191",
|
||
"email_billing": "financeiro@empresa.com.br",
|
||
"payment_method": "",
|
||
"confirm_billing": true,
|
||
"confirm_accurate": true,
|
||
"address": {
|
||
"country": "BR",
|
||
"city": "São Paulo",
|
||
"postal_code": "01310-100",
|
||
"street": "",
|
||
"state": "SP"
|
||
},
|
||
"manager_name": "João Silva",
|
||
"manager_email": "admin@empresa.com.br"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
> `manager_name` / `manager_email` podem vir no `company_profile` ou no nível `data` — Desk deve normalizar para `billing_accounts` + provisionamento.
|
||
|
||
---
|
||
|
||
## 3. Desk VM122 — `billing_accounts`
|
||
|
||
**Spec:** [023 § Modelo de dados](../../023-billing-recurrence-desk-visibility/spec.md)
|
||
**Código:** `billing_store.upsert_from_company_validated()`
|
||
|
||
| Coluna SQLite | Origem | Descrição |
|
||
|---------------|--------|-----------|
|
||
| `domain` | webhook | PK lógica |
|
||
| `session_id` | webhook | Correlação funil |
|
||
| `ticket_id` | handler | Ticket `[billing-validation]` |
|
||
| `tax_id` | `company_profile.tax_id` | |
|
||
| `legal_name` | `company_profile.legal_name` | |
|
||
| `trade_name` | `company_profile.trade_name` | |
|
||
| `email_billing` | `company_profile.email_billing` | |
|
||
| `company_profile_json` | JSON completo | Snapshot imutável + extras |
|
||
| `billing_state` | `data.billing_state` | Ver tabela §3.1 |
|
||
| `recurrence_active` | 0 até pagamento | |
|
||
| `external_customer_id` | pós FOSS | FOSS `client.id` |
|
||
| `external_subscription_id` | pós Odoo/FOSS | Assinatura |
|
||
| `plan_code` | staff / produto | ex. `ligbox-mail-business` |
|
||
| `activated_at` | pós «Activar conta» | ISO8601 |
|
||
| `activated_by` | username staff | Audit |
|
||
|
||
### 3.1 Estados `billing_state`
|
||
|
||
| Estado | Significado | Próximo passo |
|
||
|--------|-------------|----------------|
|
||
| `policy_pending` | Card visto, não confirmado | Aguardar cliente |
|
||
| `awaiting_billing_validation` | `company.validated` | Staff revisa |
|
||
| `provisioning` | Activar conta em curso | FOSS/OP/Odoo |
|
||
| `billing_active` | Recorrência activa | Monitorizar |
|
||
| `billing_paused` | Suspenso | — |
|
||
| `billing_cancelled` | Cancelado | Histórico |
|
||
|
||
---
|
||
|
||
## 4. FOSSBilling (VM123) — primeiro destino API
|
||
|
||
**Spec:** [024](../../024-openpanel-fossbilling/spec.md) · [035 foss-products](../../035-ligbox-mail-bundles-foss-openpanel/foss-products.md)
|
||
**API base:** `https://financeiro.ligbox.com.br/api/admin/`
|
||
**Código Desk:** `vm123/foss_client.py` (staff hoje; **client create — a implementar**)
|
||
|
||
### 4.1 Cliente FOSS (`client/create`)
|
||
|
||
| Campo FOSS API | Origem Desk / wizard | Transformação |
|
||
|----------------|----------------------|---------------|
|
||
| `email` | `manager_email` ou `email_billing` | lower-case; preferir `manager_email` para login cliente |
|
||
| `first_name` | `manager_name` (primeiro token) | split nome |
|
||
| `last_name` | `manager_name` (resto) | opcional |
|
||
| `company` | `legal_name` ou `trade_name` | razão social |
|
||
| `company_vat` | `tax_id` | CNPJ/CPF |
|
||
| `phone` | `phone_mobile` \|\| `contact_phone` | |
|
||
| `address_1` | `address.street` | |
|
||
| `city` | `address.city` | |
|
||
| `state` | `address.state` | |
|
||
| `postcode` | `address.postal_code` | |
|
||
| `country` | `address.country` | `BR` |
|
||
| `currency` | fixo | `BRL` |
|
||
| `status` | fixo | `active` |
|
||
| `custom_*` | `domain` | custom field `ligbox_domain` (configurar no FOSS) |
|
||
|
||
**Guardar em Desk:** `billing_accounts.external_customer_id` = `client.id`
|
||
|
||
### 4.2 Pedido FOSS (`order/create` + activate)
|
||
|
||
| Campo FOSS | Origem | Valores mail bundle |
|
||
|------------|--------|---------------------|
|
||
| `client_id` | passo anterior | |
|
||
| `product_id` / `slug` | `plan_code` | `ligbox-mail-starter` \| `business` \| `enterprise` \| `custom` |
|
||
| `period` | comercial | `1M` mensal |
|
||
| `domain` | `domain` | custom field pedido |
|
||
| `manager_email` | custom field | [035](../../035-ligbox-mail-bundles-foss-openpanel/spec.md) |
|
||
| `manager_name` | custom field | |
|
||
| `config[seats]` | bundle custom | 10–50 |
|
||
| `config[mail_gb]` | bundle custom | |
|
||
| `config[files_gb]` | bundle custom | |
|
||
|
||
**Activar hosting:** FOSS chama módulo OpenPanel → bridge (passo 5).
|
||
|
||
---
|
||
|
||
## 5. OpenPanel (VM123) — tipo de contrato / hosting
|
||
|
||
**Spec:** [028](../../028-openpanel-ce-ligbox-reengineering/spec.md) · [bridge API](../../028-openpanel-ce-ligbox-reengineering/contracts/foss-bridge-api.md)
|
||
**Trigger:** FOSS order paid/activated **ou** Desk directo (fallback)
|
||
|
||
### 5.1 Mapeamento bridge `POST /api/users`
|
||
|
||
| Campo bridge | Origem | Regra |
|
||
|--------------|--------|-------|
|
||
| `username` | derivado de `domain` | 7 chars + dígito ([024 card](../../024-openpanel-fossbilling/PROVISIONING_CLIENT_CARD.md)) |
|
||
| `password` | gerado ou `panel_password` | entregar ao gerente |
|
||
| `email` | `manager_email` | |
|
||
| `plan_name` | `plan_code` | Ver tabela §5.2 |
|
||
| `domain` | `domain` | domínio cliente |
|
||
|
||
### 5.2 Planos OpenPanel ↔ produtos FOSS
|
||
|
||
| `plan_name` OpenPanel | Produto FOSS | Serviço |
|
||
|-----------------------|--------------|---------|
|
||
| `ligbox-mail-starter` | `ligbox-mail-starter` | Email bundle 10 seats |
|
||
| `ligbox-mail-business` | `ligbox-mail-business` | 25 seats |
|
||
| `ligbox-mail-enterprise` | `ligbox-mail-enterprise` | 50 seats |
|
||
| `ligbox-mail-custom` | `ligbox-mail-custom` | Config options |
|
||
| `ligbox-site-cms` | site CMS | [024](../../024-openpanel-fossbilling/PROVISIONING_CLIENT_CARD.md) |
|
||
|
||
### 5.3 Metadata JSON no user hub (mail)
|
||
|
||
**Spec:** [035 §6.2](../../035-ligbox-mail-bundles-foss-openpanel/spec.md)
|
||
|
||
```json
|
||
{
|
||
"bundle_type": "ligbox_mail",
|
||
"max_seats": 25,
|
||
"mail_gb_per_seat": 30,
|
||
"files_gb_per_seat": 200,
|
||
"easydmarc": true,
|
||
"wizard_domain": "empresa.com.br",
|
||
"manager_name": "João Silva",
|
||
"manager_email": "admin@empresa.com.br"
|
||
}
|
||
```
|
||
|
||
**Guardar em Desk:** `company_profile_json.openpanel_username` + `openpanel_domain` após resposta bridge.
|
||
|
||
---
|
||
|
||
## 6. Odoo 16 (VM123) — empresa / financeiro
|
||
|
||
**Spec:** [023 § Motor cobrança Fase 2](../../023-billing-recurrence-desk-visibility/spec.md)
|
||
**API:** XML-RPC `res.partner`
|
||
**Código Desk:** `vm123/odoo_client.py` (**create partner cliente — a implementar**)
|
||
|
||
### 6.1 `res.partner` (empresa cliente)
|
||
|
||
| Campo Odoo | Origem wizard / Desk | Notas |
|
||
|------------|----------------------|-------|
|
||
| `name` | `legal_name` | Razão social |
|
||
| `display_name` | `trade_name` | Se suportado |
|
||
| `vat` | `tax_id` | CNPJ formatado BR |
|
||
| `email` | `email_billing` | Contacto financeiro |
|
||
| `phone` | `phone_mobile` | |
|
||
| `street` | `address.street` | |
|
||
| `city` | `address.city` | |
|
||
| `zip` | `address.postal_code` | |
|
||
| `country_id` | `address.country` | resolver `res.country` BR |
|
||
| `company_type` | fixo | `company` |
|
||
| `customer_rank` | fixo | `1` |
|
||
| `ref` | `domain` | referência interna Ligbox |
|
||
| `comment` | JSON curto | `manager_email`, `foss_client_id`, `session_id` |
|
||
|
||
**Guardar em Desk:** `external_subscription_id` ou campo dedicado `odoo_partner_id` (adicionar coluna fase 2).
|
||
|
||
### 6.2 Fase 2 — assinatura / vendas
|
||
|
||
| Odoo model | Origem | Spec |
|
||
|------------|--------|------|
|
||
| `sale.subscription` | `plan_code` + preço FOSS | 023 |
|
||
| `account.move` | pagamentos ASAAS/Iugu | 023 fase 2 |
|
||
|
||
---
|
||
|
||
## 7. Wizard VM112 — provisionamento mail (pós-activação)
|
||
|
||
**Spec:** [035 §5.2 webhook](../../035-ligbox-mail-bundles-foss-openpanel/spec.md)
|
||
|
||
```
|
||
POST https://desk.ligbox.com.br/api/v1/billing/webhook/foss/order-activated
|
||
→ Desk orquestra
|
||
POST http://10.10.10.112/api/internal/provision/mail-bundle
|
||
```
|
||
|
||
| Campo mail-bundle | Origem |
|
||
|-------------------|--------|
|
||
| `domain` | `domain` |
|
||
| `admin_email` | `manager_email` |
|
||
| `admin_name` | `manager_name` |
|
||
| `seats` | `config.seats` |
|
||
| `mail_gb_per_seat` | `config.mail_gb` |
|
||
| `files_gb_per_seat` | `config.files_gb` |
|
||
| `foss_order_id` | FOSS order |
|
||
|
||
---
|
||
|
||
## 8. Matriz resumo — um olhar
|
||
|
||
| Campo negócio | Wizard | Desk DB | FOSS client | FOSS order | OpenPanel | Odoo partner |
|
||
|---------------|:------:|:-------:|:-----------:|:----------:|:---------:|:------------:|
|
||
| Domínio | ✅ | ✅ | custom | custom | ✅ domain | ref |
|
||
| Razão social | ✅ | ✅ | company | — | — | name |
|
||
| Nome fantasia | ✅ | ✅ | — | — | — | display |
|
||
| CNPJ/CPF | ✅ | ✅ | company_vat | — | — | vat |
|
||
| Email cobrança | ✅ | ✅ | alt email | — | — | email |
|
||
| Email gerente | ✅ | profile | email | custom | email | comment |
|
||
| Nome responsável | ✅ | profile | first/last | custom | metadata | — |
|
||
| Plano / bundle | — | plan_code | — | product | plan_name | subscription* |
|
||
| Morada | ✅ | JSON | address_* | — | — | street/city/zip |
|
||
| Telefone | ✅ | JSON | phone | — | — | phone |
|
||
|
||
\* Fase 2 Odoo
|
||
|
||
---
|
||
|
||
## 9. RBAC — quem activa
|
||
|
||
**Specs:** [027](../../027-desk-rbac-function-matrix/spec.md) · [039](../../039-ligbox-ops-authorization-catalog/spec.md)
|
||
|
||
| Acção | Funções |
|
||
|-------|---------|
|
||
| Ver `company_profile` completo | super_admin, ops_lead, finance, sales_admin |
|
||
| **Activar conta** (disparar FOSS+OP+Odoo) | super_admin, ops_lead, finance |
|
||
| Ver mascarado (NOC) | noc — CNPJ/email mascarados |
|
||
|
||
---
|
||
|
||
## 10. Idempotência e erros
|
||
|
||
| Cenário | Comportamento |
|
||
|---------|---------------|
|
||
| FOSS client já existe (email) | Reutilizar `client.id`, não duplicar |
|
||
| OpenPanel user exists | Erro controlado; staff resolve manual |
|
||
| Odoo partner exists | `write` update em vez de `create` |
|
||
| Falha parcial | `billing_state=provisioning` + log steps em `provision_json` |
|
||
| Retry staff | Seguro se ids externos já gravados |
|
||
|
||
---
|
||
|
||
## 11. Histórico de versões
|
||
|
||
| Versão | Data | Autor | Alteração |
|
||
|--------|------|-------|-----------|
|
||
| 1.0 | 2026-07-01 | Roger / Cursor | Documento inicial Spec 043 |
|
||
| 1.1 | 2026-07-01 | Roger / Cursor | FOSS product_id=3 · mail-bundle-api |
|
||
|
||
---
|
||
|
||
*Manter sincronizado com alterações em VM112 wizard, FOSS custom fields e Odoo localização BR.*
|