# 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 P0–P2) - Filtro server-side por fila (endpoint único enriquecido) - Abas adicionais: Billing, Carbonio dedicado - Notificação ntfy ao cruzar stale + live simultâneo