PRJ-02Turnkey sauna building

Your Saunas: the thing being sold does not exist yet.

A custom CRM for a turnkey sauna builder. The room is designed, priced, framed, and installed by the same system, because the price depends on a shape that only exists as a drawing when the client is deciding.

PRJ-02-AScope of work

What the business does.

Turnkey sauna building: design a room to fit the space a client has, quote it, take a deposit, order the materials, build it, and install it with a crew.

The sale happens over a drawing. Everything downstream, the material list, the framing, the price, the deposit, follows from the shape agreed in that conversation.

The problem shape.

No product you can buy has a sauna in it. There is no field for a bench, no rule that a door onto a hot bench has to open outward, no concept of a wall elevation at a consistent scale.

Before the system, the drawing, the material list and the price were three separate artefacts made by three separate acts of attention. Three artefacts describing one room will eventually disagree, and the disagreement surfaces in front of the client.

PRJ-02-BDetail callouts

What was built.

Each item names the file that proves it. The planner on the CRM page is this code, running on demo data.

A

A 2D planner that prices the room as you reshape it

Drag a corner and the neighbouring walls move with it, because a diagonal wall prices a room nobody can frame. The area, the material take-off and the price follow the drag rather than being recalculated afterwards by hand.

Proof

components/sauna-planner.tsx

B

Wall elevations, every wall at the same scale

Each wall drawn as its own elevation, all at one scale on purpose, so two walls can be compared by eye without reading the numbers. Doors default to swinging outward, and rough openings add their own margin so the crew is not working it out on site.

Proof

components/wall-elevations.tsx, components/room-elevation.tsx

C

The caller card arrives before the phone rings

An inbound call lands and a card is already in Telegram: who it is, the number in a tappable form, and the last project they discussed. By the time the phone is answered the context is there. A call cannot move a project on its own.

Proof

app/api/twilio/voice/route.ts

D

Deposits by card and by bank transfer

Built on Stripe Connect, so the money lands in the contractor's own account rather than passing through ours. ACH is offered alongside card because on a large deposit the card fee is the difference between a few dollars and a few hundred. Fees are computed in whole cents and refunds return them proportionally.

Proof

lib/deposit-fee.ts, lib/stripe.ts

E

E-signature built in-house

The signature page is composited into the real PDF with both names, the date, and an audit trail. Branding comes from the company record, so the document looks like the contractor's rather than like a software vendor's.

Proof

supabase/migrations/028_esignature.sql, app/sign/

F

The rest of the working day

Stock that comes off the shelf when a client approves, once, even if the webhook fires twice. Crew payouts under one rule instead of three that disagreed. Reports that agree with each other because revenue is defined in exactly one module.

Proof

lib/inventory.ts, lib/installer-pay.ts, lib/revenue.ts

G

557 tests and 122 migrations

The test suite runs 557 tests across 49 files, and every schema change since the first day is a numbered migration. Thirteen of the tests are guard tests that read the source rather than the output, and each one had to fail against the code that shipped the bug before it was allowed in.

Proof

supabase/migrations/ (122 files), lib/__tests__/

H

Deliberately no AI

Both AI features this system inherited were removed. Neither could actually run, and one of them reported work it had not done. Saying so is more useful to the next client than a feature list that quietly implies otherwise.

Proof

See /services/ai-agents for where the AI actually is

PRJ-02-CReference

Where this lives.

Custom build under Orium Studios. Its own database, its own migration runner, its own deployment.

System
Your Saunas
Repository
sauna-crm
Trade
Turnkey sauna building

Files named on this sheet

  • sauna-crm · components/sauna-planner.tsx, the planner
  • sauna-crm · lib/deposit-fee.ts, Stripe Connect deposit fees
  • sauna-crm · lib/revenue.ts, one definition of revenue
  • sauna-crm · lib/stripe.ts, byte-identical in all three systems

Three separate deployments, three separate databases, and no shared data of any kind between clients. What they do share is the code that was proven in one of them first — lib/stripe.ts is byte-for-byte identical in all three repositories.

Back to the drawing index

SHT-08Issued for construction

Start with the audit.

A short video walkthrough of where your lead flow leaks and what it would take to close it. Free, and there is no call afterwards unless you want one.

Get my free audit