Skip to content
Vertical AI

inite.rent: cómo migramos un CRM de 318 000 líneas en 4 semanas

Migramos un CRM de alquiler de coches con 318 000 líneas y operadores en vivo a una plataforma compartida multi-tenant en 4 semanas. Qué se compartió y qué no.


Mikhail Savchenko·1 de junio de 2026·9 min de lectura
Vertical SaaSInite EcosystemCase StudyMonorepoMulti-Tenant

De qué va este case

Estamos construyendo una familia de productos SaaS que comparten la mayor parte de sus tripas. Login, billing, mensajería con clientes en canales, audit log, internacionalización, runner de asistente IA, primitivas de seguridad, rate limiting - todo eso es genérico. Lo escribimos una vez como un conjunto de paquetes compartidos y lo reusamos entre productos. Cada producto vertical (un CRM de alquiler de coches, un CRM inmobiliario, un backend de e-commerce, un sistema de ticketing de eventos, una app de operaciones de restaurante, una plataforma de reservas de cancha de club deportivo, y así sucesivamente) solo escribe la parte que es genuinamente específica de su industria. La apuesta es que la mayor parte de un producto SaaS es sustrato que se puede compartir, y una capa domain-específica pequeña pero real es lo que diferencia una vertical de otra.

Este case va de la primera vez que probamos eso con un codebase real. Cogimos nuestro CRM de alquiler de coches en producción - 318 000 líneas de TypeScript, cuatro años de lógica de negocio acumulada, operadores en vivo llevando negocios reales de alquiler en él - y lo movimos a la plataforma compartida en cuatro semanas calendario. Los operadores siguieron usando el app todo el tiempo. Para el final de la semana 3 ya corrían sus reservas diarias reales en la versión reconstruida.

El punto de escribir esto no es el trabajo de ingeniería en sí. El punto es la respuesta a una pregunta real de negocio: cuando intentas compartir código entre productos muy distintos, cuánto ahorras de verdad, y dónde se rompe el compartir?

Cómo fue la migración de verdad

Antes de la migración: un CRM de alquiler standalone. Años de código, su propio sistema de login, su propio wrapper de billing, su propia integración de mensajería con WhatsApp y Telegram, su propio audit log, su propio rate limiter. Todo escrito específicamente para el producto de alquiler, nada reusable.

Después de la migración: las mismas 318 000 líneas de lógica de negocio específica de alquiler - vehículos, reservas, tarifas, inspecciones, multas, fidelidad, reportes para co-inversores de flota - ahora se sientan sobre la plataforma compartida. El login, billing, mensajería, audit log, rate limiter, internacionalización, asistente IA - todo eso corre en paquetes compartidos que escribimos una vez y reusamos entre productos.

Medimos la frontera con precisión. De las 1 872 líneas de schema de base de datos, cerca de 220 líneas (12%) son el sustrato multi-tenant genérico - las tablas de usuario, empresa, role, clave de API; el inbox de mensajería con clientes; el audit log. Cerca de 1 650 líneas (88%) son el dominio genuinamente específico de alquiler - 67 tablas distintas para vehículos, reservas, tarifas, inspecciones y el resto.

Esa proporción 12-vs-88 es la respuesta a la pregunta de negocio. El 12% resulta ser suficiente boilerplate como para que compartir merezca la pena - porque cada uno de nuestros 15 productos verticales planificados habría escrito su propia versión de ese 12% en caso contrario. Escribir una vez y reusar entre 15 productos es la matemática que justifica la inversión en plataforma compartida. El 88% es la parte que de verdad difiere entre alquileres e inmobiliaria y restaurantes, y tratar de compartirla habría sido un error.

Cuatro semanas, semana a semana

SemanaLo que se construyó
1Fundación. El proyecto de alquiler entró al workspace compartido. Las cinco tablas multi-tenant obligatorias de la base alineadas al paquete de login compartido. El login mismo recableado por el paquete compartido. Al final de semana, el validador confirmó que la capa de tenancy casaba con la especificación de la plataforma.
2Servicios compartidos. Mensajería con clientes vía web, WhatsApp y Telegram corriendo por el paquete compartido de inbox. Runner del asistente IA reemplazando al wrapper LLM local. Capa de API compartida reemplazando al rate limiter y error reporter locales. Conversaciones con clientes fluyendo end-to-end por la plataforma al final de semana.
3Superficies de operador. Las 34 rutas multi-tenant estabilizadas. Preset de storefront, superficie AEO para visibilidad en búsqueda IA, dashboard de KPI. Operadores usando el app reconstruido para reservas diarias reales desde el miércoles.
4Hardening. Payment adapters integrados. La superficie de API para agentes IA externos (ChatGPT, Claude, personalizados) live para operaciones de alquiler. Datos personales cifrados en reposo. Audit log totalmente cableado.

El cuello de botella en las cuatro semanas no fue el trabajo de ingeniería. Fue que los datos de producción de alquiler seguían contradiciendo nuestras suposiciones sobre cómo la plataforma compartida debía estar especificada. Tres veces en la semana 2 tuvimos que elegir: reescribir el modelo de datos de alquiler para casar con la especificación de la plataforma, o reescribir la especificación de la plataforma para casar con los datos de alquiler. Cada vez reescribimos la especificación. La razón es de principios - si la especificación de la plataforma no sobrevive al contacto con un producto SaaS real, de cuatro años, en producción, entonces la especificación es lo que está mal. El codebase de alquiler es la referencia empírica. Una plataforma que no lo carga limpiamente aún no es una plataforma.

Lo que aprendimos sobre la plataforma

Tres cosas cambiaron por esta migración. Una de ellas resultó la decisión arquitectural más importante de toda la plataforma.

El problema de la franquicia - y la quinta tabla multi-tenant.

Habíamos especificado cuatro tablas multi-tenant obligatorias: usuarios, empresas, roles que los conectan, claves de API. Pensábamos que los permisos podían derivarse solo del mapping de role. El codebase de alquiler tenía un patrón de franquicia que rompía esa suposición: un Manager específico en una sucursal específica necesita acceso a reportes de inversores. La role Manager normalmente no tiene. La tabla estándar de roles no podía expresarlo.

Añadimos una quinta tabla obligatoria para overrides de permiso per-company. Cada producto vertical conforming ahora la hereda. El gatillo fue específico de alquiler; la solución es genérica.

Mensajería con clientes - el modelo más rico gana.

Nuestro paquete compartido de mensajería empezó con un modelo más simple que algunas de nuestras otras verticales piloto usaban. Los alquileres necesitaban semántica más rica: varios agentes de support trabajando un canal a la vez, con assignment y handoff apropiados. Mantuvimos el modelo más rico. Las otras piloto migrarán a él en su próximo ciclo. El principio: el paquete compartido tiene que ser el superset estricto de lo que sus consumidores necesitan. Si el piloto de alquiler necesita una feature, el paquete compartido la gana, y cada otra piloto se beneficia.

El accidente valioso - hacer que los agentes IA sean seguros de usar.

Nuestra especificación de plataforma tiene una sección que llamamos 'obligations' - invariantes de negocio como 'sin entrega de vehículo hasta que el contrato esté firmado y el depósito liquidado' o 'sin liberación de depósito hasta que la inspección post-alquiler esté registrada'. Originalmente tratábamos eso como documentación. El runtime no la forzaba; lo debía hacer el código de la aplicación.

Durante la semana 4 de la migración, cableamos esas obligations directamente en la capa de API que llaman los agentes IA externos. El resultado: cuando ChatGPT o Claude llama a nuestra API crear reserva en nombre de un cliente, la plataforma automáticamente se niega a dejar al agente saltarse el contrato o el depósito. El agente ni siquiera necesita saber que la regla existía; el runtime devuelve un error estructurado apuntando exactamente qué invariante de negocio se violó.

Esta es la parte del trabajo que, en retrospectiva, más importó. Dejar que un agente IA externo lleve tu API de reservas se supone que es la parte que da miedo del SaaS agéntico - el agente va a meter la pata con las reglas, saltarse el depósito, entregar llaves sin contrato, dejarte con la exposición legal. Nosotros no lo permitimos. Las reglas se fuerzan una capa por debajo del agente, en código que el agente no puede saltarse. Cada vertical que entreguemos a partir de ahora gana esa misma capa de seguridad gratis. No lo planificamos así; la migración de alquiler nos forzó.

Dónde encaja esto en el plan más amplio

inite.rent es uno de los 15 productos SaaS verticales de la familia Inite. Otras dos migraciones están corriendo en paralelo ahora mismo (inmobiliaria y e-commerce), y otras cuatro están en la cola (ticketing de eventos, restaurantes, viajes, clubes deportivos). Cada una parte de un codebase legacy diferente pero sigue el mismo patrón de migración que el case de alquiler estableció. La forma estructural de esa plataforma compartida está en constitución vs runtime y la tesis comercial en un motor, muchas pieles.

Este case es también un ejemplo trabajado de nuestra metodología de transformación en 6 etapas aplicada a nuestro propio trabajo de ingeniería. Break audita el código legacy. Hold estabiliza el schema para que la migración tenga inputs consistentes. Track instrumenta los call patterns para que el comportamiento de la plataforma compartida pueda compararse al legacy. Cut elimina el código horizontal duplicado localmente que la plataforma compartida ahora provee. Cast entrega la reconstrucción a los operadores usándola a diario. Form son los tres meses de ajuste de fronteras después que produjeron la forma de plataforma que tenemos hoy.

La metodología funciona igual en el trabajo de ingeniería que en engagements de automatización B2B con clientes pagando. Eso en sí es una prueba útil. La metodología no es solo un documento de ventas; la corremos en nosotros mismos.

En una frase

La reconstrucción del CRM de alquiler de coches de 318 000 líneas probó que nuestra plataforma multi-tenant compartida puede cargar un producto SaaS real, de cuatro años, con carga de producción; la migración calibró qué partes de la plataforma acertamos, cuáles erramos, y produjo una capa de seguridad accidental para llamadas de API agénticas que ahora esperamos sea la pieza individual más valiosa de la plataforma en los próximos dos años.

Los alquileres son reales. Las 318 000 líneas son reales. La migración es la referencia para lo que viene después.

Preguntas frecuentes
  • 01¿En qué se diferencia esto de un pnpm workspace o monorepo Nx normal?+

    Un workspace te da compartir código. Necesitábamos un contrato encima del compartir código. Los paquetes compartidos declaran qué tiene que implementar cada vertical consumidora (cinco tablas de tenancy, el modelo de inbox, la forma del wrapper de API). Un validador corre en CI y rompe el build si una vertical se desvía del contrato. Sin eso, una familia de 15 productos forkea silenciosamente los paquetes compartidos en seis meses, y acabas con 15 cargas de mantenimiento en lugar de una. El contrato es lo que detiene la deriva.

  • 02¿Qué pasa cuando una vertical necesita algo que la plataforma compartida aún no tiene?+

    Dos caminos. Si la necesidad es claramente genérica (varias verticales la querrían), entra a la plataforma compartida en el siguiente release y la vertical espera. Si la necesidad es genuinamente específica de la industria, se queda en el código de esa vertical. La decisión se toma contra la spec compartida, no por quien grita más fuerte. El propio piloto de alquiler produjo tres añadidos a la plataforma compartida; verticales futuras producirán otros. La plataforma crece por demanda del uso en producción, no por especulación.

  • 03¿Cómo manejan breaking changes en la plataforma compartida sin romper 15 productos?+

    Versionado semántico en cada paquete compartido, más un validador de contrato que compara la versión de dependencia declarada por cada vertical contra la que de verdad usa. Los breaking changes salen en una versión mayor que requiere migración explícita; las verticales en la mayor antigua siguen funcionando hasta migrar. El validador atrapa la deriva en CI. La parte más difícil no es el tooling - es la disciplina para rechazar parches puntuales que ayudarían a una vertical pero distorsionarían el contrato para las otras 14.

  • 04¿Por qué no usar Stripe, Auth0, Twilio para el sustrato en lugar de construirlo?+

    Usamos proveedores externos donde son claramente los mejores - Stripe para procesamiento de tarjeta, Twilio para SMS, LLMs de terceros para el runner del asistente. La plataforma compartida es la capa encima de ellos: el modelo de datos multi-tenant que mapea un cliente Stripe a una de nuestras empresas, el grafo de permisos que decide quién ve qué inbox, el audit log que sobrevive entre proveedores. SaaS externo resuelve problemas de un solo vendor; la plataforma resuelve las preocupaciones transversales que ningún vendor único posee. Ambas capas son reales y ambas pertenecen.

  • 05¿Pueden otras empresas usar esta plataforma compartida o es solo Inite?+

    Solo Inite por ahora. La plataforma está calibrada contra la forma específica de los productos SaaS que construimos - multi-tenant B2B con integración de asistente IA, superficies de API agénticas, nuestro modelo específico de reglas de seguridad. Una plataforma SaaS compartida de propósito general necesitaría tradeoffs distintos (contratos más sueltos, más superficie de configuración, ciclos de release más lentos) y no es lo que estamos construyendo. El artefacto reusable interesante de este trabajo no es el código sino la metodología - el protocolo de transformación en 6 etapas y el patrón contract-then-share. Ambos están documentados y son aplicables fuera de la familia Inite.

Seguir leyendo