12f688ff7c
Expansão do dashboard de 3 para 8 páginas com dados reais do stack: - MCPs: monitorização de 33 MCPs no gateway com ping e estado online/offline - n8n: 14 workflows com último run, duração e falhas 24h - Paperclip: 16 agentes operacionais, routines e issues (PostgreSQL) - IA/Claude: visão das 3 camadas (189 skills, 72 agents, 39 MCPs, CARL) - Operações: tickets Desk CRM por departamento + cobertura PROCs 16 ficheiros novos (3042 linhas), 3 existentes editados. Nova dependência: pg (PostgreSQL client para Paperclip). Audit: 0 vulnerabilidades (npm audit fix aplicado). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
397 lines
14 KiB
Markdown
397 lines
14 KiB
Markdown
---
|
|
title: PLAN Conductor — Expansão DashDescomplicar
|
|
date: 2026-04-06
|
|
type: plan
|
|
status: active
|
|
spec: SPEC-dashboard-expansion-q2-2026.md
|
|
tags: [conductor, plan, dashboard, parallel]
|
|
---
|
|
|
|
# Plano Conductor — Expansão DashDescomplicar
|
|
|
|
**Spec:** `docs/SPEC-dashboard-expansion-q2-2026.md`
|
|
**Projecto:** `/media/ealmeida/Dados/Dev/DashDescomplicar/`
|
|
**Método:** Conductor parallel sprints — agentes independentes por domínio
|
|
|
|
---
|
|
|
|
## Estratégia de paralelização
|
|
|
|
Cada painel (backend + frontend) é **independente** — ficheiros distintos, sem dependências cruzadas. A integração (Layout, App, server.ts) é feita no final por um único agente coordenador.
|
|
|
|
```
|
|
┌─────────────┐
|
|
│ Coordenador │
|
|
│ (Sprint 4) │
|
|
└──────┬──────┘
|
|
┌──────────────┼──────────────┐
|
|
Sprint 1 │ Sprint 3
|
|
┌────┴────┐ Sprint 2 ┌────┴────┐
|
|
│ │ │ │ │
|
|
Agent A Agent B Agent C Agent D Agent E
|
|
MCPs n8n Paperclip IA Operações
|
|
```
|
|
|
|
**Agentes A-E correm em paralelo.** Agente F (coordenador) corre depois, integrando tudo.
|
|
|
|
---
|
|
|
|
## Pré-requisitos (executar antes do conductor)
|
|
|
|
1. Instalar `pg` (PostgreSQL client):
|
|
```bash
|
|
cd /media/ealmeida/Dados/Dev/DashDescomplicar && npm install pg @types/pg
|
|
```
|
|
|
|
2. Verificar env vars disponíveis no EasyPanel (MCP_GATEWAY_TOKEN, N8N_API_KEY, PAPERCLIP_DB_*)
|
|
|
|
---
|
|
|
|
## Agent A — Painel MCPs
|
|
|
|
**Tipo:** `javascript-fullstack-specialist`
|
|
**Isolation:** worktree
|
|
**Ficheiros a criar:**
|
|
- `api/services/mcps.ts`
|
|
- `api/routes/mcps.ts`
|
|
- `src/pages/McpMonitor.tsx`
|
|
|
|
**Prompt:**
|
|
|
|
```
|
|
Estás a trabalhar no projecto DashDescomplicar (/media/ealmeida/Dados/Dev/DashDescomplicar/).
|
|
Stack: React 19 + Vite + Tailwind CSS 4 + Express 4 + TypeScript.
|
|
|
|
Lê a spec completa em docs/SPEC-dashboard-expansion-q2-2026.md, secção 4.1 (Painel MCPs).
|
|
|
|
Cria 3 ficheiros:
|
|
|
|
1. api/services/mcps.ts — Service que:
|
|
- Tem lista hardcoded de 35 MCPs (nome, porta, categoria, enabled)
|
|
- Faz ping paralelo (Promise.allSettled, timeout 5s) aos MCPs enabled via HTTP GET
|
|
- Gateway URL: process.env.MCP_GATEWAY_URL || 'https://gateway.descomplicar.pt'
|
|
- Bearer token: process.env.MCP_GATEWAY_TOKEN
|
|
- Cache de 60 segundos (variável em memória com timestamp)
|
|
- Retorna McpDashboard conforme spec
|
|
|
|
2. api/routes/mcps.ts — Router Express com GET /
|
|
- Chama o service e retorna JSON
|
|
- try/catch com 500 error handling (padrão dos outros routers no projecto)
|
|
|
|
3. src/pages/McpMonitor.tsx — Página React que:
|
|
- Faz fetch a /api/mcps com useEffect
|
|
- Mostra header com stats (total/online/offline/disabled)
|
|
- Grid de cards agrupados por categoria (crm, infra, ai, tools, external)
|
|
- Card com: nome, porta, status (cor), response_time
|
|
- Botão refresh manual
|
|
- Loading state e error state
|
|
- Segue estilo visual do projecto: ler src/pages/Monitor.tsx como referência (dark theme, motion.div, lucide icons, containerVariants/itemVariants)
|
|
|
|
Lista dos MCPs para hardcoding:
|
|
- CRM: desk-crm-v3 (3150), desk-project-minimal (3153)
|
|
- Infra: ssh-unified (3192), filesystem (local), chrome-devtools (local)
|
|
- AI: lightrag (3160), notebooklm (3190), context7 (3169), replicate (3176), memory-supabase (3151)
|
|
- Tools: mcp-time (3155), deepl (3188), pexels (3175), vimeo (3177), drawio (3184)
|
|
- External: google-workspace (3156), google-analytics (3164), gsc (3165), youtube (3166), youtube-research (3167), moloni (3158), n8n (3171), gitea (3162), stitch (external), design-systems (external)
|
|
- Gateway: authentik (3191), spaceship (3189), puppeteer (3193), lighthouse (3194)
|
|
- Locais (disabled ping): filesystem, chrome-devtools
|
|
- MCPs em .mcp.json: carl-mcp (local, porta variável), reonic (3187)
|
|
|
|
Não alteres nenhum ficheiro existente. Apenas cria os 3 novos.
|
|
```
|
|
|
|
---
|
|
|
|
## Agent B — Painel n8n
|
|
|
|
**Tipo:** `javascript-fullstack-specialist`
|
|
**Isolation:** worktree
|
|
**Ficheiros a criar:**
|
|
- `api/services/n8n.ts`
|
|
- `api/routes/n8n.ts`
|
|
- `src/pages/N8nMonitor.tsx`
|
|
|
|
**Prompt:**
|
|
|
|
```
|
|
Estás a trabalhar no projecto DashDescomplicar (/media/ealmeida/Dados/Dev/DashDescomplicar/).
|
|
Stack: React 19 + Vite + Tailwind CSS 4 + Express 4 + TypeScript.
|
|
|
|
Lê a spec completa em docs/SPEC-dashboard-expansion-q2-2026.md, secção 4.2 (Painel n8n).
|
|
|
|
Cria 3 ficheiros:
|
|
|
|
1. api/services/n8n.ts — Service que:
|
|
- Chama API REST n8n: GET /workflows e GET /executions?limit=50
|
|
- URL base: process.env.N8N_API_URL || 'https://automator.descomplicar.pt/api/v1'
|
|
- Auth: header X-N8N-API-KEY com process.env.N8N_API_KEY
|
|
- Cache de 300 segundos
|
|
- Retorna N8nDashboard conforme spec (total, active, failed_24h, workflows com last_execution)
|
|
|
|
2. api/routes/n8n.ts — Router Express com GET /
|
|
- try/catch com 500 error handling
|
|
|
|
3. src/pages/N8nMonitor.tsx — Página React que:
|
|
- Faz fetch a /api/n8n
|
|
- Stats cards: total workflows, activos, falhas 24h (destaque vermelho se >0)
|
|
- Tabela com: nome, activo (badge), último run (data + status com cor), duração
|
|
- Filtro toggle: activos/todos
|
|
- Segue estilo visual: ler src/pages/Financial.tsx como referência
|
|
|
|
Não alteres nenhum ficheiro existente. Apenas cria os 3 novos.
|
|
```
|
|
|
|
---
|
|
|
|
## Agent C — Painel Paperclip
|
|
|
|
**Tipo:** `javascript-fullstack-specialist`
|
|
**Isolation:** worktree
|
|
**Ficheiros a criar:**
|
|
- `api/services/paperclip-db.ts`
|
|
- `api/services/paperclip.ts`
|
|
- `api/routes/paperclip.ts`
|
|
- `src/pages/Paperclip.tsx`
|
|
|
|
**Prompt:**
|
|
|
|
```
|
|
Estás a trabalhar no projecto DashDescomplicar (/media/ealmeida/Dados/Dev/DashDescomplicar/).
|
|
Stack: React 19 + Vite + Tailwind CSS 4 + Express 4 + TypeScript.
|
|
|
|
Lê a spec completa em docs/SPEC-dashboard-expansion-q2-2026.md, secção 4.3 (Painel Paperclip).
|
|
|
|
O pacote `pg` já foi instalado (npm install pg @types/pg).
|
|
|
|
Cria 4 ficheiros:
|
|
|
|
1. api/services/paperclip-db.ts — Pool PostgreSQL:
|
|
- Host: process.env.PAPERCLIP_DB_HOST || 'clip.descomplicar.pt'
|
|
- Port: process.env.PAPERCLIP_DB_PORT || 54329
|
|
- Database: process.env.PAPERCLIP_DB_NAME || 'paperclip'
|
|
- User/Pass: process.env.PAPERCLIP_DB_USER, process.env.PAPERCLIP_DB_PASS
|
|
- Pool com max 5 conexões
|
|
- Validação de credenciais obrigatória (throw se não definidas)
|
|
- Export default pool
|
|
|
|
2. api/services/paperclip.ts — Queries:
|
|
- getAgents(): SELECT id, name, role, status, last_heartbeat, total_runs FROM agents WHERE status != 'archived'
|
|
- getRoutines(): SELECT id, name, cron, active, last_run, last_status FROM routines
|
|
- getIssueStats(): COUNT por estado (open, in_progress, closed últimos 7 dias)
|
|
- Retorna PaperclipDashboard conforme spec
|
|
- NOTA: os nomes exactos das tabelas e colunas podem variar — usar nomes razoáveis e documentar com comentário que podem precisar de ajuste
|
|
|
|
3. api/routes/paperclip.ts — Router Express com GET /
|
|
- try/catch, se BD inacessível retornar dados fallback (zeros)
|
|
|
|
4. src/pages/Paperclip.tsx — Página React:
|
|
- Stats cards: agentes activos/idle/error, routines activas
|
|
- Grid de cards para agentes, agrupados por role (C-Level, Director, Specialist)
|
|
- Cor do card por status: active=verde, idle=amarelo, error=vermelho
|
|
- Tabela de routines: nome, cron, activa, último run, status
|
|
- Segue estilo visual do projecto
|
|
|
|
Não alteres nenhum ficheiro existente. Apenas cria os 4 novos.
|
|
```
|
|
|
|
---
|
|
|
|
## Agent D — Painel IA / Claude Code
|
|
|
|
**Tipo:** `javascript-fullstack-specialist`
|
|
**Isolation:** worktree
|
|
**Ficheiros a criar:**
|
|
- `api/services/ai.ts`
|
|
- `api/routes/ai.ts`
|
|
- `src/pages/AiOverview.tsx`
|
|
|
|
**Prompt:**
|
|
|
|
```
|
|
Estás a trabalhar no projecto DashDescomplicar (/media/ealmeida/Dados/Dev/DashDescomplicar/).
|
|
Stack: React 19 + Vite + Tailwind CSS 4 + Express 4 + TypeScript.
|
|
|
|
Lê a spec completa em docs/SPEC-dashboard-expansion-q2-2026.md, secção 4.4 (Painel Claude Code / IA).
|
|
|
|
Cria 3 ficheiros:
|
|
|
|
1. api/services/ai.ts — Service que:
|
|
- Retorna dados maioritariamente estáticos (actualizados manualmente)
|
|
- Dados reais do stack (fonte: STK-Estado-Actual.md de 04-04-2026):
|
|
- Skills: 189 total (31 directas + 158 plugins)
|
|
- Agents CC: 72 (18 directos + 54 plugins)
|
|
- MCPs: 39 (10 enabled, 29 disabled, 33 gateway, 2 locais)
|
|
- Hooks: 26 ficheiros, 9 activos
|
|
- Plugins: 14 Descomplicar + 6 oficiais + 3 terceiros, 6 activos
|
|
- CARL: 7 domínios, ~45 regras
|
|
- Paperclip: 16 operacionais
|
|
- n8n: 14 workflows
|
|
- NotebookLM: 58 notebooks
|
|
- Cache infinito (dados estáticos)
|
|
|
|
2. api/routes/ai.ts — Router Express com GET /
|
|
|
|
3. src/pages/AiOverview.tsx — Página React:
|
|
- Layout de "stack overview" com 3 secções:
|
|
a) Camada 1 (Claude Code): cards para skills, agents, MCPs, hooks, plugins
|
|
b) Camada 2 (n8n): card simples com contagem workflows
|
|
c) Camada 3 (Paperclip): card simples com contagem agentes
|
|
- Card grande central: "3 Camadas de Execução" com diagrama visual (CSS, não SVG)
|
|
- Secção CARL: 7 domínios listados (GLOBAL, CRM, DEVELOPMENT, WORDPRESS, HUB, INFRASTRUCTURE, QUALITY, SKILLS)
|
|
- Tons roxos/violeta para diferenciar das outras páginas
|
|
- Segue estilo visual do projecto
|
|
|
|
Não alteres nenhum ficheiro existente. Apenas cria os 3 novos.
|
|
```
|
|
|
|
---
|
|
|
|
## Agent E — Painel Operações
|
|
|
|
**Tipo:** `javascript-fullstack-specialist`
|
|
**Isolation:** worktree
|
|
**Ficheiros a criar:**
|
|
- `api/services/operations.ts`
|
|
- `api/routes/operations.ts`
|
|
- `src/pages/Operations.tsx`
|
|
|
|
**Prompt:**
|
|
|
|
```
|
|
Estás a trabalhar no projecto DashDescomplicar (/media/ealmeida/Dados/Dev/DashDescomplicar/).
|
|
Stack: React 19 + Vite + Tailwind CSS 4 + Express 4 + TypeScript.
|
|
|
|
Lê a spec em docs/SPEC-dashboard-expansion-q2-2026.md, secção 4.5 (Painel Operações).
|
|
|
|
A BD MySQL (Desk CRM) já tem conexão configurada em api/db.ts (export default pool mysql2/promise).
|
|
|
|
Cria 3 ficheiros:
|
|
|
|
1. api/services/operations.ts — Service que:
|
|
- Queries ao MySQL (Desk CRM):
|
|
a) Tickets abertos: SELECT COUNT(*) FROM tbltickets WHERE status IN ('Open','In Progress','Answered')
|
|
b) Tickets alta prioridade: WHERE priority IN (2,3)
|
|
c) Tickets por departamento: JOIN tbldepartments GROUP BY department
|
|
d) Tempo médio resposta: AVG(TIMESTAMPDIFF(HOUR, date, lastreply)) dos tickets com resposta
|
|
- Dados estáticos PROCs:
|
|
- 48 procedimentos, 8 departamentos
|
|
- Cobertura por dept: D1(5), D2(3), D3(3), D4(1), D5(5), D6(8), D7(18), Cross(5)
|
|
- import db from '../db.js'
|
|
|
|
2. api/routes/operations.ts — Router Express com GET /
|
|
|
|
3. src/pages/Operations.tsx — Página React:
|
|
- Stats cards: tickets abertos, alta prioridade, tempo médio resposta
|
|
- Gráfico barras horizontal (recharts BarChart): tickets por departamento
|
|
- Tabela cobertura PROCs: departamento, número PROCs, % cobertura
|
|
- Segue estilo visual: ler src/pages/Financial.tsx como referência (usa recharts)
|
|
|
|
Não alteres nenhum ficheiro existente. Apenas cria os 3 novos.
|
|
```
|
|
|
|
---
|
|
|
|
## Agent F — Coordenador / Integração (executa após A-E)
|
|
|
|
**Tipo:** `javascript-fullstack-specialist`
|
|
**Isolation:** nenhum (merge directo)
|
|
**Ficheiros a alterar:**
|
|
- `src/components/Layout.tsx`
|
|
- `src/App.tsx` (secção de routing)
|
|
- `api/server.ts` (registar routers)
|
|
|
|
**Prompt:**
|
|
|
|
```
|
|
Estás a trabalhar no projecto DashDescomplicar (/media/ealmeida/Dados/Dev/DashDescomplicar/).
|
|
|
|
Os seguintes ficheiros novos já foram criados por agentes anteriores:
|
|
- api/routes/mcps.ts, api/services/mcps.ts, src/pages/McpMonitor.tsx
|
|
- api/routes/n8n.ts, api/services/n8n.ts, src/pages/N8nMonitor.tsx
|
|
- api/routes/paperclip.ts, api/services/paperclip.ts, api/services/paperclip-db.ts, src/pages/Paperclip.tsx
|
|
- api/routes/ai.ts, api/services/ai.ts, src/pages/AiOverview.tsx
|
|
- api/routes/operations.ts, api/services/operations.ts, src/pages/Operations.tsx
|
|
|
|
Faz a integração:
|
|
|
|
1. src/components/Layout.tsx — Adicionar 5 itens ao array NAV_ITEMS:
|
|
- { to: '/mcps', label: 'MCPs', icon: Network }
|
|
- { to: '/n8n', label: 'Automações', icon: Workflow }
|
|
- { to: '/paperclip', label: 'Paperclip', icon: Bot }
|
|
- { to: '/ai', label: 'IA / Claude', icon: Brain }
|
|
- { to: '/operations', label: 'Operações', icon: ClipboardList }
|
|
Adicionar os imports de ícones do lucide-react: Network, Workflow, Bot, Brain, ClipboardList
|
|
NOTA: verificar se 'Workflow' existe em lucide-react, se não usar 'GitBranch' ou 'Repeat'
|
|
|
|
2. src/App.tsx — Na secção de routing (BrowserRouter/Routes), adicionar:
|
|
- import McpMonitor from './pages/McpMonitor'
|
|
- import N8nMonitor from './pages/N8nMonitor'
|
|
- import Paperclip from './pages/Paperclip'
|
|
- import AiOverview from './pages/AiOverview'
|
|
- import Operations from './pages/Operations'
|
|
E as respectivas <Route> dentro do <Route element={<Layout />}>
|
|
|
|
3. api/server.ts — Adicionar imports e app.use:
|
|
- import mcpsRouter from './routes/mcps.js'
|
|
- import n8nRouter from './routes/n8n.js'
|
|
- import paperclipRouter from './routes/paperclip.js'
|
|
- import aiRouter from './routes/ai.js'
|
|
- import operationsRouter from './routes/operations.js'
|
|
- app.use('/api/mcps', mcpsRouter)
|
|
- app.use('/api/n8n', n8nRouter)
|
|
- app.use('/api/paperclip', paperclipRouter)
|
|
- app.use('/api/ai', aiRouter)
|
|
- app.use('/api/operations', operationsRouter)
|
|
|
|
Lê cada ficheiro antes de editar. Mantém o estilo existente. Não alteres mais nada.
|
|
```
|
|
|
|
---
|
|
|
|
## Sequência de execução
|
|
|
|
```
|
|
Fase 1 (paralelo): Agent A + Agent B + Agent C + Agent D + Agent E
|
|
↓ todos concluídos
|
|
Fase 2 (sequencial): Merge worktrees → main
|
|
↓
|
|
Fase 3 (sequencial): Agent F (integração)
|
|
↓
|
|
Fase 4 (validação): npm run build + teste manual
|
|
```
|
|
|
|
---
|
|
|
|
## Comando conductor
|
|
|
|
```bash
|
|
# Fase 1 — lançar 5 agentes em paralelo (worktree isolation)
|
|
# Usar: Agent tool com isolation: "worktree" e run_in_background: true
|
|
|
|
# Fase 2 — após todos concluírem, merge dos worktrees
|
|
# git merge <branch-agent-a> --no-edit
|
|
# git merge <branch-agent-b> --no-edit
|
|
# ...
|
|
|
|
# Fase 3 — Agent F integração
|
|
# Sem worktree, directo no main
|
|
|
|
# Fase 4 — validar
|
|
# npm run build
|
|
# npm run dev (testar manualmente)
|
|
```
|
|
|
|
---
|
|
|
|
## Checklist de validação final
|
|
|
|
- [ ] `npm run build` sem erros
|
|
- [ ] Todas as 8 páginas navegáveis na sidebar
|
|
- [ ] GET /api/mcps retorna dados
|
|
- [ ] GET /api/n8n retorna dados (ou erro claro se API key não configurada)
|
|
- [ ] GET /api/paperclip retorna dados (ou fallback zeros se BD inacessível)
|
|
- [ ] GET /api/ai retorna dados estáticos
|
|
- [ ] GET /api/operations retorna dados do Desk CRM
|
|
- [ ] Mobile: sidebar colapsa correctamente com 8 itens
|
|
- [ ] Zero erros na consola do browser
|