# ABE — API Server Specification ## Arquitectura general ``` React (puerto 5173) ↕ HTTP REST + WebSocket API Server Express (puerto 3001) ↕ imports directos ExplorationEngine (core) ``` El servidor vive en `src/server/` y es el único punto de entrada al motor desde el exterior. El frontend NUNCA importa código del core directamente. --- ## Tecnología del servidor - Framework: Express.js - WebSocket: socket.io (para streaming en tiempo real) - Archivos: `src/server/index.ts` y `src/server/routes/` --- ## REST Endpoints ### POST /api/sessions Lanza una nueva exploración. Request body: ```json { "url": "http://localhost:3000", "seed": 42, "maxStates": 50 } ``` Response: ```json { "sessionId": "sess_abc123", "status": "running", "startedAt": "2025-01-15T10:00:00.000Z" } ``` --- ### GET /api/sessions Lista todas las sesiones (activas e históricas). Response: ```json [ { "sessionId": "sess_abc123", "url": "http://localhost:3000", "status": "running", "startedAt": "2025-01-15T10:00:00.000Z", "anomaliesFound": 3, "statesVisited": 12 } ] ``` --- ### GET /api/sessions/:sessionId Detalle de una sesión específica. Response: ```json { "sessionId": "sess_abc123", "url": "http://localhost:3000", "status": "completed", "startedAt": "2025-01-15T10:00:00.000Z", "finishedAt": "2025-01-15T10:05:00.000Z", "statesVisited": 12, "anomaliesFound": 3, "seed": 42 } ``` --- ### DELETE /api/sessions/:sessionId Detiene una sesión activa. Response: ```json { "stopped": true } ``` --- ### GET /api/anomalies Lista todas las anomalías encontradas (todas las sesiones). Query params opcionales: `?sessionId=sess_abc123&severity=high` Response: ```json [ { "id": "anom_a1b2c3", "sessionId": "sess_abc123", "type": "http_error", "severity": "high", "description": "Form returns HTTP 500 on empty email", "timestamp": 1705312200000, "screenshotUrl": "/api/anomalies/anom_a1b2c3/screenshot" } ] ``` --- ### GET /api/anomalies/:anomalyId Detalle completo de una anomalía incluyendo pasos de reproducción. Response: el objeto IAnomaly completo serializado (definido en interfaces.md) --- ### GET /api/anomalies/:anomalyId/screenshot Devuelve la imagen PNG del screenshot de la anomalía. Response: imagen binaria con Content-Type: image/png --- ### POST /api/anomalies/:anomalyId/replay Lanza el replay de una anomalía específica. Response: ```json { "replayId": "replay_xyz", "status": "running" } ``` --- ## WebSocket Events (socket.io) El cliente se conecta a `ws://localhost:3001` y escucha estos eventos: ### Eventos que emite el SERVIDOR → cliente `session:started` ```json { "sessionId": "sess_abc123", "url": "http://localhost:3000" } ``` `state:discovered` ```json { "sessionId": "sess_abc123", "stateId": "s_xyz", "url": "/register", "title": "Register" } ``` `action:executed` ```json { "sessionId": "sess_abc123", "actionType": "click", "selector": "button#submit", "timestamp": 1705312197000 } ``` `anomaly:detected` ```json { "sessionId": "sess_abc123", "anomalyId": "anom_a1b2c3", "type": "http_error", "severity": "high", "description": "..." } ``` `session:completed` ```json { "sessionId": "sess_abc123", "statesVisited": 12, "anomaliesFound": 3 } ``` `session:error` ```json { "sessionId": "sess_abc123", "error": "Target URL unreachable" } ``` ### Eventos que emite el CLIENTE → servidor `session:stop` ```json { "sessionId": "sess_abc123" } ```