# Contrato — API Desk «Activar conta» (planeada)

**Spec:** [043](../spec.md) · depende de [activation-field-mapping.md](./activation-field-mapping.md)

**Status:** ✅ Implementada — Spec 043  
**Base URL:** `https://desk.ligbox.com.br/api/v1`

---

## POST `/billing/accounts/{id}/activate`

Dispara sequência FOSS → OpenPanel → Odoo → (opcional) wizard mail-bundle.

### Autenticação

Bearer session Desk + RBAC: `finance` \| `ops_lead` \| `super_admin` ([039](../../039-ligbox-ops-authorization-catalog/spec.md))

### Request body

```json
{
  "plan_code": "ligbox-mail-business",
  "config": {
    "seats": 25,
    "mail_gb": 30,
    "files_gb": 200
  },
  "provision_mail": true,
  "notes": "Validado por Roger — contrato verbal OK"
}
```

| Campo | Obrigatório | Descrição |
|-------|-------------|-----------|
| `plan_code` | sim | Slug produto FOSS / `plan_name` OpenPanel |
| `config` | se `ligbox-mail-custom` | seats, mail_gb, files_gb |
| `provision_mail` | não (default true) | Chamar wizard mail-bundle após FOSS |
| `notes` | não | Audit log |

### Response 200

```json
{
  "ok": true,
  "billing_account_id": 42,
  "domain": "empresa.com.br",
  "billing_state": "provisioning",
  "steps": {
    "foss": { "client_id": 101, "order_id": 55, "created": true },
    "openpanel": { "username": "empresa1x", "domain": "empresa.com.br", "success": true },
    "odoo": { "partner_id": 88, "created": true },
    "wizard": { "provisioned": true, "mail_host": "mail.empresa.com.br" }
  },
  "activated_at": "2026-07-01T12:00:00Z",
  "activated_by": "roger"
}
```

### Response 207 (parcial)

```json
{
  "ok": false,
  "billing_state": "provisioning",
  "steps": {
    "foss": { "client_id": 101, "order_id": 55 },
    "openpanel": { "error": "user already exists" },
    "odoo": { "partner_id": 88 }
  },
  "message": "OpenPanel falhou — FOSS e Odoo OK"
}
```

### Erros

| HTTP | Condição |
|------|----------|
| 400 | `plan_code` inválido ou `billing_state` não permite activação |
| 403 | RBAC insuficiente |
| 404 | `billing_account` não existe |
| 409 | Já `billing_active` |
| 502 | FOSS/Odoo indisponível |

---

## GET `/billing/accounts/{id}/activation-preview`

Devolve payload **read-only** com mapeamento que será enviado a FOSS/OP/Odoo (para UI staff antes de confirmar).

### Response 200

```json
{
  "domain": "empresa.com.br",
  "company_profile": { "...": "..." },
  "mapped": {
    "foss_client": { "email": "admin@empresa.com.br", "company": "...", "company_vat": "..." },
    "openpanel": { "plan_name": "ligbox-mail-business", "domain": "empresa.com.br" },
    "odoo_partner": { "name": "...", "vat": "...", "email": "..." }
  },
  "billing_state": "awaiting_billing_validation"
}
```

---

*Implementar em `projects/ops-desk/api/app/billing_routes.py` + `vm123/client_provision.py`*
