Sistema de gestión de clientes para trabajo social
Situación
En la ayuda socioeducativa a familias (SPFH), los especialistas trabajan directamente con familias en situaciones vitales a menudo complejas. Antes de este CMS, documentar citas, informes y planes de ayuda estaba muy fragmentado. Los horarios, las citas y los tiempos de desplazamiento se registraban a mano, y cuadrar las horas realizadas contra el cupo semanal aprobado de cada familia dependía de hojas de cálculo propensas a errores. Los administradores no tenían una visión en tiempo real de la carga real del equipo, de los solapamientos de vacaciones ni de quién estaba de servicio. Documentos sensibles de cada caso se compartían a veces localmente o por canales inseguros, y no existía una separación estricta a nivel de sistema entre los permisos administrativos y el acceso de escritura de los especialistas a los expedientes.
Tarea
El objetivo era una plataforma full-stack conforme al RGPD, eficiente e intuitiva que minimizara la carga administrativa y garantizara la seguridad de los datos. A nivel funcional necesitaba una gestión completa de clientes con atención en tándem (dos especialistas comparten un caso), un registro de jornada íntegro y a prueba de manipulaciones con cálculo de horas extra, y el cálculo automático del uso del cupo por familia con un reparto justo del tiempo cancelado. A nivel técnico, lo difícil era una autenticación segura para expedientes sensibles, una gestión de archivos escalable sin sobrecarga del servidor con documentos grandes, y seguridad de tipos de extremo a extremo, de modo que las peticiones a la API coincidan en tiempo de ejecución con los tipos del backend y estos se reflejen uno a uno en el frontend de React.
Acción
La autenticación usa JWT con estado: tokens de acceso de vida corta (15 min, en memoria del frontend) y tokens de refresco válidos 7 días como cookie httpOnly, guardando en MongoDB solo el hash SHA-256. Una rotación de tokens de refresco con detección de reutilización interpreta cualquier reuso de un token antiguo como robo y revoca de inmediato toda la familia de tokens. Los middlewares de Express (protect, adminOnly) controlan no solo el acceso a rutas, sino también guardas de escritura a nivel de campo: un especialista puede editar los datos de contacto de su familia, pero no su estado, su cupo de horas ni su asignación. La estructura en MongoDB es referenciada (User, Client, Appointment) con subdocumentos para datos muy acoplados, como las confirmaciones RSVP de los CalendarEvents. La lógica de negocio corre sobre agregaciones: el uso es progressPercent = round((totalMinutes / (weeklyHoursQuota × 60)) × 100); las citas canceladas se acreditan con 90 minutos fijos (con un tope de 2 por familia/mes) y en los casos en tándem se reparten de forma justa a 45 minutos cada uno con un factor de sobrecarga de 1,3; las horas extra se recalculan en cada fichaje de salida a partir del total de la semana ISO frente al objetivo semanal. El frontend en React 19 / Tailwind v4 ofrece a los especialistas tiras de KPI personalizadas y gráficos de anillo, y a los administradores un panel en vivo de quién ha fichado, más tablas de carga del equipo. Los documentos se suben directamente a S3 mediante una URL PUT prefirmada, de modo que la API nunca hace de proxy del archivo; los metadatos se persisten solo tras confirmar la subida. Una única WeekView controla la vista propia y la del equipo mediante un prop colorMode, y todos los tipos del frontend reflejan los esquemas Zod del backend para descartar payloads inconsistentes.
Resultado
El cálculo automático de las citas junto con el registro de jornada integrado elimina varias horas semanales de transcripción y comprobación manual por especialista. Los administradores ven cuellos de botella y excesos de cupo al instante mediante indicadores visuales —anillos de horas que se llenan en lugar de barras que se desbordan— y las solicitudes de vacaciones se validan con una vista previa en vivo de los días laborables consumidos, reduciendo los errores de planificación. La combinación de validación en tiempo de ejecución con Zod, almacenamiento de tokens con hash, acceso restringido a S3 (los enlaces de descarga caducan tras una hora) y un registro de auditoría completo en las ediciones retroactivas de fichajes garantiza una alta seguridad de datos y trazabilidad para la entidad.
Conclusiones clave
El ecosistema nativo de Node convenció: los package.json#imports nativos para los alias de rutas y las funciones de Node 22 (--watch, --env-file) mejoraron la experiencia de desarrollo y redujeron dependencias. Un pequeño fetch wrapper propio que ante un 401 refresca el token de forma transparente y reintenta la petición resultó más mantenible que Axios y mantuvo el bundle pequeño. Para cargas de casos mucho mayores, el siguiente paso sería llevar las actuales agregaciones de MongoDB basadas en tiempo hacia una arquitectura orientada a eventos (por ejemplo, con Change Streams) para calcular las métricas de horas extra y de carga de forma asíncrona en segundo plano.