Files

3.4 KiB

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:

{
  "url": "http://localhost:3000",
  "seed": 42,
  "maxStates": 50
}

Response:

{
  "sessionId": "sess_abc123",
  "status": "running",
  "startedAt": "2025-01-15T10:00:00.000Z"
}

GET /api/sessions

Lista todas las sesiones (activas e históricas).

Response:

[
  {
    "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:

{
  "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:

{ "stopped": true }

GET /api/anomalies

Lista todas las anomalías encontradas (todas las sesiones).

Query params opcionales: ?sessionId=sess_abc123&severity=high

Response:

[
  {
    "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:

{
  "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

{ "sessionId": "sess_abc123", "url": "http://localhost:3000" }

state:discovered

{ "sessionId": "sess_abc123", "stateId": "s_xyz", "url": "/register", "title": "Register" }

action:executed

{ "sessionId": "sess_abc123", "actionType": "click", "selector": "button#submit", "timestamp": 1705312197000 }

anomaly:detected

{ "sessionId": "sess_abc123", "anomalyId": "anom_a1b2c3", "type": "http_error", "severity": "high", "description": "..." }

session:completed

{ "sessionId": "sess_abc123", "statesVisited": 12, "anomaliesFound": 3 }

session:error

{ "sessionId": "sess_abc123", "error": "Target URL unreachable" }

Eventos que emite el CLIENTE → servidor

session:stop

{ "sessionId": "sess_abc123" }