fbpx

Por qué construimos un sistema de cotización en PHP + Supabase en vez de usar un CRM SaaS: el caso de una agencia de turismo mayorista

Cuando Nómades Chile llegó con el problema, la conversación empezó como suele empezar: «necesitamos ordenar las cotizaciones». Lo que parecía un problema de herramienta resultó ser un problema de lógica de negocio que ninguna herramienta del mercado resuelve bien.

Este artículo documenta qué construimos, por qué lo construimos así y qué aprendimos en el proceso.

El problema que ningún SaaS resolvía

Nómades Chile es una agencia de turismo mayorista. No vende directamente al viajero final. Vende a agencias de viaje minoristas, que a su vez venden a sus propios clientes.

Eso crea una cadena de actores que una cotización debe manejar simultáneamente: la agencia minorista, el vendedor dentro de esa agencia, el proveedor del servicio (hotel, traslado, excursión), el viajero final y el propio equipo interno de Nómades.

Una cotización no es un documento. Es un objeto vivo con múltiples capas de información que no pueden mezclarse entre sí.

El equipo llevaba años trabajando con una combinación de Excel, correos y un CRM genérico que no entendía esta estructura. El problema concreto era uno: los márgenes comerciales vivían en las mismas planillas que los datos que se compartían con clientes. Cada vez que un agente mandaba una cotización al exterior, tenía que acordarse de borrar las columnas de margen antes de exportar. El día que alguien olvidó, se supo cuánto ganaba Nómades en ese viaje.

Por qué descartamos las alternativas SaaS

Evaluamos tres categorías de herramientas antes de decidir desarrollar.

CRMs genéricos (HubSpot, Pipedrive, Monday): Están diseñados para pipelines de ventas lineales. Un lead entra, avanza por etapas y cierra. El problema de Nómades es que una cotización tiene líneas de servicio con costos netos, márgenes por línea, tipos de cambio variables, comisiones por agencia y estados independientes por proveedor. Eso no cabe en un pipeline de HubSpot sin hacer malabares con campos personalizados que nadie va a mantener.

Software de turismo especializado: Existen plataformas para agencias de viaje, pero están pensadas para el mercado europeo o norteamericano. Los flujos de trabajo, la lógica de comisiones y la estructura de proveedores no coinciden con cómo opera el mercado chileno. El soporte en español es deficiente y los costos en USD para una empresa que factura en CLP crean una fricción permanente.

Notion o Airtable a medida: Llegamos a armar una demo en Airtable. Funcionaba para datos simples, pero la separación de información entre lo que ve el equipo interno y lo que ve el cliente final requería permisos tan granulares que el mantenimiento era inviable. Y el problema del margen visible seguía sin solución real.

La conclusión fue que el negocio tenía una lógica lo suficientemente específica como para justificar un sistema propio.

Qué construimos: la arquitectura en 19 tablas

El sistema vive en PHP + Supabase (PostgreSQL). PHP maneja la lógica de negocio y el renderizado de vistas. Supabase maneja la base de datos, la autenticación y el almacenamiento de archivos.

El modelo de datos tiene 19 tablas. No es un número arbitrario: cada tabla representa una entidad real del negocio que necesita vida propia en la base de datos.

Las tablas centrales del flujo operativo son estas:

agencias y vendedores — el directorio de clientes mayoristas. Una agencia puede tener múltiples vendedores activos. Las comisiones y condiciones comerciales se definen a nivel de agencia.

leads y lead_gestiones — el pipeline de entrada. Los leads llegan desde un formulario en el sitio de Nómades vía webhook de Make, se insertan directamente en Supabase y aparecen en el CRM interno sin intervención manual.

cotizaciones — el eje del modelo. Cada cotización tiene estado, paridad de moneda, tipo de cambio, comisión aplicada y referencias a la agencia y al vendedor responsable. Los márgenes comerciales viven aquí, en columnas que solo el equipo interno puede leer.

servicios — las líneas de cada cotización. Hotel, traslados, excursiones, seguros. Cada servicio tiene costo neto (lo que paga Nómades al proveedor) y precio de venta (lo que cobra a la agencia). El margen por línea se calcula en tiempo real pero nunca sale de este contexto.

proveedores — el catálogo de servicios disponibles para armar cotizaciones. Hoteles, operadores locales, compañías de traslados.

files — el nivel superior del viaje confirmado. Cuando una cotización se acepta, se convierte en un file operativo con toda la documentación asociada.

liquidaciones y liquidacion_servicios — el cierre financiero. Qué se le debe a cada proveedor, qué pagó el cliente, qué margen final quedó.

tipos_de_cambio — tabla de referencia que almacena paridades históricas. Indispensable porque una cotización hecha en enero con un tipo de cambio determinado no puede recalcularse con el TC de marzo cuando llega el pago.

El problema del margen: cómo lo resolvimos en la base de datos

La separación de información entre lo que ve el equipo y lo que ve el cliente no es un problema de interfaz. Es un problema de arquitectura de datos.

La solución está en dos capas.

Capa 1: Row Level Security de Supabase. Cada tabla tiene políticas RLS que determinan qué puede leer cada rol. El rol agente y el rol admin pueden leer las columnas de costo neto y margen. El rol cliente no tiene acceso a esas tablas bajo ninguna circunstancia. No es que la interfaz del cliente oculte los márgenes: es que la base de datos no se los entrega, aunque alguien intente consultarlos directamente desde el navegador.

Capa 2: dos portales, un mismo sistema. El portal interno es el sistema operativo de Nómades: leads, CRM, cotizador, wiki, gestión de proveedores. El portal cliente es una vista de solo lectura del viaje comprado: itinerario día a día, vouchers, póliza de seguro, contactos de emergencia, documentación. El cliente entra con magic link a su email, ve solo su viaje, y no hay forma técnica de que llegue al portal interno porque el JWT que recibe al autenticarse solo tiene permisos de lectura sobre las tablas de su viaje específico.

Esto resuelve el problema original de forma estructural. Ya no depende de que un agente se acuerde de borrar columnas antes de exportar. La información sensible nunca está disponible para quien no debe verla.

Lo que aprendimos en el proceso

El modelo de datos es el entregable más importante. Antes de escribir una línea de PHP, pasamos varias sesiones definiendo y validando el schema. Cada tabla, cada columna, cada relación. Ese trabajo previo evitó retrabajo costoso más adelante. Los cambios de modelo de datos en un sistema en producción son caros. Los cambios de interfaz son baratos.

El tipo de cambio histórico no es un detalle menor. Al principio pensamos en calcular los montos siempre en tiempo real. El problema aparece cuando el cliente paga meses después de la cotización y el TC cambió significativamente. Guardar el TC al momento de cada transacción es una decisión de negocio disfrazada de decisión técnica.

PHP + Supabase no es una elección glamorosa, pero es una elección correcta. Para un sistema interno B2B en Chile, lo que importa es que funcione, que sea mantenible por una persona y que el hosting tenga sentido en costos. PHP renderiza las vistas en el servidor, lo que simplifica la lógica de autenticación y permisos. Supabase provee PostgreSQL con RLS, autenticación y storage sin operar infraestructura propia. El equipo de Nómades accede desde cualquier dispositivo con un browser. No hace falta más.

Para quién tiene sentido este tipo de desarrollo

No todos los problemas justifican un sistema a medida. Este caso tenía tres características que lo hacían candidato claro:

  1. Información con diferentes niveles de confidencialidad que deben separarse de forma estructural, no visual.
  2. Lógica de negocio específica que los SaaS del mercado no modelan (en este caso, la cadena mayorista-minorista con comisiones variables y tipos de cambio históricos).
  3. Flujo de trabajo ya establecido que el equipo conoce bien y que un sistema externo obligaría a abandonar o forzar.

Si tu empresa tiene un proceso que funciona, pero que vive en Excel porque ninguna herramienta del mercado lo entiende, ese es el problema que resolvemos.

Siete y Media es una agencia chilena de marketing digital y desarrollo web B2B. Construimos sistemas internos en PHP + Supabase para empresas que necesitan soluciones que los SaaS del mercado no cubren.

Artículos más recientes

Categorías

Contáctanos

Redes Sociales