Cotizador de Aberturas

Un cotizador de aberturas que da precios creíbles, no números inventados.

RolDesarrollador full-stack único: producto, motor de cálculo, backend, base de datos y seguridadClienteGrupo CPS, industria de aberturas (aluminio + vidrio)Año2026
Hablemos del proyectoEl código es privado por tratarse de un proyecto de cliente.
Next.js 16ReactTypeScriptTailwindCSS 4Three.jsSupabasePostgreSQLRLSJest
2,44× → ~1%

Cuánto bajó el error al calcular el aluminio, comparado con el sistema de fábrica. No lo arreglé con un número de ajuste a dedo, sino entendiendo de dónde venía la diferencia.

Una web donde el cliente arma su pedido de ventanas de aluminio y vidrio y recibe un precio estimado. El desafío no era la pantalla, sino calcular bien el precio: lo que parecía una fórmula simple en realidad dependía de cuánto aluminio y vidrio usa cada ventana de verdad. Para acertar, estudié las 2.641 recetas reales del software de fábrica y saqué de ahí los números que mueven el costo.

Grupo CPS fabrica aberturas de aluminio y vidrio. Cotizar a mano cada pedido es lento y depende de personal técnico. Querían una web sencilla donde el cliente se registre, arme un carrito con sus ventanas, envíe el pedido y le hagan seguimiento.

El problema estaba en la palabra "sencilla". El precio de una ventana no sale de multiplicar el área por un precio por metro cuadrado: depende de cuánto perfil de aluminio lleva cada tipo de ventana (el marco, la hoja que se abre, el contravidrio que sujeta el vidrio, los travesaños) y de la medida real del vidrio, además de herrajes, mano de obra, margen e IVA.

La empresa ya calculaba todo esto con precisión en su software de fábrica, WinMaker, que guarda una "receta" por cada tipo de ventana: 2.641 archivos en un formato cerrado, imposible de usar directo en una web. Mi primer cálculo simple se quedaba muy corto: contaba 2,44 veces menos aluminio del que la ventana usa en realidad.

Sacar de las recetas solo los números que mueven el precio, sin copiar todo el software de fábrica.

Tenía dos caminos malos: una fórmula simple (rápida pero falsa) o reconstruir entero el software de fábrica (preciso pero inviable). Elegí el punto medio: leer de las recetas únicamente las medidas que afectan el costo.

El error no era un número mal puesto, era de fondo. La fórmula simple contaba solo el contorno del marco. Pero una ventana real lleva mucho más aluminio: el marco, la hoja que se abre, el contravidrio que sujeta el vidrio y los travesaños. Y el vidrio se mide por el hueco real que queda, no por el tamaño total de la ventana.

Así que armé un programa que lee esas 2.641 recetas y extrae, para cada tipo de ventana, las medidas exactas que la fábrica ya usa. Esas medidas alimentan el cálculo de precio que ya existía: cambia cuánto material se cuenta, no la forma de poner el precio.

Fórmula simple calculaba4,32 m
Aluminio que usa de verdad~7,7 m

Ejemplo concreto: para una ventana fija de 1×1 m, la fórmula simple calculaba 4,32 m de perfil de aluminio. En la realidad usa unos 7,7 m (el marco más el contravidrio que sostiene el vidrio). Esa diferencia, sumada a cómo se mide el vidrio, explica el 2,44× sin inventar nada.

Una app full-stack con un motor de cálculo en el núcleo.

  1. 01

    Registro e inicio de sesión

    Cada cliente tiene su cuenta propia.

  2. 02

    Armado de la ventana en 3D

    El cliente elige tipo, medidas, línea, vidrio, color y accesorios, y ve la abertura renderizada en 3D, que puede girar para mirarla desde cualquier ángulo.

  3. 03

    Carrito de varias ventanas

    Junta varias aberturas en un mismo pedido y arma su presupuesto como un borrador: suma, saca y ajusta hasta dejarlo como quiere.

  4. 04

    Cotización en PDF

    Con un clic genera un PDF prolijo con todas las ventanas, sus especificaciones y el total, listo para guardar o compartir.

  5. 05

    Pedido que queda congelado

    Al enviarlo, se guardan los precios y nombres de ese momento. Nada se recalcula por detrás después.

  6. 06

    Seguimiento

    En "Mis pedidos" ve el estado de cada uno, y puede compartir un resumen por un link privado.

El cotizador no viene a reemplazar a WinMaker, el sistema con el que la fábrica cotiza desde siempre: es la puerta de entrada para el cliente. Un primer acercamiento intuitivo y atractivo, donde puede armar su abertura, probar combinaciones y sacarse las dudas por su cuenta. Y para Grupo CPS, una forma de recibir cada presupuesto que se pide y darle un seguimiento ordenado. Detrás, el cliente nunca ve costos internos ni margen: todo el cálculo ocurre en el servidor y al navegador solo llega el precio final.

Un panel interno donde los técnicos cargan la realidad de la fábrica.

Recetas técnicas parametrizables

Los técnicos cargan qué lleva cada abertura: perfiles con sus cortes, accesorios, vidrios y límites fabricables. Cada receta elige componentes de catálogos reales: perfiles y tiras de aluminio, herrajes, cámaras de DVH y mano de obra por estación.

Semáforo de costo real

Un "estado de carga" muestra qué le falta a cada receta para cotizar con costo real: rojo si la receta no tiene perfiles cargados o algún perfil está sin costo, amarillo si falta mano de obra, verde cuando el costo está completo. Nada cotiza bien por casualidad.

Resolución con fallback

Si una combinación no tiene receta cargada, el motor no rompe: cotiza por estimación con el modelo genérico y lo marca como tal, así el equipo sabe exactamente qué falta afinar.

Parámetros que gobiernan el motor

Margen, IVA, desperdicios, recargos por color con su código WinMaker, la tasa de cambio USD/UYU que usa el motor y usuarios con roles y descuentos: todo lo que afecta el precio se administra desde el panel, detrás de APIs con control de acceso por rol.

Esto es lo que hace que el sistema viva sin el programador: los dueños de los datos son los técnicos de la fábrica, no el código. La página del cliente es la mitad visible; esta es la mitad que la mantiene honesta.

Una frontera estricta entre lo público y lo privado.

UI

Navegador

Configurador · carrito · mis-pedidos.

API

app/api/*

Frontera HTTP: auth, autorización y DTOs sin datos sensibles.

SRV

src/server/*

Lógica privada: consultas, persistencia, service-role.

CALC

src/lib/cotizador/*

Motor de cálculo puro, sin I/O, 100% testeable.

DOM

src/technical/*

Tipos, normalización, compatibilidades y validaciones.

DB

supabase/schema.sql

PostgreSQL canónico con Row-Level Security.

La parte que calcula medidas está separada de la parte que arma el precio. Por eso traer los números de la fábrica cambió las cantidades de material sin tocar la lógica de precios, y todo el cálculo se puede testear solo, sin base de datos.

Hay datos de clientes y costos internos en juego: la seguridad fue requisito, no agregado.

Ningún dato directo de la base

Todo pasa por el servidor con login. La llave maestra de la base vive solo ahí, nunca llega al navegador del cliente.

Links para compartir imposibles de adivinar

El link de un resumen no es un número seguido (1, 2, 3…) sino un código aleatorio, así nadie puede cambiarlo para espiar pedidos ajenos.

Entradas siempre acotadas

Medidas hasta 6000 mm, cantidades enteras con tope, textos limitados. Nada entra sin control.

Costos internos nunca expuestos

El cliente ve el precio final, nunca el costo, el margen ni el precio por metro cuadrado. Todo el cálculo ocurre en el servidor.

Pedidos congelados y auditables

Cada pedido guarda un snapshot inmutable de precios y nombres, con folio asignado de forma atómica en la base: dos pedidos simultáneos jamás comparten número, y nada cambia después por detrás.

Moneda con red de seguridad

Los costos conviven en dólares y pesos con una convención explícita de conversión. Si la tasa falta, el sistema degrada a un factor neutro definido en vez de romper a mitad del cálculo.

Medir antes de afirmar.

Recetas de fábrica analizadas
2.641
Formato cerrado .PRO descifrado
Parser propio + evaluador AST seguro
Tests automáticos (Jest)
68+
Error de material vs. el sistema de fábrica
2,44× → ~1%
Auditoría propia del código
Hallazgos C1 a C8, catalogados y corregidos
Calidad de código
TypeScript estricto, sin errores de tipo

El "modo sombra": una herramienta que compara, ventana por ventana, lo que calcula mi sistema contra el desglose real de piezas del software de fábrica. Sirve para medir cuánto me desvío antes de dar un precio por bueno. La diferencia entre "creo que está bien" y "lo medí".

El cotizador en acción.

Recorrido por el sistema: del armado de la abertura en 3D al pedido enviado.
Visualización 3D: la ventana cotizada gira para verse desde cualquier ángulo.
PDF generado con la cotización armada
PDF generado automáticamente con la cotización armada, listo para guardar o compartir.
Panel interno de carga técnica del cotizador
El panel interno: recetas técnicas y catálogos de perfiles, tiras, vidrios, herrajes, mano de obra y parámetros que alimentan el motor.
Estado de carga de recetas con semáforo de costo real
El "estado de carga": semáforo por receta que muestra qué falta para cotizar con costo real, y qué tipologías siguen cotizando por estimación.
  • El problema difícil rara vez es el que se ve: la pantalla era lo fácil, el valor estaba en calcular bien y validar los números.
  • No copié las 2.641 recetas a la fuerza: saqué solo lo que mueve el costo y dejé el resto como investigación aparte.
  • Medir antes de afirmar: el "modo sombra" convirtió una corazonada ("el precio no cierra") en un número (2,44×) y después en una validación (~1%).
  • Seguridad y trazabilidad desde el día uno, no como parche.
  • El sistema completo incluye a quien lo mantiene: el panel interno y su semáforo de carga hacen que los técnicos, no el programador, sean los dueños de los datos.

¿Tenés un cálculo o una operación que no cierra con una fórmula simple?

Es el tipo de problema que me gusta. El código de este proyecto es privado, pero podemos hablarlo.