Skip to content

Building products — glass balcony and guillotine system manufacturing

Turning a pricing spreadsheet into a quoting engine

A multi-tenant B2B application for the dealer network of a glass balcony, guillotine and sliding system manufacturer. The dealer measures on site and picks the system and glass; the server computes cost and sale price, produces the quote, and the job is tracked through production and installation.

Stack: NestJS · TypeScript · Prisma · PostgreSQL · Next.js · Flutter · Docker

Measured results

53
API endpoints
Project status record, 12 August 2026
88 + 195
Unit and end-to-end tests — all passing
Project status record, 12 August 2026
10 decimal places
Agreement between the engine and the manufacturer’s spreadsheet
Project status record, 12 August 2026
5 roles / 23 permissions
Permission matrix
Architecture decision record, 15 August 2026
4
Errors found and reported in the manufacturer’s own spreadsheet
Calculation engine analysis report §9

The problem

The manufacturer sells glass balcony and guillotine systems through its own dealer network. A dealer takes measurements in the customer's home, chooses the system, the colour and the glass, and quotes a price. That price came out of a spreadsheet.

The trouble with the spreadsheet was not that it was slow. The trouble was that every dealer had a copy of it. When the price list changed, nobody knew who was still working from which version. A mistake in a formula propagated quietly. And three months after a quote went out, nobody could say which exchange rate it had been calculated at.

The heart of this product is not a screen — it is the calculation engine. A wrong screen gets fixed. A wrong price has already reached the customer.

The approach

We put the engine on the server, in exactly one place. The mobile app and the web panel call the same endpoint. Written twice, it would eventually produce two different totals for the same configuration — a discrepancy that surfaces only when a customer puts two quotes side by side. Panel geometry is computed server-side for the same reason: the front end draws the coordinates it is given rather than deriving its own.

We moved monetary values across the API as text. Floating point error is not an acceptable tolerance on a quote total. The front end does no arithmetic; it formats.

We left unauthorised fields out of the response entirely. For a dealer without cost visibility, the cost and margin fields do not come back empty — they are not there. Hiding a value in the interface is a design decision; security is not sending it.

We attached an exchange rate snapshot to every quote. Without it, the same quote reopened three months later would show a different total, and that is an argument neither side can win.

What it does

The system today:

  • Produces quotes. The dealer enters the system, colour, glass and measurements; the server computes cost and sale price and issues the quote.
  • Calculates and draws the panel layout. The server returns a coordinate list and the interface renders it.
  • Holds an exchange rate snapshot. A quote reopened months later still shows the same total.
  • Separates tenants. Dealer data is isolated at the data layer, so a forgotten filter in one query cannot expose another dealer's records.
  • Shapes responses by role and permission. A matrix of five roles and twenty-three permissions removes fields a user may not see from the response altogether.
  • Tracks the job down the line. After the quote, work is followed through production, installation and delivery.

How it was verified

The engine was built against the manufacturer's own spreadsheet and the output was compared digit by digit: the results agree to ten decimal places.

The comparison had an unplanned by-product — four errors were found in the manufacturer's spreadsheet and reported back. That is the strongest evidence of the engine's accuracy, because it came out precise enough to catch a deviation in the reference itself.

The API exposes 53 endpoints today, and all 88 unit and 195 end-to-end tests pass. Every change goes through a pull request with one approval, and every request is checked by CI.

The mobile demo was delivered on 30 July 2026.

Meanwhile the same product was rebuilt for a second manufacturer, with its own brand and its own set of systems. That was the real exam: whether a business application written once can stand up for a second client without being written again.

Stack

NestJS · TypeScript · Prisma · PostgreSQL · Next.js · Flutter · Docker