Saltar a contenido

Historial de Fichajes (API v2)

Endpoints para consultar el historial de fichajes de empleados. Soporta filtrado por curso escolar para ver datos históricos.


✅ Obtener Resumen Mensual de Empleados

Método/Ruta: GET /api/v2/timerecord/history/summary
Auth: Bearer JWT (rol: Superadmin)

Descripción: Obtiene un resumen mensual de fichajes por empleado con métricas agregadas. Ideal para la vista de tarjetas del dashboard de historial. Solo muestra empleados activos que tengan registros en el período consultado.

Params

Param Tipo Requerido Descripción Ejemplo
month number Mes (1-12) 1
year number Año 2026
schoolCourseId number ID del curso escolar. Si no se envía, usa el curso activo 5
departmentId number Filtrar por departamento 2
search string Búsqueda por nombre, apellido o email García
page number Página (default: 1) 1
limit number Registros por página (default: 20) 20

cURL

# Curso activo (por defecto)
curl -X GET "http://localhost:7001/api/v2/timerecord/history/summary?month=1&year=2026&page=1&limit=20" \
  -H "Authorization: Bearer <TOKEN>"

# Curso específico (histórico)
curl -X GET "http://localhost:7001/api/v2/timerecord/history/summary?month=6&year=2025&schoolCourseId=3&page=1&limit=20" \
  -H "Authorization: Bearer <TOKEN>"

# Con búsqueda
curl -X GET "http://localhost:7001/api/v2/timerecord/history/summary?month=1&year=2026&search=García&page=1&limit=20" \
  -H "Authorization: Bearer <TOKEN>"

Response 200

{
  "status": "success",
  "summary": {
    "totalActiveEmployees": 45,
    "totalHoursAll": 3520.5,
    "totalHoursAllFormatted": "3520h 30m",
    "totalOpenIncidents": 8
  },
  "data": [
    {
      "employeeId": 15,
      "fullName": "García López Juan",
      "workedDays": 18,
      "totalHours": 142.5,
      "totalHoursFormatted": "142h 30m",
      "incidents": 2
    },
    {
      "employeeId": 23,
      "fullName": "Martínez Ruiz Ana",
      "workedDays": 22,
      "totalHours": 176.0,
      "totalHoursFormatted": "176h",
      "incidents": 0
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "totalPages": 3
  }
}

Campos de respuesta

Summary (métricas globales del dashboard):

Campo Tipo Descripción
totalActiveEmployees number Total de empleados activos
totalHoursAll number Horas totales trabajadas (decimal)
totalHoursAllFormatted string Horas totales en texto ("4h 30m")
totalOpenIncidents number Incidencias abiertas sin resolver

Data (por empleado):

Campo Tipo Descripción
employeeId number ID del empleado
fullName string Nombre completo (Apellido Nombre)
workedDays number Días únicos con fichajes (registros abiertos)
totalHours number Suma de horas trabajadas (decimal)
totalHoursFormatted string Horas en texto ("4h 30m")
incidents number Incidencias abiertas sin resolver del empleado

Errors

Código Error Descripción
400 VALIDATION_ERROR Parámetros inválidos (month/year requeridos)
401 UNAUTHORIZED Token inválido o expirado
403 FORBIDDEN Usuario sin permisos de Superadmin
404 NO_ACTIVE_SCHOOL_COURSE No hay curso escolar activo configurado
404 SCHOOL_COURSE_NOT_FOUND El schoolCourseId proporcionado no existe

Notas

  • El ordenamiento es alfabético por apellido, luego por nombre
  • El compliance se calcula sobre 22 días laborables por mes (aproximado)
  • Si no se envía schoolCourseId, el sistema resuelve automáticamente el curso activo

✅ Obtener Detalle de Fichajes por Empleado

Método/Ruta: GET /api/v2/timerecord/history/details
Auth: Bearer JWT (rol: Superadmin)

Descripción: Obtiene el listado detallado de fichajes de un empleado específico. Ideal para la vista de detalle al hacer clic en una tarjeta.

Params

Param Tipo Requerido Descripción Ejemplo
employeeId number ID del empleado 15
schoolCourseId number ID del curso escolar. Si no se envía, usa el curso activo 5
startDate string (ISO) Fecha inicio. Default: inicio del mes actual 2026-01-01
endDate string (ISO) Fecha fin. Default: fin del mes actual 2026-01-31
page number Página (default: 1) 1
limit number Registros por página (default: 20) 20

cURL

# Mes actual, curso activo
curl -X GET "http://localhost:7001/api/v2/timerecord/history/details?employeeId=15&page=1&limit=20" \
  -H "Authorization: Bearer <TOKEN>"

# Rango de fechas específico
curl -X GET "http://localhost:7001/api/v2/timerecord/history/details?employeeId=15&startDate=2026-01-01&endDate=2026-01-31&page=1&limit=20" \
  -H "Authorization: Bearer <TOKEN>"

# Curso histórico
curl -X GET "http://localhost:7001/api/v2/timerecord/history/details?employeeId=15&schoolCourseId=3&startDate=2025-06-01&endDate=2025-06-30" \
  -H "Authorization: Bearer <TOKEN>"

Response 200

{
  "status": "success",
  "data": [
    {
      "date": "2026-01-28T08:00:00.000Z",
      "startTime": "2026-01-28T08:00:00.000Z",
      "endTime": "2026-01-28T14:30:00.000Z",
      "startSource": "App",
      "endSource": "App",
      "duration": 390,
      "status": "closed"
    },
    {
      "date": "2026-01-27T08:15:00.000Z",
      "startTime": "2026-01-27T08:15:00.000Z",
      "endTime": null,
      "startSource": "Web",
      "endSource": null,
      "duration": null,
      "status": "open"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 18,
    "totalPages": 1
  }
}

Campos de respuesta

Campo Tipo Descripción
date string (ISO) Fecha del fichaje
startTime string (ISO) | null Hora de entrada
endTime string (ISO) | null Hora de salida
startSource string | null Origen del fichaje de entrada (Web/App)
endSource string | null Origen del fichaje de salida (Web/App)
duration number | null Duración en minutos (null si está abierto)
status string Estado: open o closed

Errors

Código Error Descripción
400 EMPLOYEE_ID_REQUIRED El employeeId es obligatorio
400 VALIDATION_ERROR Parámetros inválidos
401 UNAUTHORIZED Token inválido o expirado
403 FORBIDDEN Usuario sin permisos de Superadmin
404 NO_ACTIVE_SCHOOL_COURSE No hay curso escolar activo configurado
404 SCHOOL_COURSE_NOT_FOUND El schoolCourseId proporcionado no existe

Notas

  • El ordenamiento es cronológico descendente (más reciente primero)
  • Si no se envían startDate/endDate, se asume el mes actual
  • La duration está en minutos para facilitar cálculos en el frontend


Relacionado