Saltar a contenido

API Fichaje v2

POST /api/v2/timerecord/start

Inicia un fichaje de entrada.

  • Auth: Authorization: Bearer <token>
  • Body (JSON):
  • latitude: number (obligatorio)
  • longitude: number (obligatorio)
  • source: string (opcional) - Origen del fichaje: "web" o "app"
  • deviceId: string (opcional) - Identificador único del dispositivo

Ejemplo:

curl -X POST "$HOST/api/v2/timerecord/start" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 40.4168,
    "longitude": -3.7038,
    "source": "app",
    "deviceId": "device-uuid-123"
  }'

Respuesta (200):

{
  "message": "ok",
  "data": {
    "latitude": 40.4168,
    "longitude": -3.7038,
    "employeeId": 123
  }
}

  • Validación de entrada: realizada con Zod (ver errors.md).
  • Reglas de negocio: validaciones de horario (si el empleado no es flexible) y geofencing. Errores detallados en errors.md.

POST /api/v2/timerecord/end

Finaliza un fichaje de salida.

  • Auth: Authorization: Bearer <token>
  • Body (JSON):
  • latitude: number (obligatorio)
  • longitude: number (obligatorio)
  • source: string (opcional) - Origen del fichaje: "web" o "app"
  • deviceId: string (opcional) - Identificador único del dispositivo

Ejemplo:

curl -X POST "$HOST/api/v2/timerecord/end" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "latitude": 40.4168,
    "longitude": -3.7038,
    "source": "app",
    "deviceId": "device-uuid-123"
  }'

Respuesta (200):

{
  "message": "ok",
  "data": {
    "id": 123,
    "employeeId": 45,
    "schoolCourseId": 1,
    "start": "2025-11-24T13:10:00.000Z",
    "end": "2025-11-24T14:05:00.000Z",
    "startSource": "app",
    "startDeviceId": "device-uuid-123",
    "endSource": "app",
    "endDeviceId": "device-uuid-123",
    "systemStart": null,
    "systemEnd": null,
    "createdAt": "2025-11-24T13:10:00.000Z",
    "updatedAt": "2025-11-24T14:05:00.000Z"
  }
}

  • Validación y reglas de negocio: geofencing y restricciones de horario de salida para empleados no flexibles (no antes de la última clase, con 5 min de tolerancia). Errores detallados en errors.md.

GET /api/v2/timerecord/open

Consulta si el empleado autenticado tiene un fichaje abierto (sin hora de fin) y, en caso afirmativo, devuelve la fecha/hora de inicio.

  • Auth: Authorization: Bearer <token>
  • Body: (sin body)

Ejemplo:

curl -X GET "$HOST/api/v2/timerecord/open" \
  -H "Authorization: Bearer $TOKEN"

Respuesta (200) con fichaje abierto:

{
  "message": "ok",
  "data": {
    "hasOpenRecord": true,
    "start": "2025-11-24T13:10:00.000Z",
    "record": {
      "id": 123,
      "employeeId": 45,
      "schoolCourseId": 1,
      "start": "2025-11-24T13:10:00.000Z",
      "end": null,
      "systemStart": null,
      "systemEnd": null,
      "createdAt": "2025-11-24T13:10:00.000Z",
      "updatedAt": "2025-11-24T13:10:00.000Z"
    }
  }
}

Respuesta (200) sin fichaje abierto:

{
  "message": "ok",
  "data": {
    "hasOpenRecord": false,
    "start": null,
    "record": null
  }
}

  • Errores de autenticación y de negocio descritos en errors.md.

Relacionado: - Dashboard de fichajes - Línea de tiempo