Cache VM112/VM122 para lista e detalhe domínio, modal purge com loading animado, cards Escopo OPS clicáveis (camada + Spec + navegação), blocklist visível na UI, e documentação nas specs e anais de referência 20260625. Co-authored-by: Cursor <cursoragent@cursor.com>
669 lines
28 KiB
Markdown
669 lines
28 KiB
Markdown
# Feature Specification: Orquestração de Serviços — Cliente & Catálogo (018)
|
||
|
||
**Criado:** 2026-06-16
|
||
**Actualizado:** 2026-06-25 (performance + Escopo OPS clicável + camadas tiles)
|
||
**Solicitado por:** Roger
|
||
**Status:** Fase 1 concluída (Desk VM122)
|
||
**Wizard cliente:** inalterado na VM112 — só e-mail (`vm112-mail`)
|
||
**Prioridade:** P1
|
||
**Sistema:** Desk VM122 (+ proxies VM112, futuro multi-wizard)
|
||
**Módulo Desk:** `overview-home` (nav **Serviços**)
|
||
**Depende de:** Spec 015 (módulos), Spec 017 (purge domínio VM112)
|
||
|
||
---
|
||
|
||
## Resumo
|
||
|
||
A página **Serviços** substitui a visão estreita «Contas / lista de domínios» por um painel operacional estilo **cPanel/WHM**: o técnico sénior selecciona um **cliente** e vê **tiles de serviços** contratados ou disponíveis (e-mail tenant, servidor dedicado, firewall, cloud, Wazuh, site).
|
||
|
||
**Fase 1 (esta entrega):** UI e modelo conceptual no frontend; clientes derivados dos domínios VM112; apenas **E-mail Tenant** activo com purge Spec 017 intacto.
|
||
**Fase 2:** API Desk `clients` + `service_instances` em SQLite.
|
||
**Fase 3:** Registry de wizards por `service_catalog.code` e purge por instância.
|
||
|
||
### Performance — Serviços IaaS (2026-06-25)
|
||
|
||
**Cadeia:** Desk `servicos.js` → VM122 `GET /api/v1/vm112/domains` → VM112 `GET /api/admin/domains` → **`zmprov gad`** (~5s sem cache).
|
||
|
||
| Camada | Problema | Mitigação | Deploy |
|
||
|--------|----------|-----------|--------|
|
||
| **VM112** | `zmprov gad` a cada pedido | Cache 90s `gad_all_domains` + lista orquestrada 60s; invalidação em `cd`/`dd`/purge | `deploy/vm112-wizard/perf-domains-list-20260625/` ✅ 2026-06-25 |
|
||
| **VM122 API** | Proxy repetia VM112 lenta | Cache 60s `VM112_DOMAINS_CACHE_TTL` | `vm112_domains.py` ✅ |
|
||
| **Desk frontend** | Ecrã preso «A carregar…» | `sessionStorage` stale-while-revalidate + dedup fetch | `servicos.js` ✅ |
|
||
| **Poll** | 30s sobrecarregava VM112 | Poll **90s** em `overview-home` | `app.js` ✅ |
|
||
| **Sessão** | API restart expulsava user | Rede ≠ logout (`ensureValidSession`) | `auth.js` ✅ |
|
||
|
||
**Resultados medidos (2026-06-25):**
|
||
|
||
| Pedido | Antes | Depois |
|
||
|--------|-------|--------|
|
||
| VM112 `/api/admin/domains` (2.º hit) | ~5–11s | **~0,03s** |
|
||
| VM112 `/api/admin/domains/{domain}` (2.º hit) | ~15–20s | **~0,04s** |
|
||
| VM112 detalhe (1.º hit, cold) | ~20s serial | **~16s** paralelo (infra+gaa+CF) |
|
||
| Desk `/api/v1/vm112/domains` (cache quente) | ~16s | **~0,08s** |
|
||
| Desk `/api/v1/vm112/domains/{domain}` (cache quente) | ~15s+ | **~3s** (1.º após lista) / **~0,1s** (2.º) |
|
||
| 1.º hit pós-restart wizard | — | ~6s lista / ~16s modal purge |
|
||
|
||
### Modal Purge / «Gerir» (2026-06-25)
|
||
|
||
**Endpoint:** `GET /api/v1/vm112/domains/{domain}` → VM112 `get_domain_detail()`.
|
||
|
||
| Gargalo | Tempo | Mitigação |
|
||
|---------|-------|-----------|
|
||
| `get_status()` — SSH CT114, DNS, HTTPS | ~9s | Cache `infra_status:{domain}` 90s |
|
||
| `zmprov gaa` (contas) | ~3s | Cache `accounts_list:{domain}` 45s |
|
||
| Cloudflare API | ~1–2s | Paralelo + cache `domain_detail:{domain}` 120s |
|
||
| UI ecrã branco | UX | **Skeleton** imediato com dados da lista clientes |
|
||
|
||
**Frontend:** `servicos.js` — modal abre com dados do cliente seleccionado; purge form activa após load.
|
||
|
||
**Loading UX (2026-06-25):** barra indeterminada, etapas VM112 rotativas, botão spinner — ver Spec **017** § UI Serviços loading.
|
||
|
||
**Desk API:** cache proxy detalhe 45s (`VM112_DOMAIN_DETAIL_TTL`).
|
||
|
||
### Escopo OPS — cards clicáveis (2026-06-25)
|
||
|
||
Coluna direita: cada escopo é **card botão** com **camada**, **Spec** e **destino**.
|
||
|
||
| ID | Label | Camada | Spec | Destino ao clicar |
|
||
|----|-------|--------|------|-------------------|
|
||
| `carbonio` | Carbonio | Aplicação MOSP | 017 | Modal Serviços (detalhe/purge) |
|
||
| `site` | ligbox-sites | Tenant utilizador | 017 | Modal Serviços |
|
||
| `portal` | Portal users | Tenant utilizador | 028 | Console › `/admin/dominio?domain=` |
|
||
| `cloudflare` | Cloudflare | Infraestrutura | 037 | Console › DNS Viewer |
|
||
| `traefik` | Traefik / SNI | Infraestrutura | 026 | Desk › Infra CODE |
|
||
| `desk` | Desk OPS | Aplicação MOSP | 017 | Desk › Eventos › tab Purges |
|
||
|
||
**Blocklist UI:** clientes `ligbox.com.br` / `itecnologys.com` — badge 🔒 na lista; banner no painel Escopo; purge modal desactivado (`purge_blocked` API).
|
||
|
||
**Tiles centro:** badge camada (`Tenant utilizador` · `Aplicação MOSP` · `Infraestrutura`) + badge comercial (`SaaS` / `IaaS`).
|
||
|
||
**Navegação:** `window.DeskNavigate.go('events', { eventsTab: 'purges' })` — helper em `app.js`.
|
||
|
||
**Cache bust frontend (VM122):** `servicos.js`, `styles.css`, `app.js` → `?v=20260625align1`.
|
||
|
||
---
|
||
|
||
```json
|
||
{
|
||
"domains": [ "..." ],
|
||
"cached": true,
|
||
"cache_age_sec": 12
|
||
}
|
||
```
|
||
|
||
**Regra deploy Roger:**
|
||
|
||
1. VM112: `systemctl restart ligbox-wizard` invalida cache wizard (~6s no 1.º Serviços IaaS).
|
||
2. VM122: preferir `docker cp` sem restart; se restart API, Desk mostra cache browser.
|
||
3. Purge/create domain invalida cache VM112 automaticamente.
|
||
|
||
Ver também Spec **017** § cache listagem domínios.
|
||
|
||
---
|
||
|
||
## Problema
|
||
|
||
| Hoje | Necessidade |
|
||
|------|-------------|
|
||
| Lista plana de domínios | Vista por **cliente** |
|
||
| Nome «Contas» ambíguo | **Serviços** — escala para novos produtos |
|
||
| Purge acoplado à lista | Purge no tile **E-mail Tenant** (Spec 017) |
|
||
| Um wizard (mail) | Vários wizards futuros (firewall, cloud, Wazuh) |
|
||
|
||
---
|
||
|
||
## Nomenclatura
|
||
|
||
| Camada | Valor |
|
||
|--------|--------|
|
||
| ID módulo / view | `overview-home` (sem breaking change) |
|
||
| Menu lateral | **Serviços** |
|
||
| Título página | **Orquestração de Serviços** |
|
||
| Subtítulo | *Clientes Ligbox — serviços activos, estado OPS e acções* |
|
||
| JS global | `DeskServices` (alias `DeskAccounts` para compat.) |
|
||
|
||
---
|
||
|
||
**Fase 1 (esta entrega):** UI e modelo conceptual no frontend; clientes derivados dos domínios VM112; apenas **E-mail Tenant** activo com purge Spec 017 intacto.
|
||
**Fase 2:** API Desk `clients` + `service_instances` em SQLite.
|
||
**Fase 3:** Registry de wizards por `service_catalog.code` e purge por instância.
|
||
**Fase 4:** Catálogo comercial completo — níveis «Pizza as a Service» + Managed Open Source.
|
||
|
||
**Posicionamento Ligbox (MSP):**
|
||
|
||
> *«Pegamos soluções open source e entregamos como serviço gerenciado — em cloud privada Ligbox, VPS dedicado ou infraestrutura local do cliente.»*
|
||
|
||
---
|
||
|
||
## Visão de oferta — «Pizza as a Service» (Roger, 2026)
|
||
|
||
A analogia **Pizza as a Service** descreve **quem gere o quê** entre cliente e provedor. Quanto mais camadas a Ligbox opera, mais «as a service» o produto é — e mais valor (e SLA) o cliente compra.
|
||
|
||
### Legenda de responsabilidade (camadas da «pizza»)
|
||
|
||
| Camada (de baixo para cima) | Equivalente técnico Ligbox |
|
||
|-----------------------------|----------------------------|
|
||
| Eletricidade / Gás | Datacenter, energia, link, Hetzner/host |
|
||
| Fogão | Hypervisor — Proxmox VE, VMs, CTs |
|
||
| Fogo | SO, rede, firewall base, hardening |
|
||
| Pizza (massa/base) | Runtime — Docker, Nginx, Traefik, DB engine |
|
||
| Toppings | Aplicação open source — Carbonio, Nextcloud, ERPNext |
|
||
| Bebidas | Integrações — DNS, SSL, backup, monitoramento |
|
||
| Conversas | Uso pelo cliente — utilizadores finais, dados de negócio |
|
||
|
||
**Azul (cliente gere)** · **Laranja (Ligbox gere)**
|
||
|
||
---
|
||
|
||
### Nível 1 — Tradicional → Consultoria / Suporte sob demanda
|
||
|
||
*Equivalente: «Feito em casa» — cliente gere tudo; Ligbox ajuda quando chamada.*
|
||
|
||
| Gerido pelo **cliente** | Oferecido pela **Ligbox** |
|
||
|-------------------------|---------------------------|
|
||
| Servidores físicos / on-prem | Consultoria Linux |
|
||
| Rede | Troubleshooting |
|
||
| Sistema operacional | Instalação inicial |
|
||
| Banco de dados | Treinamento técnico |
|
||
| Backup | Auditoria de segurança |
|
||
| Aplicação | Documentação |
|
||
| Segurança operacional | — |
|
||
|
||
| Campo catálogo | Valor |
|
||
|----------------|-------|
|
||
| `delivery_model` | `traditional` |
|
||
| `code` (ex.) | `consulting_hour`, `audit_security`, `linux_training` |
|
||
| Stack típica | Ubuntu Server, Debian, Proxmox VE (no lado do cliente) |
|
||
| Modelo comercial | Hora técnica · pacote suporte mensal básico |
|
||
| Wizard Desk | Não — ticket + assist takeover (Spec 010) |
|
||
| Tile UI | «Suporte» — sem instância provisionada |
|
||
|
||
---
|
||
|
||
### Nível 2 — IaaS → Infraestrutura gerenciada
|
||
|
||
*Equivalente: «Leve e Asse» — Ligbox entrega infra pronta; cliente cuida da aplicação.*
|
||
|
||
| Gerido pela **Ligbox** | Gerido pelo **cliente** |
|
||
|------------------------|-------------------------|
|
||
| VPS / Cloud | Aplicação |
|
||
| Virtualização (Proxmox) | Dados |
|
||
| Firewall (pfSense) | Utilizadores da app |
|
||
| Backup do servidor | — |
|
||
| Monitoramento 24/7 | — |
|
||
| SO + hardening | — |
|
||
|
||
| Campo catálogo | Valor |
|
||
|----------------|-------|
|
||
| `delivery_model` | `iaas` |
|
||
| `code` (ex.) | `managed_vps`, `managed_backup`, `vpn_corporate`, `firewall`, `monitoring_host` |
|
||
| Stack Ligbox | Proxmox VE, Docker, Nginx, pfSense, Grafana, Prometheus |
|
||
| Modelo comercial | Mensal fixo — ex. *«Servidor Linux totalmente gerenciado»* |
|
||
| Wizard Desk | `wizard-iaas-vps` (futuro) — VM, IP, backup job |
|
||
| Tile UI | Firewall, Cloud/VPS, Monitoring host — badge **IaaS** |
|
||
|
||
**Ligbox hoje (parcial):** regras Proxmox, pfSense WAN, VM112 como nó — encaixa neste nível para a camada «fogão+fogo».
|
||
|
||
---
|
||
|
||
### Nível 3 — PaaS → Plataforma gerenciada
|
||
|
||
*Equivalente: «Delivery» — ambiente pronto para deploy; cliente traz código/dados.*
|
||
|
||
| Gerido pela **Ligbox** | Gerido pelo **cliente** |
|
||
|------------------------|-------------------------|
|
||
| Infraestrutura (IaaS) | Código da aplicação |
|
||
| Banco de dados gerido | Dados de negócio |
|
||
| Deploy / CI/CD | — |
|
||
| Backup + SSL | — |
|
||
| Escalabilidade | — |
|
||
|
||
| Campo catálogo | Valor |
|
||
|----------------|-------|
|
||
| `delivery_model` | `paas` |
|
||
| `code` (ex.) | `k8s_managed`, `postgres_managed`, `cicd_pipeline`, `api_hosting` |
|
||
| Stack Ligbox | Kubernetes, PostgreSQL, Redis, GitLab, Traefik |
|
||
| Modelo comercial | Mensal por ambiente / por pipeline |
|
||
| Wizard Desk | `wizard-paas-k8s`, `wizard-paas-db` (futuro) |
|
||
| Tile UI | DevOps / CI/CD — badge **PaaS** |
|
||
|
||
---
|
||
|
||
### Nível 4 — SaaS → Solução completa gerenciada
|
||
|
||
*Equivalente: «Restaurante» — cliente só utiliza.*
|
||
|
||
| Gerido pela **Ligbox** | Gerido pelo **cliente** |
|
||
|------------------------|-------------------------|
|
||
| Tudo (infra → app → users ops) | Apenas **uso** — login, conteúdo, processos de negócio |
|
||
| Actualizações, segurança, backup | — |
|
||
| Monitoramento, suporte SLA | — |
|
||
|
||
| Campo catálogo | Valor |
|
||
|----------------|-------|
|
||
| `delivery_model` | `saas` |
|
||
| `code` (ex.) | `email_tenant`, `erpnext`, `suitecrm`, `nextcloud`, `wiki_js`, `bitwarden`, `zammad` |
|
||
| Modelo comercial | Por utilizador/mês · mensal por domínio · tier SLA |
|
||
| Wizard Desk | `vm112-mail` (e-mail) · wizards por produto (futuro) |
|
||
| Tile UI | E-mail Tenant (activo Fase 1) — badge **SaaS** |
|
||
|
||
**Ligbox hoje:** **E-mail Tenant** (Carbonio + portal + DNS + Traefik) = **SaaS / Managed Open Source** — produto flagship.
|
||
|
||
---
|
||
|
||
### Nível 5 — Managed Open Source Services (MOSP) — modelo ideal MSP
|
||
|
||
Camada comercial que a Ligbox deve priorizar: **software open source operado pela Ligbox; cliente só consome.**
|
||
|
||
| Serviço | Tecnologia | `catalog.code` | Cobrança sugerida | `delivery_model` |
|
||
|---------|------------|----------------|-------------------|------------------|
|
||
| E-mail corporativo (tenant) | Carbonio | `email_tenant` | mensal / domínio | `saas` |
|
||
| E-mail dedicado | Mailcow / VM dedicada | `mail_dedicated` | mensal / servidor | `saas` |
|
||
| Cloud Storage | Nextcloud | `nextcloud` | por utilizador | `saas` |
|
||
| ERP | ERPNext | `erpnext` | por utilizador | `saas` |
|
||
| CRM | SuiteCRM | `suitecrm` | por utilizador | `saas` |
|
||
| Wiki corporativa | Wiki.js | `wiki_js` | mensal | `saas` |
|
||
| Password Manager | Bitwarden | `bitwarden` | por utilizador | `saas` |
|
||
| Helpdesk | Zammad | `zammad` | mensal | `saas` |
|
||
| Chat corporativo | Mattermost | `mattermost` | mensal | `saas` |
|
||
| Git privado | Gitea | `gitea` | por utilizador | `saas` |
|
||
| VPN empresarial | WireGuard | `vpn_corporate` | por empresa | `iaas` |
|
||
| Monitoramento | Zabbix / Wazuh | `wazuh_domain`, `monitoring_host` | mensal | `iaas` / `saas` |
|
||
| Backup | Restic + MinIO | `backup_baas` | por GB | `iaas` |
|
||
| Firewall | pfSense | `firewall` | mensal | `iaas` |
|
||
| Site / CMS | ligbox-sites | `site_cms` | mensal | `saas` |
|
||
|
||
**Regra de produto:** cada linha do catálogo tem `delivery_model`, `managed_layers[]` (quais camadas da pizza a Ligbox opera) e `wizard_id` quando provisionável.
|
||
|
||
---
|
||
|
||
## Portfólio Ligbox — mapa completo (futuro)
|
||
|
||
### Infraestrutura
|
||
|
||
| Produto | Nível | `code` | Estado Desk |
|
||
|---------|-------|--------|-------------|
|
||
| Linux Managed Server | IaaS | `managed_vps` | Planeado |
|
||
| VPS Management | IaaS | `cloud` | Tile «Em breve» |
|
||
| Backup as a Service | IaaS | `backup_baas` | Planeado |
|
||
| Monitoring as a Service | IaaS/SaaS | `monitoring_host` | Parcial (Grafana/Infra) |
|
||
|
||
### Segurança
|
||
|
||
| Produto | Nível | `code` | Estado Desk |
|
||
|---------|-------|--------|-------------|
|
||
| Firewall as a Service | IaaS | `firewall` | Tile «Em breve» |
|
||
| VPN as a Service | IaaS | `vpn_corporate` | Planeado |
|
||
| Vulnerability Scanning | Tradicional | `vuln_scan` | Planeado |
|
||
| Wazuh SOC por domínio | SaaS | `wazuh_domain` | Tile «Em breve» + Infra 2 |
|
||
|
||
### Aplicações open source (MOSP)
|
||
|
||
| Produto | Nível | `code` | Estado Desk |
|
||
|---------|-------|--------|-------------|
|
||
| E-mail Tenant | SaaS | `email_tenant` | **Activo** (Spec 017 purge) |
|
||
| E-mail dedicado | SaaS | `mail_dedicated` | Tile «Em breve» |
|
||
| Nextcloud | SaaS | `nextcloud` | Planeado |
|
||
| ERP (ERPNext) | SaaS | `erpnext` | Planeado |
|
||
| CRM (SuiteCRM) | SaaS | `suitecrm` | Planeado |
|
||
| Site / CMS | SaaS | `site_cms` | Derivado VM112 |
|
||
| Wiki.js | SaaS | `wiki_js` | Planeado |
|
||
| Bitwarden | SaaS | `bitwarden` | Planeado |
|
||
| Zammad | SaaS | `zammad` | Planeado |
|
||
| Mattermost | SaaS | `mattermost` | Planeado |
|
||
| Gitea | SaaS | `gitea` | Planeado |
|
||
|
||
### DevOps
|
||
|
||
| Produto | Nível | `code` | Estado Desk |
|
||
|---------|-------|--------|-------------|
|
||
| Docker Hosting | PaaS | `docker_hosting` | Planeado |
|
||
| Kubernetes Hosting | PaaS | `k8s_managed` | Planeado |
|
||
| CI/CD Pipeline | PaaS | `cicd_pipeline` | Planeado |
|
||
|
||
### Suporte transversal
|
||
|
||
| Produto | Nível | `code` | Canal Desk |
|
||
|---------|-------|--------|------------|
|
||
| SLA empresarial | Overlay | `sla_enterprise` | Tickets + SLA fields |
|
||
| Monitoramento 24/7 | Overlay | `noc_24x7` | Infra + alertas |
|
||
| Administração remota | Tradicional | `remote_admin` | Assist takeover |
|
||
| Consultoria Linux | Tradicional | `consulting_hour` | Tickets |
|
||
|
||
---
|
||
|
||
## Modelo conceptual (actualizado)
|
||
|
||
```
|
||
Cliente (org)
|
||
└── Instância de serviço (service_instance)
|
||
├── service_catalog.code (email_tenant, firewall, nextcloud, …)
|
||
├── service_catalog.delivery_model (traditional | iaas | paas | saas)
|
||
├── managed_layers[] (datacenter, hypervisor, os, runtime, app, ops)
|
||
├── status (planned | provisioning | active | degraded | suspended)
|
||
├── commercial_plan (hourly | monthly_fixed | per_user | per_gb)
|
||
├── wizard_id (vm112-mail, wizard-iaas-vps, …)
|
||
├── sla_tier (basic | business | enterprise)
|
||
└── bindings[] (domain, vm_id, zone_id, agent_id, k8s_ns)
|
||
```
|
||
|
||
### Matriz de responsabilidade por `delivery_model`
|
||
|
||
| Camada | traditional | iaas | paas | saas |
|
||
|--------|:-----------:|:----:|:----:|:----:|
|
||
| Datacenter / link | C | L | L | L |
|
||
| Hypervisor / VM | C | L | L | L |
|
||
| SO / rede / firewall | C | L | L | L |
|
||
| Runtime (Docker, proxy) | C | C | L | L |
|
||
| BD / deploy / SSL | C | C | L | L |
|
||
| Aplicação open source | C | C | C | L |
|
||
| Backup / monitoramento | C | L | L | L |
|
||
| Utilizadores finais / dados negócio | C | C | C | C |
|
||
|
||
*C = Cliente · L = Ligbox*
|
||
|
||
### Catálogo de serviços — MVP + roadmap MOSP
|
||
|
||
| code | Label UI | delivery_model | Wizard | Fase Desk |
|
||
|------|----------|----------------|--------|-----------|
|
||
| `email_tenant` | E-mail Tenant | saas | `vm112-mail` | **Activo** |
|
||
| `site_cms` | Site / CMS | saas | `vm112-mail` | Derivado VM112 |
|
||
| `mail_dedicated` | Servidor E-mail Dedicado | saas | TBD | Em breve |
|
||
| `firewall` | Firewall (pfSense) | iaas | `wizard-iaas-fw` | Em breve |
|
||
| `cloud` | Cloud / VPS gerenciado | iaas | `wizard-iaas-vps` | Em breve |
|
||
| `wazuh_domain` | Wazuh / SOC por domínio | saas | `wizard-soc-wazuh` | Em breve |
|
||
| `vpn_corporate` | VPN empresarial | iaas | TBD | Planeado |
|
||
| `backup_baas` | Backup as a Service | iaas | TBD | Planeado |
|
||
| `nextcloud` | Nextcloud | saas | TBD | Planeado |
|
||
| `erpnext` | ERP (ERPNext) | saas | TBD | Planeado |
|
||
| `monitoring_host` | Monitoramento 24/7 | iaas | TBD | Planeado |
|
||
| `consulting_hour` | Consultoria / suporte | traditional | — (ticket) | Planeado |
|
||
|
||
### Derivação Fase 1 — Cliente a partir do domínio VM112
|
||
|
||
Enquanto não existir tabela `clients`:
|
||
|
||
| Campo cliente | Origem |
|
||
|---------------|--------|
|
||
| `client_id` | `domain` (chave estável) |
|
||
| `display_name` | `domain` |
|
||
| `subtitle` | `portal_admin_email` ou «sem admin portal» |
|
||
| `health` | `ok` se `carbonio_exists`, senão `warn` |
|
||
|
||
Cada domínio VM112 = **1 cliente** com pelo menos uma instância `email_tenant`.
|
||
|
||
### Separação VM122 vs VM112 (Roger — clarificação)
|
||
|
||
| Onde | Papel |
|
||
|------|--------|
|
||
| **Desk VM122** (`/opt/ligbox-ops-platform`) | Orquestração MOSP — clientes, tenants de oferta, purge OPS, estado |
|
||
| **Portal VM112** (`/opt/ligbox-wizard`) | **Apenas** wizard e-mail/domínio — Hero e `/onboard` **não** recebem catálogo multi-produto |
|
||
| **Futuro** | Cada oferta MOSP → wizard próprio (pode provisionar Proxmox, servidor físico, etc.) |
|
||
|
||
A página Serviços no Desk é o **painel do técnico**; os wizards são **um por produto**, nunca um megamenu na Hero da 112.
|
||
|
||
---
|
||
|
||
## Reteste E2E — wizard e-mail/domínio (após purge)
|
||
|
||
### Pré-requisitos
|
||
|
||
1. Domínio de teste **ausente** em VM112 (lista Serviços vazia para esse domínio)
|
||
2. Desk: menu **Serviços** → purge Spec 017 se ainda existir lixo
|
||
3. Utilizador Desk: `super_admin` ou `ops_lead`
|
||
|
||
### Passos
|
||
|
||
| # | Acção | Verificação |
|
||
|---|--------|-------------|
|
||
| 1 | Desk → **Serviços** → seleccionar domínio teste | Tile **E-mail Tenant** activo ou cliente ausente |
|
||
| 2 | Se existir: tile E-mail → **Purge** (senha Root + confirmar domínio) | Domínio desaparece da lista |
|
||
| 3 | Portal `onboard.ligbox.com.br` ou `onboard.ibytera.com` | Self-Service → registo → `/onboard` |
|
||
| 4 | Wizard: domínio → DNS → conta → infra | Webhooks no Desk (Tickets/Eventos) |
|
||
| 5 | Desk → **Serviços** → Actualizar | Cliente reaparece; tenant E-mail **Activo** |
|
||
| 6 | Modal: infra steps verdes, contas Carbonio | Purge disponível para próximo ciclo |
|
||
|
||
### Domínios protegidos (sem purge)
|
||
|
||
`ligbox.com.br`, `itecnologys.com`
|
||
|
||
|
||
## UI — Layout 3 colunas
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Orquestração de Serviços [Actualizar] │
|
||
│ stats: clientes | e-mail activo | sites | logins portal │
|
||
├──────────────┬────────────────────────────┬─────────────────────┤
|
||
│ CLIENTES │ SERVIÇOS DO CLIENTE │ ESCOPO OPS │
|
||
│ [pesquisa] │ (tiles cPanel) │ (contexto serviço) │
|
||
│ • domain A │ [E-mail Tenant] activo │ Carbonio, CF, … │
|
||
│ • domain B │ [Site/CMS] activo │ nota purge │
|
||
│ │ [Firewall] em breve │ │
|
||
│ │ [Cloud] em breve │ │
|
||
│ │ [Wazuh] em breve │ │
|
||
└──────────────┴────────────────────────────┴─────────────────────┘
|
||
```
|
||
|
||
### Coluna Clientes
|
||
|
||
- Lista scrollável de todos os clientes (domínios VM112)
|
||
- Pesquisa: domínio, e-mail admin, login portal
|
||
- Badge saúde (verde/laranja)
|
||
- Clique selecciona cliente e actualiza tiles + escopo
|
||
|
||
### Coluna Serviços (centro)
|
||
|
||
- Grid de tiles por entrada do `SERVICE_CATALOG`
|
||
- Estados visuais: `active`, `inactive`, `planned`
|
||
- **Fase 2+:** badge `delivery_model` (IaaS / PaaS / SaaS / Suporte) e cor por nível
|
||
- **Fase 2+:** agrupamento por categoria — Infra · Segurança · Apps · DevOps · Suporte
|
||
- Tile **E-mail Tenant** activo → clique abre **modal Spec 017** (detalhe + purge)
|
||
- Tile **Site/CMS** → informativo (sem purge separado na Fase 1)
|
||
- Tiles `planned` → não clicáveis, label «Em breve» + tooltip com stack e modelo comercial
|
||
|
||
### Coluna Escopo OPS
|
||
|
||
- **Cards clicáveis** (2026-06-25) — camada (tenant / app / infra), Spec, destino OPS
|
||
- Lista dos escopos purge / operação quando serviço seleccionado
|
||
- **E-mail Tenant:** 6 escopos Spec 017 (Carbonio → Desk) — mapa na tabela § Escopo OPS cards
|
||
- **Blocklist:** banner + badge 🔒 para `ligbox.com.br`, `itecnologys.com`
|
||
- **Futuro:** escopo dinâmico por `service_catalog.purge_scopes_json`
|
||
- Indicador visual **quem gere** cada camada (matriz pizza — cliente vs Ligbox)
|
||
- Nota: purge requer senha Root no modal (serviços SaaS provisionados)
|
||
- Sem cliente seleccionado: texto de ajuda + link para portfólio (doc interna)
|
||
|
||
---
|
||
|
||
## Purge (sem regressão — Spec 017)
|
||
|
||
| Item | Mantido |
|
||
|------|---------|
|
||
| API | `POST /api/v1/vm112/domains/{domain}/purge` |
|
||
| Body | `confirm_domain`, `root_password` |
|
||
| RBAC | `super_admin`, `ops_lead` |
|
||
| Blocklist | `ligbox.com.br`, `itecnologys.com` |
|
||
| Escopos VM112 | Carbonio, site, portal, CF, Traefik, Desk |
|
||
| Modal | `#vm112-domain-modal` (index.html) |
|
||
|
||
O purge continua **por domínio** na Fase 1; na Fase 3 passa a `POST /api/v1/service-instances/{id}/purge` com escopo do catálogo.
|
||
|
||
---
|
||
|
||
## RBAC
|
||
|
||
Igual Spec 017 — `can_manage_vm112_domains()` → `super_admin`, `ops_lead`.
|
||
|
||
---
|
||
|
||
## API — Fase 1 (sem alteração)
|
||
|
||
Reutiliza endpoints Spec 017:
|
||
|
||
| Método | Path |
|
||
|--------|------|
|
||
| GET | `/api/v1/vm112/domains` |
|
||
| GET | `/api/v1/vm112/domains/{domain}` |
|
||
| POST | `/api/v1/vm112/domains/{domain}/purge` |
|
||
|
||
---
|
||
|
||
## API — Fase 2 (planeada)
|
||
|
||
| Método | Path | Descrição |
|
||
|--------|------|-----------|
|
||
| GET | `/api/v1/services/catalog` | Catálogo fixo + `delivery_model`, stack, wizard, preço ref |
|
||
| GET | `/api/v1/services/catalog/{code}` | Detalhe produto + matriz responsabilidade |
|
||
| GET | `/api/v1/clients?q=` | Lista clientes |
|
||
| GET | `/api/v1/clients/{id}` | Cliente + instâncias + bindings + SLA |
|
||
| POST | `/api/v1/service-instances` | Provisionar (trigger wizard por produto) |
|
||
| PATCH | `/api/v1/service-instances/{id}` | Suspender, reactivar, alterar plano |
|
||
| POST | `/api/v1/service-instances/{id}/purge` | Purge por instância (escopo do catálogo) |
|
||
|
||
### SQLite (Fase 2)
|
||
|
||
```sql
|
||
clients (
|
||
id, name, tax_id, primary_email,
|
||
hosting_mode, -- ligbox_cloud | dedicated_vps | customer_onprem
|
||
sla_tier, created_at
|
||
)
|
||
|
||
service_catalog (
|
||
code, label, category, -- infra | security | apps | devops | support
|
||
delivery_model, -- traditional | iaas | paas | saas
|
||
managed_layers_json, -- ["hypervisor","os","app",…]
|
||
technology_stack_json, -- ["Carbonio","Traefik",…]
|
||
wizard_id,
|
||
commercial_model, -- hourly | monthly_fixed | per_user | per_gb
|
||
purge_scopes_json,
|
||
default_enabled
|
||
)
|
||
|
||
service_instances (
|
||
id, client_id, catalog_code, status,
|
||
external_ref, meta_json,
|
||
commercial_plan, monthly_value_cents,
|
||
provisioned_at, expires_at
|
||
)
|
||
|
||
service_bindings (
|
||
instance_id, resource_type, resource_id
|
||
-- resource_type: domain | vm_id | zone_id | agent_id | k8s_namespace | ticket_id
|
||
)
|
||
```
|
||
|
||
### `hosting_mode` do cliente
|
||
|
||
| Valor | Significado | Pizza |
|
||
|-------|-------------|-------|
|
||
| `ligbox_cloud` | Hospedado na infra Ligbox (Proxmox/Hetzner) | Ligbox gere datacenter+fogão |
|
||
| `dedicated_vps` | VPS dedicado gerido pela Ligbox | IaaS+ |
|
||
| `customer_onprem` | Infra no cliente; Ligbox suporta/audita | Tradicional+ |
|
||
|
||
Um mesmo cliente pode misturar modos por instância de serviço (ex.: e-mail SaaS Ligbox + ERP on-prem com suporte tradicional).
|
||
|
||
---
|
||
|
||
## Ficheiros — Fase 1
|
||
|
||
| Ficheiro | Alteração |
|
||
|----------|-----------|
|
||
| `frontend/assets/accounts.js` | Refactor → `DeskServices`, layout 3 colunas |
|
||
| `frontend/assets/styles.css` | Classes `.servicos-*` |
|
||
| `frontend/index.html` | Nav «Serviços», cache bust |
|
||
| `frontend/assets/app.js` | Títulos view |
|
||
| `api/app/modules/registry.py` | Label módulo «Serviços» |
|
||
|
||
---
|
||
|
||
## Critérios de aceite — Fase 1
|
||
|
||
- [x] Menu mostra **Serviços** (não «Contas»)
|
||
- [x] Lista **todos** os clientes/domínios VM112 na coluna esquerda
|
||
- [x] Seleccionar cliente mostra tiles de catálogo (≥1 activo para e-mail)
|
||
- [x] Tile E-mail Tenant abre modal com detalhe + purge funcional
|
||
- [x] Purge remove domínio e actualiza lista (Spec 017)
|
||
- [x] Tiles futuros visíveis como «Em breve»
|
||
- [x] Escopo OPS visível na coluna direita
|
||
- [x] Escopo OPS **cards clicáveis** com camada + Spec + navegação (2026-06-25)
|
||
- [x] Blocklist visível na UI (lista + banner Escopo + modal)
|
||
- [x] Modal purge com **loading animado** durante consulta VM112
|
||
- [x] Tiles com badge **camada** (tenant / app / infra)
|
||
- [x] RBAC inalterado
|
||
|
||
---
|
||
|
||
## Critérios de aceite — Fase 2 (catálogo comercial)
|
||
|
||
- [ ] `GET /api/v1/services/catalog` devolve todos os produtos MOSP com `delivery_model`
|
||
- [ ] Tiles agrupados por categoria (Infra, Segurança, Apps, DevOps, Suporte)
|
||
- [ ] Badge IaaS / PaaS / SaaS / Suporte em cada tile
|
||
- [ ] Coluna OPS mostra matriz «cliente vs Ligbox» para serviço seleccionado
|
||
- [ ] Cliente com `hosting_mode` visível no banner
|
||
- [ ] Instâncias `traditional` ligadas a tickets (sem wizard)
|
||
|
||
---
|
||
|
||
## Critérios de aceite — Fase 3 (multi-wizard)
|
||
|
||
- [ ] Cada `catalog.code` com `wizard_id` abre wizard correcto
|
||
- [ ] Provisionar firewall → pfSense + regras + binding `vm_id`
|
||
- [ ] Provisionar Wazuh → agente + binding + link Infra 2 SOC
|
||
- [ ] Purge por `service_instance` com escopo do catálogo (não hardcoded domínio)
|
||
|
||
---
|
||
|
||
## Critérios de aceite — Fase 4 (MSP comercial)
|
||
|
||
- [ ] Plano comercial por instância (`commercial_plan`, valor ref.)
|
||
- [ ] SLA tier no cliente e alertas quando degradado
|
||
- [ ] Relatório «o que a Ligbox gere» exportável para proposta comercial (PDF/markdown)
|
||
- [ ] Upsell: tiles «Não contratado» com CTA interno para técnico sénior
|
||
|
||
---
|
||
|
||
## Evolução multi-wizard (Fase 3)
|
||
|
||
1. `service_catalog.wizard_id` aponta para endpoint VM112 ou outro nó
|
||
2. Tile activo com acção «Abrir wizard» / «Retomar onboarding»
|
||
3. Wazuh: binding `agent_id` + link para Infra 2 SOC
|
||
4. Firewall: binding `vm_id` + link pfSense API
|
||
5. Produtos MOSP (Nextcloud, ERPNext): wizard dedicado ou Helm + PaaS base
|
||
6. Produtos **traditional**: sem wizard — cria ticket + sessão assist (Spec 010)
|
||
|
||
### Prioridade sugerida de wizards (Roger)
|
||
|
||
| Ordem | Produto | Nível | Justificativa |
|
||
|-------|---------|-------|---------------|
|
||
| 1 | E-mail Tenant | SaaS | **Em produção** — VM112 |
|
||
| 2 | Firewall pfSense | IaaS | Já existe stack Proxmox + API |
|
||
| 3 | Wazuh por domínio | SaaS | Infra 2 SOC parcial |
|
||
| 4 | VPS gerenciado | IaaS | Base para outros produtos |
|
||
| 5 | Nextcloud | SaaS | Alto valor MOSP |
|
||
| 6 | ERPNext | SaaS | Upsell empresarial |
|
||
| 7 | K8s / CI/CD | PaaS | Clientes dev |
|
||
|
||
---
|
||
|
||
## Valor para o Técnico de Suporte Sénior
|
||
|
||
| Necessidade OPS | Como a página Serviços responde |
|
||
|-----------------|----------------------------------|
|
||
| «O que este cliente comprou?» | Tiles por `delivery_model` + estado |
|
||
| «O que nós gerimos vs cliente?» | Matriz pizza / `managed_layers` |
|
||
| «Onde está provisionado?» | Bindings (domínio, VM, zona, agente) |
|
||
| «Posso apagar para teste?» | Purge Spec 017 (e-mail) → generalizado Fase 3 |
|
||
| «Qual wizard retomar?» | `wizard_id` + estado `provisioning` |
|
||
| «Isto é incidente ou gap comercial?» | Tile «Não contratado» vs `degraded` |
|
||
|
||
---
|
||
|
||
## Referências
|
||
|
||
- Spec 017 — purge domínio VM112
|
||
- Spec 015 — registry módulos `overview-home`
|
||
- Spec 010 — assist takeover (suporte tradicional)
|
||
- VM112 API — `/api/admin/domains`
|
||
- Analogia comercial — **Pizza as a Service** (On-Prem → IaaS → PaaS → SaaS)
|
||
- Posicionamento MSP — **Managed Open Source Services (MOSP)**
|