case study · Pricing engine · Full-stack
Aluminum Joinery Quoter
An aluminum joinery quoter that gives credible prices, not made-up numbers.
How much the error in calculating the aluminum dropped, compared to the factory system. I did not fix it with a hand-tuned fudge factor, but by understanding where the difference came from.
A web app, and now a mobile app too, where the client builds their order of aluminum-and-glass windows and gets a price. The challenge was not the screen, but getting the price right: what looked like a simple formula actually depended on how much aluminum and glass each window really uses. To get it right, I studied the 2,641 real recipes from the factory software, pulled out the numbers that drive the cost, and then validated it with test orders the factory itself priced in that software.
01 · business problem
Grupo CPS manufactures aluminum-and-glass joinery. Quoting each order by hand is slow and depends on technical staff: every client inquiry took up someone’s time at the factory before anyone even knew whether the order was serious.
They wanted a simple web app where the client signs up, builds a cart with their windows, sends the order and tracks it. The problem was in the word “simple”: the price of a window does not come from multiplying area by a price per square meter. It depends on how much aluminum profile each window type uses (frame, sash, glazing bead, transoms), on the real glass measurement, on hardware, labor, margin and VAT.
The company already calculated all of this precisely in its factory software, WinMaker, which stores one “recipe” per window type: 2,641 files in a closed format, impossible to use directly on a website. My first simple calculation counted 2.44× less aluminum than the window actually uses.
02 · constraints
What I had to work around.
No access to the factory software from the web
WinMaker is a desktop system with its own format. It exposes no API and cannot be queried live: whatever I needed from it had to be extracted once and live in my model.
Internal costs that can never leak
The client must see a final price, never the cost, the margin or the price per square meter. Any design where the browser does the math was out from the start.
Data maintained by technicians, not the programmer
Recipes, catalogs, colors and parameters change with the factory. They had to be editable from a panel, without touching code.
A single developer
Product, engine, backend, database and security, in parallel with other company systems. Every layer had to be simple to maintain.
the key decision
Pull from the recipes only the numbers that move the price, without copying the whole factory software.
I had two bad options: a simple formula (fast but false) or rebuilding the entire factory software (precise but unfeasible). I chose the middle ground: read from the recipes only the measurements that affect the cost.
The error was not a wrong number, it was structural. The simple formula counted only the outline of the frame. But a real window holds much more aluminum: the frame, the opening sash, the bead that holds the glass and the transoms. And the glass is measured by the real opening that is left, not by the total size of the window.
So I built a program that reads those 2,641 recipes and pulls out, for each window type, the exact measurements the factory already uses. Those measurements feed the pricing calculation that already existed: what changes is how much material is counted, not how the price is built.
Concrete example, the one I measured with: a 1200×1000 mm fixed window with one transom. The simple formula calculated 4.75 m of aluminum profile. For that same window, the factory software breaks down 11.61 m: the frame, the transom and the glazing bead of each pane. With the measurements pulled from the recipes, my calculation gives 11.72 m. That is where the 2.44× comes from, and where the ~1% comes from.
03 · technical decisions and why
Why it is built this way.
Pure pricing engine, no I/O
All the pricing is pure functions, testable with no database. That is why it could be validated against the factory without spinning up any service, and the mobile app reuses it as is to quote offline.
Geometry separated from costing
The recipes changed how much material is counted without touching how the price is built. Later the costing became real too (each profile by its weight and the per-kilo price of the chosen color, labor per recipe) without touching the geometry. Each half changed without breaking the other.
Custom parser and AST evaluator for the .PRO format
Instead of executing the recipes, a static parser extracts per window type only the geometric constants (74, 126, 82/148 mm depending on the type), and each one is cited to its source file.
Immutable snapshot per order
Each order freezes the prices and names of that moment, with its number assigned atomically in the database (FOR UPDATE). Two simultaneous orders never share a number and a sent price never changes behind the scenes.
All the calculation on the server side
Endpoints return DTOs with no sensitive data. The service role lives only on the server and RLS is enabled with no public policies.
No complete recipe, no price
A line and window-type combination without a complete recipe is not offered, and a window that needs technical review is saved without a price. I would rather not quote than quote with an estimate dressed up as a price.
The order goes back to the factory software
Each order generates a .pto file the factory opens in WinMaker, which draws it and breaks it down with its own recipe. The format I first had to decode ended up being where the order lands.
04 · what was discarded
What I ruled out along the way.
Area × price per m² formula
Fast, but it counted 2.44× less aluminum than real. A hand-tuned correction factor would have hidden the error instead of fixing it.
Porting all of WinMaker to the web
Precise, but unfeasible: 2,641 recipes in a closed format and a full manufacturing engine, for what had to be an entry-level quoter.
Summary links with sequential IDs
They allowed enumerating other people’s orders by changing a number. Replaced with UUID tokens impossible to guess.
Calculating with costs in the browser
It would have exposed costs and margins to anyone opening the dev tools. The calculation with costs runs on the server; the mobile app quotes offline, but only with sale prices.
what was built
A full-stack app with a pricing engine at its core.
- 01
Step-by-step builder, with the window in 3D
The client picks type, dimensions, line, glass, color and accessories across four screens, with a live price. They see the window in 3D, which they can rotate, and the technical drawing, and can compare lines and glass before deciding.
- 02
Quote without an account
They leave their contact details first and then build the window. Clients with an account keep drafts and orders.
- 03
Several windows per order
They add, duplicate and adjust windows in one order until it is the way they want.
- 04
Quote as a PDF
A clean PDF with all the windows, their specs and the total. Resellers get a version with their own brand to hand to their client.
- 05
Frozen order and tracking
On submit, the prices and names of that moment are saved and nothing is recalculated behind the scenes. In “My orders” they see the status of each one and can share a summary via a private link.
- 06
Offline mobile app (in development)
An app that uses the same pricing engine as the web and quotes with no signal, using downloaded sale prices. Orders wait in a queue and send themselves when the connection comes back.
The quoter does not replace WinMaker, the system the factory has always worked with: it is the client’s front door, and the order ends up there, as a file WinMaker opens. The client never sees internal costs or margin: only the final price reaches the browser and the app.
the other side: administration
An internal panel where technicians load the factory’s reality.
Parameterizable technical recipes
Technicians load what each window type takes: profiles with their cuts, accessories, glass and manufacturable limits. Each recipe picks components from real catalogs: profiles with their price per color, accessories, IGU spacers and labor.
Load status per recipe
A board shows what each recipe is missing to quote with real cost: profiles not loaded, profiles with no price in the color, limits or accessories. Whatever is incomplete is not offered to the client.
From order to workshop
Each order shows its cost breakdown and moves through statuses aligned with the company’s sales board. From there, the team generates the .pto file the factory opens in WinMaker.
Parameters that govern the engine
Margin, VAT, waste factors, colors with their WinMaker code, the dollar exchange rate taken from the Central Bank (with history and a manual fallback), and users with roles and discounts: everything that affects the price is managed from the panel, behind APIs with role-based access control.
This is what lets the system live without the programmer: the owners of the data are the factory technicians, not the code. The client-facing page is the visible half; this is the half that keeps it honest.
architecture
A strict boundary between public and private.
Web and mobile app
Configurator · orders · Expo app that quotes offline.
app/api/*
HTTP boundary: auth, authorization and DTOs with no sensitive data.
src/server/*
Private logic: orders, PDF, the .pto file and the exchange rate.
src/lib/cotizador/*
Pure pricing engine, no I/O; the app reuses it to quote offline.
src/technical/* · src/shared/*
Window types, validations and contracts shared by web and mobile.
PostgreSQL
Canonical schema on self-hosted Supabase, with Row-Level Security.
The part that calculates measurements is separated from the part that builds the price, and neither touches the database. That is why bringing in the factory numbers did not break the prices, real costing did not break the geometry, and the mobile app could use the same engine without rewriting it.
security by design
Client data and internal costs are at stake: security was a requirement, not an add-on.
No data served straight from the database
Everything goes through the server with login. The database master key lives only there, it never reaches the client’s browser.
Share links impossible to guess
A summary link is not a running number (1, 2, 3…) but a random code, so nobody can change it to peek at other people’s orders.
Inputs always bounded
Dimensions within each recipe’s limits, integer quantities with a cap, limited text. An unknown color stops the quote instead of quoting wrong.
Internal costs never exposed
The client sees the final price, never the cost or the margin. The calculation with costs happens on the server, and the mobile app only receives sale prices.
Frozen, auditable orders
Each order stores an immutable snapshot of prices and names, with its number assigned atomically in the database: two simultaneous orders never share a number, and nothing changes behind the scenes afterward.
Access control checked on every build
A test fails the build if any API route is left without access control. A self-run audit also closed a cost leak in a public route and hardened the headers.
05 · measurable result
What can be measured.
error in the aluminum calculation against the factory system, fixed in the geometry rather than with a correction factor.
real factory recipes analyzed by reverse engineering.
with test orders the factory itself priced in WinMaker: the web’s cost never falls below the workshop’s.
at cotizador.grupocps.com.uy, the front door for Grupo CPS clients.
quality & engineering
How I know the numbers are right.
- Factory recipes analyzed
- 2,641
- Proprietary .PRO format cracked
- Custom parser + safe AST evaluator
- Material error vs. the factory system
- 2.44× → ~1%
- Validation
- Test orders priced by the factory in WinMaker
- Calibration
- The company’s historical quote archive
- Access control
- Checked by a test on every API route
- Code quality
- Strict TypeScript, no type errors
The “shadow mode”: a tool that compares, window by window, what my system calculates against the real parts breakdown from the factory software. It measures how far off I am before calling a price good. Then came the real test: orders the factory priced in its own software and sent back, with one fixed rule: every gap gets closed with a cause, not a coefficient.
demo
The quoter in action.



takeaways
- The hard problem is rarely the visible one: the screen was the easy part, the value was in calculating well and validating the numbers.
- I did not brute-force copy the 2,641 recipes: I pulled out only what moves the cost and left the rest as separate research.
- Measure before you claim: “shadow mode” turned a hunch (“the price doesn’t add up”) into a number (2.44×) and then into a validation (~1%).
- A complete system includes whoever maintains it: the internal panel and its load status make the technicians, not the programmer, the owners of the data.
- A pure core pays off: since the engine never touched the database, the offline mobile app came out by reusing it, without rewriting the calculation.
Want to talk about this project?
The code is private, but I can walk you through how it is built. Write to me if this interests you or you want to talk about a role.