PROJECT_01

Skilled Proyectos Industriales

Skilled ERP

ERP for payroll, employees, inventory and tools: a Flask JSON API with 216 endpoints and a React/Vite SPA, with real-time notifications over Socket.IO.

TYPE
Full Stack · Security
STATUS
IN PRODUCTION
SCREENSHOTS
5
  • React 18
  • Vite
  • TailwindCSS
  • Python 3.12
  • Flask 3
  • SQLAlchemy 2
  • PostgreSQL
  • Redis
  • Socket.IO
  • Docker
  • Nginx
  • Cloudflare R2

CONTEXT

Internal management system that brings payroll, employee records, inventory and tools together on a single platform, with strict control over what each of the 6 roles can see.

WHAT IT COVERS

  • Employees: create, edit and deactivate, with employment, personal, medical and financial fields filtered by a per-role whitelist.
  • Payroll: pre-payroll, deductions, extra deposits, loans with repayments and per-period adjustments.
  • Hours: weekly reports, daily records, absences, vacation balance and RFID/QR clock-in.
  • Inventory: products, warehouses and QR-labelled shelves, requests with approval flow and partial delivery, physical counts with automatic adjustment, and purchase orders.
  • Tools: catalogue and physical units traceable by serial/QR, with assignments, maintenance, incidents and authorized write-off.
  • PDF and Excel reports (receipts, certificates, per-project totals) sanitized against formula injection.

ARCHITECTURE

  • JSON API in Flask 3 + SQLAlchemy 2 with 18 blueprints and 216 documented endpoints; migrations with Alembic.
  • Production chain: Cloudflare Tunnel → Nginx → Gunicorn → Flask. The origin publishes no inbound ports.
  • 4 gevent workers with real WebSockets; all shared state (rate limiting, lockout, anti-replay, events) lives in Redis.
  • Files on Cloudflare R2: a public bucket for the catalogue and a private one for documents, with disk as fallback.
  • Docker Compose for development: api, PostgreSQL, Redis and ClamAV, each with its own volume.

SECURITY AND CONCURRENCY

  • Two-step login: the password returns a single-use token, and only with it can the TOTP code be requested; the 2FA secret is stored encrypted.
  • JWT with refresh in an httpOnly cookie and automatic renewal; several in-flight requests share a single refresh.
  • External images are checked against SSRF and by magic bytes, rewritten to WebP and scanned with ClamAV before being stored.
  • Inventory movements lock the row with SELECT … FOR UPDATE, so two operations on the same stock cannot overwrite each other.
  • Rate limiting and escalating account lockout with Flask-Limiter on Redis; security headers with Flask-Talisman.

OBSERVABILITY

  • Every response goes through an after_request hook that increments counters in Redis and stores the detail of slow and failed requests.
  • Systems panel with p50/p95/p99, traffic, active sessions, account lockouts, security events and an audit of orphan files on R2.
  • 36 test modules with pytest.

SCREENSHOTS

Diagram of a request path: browser, Cloudflare, tunnel, Nginx, Gunicorn and database
Path of a request
Diagram of the four gevent workers sharing state in Redis behind a Cloudflare tunnel
Workers and outbound tunnel
Diagram of the image pipeline and the row lock in PostgreSQL
Files and concurrency
Diagram of the two-step TOTP login and the metrics pipeline
2FA login and metrics
Diagram of event propagation through Redis to Socket.IO rooms and session renewal
Real time and session

01 01