PROYECTO_01

Skilled Proyectos Industriales

Skilled ERP

ERP de nóminas, empleados, inventario y herramientas: API JSON en Flask con 216 endpoints y SPA en React/Vite, con notificaciones en tiempo real por Socket.IO.

TIPO
Full Stack · Seguridad
ESTADO
EN PRODUCCIÓN
CAPTURAS
5
  • React 18
  • Vite
  • TailwindCSS
  • Python 3.12
  • Flask 3
  • SQLAlchemy 2
  • PostgreSQL
  • Redis
  • Socket.IO
  • Docker
  • Nginx
  • Cloudflare R2

CONTEXTO

Sistema de gestión interna que concentra nóminas, expedientes de empleados, inventario y herramientas en una sola plataforma, con control estricto de qué información puede ver cada uno de los 6 roles.

QUÉ CUBRE

  • Empleados: alta, baja y edición, con campos laborales, personales, médicos y financieros filtrados por whitelist según el rol.
  • Nómina: prenómina, descuentos, depósitos extra, préstamos con abonos y ajustes por periodo.
  • Horas: reportes semanales, registros diarios, ausencias, saldo de vacaciones y captura por RFID/QR.
  • Inventario: productos, almacenes y estantes con QR, solicitudes con flujo de aprobación y entrega parcial, tomas físicas con ajuste automático y órdenes de compra.
  • Herramientas: catálogo y unidades físicas rastreables por serie/QR, con asignaciones, mantenimientos, incidencias y baja autorizada.
  • Reportes en PDF y Excel (recibos, constancias, totales por proyecto) saneados contra inyección de fórmulas.

ARQUITECTURA

  • API JSON en Flask 3 + SQLAlchemy 2 con 18 blueprints y 216 endpoints documentados; migraciones con Alembic.
  • Cadena de producción: Cloudflare Tunnel → Nginx → Gunicorn → Flask. El origen no publica ningún puerto hacia afuera.
  • 4 workers gevent con WebSocket real; todo el estado compartido (rate-limit, lockout, anti-replay, eventos) vive en Redis.
  • Archivos en Cloudflare R2: bucket público para el catálogo y privado para documentos, con disco como respaldo.
  • Docker Compose para desarrollo: api, PostgreSQL, Redis y ClamAV, cada uno con su volumen.

SEGURIDAD Y CONCURRENCIA

  • Login en dos pasos: la contraseña devuelve un token de un solo uso y solo con él se pide el código TOTP; el secreto 2FA se guarda cifrado.
  • JWT con refresh en cookie httpOnly y renovación automática; varias peticiones en vuelo comparten un solo refresh.
  • Las imágenes externas se validan contra SSRF y por magic bytes, se reescriben a WebP y se escanean con ClamAV antes de guardarse.
  • Los movimientos de inventario toman la fila con SELECT … FOR UPDATE, de modo que dos operaciones sobre el mismo stock no se pisan.
  • Rate-limit y bloqueo escalado de cuenta con Flask-Limiter sobre Redis; cabeceras de seguridad con Flask-Talisman.

OBSERVABILIDAD

  • Cada respuesta pasa por un after_request que suma contadores en Redis y guarda el detalle de las peticiones lentas y fallidas.
  • Panel de sistemas con p50/p95/p99, tráfico, sesiones activas, bloqueos de cuenta, eventos de seguridad y auditoría de archivos huérfanos en R2.
  • 36 módulos de pruebas con pytest.

CAPTURAS

Diagrama del camino de una petición: navegador, Cloudflare, túnel, Nginx, Gunicorn y base de datos
Camino de una petición
Diagrama de los cuatro workers gevent compartiendo estado en Redis tras un túnel de Cloudflare
Workers y túnel saliente
Diagrama del pipeline de imágenes y del bloqueo de fila en PostgreSQL
Archivos y concurrencia
Diagrama del login en dos pasos con TOTP y del pipeline de métricas
Login 2FA y métricas
Diagrama de la propagación de eventos por Redis a las salas de Socket.IO y la renovación de sesión
Tiempo real y sesión

01 01