Los números The Numbers

Antes de contar la historia, los datos duros. Porque en ingeniería, medir es lo primero. Before telling the story, the hard data. Because in engineering, measuring comes first.

297 Commits
320K Líneas de códigoLines of code
700+ ArchivosFiles
7.5 MesesMonths
15+ APIs RESTful
30+ Modelos de datosData models
CapaLayer LíneasLines ArchivosFiles
Backend (API)83,245143
Frontend (Web)156,864401
App Móvil (Flutter)Mobile App (Flutter)43,517155
Scripts & Utils24,005
AI Agent8,455
Total~320,000700+

El problema The Problem

Una empresa de transporte con +50 tractores de patio, remolques, operadores y clientes — manejando todo con hojas de Excel, mensajes de WhatsApp y llamadas telefónicas. Las asignaciones de servicio tardaban horas. Nadie sabía dónde estaba cada unidad. Los documentos vencidos se descubrían cuando ya era multa. La facturación era manual. A trucking company with 50+ yard trucks, trailers, operators and clients — managing everything with Excel sheets, WhatsApp messages and phone calls. Service assignments took hours. Nobody knew where each unit was. Expired documents were discovered when they were already fines. Invoicing was manual.

El reto: construir un sistema completo que digitalizara toda la operación — desde la solicitud de servicio hasta la factura electrónica, pasando por tracking GPS en tiempo real, gestión documental y mantenimiento preventivo. The challenge: build a complete system that digitizes the entire operation — from the service request to the electronic invoice, including real-time GPS tracking, document management and preventive maintenance.

El software de logística no perdona errores. Cada minuto que un camión está parado es dinero. Cada documento vencido es una multa. Cada asignación tardía es un cliente perdido. Logistics software doesn't forgive mistakes. Every minute a truck is idle is money. Every expired document is a fine. Every late assignment is a lost client.

El stack The Stack

Node.js TypeScript Express Prisma ORM MySQL 8 React Redux Material-UI Flutter Socket.IO Firebase Docker AWS (EC2 + S3)

La decisión fue clara desde el principio: TypeScript en todo. Backend, frontend y tipos compartidos. Un solo lenguaje para reducir context switching. Prisma como ORM porque las migraciones son declarativas y el type safety es real — si el modelo cambia, el compilador te lo dice antes de que el usuario lo descubra. The decision was clear from the start: TypeScript everywhere. Backend, frontend and shared types. One language to reduce context switching. Prisma as ORM because migrations are declarative and type safety is real — if the model changes, the compiler tells you before the user discovers it.

La arquitectura The Architecture


  ┌─────────────┐   ┌──────────────┐   ┌──────────────────┐
  │  Flutter App │   │  React + MUI │   │  External APIs   │
  │  (Operators) │   │  (Admin/Sup) │   │  (GPS, PAC, S3)  │
  └──────┬──────┘   └──────┬───────┘   └────────┬─────────┘
         │                 │                     │
         └────────┬────────┘                     │
                  ▼                              │
  ┌───────────────────────────────────────────────────────┐
  │              Express.js API (Port 6060)                │
  │  ┌──────────┐ ┌────────────┐ ┌─────────────────────┐  │
  │  │ REST API │ │ Socket.IO  │ │  Background Jobs    │  │
  │  │ 15+ CRUD │ │ Real-time  │ │  Cron / Expiration  │  │
  │  └──────────┘ └────────────┘ └─────────────────────┘  │
  │                                                        │
  │  ┌──────────────────────────────────────────────────┐  │
  │  │  Prisma ORM  →  30+ Models  →  MySQL 8.0        │  │
  │  └──────────────────────────────────────────────────┘  │
  └────────────────────────────────────────────────────────┘
                  │                    │
        ┌────────┘                    └────────┐
        ▼                                      ▼
  ┌──────────┐                          ┌──────────────┐
  │  AWS S3  │                          │  Firebase    │
  │  Docs    │                          │  Push Notif  │
  └──────────┘                          └──────────────┘

Tres capas limpias: Routes → Controllers → Services. Prisma como singleton centralizado. WebSockets para tracking en tiempo real. Firebase para push notifications a la app móvil. S3 para documentos con URLs prefirmadas. Three clean layers: Routes → Controllers → Services. Prisma as a centralized singleton. WebSockets for real-time tracking. Firebase for push notifications to the mobile app. S3 for documents with presigned URLs.

Los módulos The Modules

No fue un MVP bonito. Fue un sistema enterprise completo. Estos son los módulos en producción: It wasn't a pretty MVP. It was a complete enterprise system. These are the production modules:

🚛 Gestión de FlotaFleet Management

Tractores, remolques, dollies. Estados, asignaciones, documentación. Integración GPS dual (Samsara + Teli).Trucks, trailers, dollies. States, assignments, documentation. Dual GPS integration (Samsara + Teli).

👷 OperadoresOperators

Perfiles, documentos (licencias, permisos, médicos), estados de disponibilidad, tracking continuo desde la app.Profiles, documents (licenses, permits, medical), availability states, continuous tracking from the app.

📋 Servicios y ViajesServices & Trips

Solicitudes de servicio, asignación de operadores y unidades, viajes con segmentos y cálculo de distancias en tiempo real.Service requests, operator and unit assignment, trips with segments and real-time distance calculation.

🧾 Facturación CFDI 4.0CFDI 4.0 Invoicing

Facturas electrónicas, Carta Porte 2.0, timbrado con PAC, PDFs, series y folios automáticos.Electronic invoices, Carta Porte 2.0, PAC stamping, PDFs, automatic series and folios.

📄 Gestión DocumentalDocument Management

Documentos de operadores, unidades y empresas en S3. Alertas de vencimiento automáticas (30, 15, 7 días).Operator, vehicle and company documents on S3. Automatic expiration alerts (30, 15, 7 days).

🔧 MantenimientoMaintenance

Preventivo y correctivo. Catálogo de piezas. Control de diesel y gastos operativos por unidad.Preventive and corrective. Parts catalog. Diesel tracking and operative expenses per unit.

💰 CotizacionesQuotations

Manuales y automatizadas con GlobalMap. Enlaces compartibles, PDFs, conversión a servicio.Manual and automated with GlobalMap. Shareable links, PDFs, conversion to service.

📊 Reportes FinancierosFinancial Reports

Estado de cuenta por cliente, reporte de facturación, control de cobranza con días de vencimiento.Account statements per client, billing reports, collections tracking with overdue days.

Las decisiones difíciles The Hard Decisions

Tracking GPS en tiempo real Real-time GPS tracking

Necesitábamos saber la ubicación de cada tractor en tiempo real. No es trivial. Hay dos proveedores GPS (Samsara y Teli), cada uno con su API distinta. Los operadores también reportan ubicación desde la app Flutter cada 30 segundos. We needed to know each truck's location in real time. It's not trivial. There are two GPS providers (Samsara and Teli), each with a different API. Operators also report location from the Flutter app every 30 seconds.

La solución: Socket.IO con múltiples namespaces. Un namespace para tracking de servicios, otro para tracking continuo de operadores. El frontend renderiza todo en un mapa en tiempo real. Cuando un supervisor abre el dashboard, ve cada unidad moviéndose — sin recargar la página. The solution: Socket.IO with multiple namespaces. One namespace for service tracking, another for continuous operator tracking. The frontend renders everything on a real-time map. When a supervisor opens the dashboard, they see each unit moving — without reloading the page.

Gestión inteligente de viajes Smart trip management

Cada solicitud de servicio se convierte en un viaje con segmentos automáticos. El sistema calcula distancias reales entre puntos (Google Distance Matrix), registra tiempos de cada etapa y permite al supervisor asignar operador y unidad considerando disponibilidad, documentos vigentes y tipo de remolque requerido. Each service request becomes a trip with automatic segments. The system calculates real distances between points (Google Distance Matrix), records timing for each stage, and lets the supervisor assign operator and unit based on availability, valid documents, and required trailer type.

El dashboard muestra en tiempo real el estado de cada viaje: pendiente, en progreso, completado. Los eventos se registran con timestamps y coordenadas GPS. Lo que antes era un caos de llamadas ahora es un flujo visual claro. The dashboard shows each trip's status in real time: pending, in progress, completed. Events are logged with timestamps and GPS coordinates. What used to be chaos of phone calls is now a clear visual workflow.

Facturación electrónica CFDI 4.0 + Carta Porte CFDI 4.0 Electronic Invoicing + Carta Porte

Si nunca has implementado facturación electrónica mexicana, imagina esto: un XML con estructura definida por el SAT, que debe firmarse digitalmente, enviarse a un PAC (Proveedor Autorizado de Certificación) para timbrado, y si es transporte necesitas el complemento Carta Porte 2.0 con datos del vehículo, operador, mercancía, origen, destino y permisos. If you've never implemented Mexican electronic invoicing, picture this: an XML with SAT-defined structure, digitally signed, sent to a PAC (Authorized Certification Provider) for stamping, and for transportation you need the Carta Porte 2.0 complement with vehicle, operator, merchandise, origin, destination and permit data.

El servicio de facturación tiene 2,400 líneas. Es el archivo más grande del proyecto. Cada campo tiene reglas del SAT que hay que cumplir al pie de la letra. Un espacio de más en un RFC y el timbrado falla. The invoicing service has 2,400 lines. It's the largest file in the project. Every field has SAT rules that must be followed to the letter. One extra space in an RFC and the stamping fails.

Lección aprendida: la facturación electrónica no es un feature — es un proyecto dentro del proyecto. Empezamos a implementarla pensando que serían 2 semanas. Fueron 6. Cada caso edge del SAT es un bug esperando aparecer. Lesson learned: electronic invoicing isn't a feature — it's a project within the project. We started thinking it would take 2 weeks. It took 6. Every SAT edge case is a bug waiting to appear.

La evolución — 7.5 meses en commits The Evolution — 7.5 Months in Commits

Jul 2025 — El arranqueJul 2025 — The Launch
Primer commit. Setup de Docker, Prisma, Express. Modelos base: usuarios, empresas, tractores. Auth con JWT. 4 commits.First commit. Docker, Prisma, Express setup. Base models: users, companies, trucks. JWT auth. 4 commits.
Ago 2025 — CRUD e infraestructuraAug 2025 — CRUD & Infrastructure
CRUDs completos. Sistema de documentos con S3. Remolques. Ubicaciones. 16 commits.Complete CRUDs. Document system with S3. Trailers. Locations. 16 commits.
Sep 2025 — Frontend toma formaSep 2025 — Frontend Takes Shape
React + MUI. Dashboard principal. Tablas con filtros. Operadores y unidades en el mapa. 31 commits.React + MUI. Main dashboard. Tables with filters. Operators and units on the map. 31 commits.
Oct 2025 — Servicios y viajesOct 2025 — Services & Trips
Sistema de solicitudes. Algoritmo de asignación. Viajes con segmentos automáticos. Socket.IO para tracking. 34 commits.Request system. Assignment algorithm. Trips with automatic segments. Socket.IO for tracking. 34 commits.
Nov 2025 — App móvil + GPSNov 2025 — Mobile App + GPS
Flutter app para operadores. Integración Samsara y Teli. Tracking continuo. Push notifications con Firebase. 40 commits.Flutter app for operators. Samsara and Teli integration. Continuous tracking. Push notifications with Firebase. 40 commits.
Dic 2025 — Mantenimiento + catálogosDec 2025 — Maintenance + Catalogs
Módulo de mantenimiento preventivo/correctivo. Catálogo de piezas. Control de diesel. Reportes de incidentes. 38 commits.Preventive/corrective maintenance module. Parts catalog. Diesel tracking. Incident reports. 38 commits.
Ene 2026 — Facturación electrónicaJan 2026 — Electronic Invoicing
CFDI 4.0 desde cero. Carta Porte 2.0. Integración con PAC. Cotizaciones automatizadas. 54 commits — el mes más intenso.CFDI 4.0 from scratch. Carta Porte 2.0. PAC integration. Automated quotations. 54 commits — the most intense month.
Feb 2026 — Reportes + polishFeb 2026 — Reports + Polish
Estados de cuenta. Reportes de cobranza. Gastos operativos. Edición inline estilo Excel. GDPR/LFPDPPP. 55 commits.Account statements. Collections reports. Operative expenses. Inline Excel-style editing. GDPR/LFPDPPP. 55 commits.
Mar 2026 — Producción 🚀Mar 2026 — Production 🚀
Deploy final. La empresa opera en producción con facturación real. El sistema está vivo.Final deploy. The company operates in production with real invoicing. The system is alive.

Lo que aprendí What I Learned

1. Prisma es brutal para productividad 1. Prisma is brutal for productivity

Con 30+ modelos interrelacionados, tener un ORM que genera tipos TypeScript automáticamente fue la diferencia entre moverme rápido y ahogarme en errores. prisma.$transaction() para operaciones atómicas. include anidados para queries complejas. El schema como fuente de verdad. With 30+ interrelated models, having an ORM that auto-generates TypeScript types was the difference between moving fast and drowning in errors. prisma.$transaction() for atomic operations. Nested include for complex queries. The schema as the source of truth.

2. Socket.IO + React = magia para dashboards de logística 2. Socket.IO + React = magic for logistics dashboards

Ver camiones moviéndose en un mapa en tiempo real es lo que hace que el cliente diga "esto sí funciona". No es técnicamente difícil — es un useEffect que escucha eventos y actualiza el estado. Pero el impacto de negocio es enorme. Watching trucks move on a map in real time is what makes the client say "this actually works." It's not technically hard — it's a useEffect that listens to events and updates state. But the business impact is enormous.

3. Los documentos vencidos son el problema #1 en logística 3. Expired documents are the #1 problem in logistics

Antes de este proyecto no sabía cuántos tipos de documentos necesita un tractor para operar legalmente en México. Licencia federal, verificación vehicular, seguro, tarjeta de circulación, permiso SCT... y cada uno vence. Un cron job que revisa vencimientos y dispara alertas automáticas a 30, 15 y 7 días ahorró miles de pesos en multas. Before this project I didn't know how many document types a truck needs to legally operate in Mexico. Federal license, vehicle inspection, insurance, registration, SCT permit... and each one expires. A cron job that checks expirations and fires automatic alerts at 30, 15 and 7 days saved thousands in fines.

4. AI como copiloto, no como piloto 4. AI as copilot, not pilot

Usé GitHub Copilot y Claude extensivamente durante el desarrollo. Para servicios CRUD repetitivos: increíble. Para lógica de negocio compleja como el algoritmo de asignación o la facturación: necesitas entender cada línea. La IA acelera, pero el criterio de ingeniería no es delegable. I used GitHub Copilot and Claude extensively during development. For repetitive CRUD services: incredible. For complex business logic like the assignment algorithm or invoicing: you need to understand every line. AI accelerates, but engineering judgment isn't delegable.

El dato más honesto: los tests son el punto débil. 763 líneas de tests vs 320K de código. En un proyecto real con un solo desarrollador y deadline agresivo, los tests son lo primero que se sacrifica. No estoy orgulloso, pero es la realidad. The most honest metric: tests are the weak spot. 763 lines of tests vs 320K of code. In a real project with one developer and an aggressive deadline, tests are the first thing sacrificed. I'm not proud, but it's reality.

El servidor The Server

Todo corre en una instancia EC2 m7i-flex.large (2 vCPU, 8 GB RAM). Docker Compose con 4 contenedores: API, Frontend (nginx), MySQL 8.0 y Prisma Studio. Backups automáticos a S3 con cleanup de locales cada 7 días. Everything runs on an EC2 m7i-flex.large instance (2 vCPU, 8 GB RAM). Docker Compose with 4 containers: API, Frontend (nginx), MySQL 8.0 and Prisma Studio. Automatic backups to S3 with local cleanup every 7 days.

Con la carga actual: 3.1 GB de RAM usados, 1.1 GB de swap. Funciona, pero ya estamos cerca del límite. El siguiente paso es migrar a una instancia con 16 GB cuando entren más clientes. With current load: 3.1 GB RAM used, 1.1 GB swap. It works, but we're close to the limit. Next step is migrating to a 16 GB instance when more clients come on board.

Lo que viene What's Next

320,000 líneas de código no te hacen un buen ingeniero. Pero construir algo que funciona en producción, que resuelve problemas reales y que una empresa usa todos los días — eso sí. 320,000 lines of code don't make you a good engineer. But building something that works in production, that solves real problems and that a company uses every day — that does.