Praesenti
API

Turnos Rotativos

Los turnos rotativos se utilizan cuando el horario del empleado rota cada ciertos días y no cumple un patrón semanal.

Un turno rotativo es una secuencia de pasos (steps). Cada paso dura duration días y puede ser un día de trabajo, con startsAt y endsAt en minutos desde la medianoche (por ejemplo, 480 = 08:00), o un franco (dayOff: true), en cuyo caso los horarios van en null.

Igual que los turnos fijos, los rotativos tienen versiones: si se modifica uno que ya está usado en una asignación, se crea una nueva versión con otro id. Los endpoints de consulta devuelven siempre la última versión.

Obtener todos los turnos rotativos

Obtiene la lista de turnos rotativos vigentes de la organización.

Método: GET /rotation-shifts

Parámetros

ParámetroTipoRequeridoDescripción
shift_assignment_idstring❌ID de una asignación de turnos. Si se envía, cambia el formato de la respuesta (ver más abajo)

Respuesta exitosa (200)

[
  {
    "id": 12,
    "createdAt": "2026-07-01T08:00:00.000Z",
    "updatedAt": "2026-07-01T08:00:00.000Z",
    "deletedAt": null,
    "name": "Rotativo 4x2",
    "steps": [
      {
        "id": 201,
        "createdAt": "2026-07-01T08:00:00.000Z",
        "updatedAt": "2026-07-01T08:00:00.000Z",
        "deletedAt": null,
        "order": 1,
        "name": "Dia",
        "dayOff": false,
        "startsAt": 480,
        "endsAt": 960,
        "duration": 4
      },
      {
        "id": 202,
        "createdAt": "2026-07-01T08:00:00.000Z",
        "updatedAt": "2026-07-01T08:00:00.000Z",
        "deletedAt": null,
        "order": 2,
        "name": "Descanso",
        "dayOff": true,
        "startsAt": null,
        "endsAt": null,
        "duration": 2
      }
    ]
  }
]

Si se envía shift_assignment_id, la respuesta es un objeto cuyas claves son IDs de turno rotativo, con el mismo formato que en turnos fijos: { "12": { "shift": { ... }, "deleted": false } }. deleted es true cuando el turno usado en la asignación ya no tiene una versión vigente.

Códigos de respuesta

CódigoDescripción
200Exitoso
500Error interno del servidor

Obtener un turno rotativo específico

Obtiene la última versión de un turno rotativo a partir del ID de cualquiera de sus versiones.

Método: GET /rotation-shifts/:rotation_id

Parámetros

ParámetroTipoDescripción
rotation_idstringID del turno rotativo

Respuesta exitosa (200)

{
  "id": 12,
  "createdAt": "2026-07-01T08:00:00.000Z",
  "updatedAt": "2026-07-01T08:00:00.000Z",
  "deletedAt": null,
  "name": "Rotativo 4x2",
  "steps": [
    {
      "id": 201,
      "createdAt": "2026-07-01T08:00:00.000Z",
      "updatedAt": "2026-07-01T08:00:00.000Z",
      "deletedAt": null,
      "order": 1,
      "name": "Dia",
      "dayOff": false,
      "startsAt": 480,
      "endsAt": 960,
      "duration": 4
    },
    {
      "id": 202,
      "createdAt": "2026-07-01T08:00:00.000Z",
      "updatedAt": "2026-07-01T08:00:00.000Z",
      "deletedAt": null,
      "order": 2,
      "name": "Descanso",
      "dayOff": true,
      "startsAt": null,
      "endsAt": null,
      "duration": 2
    }
  ]
}

Códigos de respuesta

CódigoDescripción
200Exitoso
404Turno rotativo no encontrado
500Error interno del servidor

Crear un nuevo turno rotativo

Crea un nuevo turno rotativo con su secuencia de pasos. name es obligatorio y no puede repetirse. Cada paso necesita name; los pasos que no son franco necesitan startsAt y endsAt. Tiene que haber al menos un paso de trabajo.

Método: POST /rotation-shifts

Body requerido

{
  "name": "Rotativo 4x2",
  "steps": [
    {
      "order": 1,
      "duration": 4,
      "dayOff": false,
      "name": "Dia",
      "startsAt": 480,
      "endsAt": 960
    },
    {
      "order": 2,
      "duration": 2,
      "dayOff": true,
      "name": "Descanso",
      "startsAt": null,
      "endsAt": null
    }
  ]
}

Respuesta exitosa (200)

{
  "id": 13,
  "createdAt": "2026-07-10T12:09:11.182-03:00",
  "updatedAt": "2026-07-10T12:09:11.182-03:00",
  "deletedAt": null,
  "name": "Rotativo 4x2",
  "steps": [
    {
      "id": 210,
      "createdAt": "2026-07-10T12:09:11.182-03:00",
      "updatedAt": "2026-07-10T12:09:11.182-03:00",
      "deletedAt": null,
      "order": 1,
      "name": "Dia",
      "dayOff": false,
      "startsAt": 480,
      "endsAt": 960,
      "duration": 4
    },
    {
      "id": 211,
      "createdAt": "2026-07-10T12:09:11.182-03:00",
      "updatedAt": "2026-07-10T12:09:11.182-03:00",
      "deletedAt": null,
      "order": 2,
      "name": "Descanso",
      "dayOff": true,
      "startsAt": null,
      "endsAt": null,
      "duration": 2
    }
  ]
}

Códigos de respuesta

CódigoDescripción
200Creado exitosamente
400Solicitud inválida, sin pasos, sin días de trabajo o paso de trabajo sin horario
409Ya existe un turno con ese nombre
500Error interno del servidor

Actualizar un turno rotativo

Actualiza nombre y pasos de un turno rotativo existente. Cada elemento de steps lleva un action: add (paso nuevo), update (modifica el paso stepID) o delete (elimina el paso stepID). El turno tiene que quedar con al menos un paso.

Si el turno ya está usado en una asignación, se crea una nueva versión y las asignaciones existentes siguen usando la anterior, salvo que se indique otra cosa:

  • shiftAssignmentIDs: IDs de las asignaciones que deben pasar a usar la nueva versión. Tiene que incluir también todas las asignaciones posteriores que usan el turno; si no, la API responde 400.
  • createNewVersion: si es true, la última asignación de turnos pasa a usar la nueva versión. Si esa asignación empieza hoy, se modifica; si no, se crea una nueva asignación a partir de hoy, copia de la última.

Método: PUT /rotation-shifts/:rotation_id

Body

{
  "name": "Rotativo 4x3",
  "steps": [
    {
      "action": "update",
      "stepID": 210,
      "order": 1,
      "duration": 4,
      "name": "Dia",
      "dayOff": false,
      "startsAt": 500,
      "endsAt": 980
    },
    {
      "action": "add",
      "stepID": null,
      "order": 2,
      "duration": 3,
      "name": "Descanso",
      "dayOff": true,
      "startsAt": null,
      "endsAt": null
    }
  ],
  "shiftAssignmentIDs": [301],
  "createNewVersion": false
}

Respuesta exitosa (200)

No retorna contenido.

Códigos de respuesta

CódigoDescripción
200Actualizado exitosamente
400Solicitud inválida, stepID inexistente, paso de trabajo sin horario o shiftAssignmentIDs incompleto
404Turno rotativo o asignación no encontrados
409Ya existe un turno con ese nombre
500Error interno del servidor

Eliminar un turno rotativo

Elimina un turno rotativo por ID. Cuando el turno está usado en asignaciones, se pueden enviar sus IDs en shiftAssignmentIDs para quitarlo también de esas asignaciones (tienen que incluirse todas las asignaciones posteriores que lo usan). Si se envía createNewVersion: true, el turno se quita de la última asignación; si esa asignación no empieza hoy, se crea una nueva a partir de hoy sin el turno.

Método: DELETE /rotation-shifts/:rotation_id

Body opcional

{
  "shiftAssignmentIDs": [301],
  "createNewVersion": false
}

Respuesta exitosa (200)

{
  "message": "deleted successfuly",
  "deleted": true
}

Códigos de respuesta

CódigoDescripción
200Eliminado exitosamente
400Solicitud inválida o shiftAssignmentIDs incompleto
404Turno rotativo o asignación no encontrados
500Error interno del servidor