ligbox-ops-platform/specs/029-tickets-workspace/ARCHITECTURE.md
Ligbox Spec Hub 468e6bd573 Add Spec 029 Tickets Workspace — motor de tickets P0-P2
Rebuilt from Cursor transcript: tickets-workspace.js, tickets-detail-panel.js,
app.js delegation, CSS, desk-live-stub. VM122 deploy pending SSH.
2026-06-19 19:20:23 +00:00

165 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Tickets Workspace — Arquitectura (P0 → P2)
**Data:** 2026-06-19
**Solicitado por:** Roger
**VM:** 122 — `desk.ligbox.com.br`
---
## Visão geral
O ecrã **Tickets** foi modularizado em três camadas frontend, inspirado em Site24x7 / Form Manager (leve, scan rápido). O `app.js` mantém-se como orquestrador global; a lógica de fila e detalhe vive em módulos dedicados.
```
┌─────────────────────────────────────────────────────────────────┐
│ index.html │
│ auth.js → modules.js → live-presence.js │
│ tickets-workspace.js → tickets-detail-panel.js → app.js │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ app.js (orquestrador) │
│ renderTickets() ──delega──► TicketsWorkspace.renderPage() │
│ renderTicketDetail() ──delega──► TicketsDetailPanel.render()│
│ refresh({ poll }) ──poll──► TicketsWorkspace.softRefresh() │
└─────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌──────────────────────┐ ┌──────────────────────────────┐
│ tickets-workspace.js │ │ tickets-detail-panel.js │
│ P0: 8 KPIs + cards │ │ P1: abas + próxima acção │
│ P1: filas chips │ │ Resumo | Ao vivo | Funil │
│ P2: KPI click filter │ │ │
│ P2: softRefresh │ │ │
└──────────────────────┘ └──────────────────────────────┘
▼ APIs (paralelo em loadContext)
┌─────────────────────────────────────────────────────────────────┐
│ GET /v1/desk/tickets — lista base │
│ GET /v1/live/presence — sinal LIVE 🟢 (Spec 027) │
│ GET /v1/onboard/funnel — fase funil + stale │
│ GET /v1/desk/summary — onboard_stale_hours (SLA) │
│ GET /v1/desk/tickets/{id} — detalhe (painel) │
│ GET /v1/assist/sessions/{id} — assist + timeline │
│ GET /v1/live/sessions/{id}/trail — aba Ao vivo │
└─────────────────────────────────────────────────────────────────┘
```
---
## Módulos
### 1. `tickets-workspace.js` — Lista e fila
| Função | Responsabilidade |
|--------|------------------|
| `loadContext()` | Fetch paralelo presence + funnel + summary |
| `enrichTicket(t)` | Adiciona `_live`, `_stale`, `_stage`, ícones |
| `computeIndicators()` | 8 KPIs do topo |
| `ticketCardHtml(t)` | Card com 3 sinais (estado, live, fase/SLA) |
| `filterByQueue()` / `filterBySearch()` | Filas inteligentes + busca |
| `renderPage()` | Montagem completa (P0) |
| `softRefresh()` | Poll sem flash — actualiza KPIs e sinais live (P2) |
| `setQueueFilter()` | KPI ou chip clicável filtra lista (P2) |
**Estado interno:** `context`, `queueFilter`, `searchQuery`, `_pageReady`, `_listFingerprint`
### 2. `tickets-detail-panel.js` — Painel direito
| Função | Responsabilidade |
|--------|------------------|
| `computeNextAction()` | Banner contextual (Carbonio, live, stale, billing…) |
| `tabsHtml()` | Abas Resumo \| Ao vivo \| Funil |
| `resumoHtml()` | KV + assist + carbonio + fechar ticket |
| `livePaneHtml()` | Presença + trail telemetria |
| `funilPaneHtml()` | Relógio por fase + timeline eventos |
| `render()` | Carrega ticket + meta assist + render tabbed UI |
**Dependências:** `assistActionsHtml`, `phaseTimingCardHtml`, `DeskLive.renderNavigationTab`, `DeskLive.openTrail`
### 3. `app.js` — Delegação mínima
- `renderTickets({ poll })` — se `poll && _pageReady``softRefresh`, senão `renderPage`
- `renderTicketDetail()` — delega a `TicketsDetailPanel` se existir
- `refresh()` — tickets usa soft refresh no intervalo global
### 4. `live-presence.js` (existente)
- Fornece `DeskLive.enabled()`, presence map, trail, modal
- Reutilizado na aba **Ao vivo** sem duplicar lógica
---
## Entregas por prioridade
### P0 — Lista command center ✅
- 8 indicadores no topo
- Cards com 3 sinais (estado, live/offline, fase ou «parado Nh»)
- Ícones opcionais 💳 🔒 ⚠️ LEAD
- Busca client-side
- Módulo `tickets-workspace.js` separado
### P1 — Detalhe e filas ✅
- Abas **Resumo | Ao vivo | Funil**
- Banner **próxima acção** com CTA (assumir, escalar, resolver Carbonio)
- **Filas inteligentes** (chips): Live, Parados, Sem dono, Billing, Wazuh, Escalados
- Módulo `tickets-detail-panel.js` separado
### P2 — Interacção e tempo real ✅
- **KPIs clicáveis** — mesmo filtro que chips (toggle)
- **softRefresh** — poll ~30s actualiza live/stale sem re-render completo
- Fingerprint da lista evita flash quando estrutura não muda
---
## Fluxo de dados (enrichment)
```
Ticket API (raw)
├─ session_id ──► liveBySession[path, ip, last_seen]
│ └──► _live, _livePath
├─ session_id ──► funnelBySession[current_stage, stale, last_event_at]
│ └──► _stage, _stale, _idleHours
└─ payload fields ──► _billing, _wazuh, _carbonioHint, _unassigned
```
---
## Debug rápido
| Sintoma | Verificar |
|---------|-----------|
| LIVE sempre offline | `/v1/live/presence` + `session_id` no ticket |
| «parado Nh» errado | `/v1/onboard/funnel` + `onboard_stale_hours` em summary |
| Flash na lista | `softRefresh` vs `renderPage`; fingerprint |
| Aba Ao vivo vazia | Módulo `wizard-live` activo; trail em `/v1/live/sessions/{id}/trail` |
| Próxima acção não aparece | `computeNextAction` — prioridade Carbonio > live > stale |
---
## Ficheiros
```
frontend/
index.html # scripts + cache bust
assets/
app.js # delegação renderTickets / refresh
tickets-workspace.js # P0 + P1 filas + P2 poll
tickets-detail-panel.js # P1 abas + próxima acção
live-presence.js # telemetria Spec 027
styles.css # .tickets-* .ticket-detail-*
specs/027-wizard-live-analytics/
TICKETS-WORKSPACE-ARCHITECTURE.md # este documento
```
---
## Próximo (fora P0P2)
- Filtro server-side por fila (endpoint único enriquecido)
- Abas adicionais: Billing, Carbonio dedicado
- Notificação ntfy ao cruzar stale + live simultâneo