# E-mail Ligbox — arquitetura corrigida (VM112)

**Atualizado:** 2026-06-19 (Roger)  
**Estado:** ✅ Produção validada

---

## Regra de ouro

| Domínio | Servidor Carbonio | IP | Hostname SMTP |
|---------|-------------------|-----|---------------|
| **`ligbox.com.br`** | **VM112** | `10.10.10.112` | `mail.ligbox.com.br` |
| `dratcoin.com`, `ibytera.com`, tenants onboarding | VM112 | `10.10.10.112` | `mail.ligbox.com.br` |
| `nutranik.com` | VM108 (outro produto) | `10.10.10.108` | `mail.ligbox.com.br` (hostname partilhado, domínio diferente) |

**Não usar VM108 para `@ligbox.com.br`.** Caixas Ligbox (`admin@`, `rogerio@`, `ops@`, etc.) vivem na **VM112**.

**Não criar domínios/contas `itecnologys.com` na VM112** — notificações admin usam `admin@ligbox.com.br`.

---

## Wizard onboarding (VM112)

| Parâmetro | Valor |
|-----------|--------|
| `NOTIFY_ADMIN_EMAIL` | `admin@ligbox.com.br` |
| `NOTIFY_FROM_EMAIL` | `noreply@ligbox.com.br` |
| `SMTP_HOST` / `SMTP_PORT` | `127.0.0.1:25` (Postfix Carbonio local) |

**Ficheiro env:** `/opt/ligbox-deploy/env/.env` (carregado pelo systemd `ligbox-wizard.service`)

**Código:** `backend/app/services/notifications.py` — dispara admin, cliente e boas-vindas em `POST /api/onboarding/account/create`.

**Doc operacional:** [`NOTIFICACOES_E_TERMINAL.md`](../NOTIFICACOES_E_TERMINAL.md)

---

## Desk Ops / técnicos (VM122)

Postfix na VM122 é MTA local da API Desk (`mail_notify.py`).

### transport_maps (`/etc/postfix/transport`)

```
ligbox.com.br   lmtp:[10.10.10.112]:7025
ibytera.com     lmtp:[10.10.10.112]:7025
dratcoin.com    lmtp:[10.10.10.112]:7025
```

### API Docker (`.env`)

```env
DESK_SMTP_HOST=10.10.10.122
DESK_SMTP_PORT=25
DESK_MAIL_FROM=ligbox-ops@ligbox.com.br
DESK_ROOT_NOTIFY_EMAIL=admin@ligbox.com.br
```

### Cadastro de técnicos

- Preferir e-mails **`@ligbox.com.br`** (Spec 004).
- OTP, aprovação e notificações root → `admin@ligbox.com.br` na VM112.

**Doc Desk:** `ligbox-ops-platform/docs/postfix-vm122.md`

---

## Problema corrigido (2026-06-19)

| Sintoma | Causa | Correção |
|---------|-------|----------|
| Admin não recebia e-mail do wizard | `NOTIFY_ADMIN_EMAIL=admin@itecnologys.com` — caixa inexistente no Carbonio | `admin@ligbox.com.br` |
| Desk OTP / aprovação não chegava | VM122 enviava `@ligbox.com.br` para LMTP **VM108** (domínio não existe lá) | `transport` → **VM112:7025** |
| Fila presa `@itecnologys.com` | MX público timeout | `postsuper -d ALL deferred`; usar `@ligbox.com.br` no Desk |

---

## Testes rápidos

### VM112 — wizard SMTP

```bash
cd /opt/ligbox-wizard/backend
/opt/ligbox-wizard/.venv/bin/python3 - <<'PY'
import smtplib
from email.mime.text import MIMEText
msg = MIMEText("teste wizard")
msg["Subject"] = "[TEST] wizard admin"
msg["From"] = "noreply@ligbox.com.br"
msg["To"] = "admin@ligbox.com.br"
with smtplib.SMTP("127.0.0.1", 25, timeout=15) as s:
    s.sendmail(msg["From"], [msg["To"]], msg.as_string())
print("OK")
PY
```

### VM122 — Desk SMTP

```bash
python3 - <<'PY'
import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["From"] = "ligbox-ops@ligbox.com.br"
msg["To"] = "admin@ligbox.com.br"
msg["Subject"] = "[TEST] desk"
msg.set_content("teste desk")
with smtplib.SMTP("127.0.0.1", 25, timeout=15) as s:
    s.send_message(msg)
print("OK")
PY
journalctl | grep "admin@ligbox.com.br" | tail -3
```

Resultado esperado na VM122: `status=sent` via `relay=10.10.10.112:7025`.

---

## Documentos relacionados

| Documento | Conteúdo |
|-----------|----------|
| [`NOTIFICACOES_E_TERMINAL.md`](../NOTIFICACOES_E_TERMINAL.md) | Notificações wizard (admin, cliente, boas-vindas) |
| [`SPEC_FUNCIONAL_VM112_LIGBOX_ONBOARD.md`](SPEC_FUNCIONAL_VM112_LIGBOX_ONBOARD.md) | Spec funcional VM112 |
| `ligbox-ops-platform/docs/postfix-vm122.md` | Postfix Desk |
| `ligbox-ops-platform/specs/004-desk-account-management/` | Cadastro e OTP técnicos |
