Personal
Empleados, hojas de horas y turnos. Forma parte del vertical de negocio. Leyenda: ✅ hecho · 🟡 en curso · ⬜ pendiente.
Lista
✅ Hojas de horas
Empleados, hojas de horas y turnos.
✅ Fichas de personal
CRUD de la nómina más un historial salarial de solo-anexado con fecha de vigencia por /v1/staff/:id/compensation — un aumento es una fila nueva.
✅ Turnos
Vocabulario de turnos y asignaciones por fecha; la lectura unida de la nómina pinta la semana con una sola llamada, y la doble asignación es un rechazo de la base (409).
✅ Control horario
Reloj de fichaje tipo quiosco por /v1/time-tracking — el fichaje doble se rechaza (409), la pausa acumula al cerrarse, sellos de aprobación y lecturas por rango.
✅ Ausencias
El saldo de ausencias es siempre SUM(delta_days) sobre un libro con signo; la aprobación escribe la fila negativa en la misma transacción, y los días excluyen fines de semana y feriados.
✅ Horas extra
Calculado desde entradas aprobadas contra la ventana del turno (trabajado − programado − gracia) con upsert al recalcular; entradas manuales y aprobar/rechazar.
✅ Nómina
Las corridas de /v1/payroll se calculan de forma determinista desde compensación + tiempo/extra/ausencias aprobados; asentar escribe una partida balanceada Gasto de Salarios / Salarios por Pagar en la misma transacción, y marcar-pagado mueve Salarios por Pagar a Caja.
Evidencia
Personal es real: staff_members + staff_compensation (V08_03) detrás de /v1/staff y shift_types + shift_assignments (V08_04) detrás de /v1/shifts, con alcance por compañía. Probado en vivo en el catálogo de desarrollo — dos empleados creados (uno asalariado, uno por hora con un aumento como nueva fila con fecha de vigencia, nunca una mutación), turnos Mañana y Tarde, seis asignaciones en tres días leídas como una nómina unida, transiciones completado/ausente aplicadas, y una asignación duplicada rechazada por la restricción única de la base como 409; una compañía ajena no ve nada. Filas verificadas en Postgres. La ola de RRHH completa también está en vivo: time_entries (V08_05) detrás de /v1/time-tracking — fichaje tipo quiosco con el doble fichaje rechazado como 409 y un conmutador de pausa — leave_types + leave_requests + leave_ledger + public_holidays (V08_06) detrás de /v1/leave y /v1/holidays, y overtime_entries (V08_07) detrás de /v1/overtime. Probado de punta a punta: una entrada de 9h contra una asignación de Mañana computó 55 minutos extra (turno de 8h, 5min de gracia) y recomputar hace upsert; una asignación de 15 días de Vacaciones, una solicitud de jueves a martes contó 3 días porque el fin de semana y un feriado creado en viernes se excluyen, y la aprobación escribió la fila -3 del libro en la misma transacción, dejando saldo 12 como SUM(delta_days). Y la épica cierra con Nómina: payroll_runs + payroll_run_lines (V08_08) detrás de /v1/payroll, corridas que se calculan de forma determinista desde la compensación más el tiempo, las horas extra y las ausencias pagadas aprobadas, y asientan partidas contables REALES y balanceadas en el libro mayor. Probado en vivo: la corrida de 2026-08 pagó el salario mensual más 3 días de vacaciones a mensual/21.67 y las 9h por hora más 55 minutos extra a 1.5x, una regla CCSS de 10.67% retuvo por línea, y el asiento registró Gasto de Salarios 288,760,060 = Salarios por Pagar 257,949,362 + Impuestos por Pagar 30,810,698 — débitos iguales a créditos en journal_entry_lines, el re-asiento se rechazó con exactamente una partida bajo la clave de idempotencia, y marcar-pagado asentó la segunda partida balanceada moviendo Salarios por Pagar a Caja. Hojas de horas sigue en el registro time-clock de hospitality; personal, turnos, control horario, ausencias, horas extra y nómina son registros de commerce.