Files
DashDescomplicar/okf/entidades/Express-API.md
T

83 lines
3.8 KiB
Markdown

---
type: Entity
layer: wiki
tags: [stack, dashdescomplicar, backend, express, api, core]
title: "Express-API"
---
# Express-API
Servidor backend Express 4 que expõe a REST API do DashDescomplicar. Orquestra 15 rotas, middleware de segurança e serve o frontend estático em produção.
## Responsabilidades
- **Roteamento**: 15 rotas REST (`/api/dashboard`, `/api/monitor`, `/api/hetzner`, `/api/wp-monitor`, `/api/server-metrics`, `/api/financial`, `/api/mcps`, `/api/n8n`, `/api/paperclip`, `/api/operations`, `/api/ai`, `/api/beszel`, `/api/sessions`, `/api/diagnostic`, `/api/health`)
- **Segurança**: Rate limiting (100 req/15min produção, 1000/15min dev), CORS restrito, validação Zod em todas as rotas, OIDC opcional
- **Error Handling**: UUIDs para tracking de erros, sem stack traces em produção, logs estruturados
- **Static Serving**: Serve o bundle Vite (React SPA) em produção na porta 3001
- **Health Check**: Endpoint `/health` (público) e `/api/health` (autenticado)
## Stack
- **Runtime**: Node.js 22+ (Alpine no Docker)
- **Framework**: Express 4.19+ com TypeScript 5.9
- **Validação**: Zod 4.3 (`z.object()`, `.passthrough()`, `z.coerce`)
- **Rate Limit**: `express-rate-limit` 8.2
- **CORS**: `cors` 2.8
- **Auth**: `express-openid-connect` (opcional, via `OIDC_ENABLED`)
- **DB Drivers**: `mysql2` 3.11 (promise), `ssh2` 1.17, `better-sqlite3` 12.9
- **Observabilidade**: SQLite local (`~/.claude-work/sessions.db`) para sessões Claude Code
## Localizações
- **Código**: `Dev/DashDescomplicar/api/server.ts` (238 linhas)
- **Rotas**: `api/routes/` (14 ficheiros)
- **Serviços**: `api/services/` (16 ficheiros)
- **Middleware**: `api/middleware/validation.ts`
- **DB Pool**: `api/db.ts`
- **Deploy**: `dash.descomplicar.pt:3001` (EasyPanel Swarm)
- **Dev**: `http://localhost:3001` (tsx watch)
## Rotas Expostas
| Rota | Ficheiro | Fonte Dados |
|---|---|---|
| `GET /api/dashboard` | `routes/dashboard.ts` | Desk CRM MySQL (16 queries paralelas) |
| `GET /api/monitor` | `routes/monitor.ts` | `tbl_eal_monitoring` (MySQL) |
| `GET /api/diagnostic` | `routes/diagnostic.ts` | Testes de conectividade (17 checks) |
| `GET/POST /api/hetzner` | `routes/hetzner.ts` | Hetzner Cloud API + MySQL |
| `GET/POST /api/wp-monitor` | `routes/wp-monitor.ts` | Plugin WP → MySQL (API key auth) |
| `POST /api/server-metrics` | `routes/server-metrics.ts` | SSH2 (EasyPanel) + MySQL |
| `GET /api/financial` | `routes/financial.ts` | Desk CRM MySQL (7 queries) |
| `GET /api/mcps` | `routes/mcps.ts` | MCP Gateway (HTTP ping, cache 60s) |
| `GET /api/n8n` | `routes/n8n.ts` | n8n REST API (cache 300s) |
| `GET /api/paperclip` | `routes/paperclip.ts` | PostgreSQL Paperclip (com fallback) |
| `GET /api/operations` | `routes/operations.ts` | Desk CRM MySQL (4 queries) |
| `GET /api/ai` | `routes/ai.ts` | Dados estáticos (snapshot STK) |
| `GET /api/beszel` | `routes/beszel.ts` | Beszel PocketBase API + MySQL |
| `GET /api/sessions` | `routes/sessions.ts` | SQLite local (better-sqlite3) |
## Dependências
- **MySQL-Pool**: Conexão ao Desk CRM (`176.9.3.158`)
- **Variáveis de Ambiente**: `DB_*`, `HETZNER_TOKEN`, `WP_MONITOR_API_KEY`, `N8N_API_KEY`, `BESZEL_*`, `EASY_*`, `MCP_GATEWAY_*`, `OIDC_*`, `OBSERVABILIDADE_DB`
- **Docker-Deploy**: Empacotado via `Dockerfile` → EasyPanel Swarm
- **Observabilidade-Sessions**: Abre ligação SQLite para sessões Claude Code
## Consome de
- Desk CRM (MySQL — `176.9.3.158:3306`)
- Hetzner Cloud API (`api.hetzner.cloud/v1`)
- MCP Gateway (`gateway.descomplicar.pt`)
- n8n API (`automator.descomplicar.pt/api/v1`)
- Paperclip PostgreSQL (container Docker)
- Beszel PocketBase API
- EasyPanel Server (SSH2 porta 22)
- Sistema de ficheiros local (SQLite sessions.db)
## Fornece a
- Todos os 8 painéis frontend (via fetch à API)
- Dashboard-Engine (dados agregados para `App.tsx`)
- Sistema de diagnóstico (`/api/diagnostic`)