Contexto
Seprinsa es un sistema privado (sin URL pública) para una empresa de seguridad privada que necesitaba centralizar la gestión de su personal operativo: guardias, supervisores y coordinadores. El objetivo era cubrir el ciclo completo de RR.HH. operativo —alta de personal, control de asistencia, evaluación de competencia laboral, cumplimiento documental y supervisión de servicios en sitio— en una sola plataforma.
El proyecto tiene dos generaciones. La v1 (Serpinsa-Sistema) fue el sistema original que validó el dominio y las funcionalidades. La v2 (seprinsav2/api + seprinsav2/dashboard) es una reescritura completa que separó el backend del frontend y añadió capacidades de tiempo real y biometría.
El reto
La seguridad privada tiene reglas duras: turnos que cruzan medianoche, guardias que deben fichar dentro de una zona física concreta, documentación legal que vence cada mes (IMSS, Infonavit, SAT, nómina, REPSE) y evaluaciones de competencia con metodología propia. Modelar todo esto con la fidelidad que exige el negocio —y hacerlo usable tanto en un escritorio de coordinación como en el móvil de un guardia en campo— fue el verdadero reto.
A esto se sumó la necesidad de roles diferenciados: cada perfil ve una aplicación distinta, con permisos jerárquicos estrictos sobre quién puede crear, evaluar o supervisar a quién.
Arquitectura
La v2 separa responsabilidades en dos repositorios:
api— servidor Express 5 sobre MongoDB (Mongoose). Expone una API REST organizada por rol (/api/admin,/api/coordinator,/api/supervisor,/api/guard,/api/client) más módulos transversales de evaluaciones, IA y configuración. La autenticación es JWT (access + refresh) con bcrypt, bloqueo por intentos fallidos y soporte de PIN. Los archivos se guardan en Cloudflare R2 (compatible S3) y la cabecera se asegura con Helmet.dashboard— aplicación Next.js 16 (App Router, React 19) con un árbol de rutas por rol. Usa MUI y shadcn/ui sobre Tailwind v4, ApexCharts para métricas, Framer Motion para transiciones y Google Maps para visualizar sitios y zonas.
La pieza más interesante es el canal de tiempo real: la API levanta un servidor Socket.IO autenticado por JWT donde los guardias emiten location:ping con coordenadas y telemetría del dispositivo (batería, señal, tipo de red), que se persisten y se reemiten a una sala locations para que supervisión vea posiciones en vivo. La lógica de geofencing (distancia haversine, contención en círculos y polígonos) vive en lib/geo.ts y se espeja en el dashboard para validar igual en cliente y servidor.
De la v1 a la v2
La v1 era un monorepo pnpm con tres paquetes: un servidor Express + tRPC v11, un frontend Astro 5 SSR con islas de React 19, y un paquete shared de esquemas Zod consumidos por ambos lados. Un solo proceso Node servía tanto la API como el frontend ya compilado. Era una arquitectura elegante y type-safe de extremo a extremo, con vistas de equipo, asistencia, bitácora, evaluación de competencia y hasta un asistente conversacional flotante (con voz) que navegaba y rellenaba formularios.
La v2 rompió ese monolito en API REST + dashboard independientes. ¿Por qué? La separación permite desplegar y escalar cada parte por su cuenta, abre la puerta a clientes móviles que consumen la misma API, y simplifica el modelo mental por rol al pasar de un único árbol Astro a aplicaciones Next.js claramente segmentadas. Además, la v2 incorpora lo que la v1 no tenía: ubicación GPS en tiempo real por WebSocket, verificación biométrica facial (face-api.js + descriptores guardados por usuario), rondas con check-in, botón de pánico/SOS y un módulo de cumplimiento documental mensual por oficina.
En resumen: la v1 demostró el dominio con un stack cohesionado; la v2 lo industrializó con una arquitectura desacoplada y capacidades operativas en campo.
Funcionalidades clave
- Gestión de personal (staff): alta, edición, expediente de información extendida, reseteo de contraseña y registro/baja de rostro biométrico.
- Asistencia con geofencing: clock-in / clock-out validado contra zonas (círculo o polígono) del sitio, con manejo correcto de turnos nocturnos que cruzan medianoche.
- Monitoreo en tiempo real: mapa de posiciones de guardias vía Socket.IO, con telemetría del dispositivo y estado en línea/offline.
- Evaluación de competencia (GCP): plantillas configurables con factores, pesos que suman 100% y umbrales de “Grado de Competencia al Puesto” (no apto / a capacitar / competente), por rol y frecuencia.
- Asistente IA (Guard IA): ayuda a crear y editar plantillas de evaluación mediante herramientas (
patch_template,edit_template), y extracción de datos de documentos con visión por IA. - Cumplimiento documental: carga y descarga de documentos legales (IMSS, Infonavit, SAT, nómina, REPSE) por oficina, mes y año, con calendario y resumen.
- Clientes, sitios y zonas: jerarquía cliente → sitio → zona geográfica, con tipos de servicio.
- Portales por rol: paneles dedicados para guardia (turnos, bitácora, incidentes, rondas, SOS, post-órdenes), supervisor, coordinador, admin y cliente (reportes, solicitudes, facturación).
Decisiones técnicas y retos
- Permisos jerárquicos: cinco roles (
root,admin,coordinator,supervisor,guard) con conjuntos derivados (ADMIN_ROLES,COORDINATOR_ROLES…) aplicados como middleware en cada ruta, evitando comprobaciones ad-hoc. - Geofencing compartido: misma matemática en API y dashboard para que la validación nunca difiera entre cliente y servidor.
- Turnos que cruzan medianoche: la búsqueda de turno abierto revisa las claves de día de hoy y ayer (zona horaria CDMX) para no “perder” un fichaje nocturno.
- Seguridad por capas: JWT con refresh, bloqueo por intentos, PIN alterno, claves de terceros cifradas en base de datos y secretos servidos vía un modelo dedicado.
- IA con costo controlado: integración con DeepSeek para el asistente y OpenAI Vision para extracción documental, con registro de uso (
AIUsage) y consulta de saldo.
Resultado
Seprinsa pasó de un prototipo monolítico type-safe (v1) a una plataforma operativa desacoplada (v2) capaz de gestionar el ciclo completo del personal de seguridad: desde el alta y la evaluación de competencia, hasta el control de asistencia geolocalizado y el monitoreo en vivo de guardias en campo. La arquitectura API + dashboard por rol deja el sistema preparado para crecer hacia nuevos clientes y dispositivos sin tocar el núcleo del negocio.