Skip to content

API REST de SIVA

Documentación de referencia de la API del backend (backend/). Todos los endpoints se montan bajo el prefijo /api salvo la interfaz de Swagger. La fuente interactiva está en /api/docs (Swagger UI) y el contrato máquina-legible en /api/docs.json y openapi.yaml.

Convenciones generales

AspectoDetalle
Base URL (dev)http://localhost:3000/api
FormatoJSON (Content-Type: application/json); subidas con multipart/form-data
AutenticaciónAuthorization: Bearer <accessToken>
Envoltura de éxito{ "success": true, "data": ... }
Envoltura de error{ "success": false, "error": { "code", "message", "details?" } }
Paginación?page=1&limit=50; respuesta con total, page, limit, totalPages
Rate limit global200 req / 15 min por IP (RATE_LIMIT_MAX/RATE_LIMIT_WINDOW_MS)
Rate limit sensible10 req / 15 min en login, refresh, forgot/reset password y verify-email
Cabecera de trazaX-Request-Id (generada por requestId)

Roles

requireRole(ADMIN) autoriza a ADMIN y SUPERADMIN; requireRole(ADMIN, SUPERVISOR) autoriza a ADMIN, SUPERVISOR y SUPERADMIN. SUPERADMIN siempre pasa (backend/src/middlewares/role.middleware.ts). Los roles válidos son SUPERADMIN, ADMIN, SUPERVISOR.

Tras la revisión de permisos, las rutas operativas (catálogos, convocatorias, ejercicios, ubicaciones, vigilantes, asignaciones, notificación, asistencia y configuración) admiten ADMIN y SUPERVISOR. Solo Usuarios y Plantillas permanecen restringidos a ADMIN. Dentro de Configuración, un SUPERVISOR recibe 403 al intentar modificar las claves reservadas a ADMIN (colores_miembros_tribunal, colores_roles_usuarios, envio_correos_vigilantes, etiqueta_colores_predefinidos, export_field_labels, penalizacion_duracion_dias, penalizacion_habilitada, modo_asignacion_aulas_default).

Códigos de error comunes

HTTPcodeCausa
400VALIDATION_ERRORBody/query inválido (Zod). Incluye details[] por campo.
400BAD_REQUESTPetición semánticamente incorrecta.
401UNAUTHORIZEDSin token, token inválido/caducado, credenciales incorrectas, usuario inactivo o email no verificado.
403FORBIDDENAutenticado pero sin permisos, o acceso a 1:1 ajeno.
404NOT_FOUNDRecurso inexistente.
409CONFLICTConflicto de unicidad o regla de negocio.
429RATE_LIMIT_EXCEEDEDSe superó el límite de peticiones.
500INTERNAL_SERVER_ERRORError no controlado.

Paginación

La mayoría de listados devuelven:

json
{
  "success": true,
  "data": {
    "data": [],
    "total": 123,
    "page": 1,
    "limit": 50,
    "totalPages": 3
  }
}

⚠️ Excepción: GET /api/users devuelve { items, meta: { total, page, limit, totalPages } }.

Flujo de autenticación

Tabla resumen de endpoints

Autenticación — /api/auth

MétodoRutaDescripciónAuth / Rol
POST/api/auth/loginIniciar sesiónNo
POST/api/auth/logoutCerrar sesiónSí (cualquiera)
POST/api/auth/refresh-tokenRenovar access tokenNo
POST/api/auth/change-passwordCambiar contraseña propiaSí (cualquiera)
POST/api/auth/forgot-passwordSolicitar restablecimientoNo
POST/api/auth/reset-passwordRestablecer con tokenNo
POST/api/auth/verify-emailVerificar correoNo
GET/api/auth/meUsuario autenticadoSí (cualquiera)

Usuarios — /api/users

MétodoRutaDescripciónAuth / Rol
GET/api/users/mePerfil propioSí (cualquiera)
PUT/api/users/meActualizar perfil propioSí (cualquiera)
POST/api/users/me/avatarSubir avatarSí (cualquiera)
DELETE/api/users/me/avatarEliminar avatarSí (cualquiera)
GET/api/usersListar usuariosSí (ADMIN)
GET/api/users/:idObtener usuarioSí (ADMIN)
POST/api/usersCrear usuarioSí (ADMIN)
PUT/api/users/:idActualizar usuarioSí (ADMIN)
DELETE/api/users/:idEliminar usuarioSí (ADMIN)
PATCH/api/users/:id/statusActivar/desactivarSí (ADMIN)

Vigilantes — /api/vigilantes

MétodoRutaDescripciónAuth / Rol
GET/api/vigilantesListar vigilantesSí (ADMIN, SUPERVISOR)
GET/api/vigilantes/:idObtener vigilanteSí (ADMIN, SUPERVISOR)
GET/api/vigilantes/:id/historial-asistenciaHistorial de asistenciaSí (ADMIN, SUPERVISOR)
GET/api/vigilantes/:id/penalizacionesPenalizaciones del vigilanteSí (ADMIN, SUPERVISOR)
POST/api/vigilantesCrear vigilanteSí (ADMIN, SUPERVISOR)
PUT/api/vigilantes/:idActualizar vigilanteSí (ADMIN, SUPERVISOR)
DELETE/api/vigilantes/:idEliminar vigilanteSí (ADMIN, SUPERVISOR)
POST/api/vigilantes/import/previewPrevisualizar importaciónSí (ADMIN, SUPERVISOR)
POST/api/vigilantes/import/executeEjecutar importaciónSí (ADMIN, SUPERVISOR)
PUT/api/vigilantes/:id/toggle-bloqueadoBloquear/desbloquearSí (ADMIN, SUPERVISOR)

Etiquetas — /api/tags

MétodoRutaDescripciónAuth / Rol
GET/api/tagsListar etiquetasSí (ADMIN, SUPERVISOR)
POST/api/tagsCrear etiquetaSí (ADMIN, SUPERVISOR)
PUT/api/tags/:idActualizar etiquetaSí (ADMIN, SUPERVISOR)
DELETE/api/tags/:idEliminar etiquetaSí (ADMIN, SUPERVISOR)

Sedes — /api/sedes

MétodoRutaDescripciónAuth / Rol
GET/api/sedesListar sedesSí (ADMIN, SUPERVISOR)
GET/api/sedes/municipiosMunicipios distintosSí (ADMIN, SUPERVISOR)
GET/api/sedes/provinciasProvincias distintasSí (ADMIN, SUPERVISOR)
GET/api/sedes/:idObtener sedeSí (ADMIN, SUPERVISOR)
POST/api/sedesCrear sedeSí (ADMIN, SUPERVISOR)
PUT/api/sedes/:idActualizar sedeSí (ADMIN, SUPERVISOR)
DELETE/api/sedes/:idEliminar sedeSí (ADMIN, SUPERVISOR)
PUT/api/sedes/:id/toggle-activeActivar/desactivarSí (ADMIN, SUPERVISOR)

Edificios — /api/edificios

MétodoRutaDescripciónAuth / Rol
GET/api/edificiosListar edificiosSí (ADMIN, SUPERVISOR)
GET/api/edificios/:idObtener edificioSí (ADMIN, SUPERVISOR)
POST/api/edificiosCrear edificioSí (ADMIN, SUPERVISOR)
PUT/api/edificios/:idActualizar edificioSí (ADMIN, SUPERVISOR)
DELETE/api/edificios/:idEliminar edificioSí (ADMIN, SUPERVISOR)

Aulas — /api/aulas

MétodoRutaDescripciónAuth / Rol
GET/api/aulasListar aulasSí (ADMIN, SUPERVISOR)
GET/api/aulas/:idObtener aulaSí (ADMIN, SUPERVISOR)
POST/api/aulasCrear aulaSí (ADMIN, SUPERVISOR)
PUT/api/aulas/:idActualizar aulaSí (ADMIN, SUPERVISOR)
DELETE/api/aulas/:idEliminar aulaSí (ADMIN, SUPERVISOR)

Plantas — /api/plantas

MétodoRutaDescripciónAuth / Rol
GET/api/plantasListar plantasSí (ADMIN, SUPERVISOR)
POST/api/plantasCrear plantaSí (ADMIN, SUPERVISOR)
PUT/api/plantas/:idActualizar plantaSí (ADMIN, SUPERVISOR)
DELETE/api/plantas/:idEliminar plantaSí (ADMIN, SUPERVISOR)
GET/api/plantas/edificio/:edificioIdPlantas de un edificioSí (ADMIN, SUPERVISOR)
POST/api/plantas/edificio/:edificioId/assign/:plantaIdAsignar plantaSí (ADMIN, SUPERVISOR)
DELETE/api/plantas/edificio/:edificioId/assign/:plantaIdDesasignar plantaSí (ADMIN, SUPERVISOR)

Convocatorias — /api/convocatorias

MétodoRutaDescripciónAuth / Rol
GET/api/convocatoriasListar convocatoriasSí (ADMIN, SUPERVISOR)
GET/api/convocatorias/:idObtener convocatoriaSí (ADMIN, SUPERVISOR)
POST/api/convocatoriasCrear convocatoriaSí (ADMIN, SUPERVISOR)
PUT/api/convocatorias/:idActualizar convocatoriaSí (ADMIN, SUPERVISOR)
PUT/api/convocatorias/:id/estadoCambiar estadoSí (ADMIN, SUPERVISOR)
DELETE/api/convocatorias/:idEliminar convocatoriaSí (ADMIN, SUPERVISOR)

Tipos de ejercicio — /api/tipos-ejercicio

MétodoRutaDescripciónAuth / Rol
GET/api/tipos-ejercicioListar tiposSí (ADMIN, SUPERVISOR)
POST/api/tipos-ejercicioCrear tipoSí (ADMIN, SUPERVISOR)
PUT/api/tipos-ejercicio/:idActualizar tipoSí (ADMIN, SUPERVISOR)
DELETE/api/tipos-ejercicio/:idEliminar tipoSí (ADMIN, SUPERVISOR)

Tribunal — /api/tribunal-miembros

MétodoRutaDescripciónAuth / Rol
GET/api/tribunal-miembrosListar miembrosSí (cualquiera)
GET/api/tribunal-miembros/:idObtener miembroSí (cualquiera)
POST/api/tribunal-miembrosCrear miembroSí (ADMIN, SUPERVISOR)
PUT/api/tribunal-miembros/:idActualizar miembroSí (ADMIN, SUPERVISOR)
PUT/api/tribunal-miembros/:id/toggle-renunciaMarcar/desmarcar renunciaSí (ADMIN, SUPERVISOR)
DELETE/api/tribunal-miembros/:idEliminar miembroSí (ADMIN, SUPERVISOR)

Ejercicios — /api/ejercicios

MétodoRutaDescripciónAuth / Rol
GET/api/ejerciciosListar ejerciciosSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:idObtener ejercicioSí (ADMIN, SUPERVISOR)
POST/api/ejerciciosCrear ejercicioSí (ADMIN, SUPERVISOR)
PUT/api/ejercicios/:idActualizar ejercicioSí (ADMIN, SUPERVISOR)
DELETE/api/ejercicios/:idEliminar ejercicioSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:id/impacto-cierreAdvertencias de cierreSí (ADMIN, SUPERVISOR)
PUT/api/ejercicios/:id/estadoCambiar estado (cerrar/reabrir)Sí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/sedesSedes del ejercicioSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/sedesAñadir sedeSí (ADMIN, SUPERVISOR)
DELETE/api/ejercicios/:ejercicioId/sedes/:idQuitar sedeSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/sedes/:ejercicioSedeId/aulasAulas de la sedeSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/sedes/:ejercicioSedeId/aulasAñadir aulaSí (ADMIN, SUPERVISOR)
DELETE/api/ejercicios/:ejercicioId/sedes/:ejercicioSedeId/aulas/:idQuitar aulaSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/vigilantesVigilantes del ejercicioSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/vigilantes/disponiblesVigilantes disponiblesSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/vigilantesSeleccionar vigilantesSí (ADMIN, SUPERVISOR)
DELETE/api/ejercicios/:ejercicioId/vigilantes/:vigilanteIdQuitar vigilanteSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/vigilantes/exportExportar vigilantes (Excel)Sí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/ubicacionesEstructura de ubicacionesSí (ADMIN, SUPERVISOR)
PUT/api/ejercicios/:ejercicioId/ubicacionesGuardar ubicacionesSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/ubicaciones/validarValidar ubicacionesSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/grupos-vigilantesGrupos y vigilantesSí (ADMIN, SUPERVISOR)
PUT/api/ejercicios/:ejercicioId/grupos-vigilantesGuardar gruposSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/penalizacionesRegistrar no asistidosSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/penalizacionesPenalizaciones activasSí (ADMIN, SUPERVISOR)

Asignación rápida (simulación) — /api/ejercicios

MétodoRutaDescripciónAuth / Rol
GET/api/ejercicios/:id/simulation-metaMeta de la ventanaSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:id/simulateGenerar propuestaSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:id/apply-simulationAplicar propuestaSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:id/export-asignacionesExportar asignacionesSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:id/control-asistenciaDocumento de controlSí (ADMIN, SUPERVISOR)

Asignaciones — /api/asignaciones

MétodoRutaDescripciónAuth / Rol
GET/api/asignacionesListar asignacionesSí (ADMIN, SUPERVISOR)
GET/api/asignaciones/:idObtener asignaciónSí (ADMIN, SUPERVISOR)
POST/api/asignacionesCrear asignación manualSí (ADMIN, SUPERVISOR)
PUT/api/asignaciones/:idActualizar asignaciónSí (ADMIN, SUPERVISOR)
DELETE/api/asignaciones/:idEliminar asignaciónSí (ADMIN, SUPERVISOR)
POST/api/asignaciones/autoAuto-asignarSí (ADMIN, SUPERVISOR)
PUT/api/asignaciones/:id/anular-asistenciaAnular asistenciaSí (ADMIN, SUPERVISOR)
PUT/api/asignaciones/:id/restaurar-asistenciaRestaurar asistenciaSí (ADMIN, SUPERVISOR)

Llamamientos — /api

MétodoRutaDescripciónAuth / Rol
GET/api/ejercicios/:ejercicioId/llamamientosLlamamientos del ejercicioSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/llamamientosCrear llamamientoSí (ADMIN, SUPERVISOR)
GET/api/llamamientos/:idObtener llamamientoSí (ADMIN, SUPERVISOR)
DELETE/api/llamamientos/:idEliminar llamamientoSí (ADMIN, SUPERVISOR)
GET/api/llamamientos/:id/impacto-anulacionImpacto de anulaciónSí (ADMIN, SUPERVISOR)
POST/api/llamamientos/:id/anularAnular llamamientoSí (ADMIN, SUPERVISOR)
GET/api/llamamientos/:id/correosCorreos del llamamientoSí (ADMIN, SUPERVISOR)
POST/api/vigilante-llamamientos/:id/confirmarConfirmar vigilanteSí (ADMIN, SUPERVISOR)
POST/api/vigilante-llamamientos/:id/rechazarRechazar vigilanteSí (ADMIN, SUPERVISOR)
POST/api/vigilante-llamamientos/:id/desconfirmarDesconfirmarSí (ADMIN, SUPERVISOR)
PATCH/api/vigilante-llamamientos/:id/sedeEditar sede preferidaSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/confirmaciones/pendientesConfirmaciones pendientesSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/confirmaciones/importar-excelPrevisualizar importaciónSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/confirmaciones/aplicar-excelAplicar importaciónSí (ADMIN, SUPERVISOR)
POST/api/vigilante-llamamientos/:id/reenviar-correoReenviar correoSí (ADMIN, SUPERVISOR)

Notificaciones — /api

MétodoRutaDescripciónAuth / Rol
GET/api/ejercicios/:ejercicioId/notificacionesNotificaciones del ejercicioSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/notificacionesCrear notificación (multipart, hasta 10 archivos)Sí (ADMIN, SUPERVISOR)
GET/api/notificaciones/:idObtener notificaciónSí (ADMIN, SUPERVISOR)
POST/api/notificaciones/:id/anularAnular notificaciónSí (ADMIN, SUPERVISOR)
POST/api/notificaciones/:id/documentosAñadir documentoSí (ADMIN, SUPERVISOR)
DELETE/api/notificaciones/:id/documentos/:documentoIdEliminar documentoSí (ADMIN, SUPERVISOR)
POST/api/notificacion-vigilantes/:id/reenviar-correoReenviar correo individualSí (ADMIN, SUPERVISOR)
POST/api/notificaciones/:id/reenviarReenviar notificaciónSí (ADMIN, SUPERVISOR)
GET/api/ejercicios/:ejercicioId/documentosDocumentos del ejercicioSí (ADMIN, SUPERVISOR)
POST/api/ejercicios/:ejercicioId/documentosSubir documento de ejercicioSí (ADMIN, SUPERVISOR)
DELETE/api/ejercicios/:ejercicioId/documentos/:documentoIdEliminar documentoSí (ADMIN, SUPERVISOR)

Plantillas de email — /api/templates

MétodoRutaDescripciónAuth / Rol
GET/api/templates/typesTipos disponiblesSí (ADMIN)
GET/api/templatesListar plantillasSí (ADMIN)
GET/api/templates/:idObtener plantillaSí (ADMIN)
POST/api/templatesCrear plantillaSí (ADMIN)
PUT/api/templates/:idActualizar plantillaSí (ADMIN)
DELETE/api/templates/:idEliminar plantillaSí (ADMIN)
PATCH/api/templates/:id/activateActivar/desactivarSí (ADMIN)
POST/api/templates/:id/previewPrevisualizarSí (ADMIN)
GET/api/templates/active/:tipoPlantilla activa por tipoSí (ADMIN, SUPERVISOR)

Plantillas de documento — /api/document-templates

MétodoRutaDescripciónAuth / Rol
GET/api/document-templatesListar plantillasSí (ADMIN, SUPERVISOR)
GET/api/document-templates/typesTipos disponiblesSí (ADMIN, SUPERVISOR)
GET/api/document-templates/:idObtener plantillaSí (ADMIN, SUPERVISOR)
POST/api/document-templatesCrear plantillaSí (ADMIN, SUPERVISOR)
PUT/api/document-templates/:idActualizar plantillaSí (ADMIN, SUPERVISOR)
POST/api/document-templates/:id/previewPrevisualizarSí (ADMIN, SUPERVISOR)
DELETE/api/document-templates/:idEliminar plantillaSí (ADMIN, SUPERVISOR)
PATCH/api/document-templates/:id/activateActivar/desactivarSí (ADMIN, SUPERVISOR)

Configuración — /api/configuracion

MétodoRutaDescripciónAuth / Rol
GET/api/configuracion/colores-roles-usuariosColores por rolSí (cualquiera)
GET/api/configuracion/colores-miembros-tribunalColores de tribunalSí (cualquiera)
GET/api/configuracion/etiqueta-coloresColores de etiquetasSí (cualquiera)
GET/api/configuracion/pagina-ayuda/checkComprueba la URL de ayudaSí (cualquiera)
GET/api/configuracionListar parámetrosSí (ADMIN, SUPERVISOR)
PUT/api/configuracion/:claveActualizar parámetroSí (ADMIN, SUPERVISOR*)

* El SUPERVISOR no puede modificar las claves reservadas a ADMIN (ver Roles). El intento responde 403.

Otros

MétodoRutaDescripciónAuth / Rol
PUT/api/penalizaciones/:id/levantarLevantar penalizaciónSí (ADMIN, SUPERVISOR)
GET/api/ubicaciones/usosEjercicios abiertos que usan una ubicaciónSí (ADMIN, SUPERVISOR)
GET/api/summaryKPIs del dashboardSí (ADMIN, SUPERVISOR)
GET/api/healthSalud del servicio y BDNo
GET/api/files/download/:objectNameDescargar ficheroNo
GET/api/docsSwagger UINo
GET/api/docs.jsonEspecificación OpenAPINo

1. Autenticación

POST /api/auth/login

  • Descripción: autentica con email y contraseña. Requiere cuenta activa y email verificado.
  • Autenticación: no.
  • Body:
json
{ "email": "superadmin@inap.es", "password": "********" }
CampoTipoRequeridoDescripción
emailstring (email)Correo del usuario
passwordstringContraseña
  • Respuestas:
    • 200:
json
{
  "success": true,
  "data": {
    "accessToken": "eyJ...",
    "refreshToken": "eyJ...",
    "user": { "id": "uuid", "name": "Super Administrador", "email": "superadmin@inap.es", "role": "SUPERADMIN" }
  }
}
  • 401 credenciales inválidas, usuario inactivo o email no verificado.
  • 429 demasiados intentos.
  • Errores comunes: contraseña incorrecta, cuenta desactivada, email sin verificar.

POST /api/auth/logout

  • Descripción: invalida el refresh_token del usuario autenticado.
  • Autenticación: requerida.
  • Body: ninguno.
  • Respuestas: 200 { success: true, data: null }; 401.

POST /api/auth/refresh-token

  • Descripción: emite un nuevo par de tokens si el refresh es válido y coincide con el almacenado (rotación).
  • Autenticación: no.
  • Body: { "refreshToken": "eyJ..." } (refreshToken requerido).
  • Respuestas:
json
{ "success": true, "data": { "accessToken": "eyJ...", "refreshToken": "eyJ..." } }
  • 401 refresh inválido o usuario inactivo.
  • Errores comunes: token caducado, refresh ya rotado.

POST /api/auth/change-password

  • Descripción: cambia la contraseña del usuario autenticado.
  • Autenticación: requerida.
  • Body: { "currentPassword": "...", "newPassword": "..." }; newPassword debe cumplir la política (password-policy).
  • Respuestas: 200 { data: null }; 400 validación; 401 contraseña actual incorrecta.

POST /api/auth/forgot-password

  • Descripción: genera token de restablecimiento y envía email (respuesta genérica anti-enumeración).
  • Autenticación: no.
  • Body: { "email": "usuario@inap.es" }.
  • Respuestas: 200 { data: { message: "Si el email está registrado, ..." } }.

POST /api/auth/reset-password

  • Descripción: restablece la contraseña con token.
  • Autenticación: no.
  • Body: { "token": "...", "newPassword": "..." }.
  • Respuestas: 200 { data: { message: "Contraseña restablecida correctamente." } }; 400 token inválido/caducado.

POST /api/auth/verify-email

  • Descripción: verifica el correo con el token enviado.
  • Autenticación: no.
  • Body: { "token": "..." }.
  • Respuestas: 200 { data: { message: "Correo electrónico verificado correctamente." } }; 400.

GET /api/auth/me

  • Descripción: devuelve el usuario autenticado (con perfil).
  • Autenticación: requerida.
  • Respuestas: 200 { data: { id, name, email, role, profile? } }; 401.

2. Usuarios

GET /api/users/me

  • Descripción: perfil propio.
  • Autenticación: requerida.
  • Respuestas: 200 usuario con perfil; 401.

PUT /api/users/me

  • Descripción: actualiza nombre, email y perfil propios.
  • Autenticación: requerida.
  • Body:
json
{
  "name": "Nombre Apellidos",
  "email": "usuario@inap.es",
  "profile": { "dni": "12345678Z", "phone": "600000000", "company": "INAP", "notes": "" }
}
CampoTipoRequerido
namestring (1..100)No
emailstring (email)No
profile.dnistring (≤9) / nullNo
profile.phonestring (≤20) / nullNo
profile.companystring (≤255) / nullNo
profile.notesstring / nullNo
  • Respuestas: 200; 400; 409 email duplicado.

POST /api/users/me/avatar

  • Descripción: sube el avatar (multipart/form-data, campo avatar).
  • Autenticación: requerida.
  • Body: fichero de imagen (extensiones permitidas por STORAGE_ALLOWED_IMAGE_EXTENSIONS, tamaño máximo MAX_AVATAR_MB).
  • Respuestas: 200 con clave/URL del avatar; 400 tipo o tamaño no permitido.

DELETE /api/users/me/avatar

  • Descripción: elimina el avatar propio.
  • Autenticación: requerida.
  • Respuestas: 200.

GET /api/users

  • Descripción: lista paginada de usuarios.
  • Autenticación: requerida (ADMIN).
  • Query:
ParamTipoRequeridoDescripción
pageint ≥1NoPágina (def. 1)
limitint 1..1000NoTamaño (def. 50)
searchstringNoNombre o email
roleSUPERADMIN|ADMIN|SUPERVISORNoFiltro por rol
isActivetrue|falseNoFiltro por estado
  • Respuestas (forma especial):
json
{
  "success": true,
  "data": {
    "items": [
      { "id": "uuid", "name": "Laura", "email": "laura@inap.es", "role": "ADMIN", "is_active": true, "profile": null }
    ],
    "meta": { "total": 1, "page": 1, "limit": 50, "totalPages": 1 }
  }
}

GET /api/users/:id

  • Descripción: obtiene un usuario por UUID.
  • Autenticación: requerida (ADMIN).
  • Params: id (uuid).
  • Respuestas: 200; 404.

POST /api/users

  • Descripción: crea un usuario. Un ADMIN no puede crear ADMIN ni SUPERADMIN.
  • Autenticación: requerida (ADMIN).
  • Body: { "name", "email", "password", "role": "SUPERVISOR\|ADMIN" }.
  • Respuestas: 200/201; 400; 403 por jerarquía; 409 email duplicado.

PUT /api/users/:id

  • Descripción: actualiza nombre, email, rol y estado.
  • Autenticación: requerida (ADMIN).
  • Body: { "name?", "email?", "role?", "is_active?" }.
  • Respuestas: 200; 400; 404; 409.

DELETE /api/users/:id

  • Descripción: elimina/desactiva un usuario.
  • Autenticación: requerida (ADMIN).
  • Respuestas: 200; 404; 403 (no eliminarse a sí mismo / jerarquía).

PATCH /api/users/:id/status

  • Descripción: activa o desactiva un usuario.
  • Autenticación: requerida (ADMIN).
  • Body: { "is_active": true }.
  • Respuestas: 200; 404.

3. Vigilantes

GET /api/vigilantes

  • Descripción: lista paginada de vigilantes.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query:
ParamTipoRequeridoDescripción
pageint ≥1NoPágina (def. 1)
limitint (-1 o 1..1000)NoTamaño (-1 = todos, def. 50)
searchstringNoBúsqueda sin acentos
tagsstringNoIDs de etiquetas
bloqueadotrue|falseNoFiltro de bloqueo
fechaDesde / fechaHastastringNoRango de fechas
  • Respuestas: 200 paginado ({ data, total, page, limit, totalPages }).

GET /api/vigilantes/:id

  • Descripción: detalle de un vigilante.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

GET /api/vigilantes/:id/historial-asistencia

  • Descripción: historial de asistencia del vigilante.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 { data: { ... } }; 404.

GET /api/vigilantes/:id/penalizaciones

  • Descripción: penalizaciones del vigilante.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/vigilantes

  • Descripción: crea un vigilante (valida DNI/NIE).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "dni": "12345678Z",
  "nombre": "Ana",
  "primer_apellido": "García",
  "segundo_apellido": "",
  "correo_electronico_corporativo": "ana@inap.es",
  "correo_electronico_personal": null,
  "telefono": "600000000",
  "tagIds": ["uuid-tag"],
  "bloqueado": false,
  "motivoBloqueo": null,
  "comentarios": null
}
CampoTipoRequeridoDescripción
dnistring (NIF/NIE válido)Documento
nombre / primer_apellidostring 1..100Nombre y primer apellido
segundo_apellidostring ≤100NoSe guarda "" si vacío
correo_electronico_corporativo / _personalstring (email)NoCorreos
telefonostring ≤20NoTeléfono
tagIdsuuid[]NoEtiquetas
bloqueadobooleanNoDef. false
motivoBloqueostring ≤1000No
comentariosstringNo
  • Respuestas: 200; 400 DNI inválido; 409 DNI duplicado.

PUT /api/vigilantes/:id

  • Descripción: actualiza un vigilante (incluye motivoDesbloqueo).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: mismos campos que el alta, todos opcionales.
  • Respuestas: 200; 404; 409.

DELETE /api/vigilantes/:id

  • Descripción: elimina un vigilante.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si está referenciado.

PUT /api/vigilantes/:id/toggle-bloqueado

  • Descripción: alterna el bloqueo, con motivo opcional.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "motivo": "Texto opcional" } (por defecto {}).
  • Respuestas: 200; 404.

POST /api/vigilantes/import/preview

  • Descripción: analiza filas de una importación y devuelve coincidencias/conflictos sin persistir.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "filas": [ImportRow], "batchTagIds": ["uuid"]? } (mínimo 1 fila).
  • Respuestas: 200 con previsualización; 400.

POST /api/vigilantes/import/execute

  • Descripción: aplica la importación según las decisiones por fila.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "rows": [
    { "data": { "rowId": "1", "dni": "12345678Z", "nombre": "Ana", "primer_apellido": "García" },
      "include": true, "updateFields": ["telefono"] }
  ],
  "batchTagIds": ["uuid"],
  "archivoNombre": "vigilantes.xlsx"
}
  • Respuestas: 200 con totales (nuevos, actualizados, errores); 400.

4. Etiquetas

GET /api/tags

  • Descripción: lista etiquetas; admite filtro scope.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: scope (string, opcional).
  • Respuestas: 200 { data: Tag[] }.

POST /api/tags

  • Descripción: crea una etiqueta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre": "TIC", "color": "#2563eb", "scope": "general" }.
    • nombre requerido (1..100, trim). color opcional, formato #RRGGBB (def. #6c757d). scope opcional (1..20).
  • Respuestas: 200; 400; 409.

PUT /api/tags/:id

  • Descripción: actualiza una etiqueta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: igual que alta (nombre obligatorio; color/scope opcionales).
  • Respuestas: 200; 404; 409.

DELETE /api/tags/:id

  • Descripción: elimina una etiqueta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si está en uso.

5. Sedes

GET /api/sedes

  • Descripción: lista paginada de sedes (soporta ordenación).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, search, municipio, provincia, is_active.
  • Respuestas: 200 paginado.

GET /api/sedes/municipios

  • Descripción: municipios distintos.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 { data: string[] }.

GET /api/sedes/provincias

  • Descripción: provincias distintas.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 { data: string[] }.

GET /api/sedes/:id

  • Descripción: detalle de sede con edificios.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/sedes

  • Descripción: crea una sede.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "nombre": "Sede Central",
  "direccion": "C/ Ejemplo 1",
  "municipio": "Madrid",
  "codigo_postal": "28001",
  "provincia": "Madrid",
  "responsable": "Nombre",
  "telefono": "910000000",
  "correo_contacto": "sede@inap.es",
  "observaciones": "",
  "como_llegar": ""
}
CampoTipoRequerido
nombrestring 1..255
direccionstring ≥1
municipio / codigo_postal / provincia / responsable / telefono / correo_contacto / observaciones / como_llegarstringNo
  • Respuestas: 200; 400.

PUT /api/sedes/:id

  • Descripción: actualiza una sede (incluye is_active).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: mismos campos, opcionales y anulables.
  • Respuestas: 200; 404.

DELETE /api/sedes/:id

  • Descripción: elimina una sede.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si tiene edificios o uso.

PUT /api/sedes/:id/toggle-active

  • Descripción: activa/desactiva la sede.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

6. Edificios

GET /api/edificios

  • Descripción: lista paginada de edificios, filtrable por sede_id.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, sede_id, search.
  • Respuestas: 200 paginado.

GET /api/edificios/:id

  • Descripción: detalle de edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/edificios

  • Descripción: crea un edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre", "sede_id": "uuid", "direccion?", "estado?": "activo|inactivo|en_obras", "observaciones?" }.
  • Respuestas: 200; 400; 404 sede inexistente.

PUT /api/edificios/:id

  • Descripción: actualiza un edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: campos opcionales (nombre, sede_id, direccion, estado, observaciones).
  • Respuestas: 200; 404.

DELETE /api/edificios/:id

  • Descripción: elimina un edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si tiene aulas.

7. Aulas

GET /api/aulas

  • Descripción: lista paginada de aulas con filtros.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, edificio_id, search, tipo (general|informatica), tag_ids (CSV), capacidad_min, capacidad_max, solo_disponibles.
  • Respuestas: 200 paginado.

GET /api/aulas/:id

  • Descripción: detalle de aula.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/aulas

  • Descripción: crea un aula.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre", "edificio_id": "uuid", "capacidad": 30, "planta_id?", "tipo?": "general|informatica", "equipamiento?", "estado?": "disponible|mantenimiento|inactiva", "observaciones?", "tagIds?": [] }.
    • nombre y edificio_id y capacidad (entero positivo) requeridos.
  • Respuestas: 200; 400; 404.

PUT /api/aulas/:id

  • Descripción: actualiza un aula.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: campos opcionales.
  • Respuestas: 200; 404.

DELETE /api/aulas/:id

  • Descripción: elimina un aula.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si está en uso.

8. Plantas

GET /api/plantas

  • Descripción: lista todas las plantas.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 { data: Planta[] }.

POST /api/plantas

  • Descripción: crea una planta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre": "Planta baja", "orden": 0 } (nombre req., orden opcional).
  • Respuestas: 200; 400; 409 nombre duplicado.

PUT /api/plantas/:id

  • Descripción: actualiza una planta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

DELETE /api/plantas/:id

  • Descripción: elimina una planta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

GET /api/plantas/edificio/:edificioId

  • Descripción: plantas asociadas a un edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/plantas/edificio/:edificioId/assign/:plantaId

  • Descripción: asigna una planta a un edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

DELETE /api/plantas/edificio/:edificioId/assign/:plantaId

  • Descripción: desasigna una planta de un edificio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

9. Convocatorias

GET /api/convocatorias

  • Descripción: lista paginada de convocatorias.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, estado (ABIERTA|CERRADA), search, anio_desde, anio_hasta.
  • Respuestas: 200 paginado.

GET /api/convocatorias/:id

  • Descripción: detalle con ejercicios y tribunal.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/convocatorias

  • Descripción: crea una convocatoria.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre", "anio": 2026, "observaciones?" }.
  • Respuestas: 200; 400.

PUT /api/convocatorias/:id

  • Descripción: actualiza una convocatoria.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre?", "anio?", "observaciones?" }.
  • Respuestas: 200; 404.

PUT /api/convocatorias/:id/estado

  • Descripción: cambia el estado (ABIERTA/CERRADA).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "estado": "CERRADA" }.
  • Respuestas: 200; 400; 404; 409 si hay ejercicios abiertos.

DELETE /api/convocatorias/:id

  • Descripción: elimina una convocatoria.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si tiene ejercicios.

10. Tipos de ejercicio

GET /api/tipos-ejercicio

  • Descripción: lista el catálogo de tipos de ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 { data: TipoEjercicio[] }.

POST /api/tipos-ejercicio

  • Descripción: crea un tipo.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre": "Acceso libre" } (req., 1..100, trim).
  • Respuestas: 200; 400; 409.

PUT /api/tipos-ejercicio/:id

  • Descripción: renombra un tipo (propaga el cambio a ejercicios).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre": "Nuevo nombre" }.
  • Respuestas: 200; 404; 409.

DELETE /api/tipos-ejercicio/:id

  • Descripción: elimina un tipo.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

11. Tribunal

GET /api/tribunal-miembros

  • Descripción: lista paginada de miembros de tribunal.
  • Autenticación: requerida (cualquier rol).
  • Query: page, limit, convocatoria_id, tipo (TITULAR|SUPLENTE), cargo (PRESIDENTE|VOCAL|SECRETARIO), search, renuncia.
  • Respuestas: 200 paginado.

GET /api/tribunal-miembros/:id

  • Descripción: detalle de miembro.
  • Autenticación: requerida (cualquier rol).
  • Respuestas: 200; 404.

POST /api/tribunal-miembros

  • Descripción: crea un miembro.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "convocatoria_id": "uuid", "tipo": "TITULAR", "nombre": "...", "cargo": "VOCAL", "correo_electronico?", "telefono?", "renuncia?": false, "motivoRenuncia?", "comentarios?" }.
  • Respuestas: 200; 400; 404.

PUT /api/tribunal-miembros/:id

  • Descripción: actualiza un miembro.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: tipo y cargo obligatorios en el esquema; resto opcional (incluye motivoReincorporacion).
  • Respuestas: 200; 404.

PUT /api/tribunal-miembros/:id/toggle-renuncia

  • Descripción: alterna la renuncia.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "motivo": "..." } (opcional).
  • Respuestas: 200; 404.

DELETE /api/tribunal-miembros/:id

  • Descripción: elimina un miembro.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

12. Ejercicios

GET /api/ejercicios

  • Descripción: lista paginada de ejercicios.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, convocatoria_id, search, estado (ABIERTA|CERRADA).
  • Respuestas: 200 paginado.

GET /api/ejercicios/:id

  • Descripción: detalle del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios

  • Descripción: crea un ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre", "convocatoria_id": "uuid", "tipo", "fecha?", "hora_vigilantes_aula_tribunal?", "hora_comienzo_ejercicio?", "duracion_acceso_libre?", "duracion_promocion_interna?", "observaciones?" }.
  • Respuestas: 200; 400; 404.

PUT /api/ejercicios/:id

  • Descripción: actualiza un ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: campos opcionales.
  • Respuestas: 200; 404; 409 si está cerrado.

DELETE /api/ejercicios/:id

  • Descripción: elimina un ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si tiene dependencias.

GET /api/ejercicios/:id/impacto-cierre

  • Descripción: devuelve advertencias antes de cerrar (asistencia pendiente, etc.).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

PUT /api/ejercicios/:id/estado

  • Descripción: cambia el estado del ejercicio (cerrar/reabrir).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "estado": "CERRADA" }.
  • Respuestas: 200; 400; 404; 409 si hay asistencia pendiente.

GET /api/ejercicios/:ejercicioId/sedes

  • Descripción: sedes asociadas al ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/sedes

  • Descripción: añade una sede al ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "sede_id": "uuid" }.
  • Respuestas: 200; 400; 409 duplicado.

DELETE /api/ejercicios/:ejercicioId/sedes/:id

  • Descripción: quita una sede del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 con dependencias.

GET /api/ejercicios/:ejercicioId/sedes/:ejercicioSedeId/aulas

  • Descripción: aulas configuradas en la sede del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/sedes/:ejercicioSedeId/aulas

  • Descripción: añade un aula a la sede del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "aula_id": "uuid" }.
  • Respuestas: 200; 400; 404; 409.

DELETE /api/ejercicios/:ejercicioId/sedes/:ejercicioSedeId/aulas/:id

  • Descripción: quita un aula de la sede del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.
  • ⚠️ Nota: el controlador lee req.params.ejercicioSedeAulaId, pero la ruta define :id (ver DEUDA_TECNICA.md).

GET /api/ejercicios/:ejercicioId/vigilantes

  • Descripción: vigilantes seleccionados en el ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

GET /api/ejercicios/:ejercicioId/vigilantes/disponibles

  • Descripción: vigilantes disponibles para seleccionar.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/vigilantes

  • Descripción: selecciona vigilantes para el ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "vigilante_ids": ["uuid", "..."] } (mín. 1).
  • Respuestas: 200; 400; 404.

DELETE /api/ejercicios/:ejercicioId/vigilantes/:vigilanteId

  • Descripción: quita un vigilante del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

GET /api/ejercicios/:ejercicioId/vigilantes/export

  • Descripción: exporta el listado de vigilantes a Excel (binario).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 (application/vnd.openxmlformats-officedocument.spreadsheetml.sheet).

GET /api/ejercicios/:ejercicioId/ubicaciones

  • Descripción: estructura jerárquica de sedes/edificios/aulas del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

PUT /api/ejercicios/:ejercicioId/ubicaciones

  • Descripción: guarda la configuración de ubicaciones y capacidades.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "sedes": [
    {
      "sede_id": "uuid",
      "edificios": [
        {
          "edificio_id": "uuid",
          "modo": "calcular_aulas",
          "vigilantes_manual": 2,
          "aulas": [
            { "aula_id": "uuid", "modo": "ratio", "ratio_denominador": 25 },
            { "aula_id": "uuid", "modo": "fijo", "vigilantes_fijos": 2 }
          ]
        }
      ]
    }
  ]
}
  • Respuestas: 200; 400; 404; 409 (p. ej. impacto sobre ejercicios existentes).

POST /api/ejercicios/:ejercicioId/ubicaciones/validar

  • Descripción: valida el impacto del cambio sin persistir.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: igual que saveUbicaciones.
  • Respuestas: 200 con UbicacionesImpacto; 400.

GET /api/ejercicios/:ejercicioId/grupos-vigilantes

  • Descripción: grupos y vigilantes del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

PUT /api/ejercicios/:ejercicioId/grupos-vigilantes

  • Descripción: guarda grupos y asignación de vigilantes a grupos.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "grupos": [ { "nombre": "Grupo A", "vigilantes": [ { "vigilante_id": "uuid", "orden": 0 } ] } ] }.
  • Respuestas: 200; 400; 404.

POST /api/ejercicios/:ejercicioId/penalizaciones

  • Descripción: registra como no asistidos a los vigilantes del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

GET /api/ejercicios/:ejercicioId/penalizaciones

  • Descripción: penalizaciones activas del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

13. Asignación rápida (simulación)

GET /api/ejercicios/:id/simulation-meta

  • Descripción: datos y metadatos para la ventana de asignación rápida.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 con SimulationMeta; 404.

POST /api/ejercicios/:id/simulate

  • Descripción: genera una propuesta de reparto (no persistente).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "ejercicio_id": "uuid",
  "scope": { "tipo": "todas" },
  "reglas": [
    { "id": "resp", "activa": true, "orden": 0 },
    { "id": "pref", "activa": true, "orden": 1 }
  ],
  "respetarCapacidad": true,
  "ratioManual": 3,
  "minResponsablesAula": 1,
  "reasignarTodo": false,
  "asignacionEquitativa": false,
  "priorizarSinPreferencia": false,
  "designarResponsablesAuto": false,
  "excluirVigilanteIds": [],
  "fijados": [
    { "vigilanteId": "uuid", "targetType": "aula", "targetId": "uuid", "esResponsable": true }
  ]
}
CampoTipoRequeridoDescripción
ejercicio_iduuidEjercicio
scopeunión discriminada todas|sedes|edificios|aulasAlcance (sedes/edificios/aulas requieren ids[])
reglas[]{ id: resp|pref|orden|equidad, activa, orden }Sí (mín. 1)Reglas y prioridad
respetarCapacidadbooleanNo (def. true)
ratioManualint ≥1No (def. 3)
minResponsablesAulaint ≥1No (def. 1)
reasignarTodobooleanNo
asignacionEquitativabooleanNo
priorizarSinPreferenciabooleanNo
designarResponsablesAutobooleanNo
excluirVigilanteIdsuuid[]No
fijados[]{ vigilanteId, targetType, targetId, esResponsable }NoFijados manualmente
  • Respuestas: 200 con ResultadoSimulacion; 400; 404; 409.

POST /api/ejercicios/:id/apply-simulation

  • Descripción: persiste la propuesta de reparto.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "ejercicio_id": "uuid",
  "reasignarTodo": false,
  "reconciliar": false,
  "assignments": [
    { "vigilanteId": "uuid", "targetType": "aula", "targetId": "uuid", "esResponsable": true }
  ]
}
  • Respuestas: 200; 400; 404; 409 (p. ej. vigilante ya notificado).

GET /api/ejercicios/:id/export-asignaciones

  • Descripción: exporta las asignaciones en XLSX o PDF.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: formato (xlsx def. | pdf).
  • Respuestas: 200 binario (Content-Type según formato); 404.

GET /api/ejercicios/:id/control-asistencia

  • Descripción: genera el documento de control de asistencia con una plantilla.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: templateId (uuid, requerido).
  • Respuestas: 200 binario (PDF/HTML); 400; 404.

14. Asignaciones

GET /api/asignaciones

  • Descripción: lista paginada de asignaciones, filtrable por ejercicio_id.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, ejercicio_id.
  • Respuestas: 200 paginado.

GET /api/asignaciones/:id

  • Descripción: detalle de asignación.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/asignaciones

  • Descripción: crea una asignación manual (exactamente un destino).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{ "ejercicio_sede_aula_id": "uuid", "vigilante_id": "uuid", "es_responsable_aula": false }

(o ejercicio_sede_edificio_id en lugar de ejercicio_sede_aula_id).

  • Respuestas: 200; 400 si no se indica exactamente un destino; 404; 409 duplicado.

PUT /api/asignaciones/:id

  • Descripción: actualiza responsable y estado de asistencia.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "es_responsable_aula?": bool, "estado_asistencia?": "pendiente|asistio|no_asistio" }.
  • Respuestas: 200; 404.

DELETE /api/asignaciones/:id

  • Descripción: elimina una asignación.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409 si está notificada.

POST /api/asignaciones/auto

  • Descripción: auto-asigna vigilantes a las aulas del ejercicio (motor sencillo).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "ejercicio_id": "uuid", "reasignar": false }.
  • Respuestas: 200; 400; 404.

PUT /api/asignaciones/:id/anular-asistencia

  • Descripción: anula la asistencia con motivo.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "motivo": "..." }.
  • Respuestas: 200; 400; 404.

PUT /api/asignaciones/:id/restaurar-asistencia

  • Descripción: restaura una asistencia anulada.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

15. Llamamientos

GET /api/ejercicios/:ejercicioId/llamamientos

  • Descripción: lista los llamamientos del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/llamamientos

  • Descripción: crea un llamamiento y envía correos a los vigilantes.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body:
json
{
  "vigilante_ids": ["uuid", "uuid"],
  "reintentar_ids": [],
  "fecha_limite_respuesta": "2026-06-01T23:59:00.000Z"
}
  • Respuestas: 200 con Llamamiento; 400; 404; 409.

GET /api/llamamientos/:id

  • Descripción: detalle del llamamiento.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

DELETE /api/llamamientos/:id

  • Descripción: elimina un llamamiento.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

GET /api/llamamientos/:id/impacto-anulacion

  • Descripción: impacto de anular el llamamiento.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/llamamientos/:id/anular

  • Descripción: anula el llamamiento con motivo.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "motivo": "..." }.
  • Respuestas: 200; 400; 404; 409 por coherencia.

GET /api/llamamientos/:id/correos

  • Descripción: correos asociados al llamamiento.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/vigilante-llamamientos/:id/confirmar

  • Descripción: confirma al vigilante, opcionalmente con sede preferida.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "sede_id": "uuid" } (opcional/null).
  • Respuestas: 200; 404; 409.

POST /api/vigilante-llamamientos/:id/rechazar

  • Descripción: marca rechazo.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/vigilante-llamamientos/:id/desconfirmar

  • Descripción: revierte la confirmación.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

PATCH /api/vigilante-llamamientos/:id/sede

  • Descripción: edita la sede preferida.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "sede_id": "uuid" }.
  • Respuestas: 200; 404.

GET /api/ejercicios/:ejercicioId/confirmaciones/pendientes

  • Descripción: confirmaciones pendientes del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/confirmaciones/importar-excel

  • Descripción: previsualiza una importación de confirmaciones desde Excel (multipart, campo file).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200 con ExcelPreview; 400.

POST /api/ejercicios/:ejercicioId/confirmaciones/aplicar-excel

  • Descripción: aplica las confirmaciones importadas.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "filas": [ { "vigilante_llamamiento_id": "uuid", "sede_id?": "uuid", "actualizar_datos?": { ... } } ] }.
  • Respuestas: 200; 400; 404.

POST /api/vigilante-llamamientos/:id/reenviar-correo

  • Descripción: reenvía el correo individual del llamamiento.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 500 si falla SMTP.

16. Notificaciones

GET /api/ejercicios/:ejercicioId/notificaciones

  • Descripción: lista las notificaciones del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/notificaciones

  • Descripción: crea y envía una notificación. multipart/form-data.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body (multipart):
CampoTipoRequeridoDescripción
asuntostringAsunto
cuerpostringCuerpo (HTML/texto)
filesfile[] (máx. 10)NoAdjuntos
  • Respuestas: 200 con la notificación; 400; 404.
  • Errores comunes: fallo SMTP (se registra; el estado del correo queda correo_enviado=false).

GET /api/notificaciones/:id

  • Descripción: detalle de la notificación con destinatarios y documentos.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/notificaciones/:id/anular

  • Descripción: anula la notificación.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "motivo": "...", "anular_asignaciones": false }.
  • Respuestas: 200; 400; 404; 409.

POST /api/notificaciones/:id/documentos

  • Descripción: añade un documento a la notificación (multipart, campo file).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 400; 404.

DELETE /api/notificaciones/:id/documentos/:documentoId

  • Descripción: elimina un documento de la notificación.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/notificacion-vigilantes/:id/reenviar-correo

  • Descripción: reenvía el correo a un destinatario concreto.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/notificaciones/:id/reenviar

  • Descripción: reenvía la notificación completa.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

GET /api/ejercicios/:ejercicioId/documentos

  • Descripción: documentos asociados al ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/ejercicios/:ejercicioId/documentos

  • Descripción: sube un documento al ejercicio (multipart, campo file).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 400; 404.

DELETE /api/ejercicios/:ejercicioId/documentos/:documentoId

  • Descripción: elimina un documento del ejercicio.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

17. Plantillas de email

GET /api/templates/types

  • Descripción: tipos de plantilla disponibles.
  • Autenticación: requerida (ADMIN).
  • Respuestas: 200 { data: [...] }.

GET /api/templates

  • Descripción: lista paginada de plantillas.
  • Autenticación: requerida (ADMIN).
  • Query: page, limit, search, tipo, is_active, is_system.
  • Respuestas: 200 paginado.

GET /api/templates/:id

  • Descripción: detalle de plantilla.
  • Autenticación: requerida (ADMIN).
  • Respuestas: 200; 404.

POST /api/templates

  • Descripción: crea una plantilla.
  • Autenticación: requerida (ADMIN).
  • Body: { "nombre", "description?", "tipo", "asunto", "cuerpo", "is_active": false }.
  • Respuestas: 200; 400.

PUT /api/templates/:id

  • Descripción: actualiza una plantilla.
  • Autenticación: requerida (ADMIN).
  • Respuestas: 200; 404; 409 si es de sistema y se intenta modificar el tipo.

DELETE /api/templates/:id

  • Descripción: elimina una plantilla (no de sistema).
  • Autenticación: requerida (ADMIN).
  • Respuestas: 200; 404; 409.

PATCH /api/templates/:id/activate

  • Descripción: activa/desactiva (desactiva las demás del mismo tipo).
  • Autenticación: requerida (ADMIN).
  • Respuestas: 200; 404.

POST /api/templates/:id/preview

  • Descripción: renderiza la plantilla con variables.
  • Autenticación: requerida (ADMIN).
  • Body: { "variables": { "nombre": "Ana" } }.
  • Respuestas: 200; 404.

GET /api/templates/active/:tipo

  • Descripción: plantilla activa de un tipo (EmailTemplateTipo).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

18. Plantillas de documento

GET /api/document-templates

  • Descripción: lista paginada de plantillas de documento.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, search, tipo, is_active, is_system.
  • Respuestas: 200 paginado.

GET /api/document-templates/types

  • Descripción: tipos y variables disponibles.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200.

GET /api/document-templates/:id

  • Descripción: detalle de plantilla.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/document-templates

  • Descripción: crea una plantilla HTML (Handlebars).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "nombre", "descripcion?", "tipo": "CONTROL_ASISTENCIA", "html" }.
  • Respuestas: 200; 400.

PUT /api/document-templates/:id

  • Descripción: actualiza una plantilla.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

POST /api/document-templates/:id/preview

  • Descripción: previsualiza con variables.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "variables": {} }.
  • Respuestas: 200; 404.

DELETE /api/document-templates/:id

  • Descripción: elimina una plantilla (no de sistema).
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404; 409.

PATCH /api/document-templates/:id/activate

  • Descripción: activa/desactiva.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas: 200; 404.

19. Configuración

GET /api/configuracion/colores-roles-usuarios

  • Descripción: mapa de colores por rol de usuario.
  • Autenticación: requerida (cualquier rol).
  • Respuestas: 200 { data: Record<string,string> }.

GET /api/configuracion/colores-miembros-tribunal

  • Descripción: mapa de colores de miembros de tribunal.
  • Autenticación: requerida (cualquier rol).
  • Respuestas: 200.

GET /api/configuracion/etiqueta-colores

  • Descripción: mapa de colores de etiquetas.
  • Autenticación: requerida (cualquier rol).
  • Respuestas: 200.

GET /api/configuracion/pagina-ayuda/check

  • Descripción: comprueba que la URL de la página de ayuda configurada (url_pagina_ayuda) responde. Hace la petición desde el servidor (evita CORS) con un timeout de 8 s. Devuelve la URL efectiva (valor configurado o el por defecto https://ayuda.siva.funcioconecta.com) y el estado obtenido. ok es true para respuestas 2xx/3xx.
  • Autenticación: requerida (cualquier rol).
  • Respuestas: 200 { data: { ok: boolean, url: string, status: number | null } }; status es null si la petición falló.

GET /api/configuracion

  • Descripción: lista paginada de parámetros del sistema.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: page, limit, search.
  • Respuestas: 200 paginado.

PUT /api/configuracion/:clave

  • Descripción: actualiza el valor de un parámetro por su clave. El SUPERVISOR no puede modificar las claves reservadas a ADMIN (ver Roles); entre ellas url_pagina_ayuda, que además debe ser una URL http(s) válida.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Params: clave (string).
  • Body: { "valor": "nuevo valor" }.
  • Respuestas: 200; 400; 403 si el SUPERVISOR intenta editar una clave reservada; 404.

20. Otros

PUT /api/penalizaciones/:id/levantar

  • Descripción: levanta (revoca) una penalización activa.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Body: { "motivo": "..." }.
  • Respuestas: 200; 400; 404.

GET /api/ubicaciones/usos

  • Descripción: ejercicios abiertos que usan una ubicación concreta.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Query: tipo (sede|edificio|aula), id (uuid).
  • Respuestas: 200 { data: { ejercicios: [...] } }; 400 si falta id.

GET /api/summary

  • Descripción: KPIs del dashboard.
  • Autenticación: requerida (ADMIN, SUPERVISOR).
  • Respuestas:
json
{
  "success": true,
  "data": {
    "totalVigilantes": 5001,
    "vigilantesActivos": 4900,
    "vigilantesBloqueados": 101,
    "totalConvocatorias": 6,
    "convocatoriasPorEstado": { "ABIERTA": 4, "CERRADA": 2 },
    "totalEjercicios": 17,
    "ejerciciosHoy": 0,
    "totalAsignaciones": 3200,
    "totalSedes": 23,
    "totalAulas": 144
  }
}

GET /api/health

  • Descripción: estado del servicio y de la base de datos.
  • Autenticación: no.
  • Respuestas: 200 { data: { status: "ok", timestamp, database: "connected" } }.

GET /api/files/download/:objectName

  • Descripción: descarga/stream de un fichero del almacenamiento local.
  • Autenticación: no.
  • Params: objectName (ruta codificada).
  • Respuestas: 200 binario; 404 si no existe.

GET /api/docs

  • Descripción: interfaz Swagger UI.
  • Autenticación: no.

GET /api/docs.json

  • Descripción: especificación OpenAPI en JSON.
  • Autenticación: no.

21. Jobs programados (no HTTP)

JobExpresiónDescripción
expirar-pendientes0 * * * *Pasa a SIN_RESPUESTA los VigilanteLlamamiento pendientes con plazo vencido y cierra los llamamientos activos vencidos.
expirar-penalizaciones0 * * * *Marca como finalizada las penalizaciones vencidas.

SIVA — Sistema Integral de Vigilantes de Aulas