# 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.*
