Saltar al contenido
Volver a proyectos

Sistema de Fichaje para Hostelería: API Propia, App Móvil y 4 Idiomas

Sistema de Fichaje para Hostelería: API Propia, App Móvil y 4 Idiomas

Resumen

Control Horario Onya nace de una necesidad real vivida trabajando en un hotel en Suiza. El objetivo fue sustituir las hojas de papel por un sistema fiable: una API propia en FastAPI que guarda cada fichaje como un intervalo, una app móvil para fichar durante el turno y una web para que administración revise registros, apruebe correcciones y exporte informes, sin perder la trazabilidad.

2
Frontends: móvil y web
4
Idiomas (ES/EN/DE/HU)
2
Roles: trabajador y admin

El Problema

En un hotel de Suiza el control horario seguía dependiendo de hojas en papel. Eso servía para salir del paso, pero fallaba en lo importante: descansos poco claros, turnos partidos difíciles de revisar, olvidos corregidos a mano y poca visibilidad sobre las horas reales, las extras o el déficit. El problema no era crear un formulario digital, sino convertir una rutina diaria en un sistema fiable para empleados y administración.

La Solución

Diseñé un sistema completo de control horario para hostelería: un backend propio en FastAPI con SQLAlchemy, Alembic y JWT, y dos clientes que consumen la misma API: una app móvil en React Native y una SPA web. Cubre el ciclo completo —fichaje de entrada, salida y descansos, calendario, dashboard de horas, solicitudes de corrección con aprobación y panel de administración por rol— y centraliza el cálculo horario para que trabajador y administración vean siempre los mismos números.

Herramientas

Qué utilicé y por qué

Elegí herramientas que me permitieran construir un backend propio sólido y consumirlo desde dos clientes (móvil y web) con una interfaz usable por perfiles no técnicos.

FastAPI y SQLAlchemy

Backend propio que concentra la lógica de negocio, la autenticación y la persistencia. Cada fichaje se guarda como un intervalo (trabajo o descanso) con inicio y fin.

Alembic

Migraciones versionadas para evolucionar el esquema (añadir columnas o tablas) sin perder datos entre versiones.

React Native

App móvil con React Navigation y AsyncStorage para fichar rápido durante el turno y consultar horas. Sesión persistida en el dispositivo y consumo de la API con axios.

SPA web

Frontend web ligero para administración: panel de trabajadores, panel de admin y módulos comunes de autenticación, interfaz e internacionalización.

JWT y bcrypt

Login con token JWT (python-jose), contraseñas hasheadas con bcrypt (Passlib) y una dependencia que valida el rol en cada ruta protegida.

Internacionalización

Interfaz en español, inglés, alemán y húngaro, pensada para equipos de hotel con trabajadores de distintos países.

Funcionalidades

Qué incluye el producto

El objetivo no era hacer una demo de fichaje, sino cubrir el ciclo completo que aparece en un hotel: registrar, revisar, corregir, calcular y administrar.

01

Acceso por credenciales y rol

Login con usuario y contraseña, token JWT y rol (trabajador o admin) que decide qué rutas de la API y qué pantallas ve cada perfil.

02

Fichaje guiado

La API expone /work/in, /work/out, /break/in y /break/out. Al fichar la salida, busca el último intervalo abierto y le pone fin: es imposible tener dos jornadas abiertas a la vez.

03

Descansos y turnos partidos

Cada intervalo se modela por separado (trabajo o descanso), de modo que un turno partido o varios descansos se calculan sin ambigüedad, no con una resta simple.

04

Dashboard y resumen de horas

El endpoint /history/summary agrega las horas por día para alimentar el calendario y las tablas. El trabajador ve sus horas reales, sus descansos y sus extras.

05

Solicitudes de corrección trazables

Si alguien olvida fichar, no se edita el historial a escondidas: crea una solicitud con el horario propuesto. Al aprobarla, se reemplazan los intervalos del día y queda registrada en el log de auditoría.

06

Administración y exportación

El admin gestiona usuarios (CRUD), aprueba o rechaza correcciones y descarga informes en CSV generados con pandas.

Proceso

Cómo lo construí

El proyecto salió de observar una fricción real y convertirla en producto. Primero entendí el flujo manual, después lo traduje a una API, unas pantallas y unas reglas de negocio.

01

Observé el proceso en papel

Partí del uso real: trabajadores apuntando horas, responsables revisando hojas y dudas frecuentes sobre descansos, turnos partidos u horas extra.

02

Definí usuarios y permisos

Separé trabajador y administrador para que cada perfil viera solo lo que necesita: fichar y consultar, o revisar correcciones y gestionar usuarios.

03

Diseñé el modelo de datos

Llevé el problema a tablas relacionales con SQLAlchemy: users, time_logs, correction_requests y audit_logs, con estados, relaciones e índices.

04

Construí la API en FastAPI

Endpoints de fichaje, resumen y correcciones para el trabajador; CRUD de usuarios, aprobación de correcciones y export para el admin; todo protegido por JWT.

05

Centralicé el cálculo horario

Modelé cada fichaje como un intervalo. Así el dashboard, el calendario y el panel de admin parten de la misma fuente y nunca dan resultados distintos.

06

Conecté dos clientes

Una app móvil en React Native para fichar y una SPA web para administrar, ambas consumiendo la misma API con la sesión guardada en el dispositivo o el navegador.

Dudas y decisiones

Problemas que tuve que resolver

Las partes difíciles no estuvieron solo en la interfaz, sino en convertir reglas humanas y excepciones del día a día en una lógica consistente.

No todos los días son iguales

Había que soportar turno simple, turno partido, descansos explícitos y jornadas que todavía no están cerradas (sin end_at).

Fechas y zonas horarias

Agrupar por día usando la fecha local fue clave. Un fichaje guardado en UTC no siempre debe agruparse por el día UTC, especialmente en una app usada en distintos husos.

Correcciones sin perder trazabilidad

La duda era si permitir editar los fichajes directamente. Opté por solicitudes con estado y aprobación, que guardan el antes y el después y dejan rastro en la auditoría.

Simplicidad para el empleado

La app tenía que funcionar para personas que no quieren aprender un sistema nuevo. Por eso el fichaje muestra pocas acciones, pero bien elegidas según el último registro del día.

Una sola fuente de verdad, dos clientes

Móvil y web no podían divergir. Toda la lógica vive en la API; los clientes solo presentan y envían, lo que evita cálculos duplicados que se contradigan.

Equipo internacional

El hotel podía tener trabajadores de varios países, así que añadí cuatro idiomas (español, inglés, alemán y húngaro) desde el principio.

Arquitectura

Cómo está construido

La arquitectura separa la API (lógica y datos) de los dos clientes que la consumen, para que cada parte evolucione sin mezclar responsabilidades.

1

app/ contiene el backend FastAPI: main.py (rutas), models.py (SQLAlchemy), schemas.py (Pydantic), auth.py (JWT y roles), database.py y config.py.

2

La autenticación usa JWT (python-jose) y bcrypt (Passlib); una dependencia valida el token y el rol en cada petición protegida.

3

PostgreSQL (o SQLite en local) guarda usuarios, fichajes como intervalos, solicitudes de corrección y auditoría; Alembic gestiona las migraciones.

4

El cliente móvil en React Native (React Navigation + AsyncStorage) consume la API con axios y conserva la sesión en el dispositivo.

5

La SPA web sirve la administración: panel de trabajadores, panel de admin y módulos comunes de autenticación, interfaz e i18n.

6

El cálculo horario vive en el backend, de modo que móvil y web muestran siempre los mismos números.

Modelo de datos

Cuatro tablas para un ciclo completo

El modelo es deliberadamente pequeño, pero cubre fichaje, corrección y auditoría sin ambigüedades.

users

Empleados con sus credenciales, rol (trabajador o admin) e idioma preferido de la interfaz.

username (unique)email (unique)hashed_passwordrolelanguageis_active
time_logs

Cada fila es un intervalo de tiempo (trabajo o descanso) con inicio y fin. Es la base de todo el cálculo de horas.

user_idlog_type (work|break)start_atend_at
correction_requests

Solicitud de cambio de horario que guarda el antes y el después en JSON, con su estado y la razón del administrador.

user_idtarget_datebefore_payload (JSON)after_payload (JSON)statusadmin_reason
audit_logs

Registro de las acciones administrativas (aprobaciones, cambios) para que nada quede sin rastro.

admin_idactiondetailstimestamp

Contrato de API

La API que comparten móvil y web

Toda la lógica vive en la API; los dos clientes solo presentan datos y envían acciones. Estos son los endpoints clave.

POST/work/in

Inicia la jornada: crea un intervalo de trabajo si no hay ninguno abierto.

auth: JWT (trabajador)

POST/work/out

Cierra la jornada: pone end_at al último intervalo abierto.

auth: JWT (trabajador)

GET/history/summary

Resumen de horas por día para el calendario y las tablas.

auth: JWT

POST/requests

Crea una solicitud de corrección con el horario propuesto (before/after).

auth: JWT (trabajador)

GET/export/csv

Descarga el informe en CSV generado con pandas.

auth: JWT (admin)

Stack Tecnológico

Tecnologías utilizadas

React NativeTypeScriptFastAPISQLAlchemyAlembicPostgreSQLpython-jose (JWT)Passlib (bcrypt)React NavigationAsyncStoragepandas

¿Tienes un proyecto similar?

Puedo ayudarte a diseñar, construir y desplegar productos digitales claros, seguros y preparados para operar en producción.