# Documentación API - Servicio SQL Injector **Base URL**: `http://localhost:3120/v1` Este servicio permite la ejecución remota de consultas SQL en tiendas distribuidas mediante un mecanismo de polling, almacenamiento de resultados y consulta de historial. --- ## 1. Consultar Comandos Pendientes (Polling) Este endpoint es consumido por el cliente (tienda) para saber si tiene algún comando SQL pendiente de ejecutar. - **Método**: `GET` - **Ruta**: `/commands` - **Parámetros (Query)**: - `store_id`: ID de la tienda (Requerido). - `id_cliente`: ID del cliente (Opcional). **Ejemplo de Solicitud**: ```http GET /v1/commands?store_id=44&id_cliente=1 ``` **Respuestas**: - **200 OK**: Se encontró un comando pendiente. ```json { "command_id": 123, "sql": "SELECT * FROM users LIMIT 1", "privilegio": "READ" } ``` - **204 No Content**: No hay comandos pendientes. - **500 Internal Server Error**: Error del servidor. --- ## 2. Crear Nuevo Comando Permite a un administrador o sistema central poner en cola una instrucción SQL para ser ejecutada por una tienda específica. - **Método**: `POST` - **Ruta**: `/commands` - **Cuerpo (JSON)**: - `store_id` (Number): ID de la tienda objetivo (Requerido). - `sql` (String): Sentencia SQL a ejecutar (Requerido). - `privilegio` (String): Nivel de permiso, por defecto "READ". Opcional. - `id_user` (Number): ID del usuario que solicita el comando. Opcional. - `id_cliente` (Number): ID del cliente. Opcional. **Ejemplo de Solicitud**: ```json { "store_id": 44, "sql": "SELECT count(*) FROM ventas", "privilegio": "READ", "id_user": 1, "id_cliente": 1 } ``` **Respuesta Exitosa (201 Created)**: ```json { "success": true, "message": "Comando creado exitosamente", "command_id": 124 } ``` --- ## 3. Guardar Resultado de Comando Este endpoint es utilizado por el cliente (tienda) para reportar el resultado de la ejecución del SQL. - **Método**: `POST` - **Ruta**: `/commands/result` - **Cuerpo (JSON)**: - `command_id` (Number): ID del comando ejecutado (Requerido). - `result` (Object/Array): El resultado de la consulta SQL. *Nota: Si se envía el cuerpo sin la propiedad `result`, el sistema intentará tomar todo el cuerpo como el resultado.* **Ejemplo de Solicitud**: ```json { "command_id": 124, "result": [ { "count": 150 } ] } ``` **Respuesta Exitosa (200 OK)**: ```json { "success": true, "message": "Resultado guardado correctamente" } ``` --- ## 4. Consultar Estado/Resultado de Comando Permite consultar si un comando específico ya fue ejecutado y obtener su resultado. - **Método**: `GET` - **Ruta**: `/commands/:command_id` - **Parámetros (Path)**: - `command_id`: ID del comando a consultar. **Ejemplo de Solicitud**: ```http GET /v1/commands/124 ``` **Respuestas**: - **200 OK**: Comando completado. ```json { "command_id": 124, "status": "completed", "result": [ { "count": 150 } ], "processed_at": "2026-01-13T19:00:00.000Z" } ``` - **404 Not Found**: El comando no existe o aún no ha sido procesado (estado pendiente). --- ## 5. Historial de Comandos por Usuario Devuelve una lista de los últimos comandos solicitados por un usuario específico. - **Método**: `GET` - **Ruta**: `/commands/user/:id_user` - **Parámetros (Path)**: - `id_user`: ID del usuario. - **Parámetros (Query)**: - `limit`: Cantidad de registros a traer (Default: 50). **Ejemplo de Solicitud**: ```http GET /v1/commands/user/1?limit=5 ``` **Respuesta Exitosa (200 OK)**: ```json [ { "command_id": 124, "store_id": 44, "sql": "SELECT count(*) FROM ventas", "privilegio": "READ", "estado": "1", "fecha_solicitud": "2026-01-13T18:55:00.000Z", "fecha_proceso": "2026-01-13T19:00:00.000Z", "json_response": [ { "count": 150 } ] } ] ``` --- ## 6. Estado de Tiendas (Heartbeat) Devuelve el estado de conectividad de las tiendas basado en su último heartbeat. - **Método**: `GET` - **Ruta**: `/stores/status` - **Parámetros (Query)**: - `filter` (String): Filtrar por estado de conectividad. Valores: `online`, `offline`, `all` (Default: `all`). - `id_cliente` (Number): Filtrar por ID de cliente. Opcional. **Estados de Conectividad**: - **ONLINE**: Último ping hace menos de 2 minutos (120 segundos) - **DEGRADED**: Último ping entre 2 y 5 minutos (120-300 segundos) - **OFFLINE**: Último ping hace más de 5 minutos (>300 segundos) **Ejemplo de Solicitud**: ```http GET /v1/stores/status?filter=online GET /v1/stores/status?filter=all&id_cliente=1 ``` **Respuesta Exitosa (200 OK)**: ```json { "total": 2, "filter_applied": "online", "stores": [ { "store_id": 44, "id_cliente": 1, "instance_id": "sql_inyector", "connectivity": "ONLINE", "status": "alive", "last_ping": "2026-02-09T18:15:30.000Z", "seconds_since_ping": 45, "extra_info": { "message": "Consultando comandos", "timestamp": "2026-02-09T18:15:30.000Z" } }, { "store_id": 370, "id_cliente": 1, "instance_id": "sql_inyector", "connectivity": "OFFLINE", "status": "alive", "last_ping": "2026-02-09T17:50:00.000Z", "seconds_since_ping": 1530, "extra_info": null } ] } ``` **Notas Importantes**: - Si una tienda **nunca ha enviado un heartbeat**, NO aparecerá en la respuesta de este endpoint. - Solo se muestran tiendas que tienen al menos un registro en `tb_store_process_heartbeat` con `process_name = 'sql_inyector'`. - Para ver tiendas que nunca se han conectado, necesitarías tener una tabla maestra de tiendas y hacer un LEFT JOIN. --- ## Códigos de Estado HTTP - **200 OK**: Solicitud exitosa - **201 Created**: Recurso creado exitosamente - **204 No Content**: Solicitud exitosa sin contenido - **400 Bad Request**: Parámetros inválidos o faltantes - **404 Not Found**: Recurso no encontrado - **500 Internal Server Error**: Error del servidor