Back to the work

Floor planner

A tool I built for myself to plan a house's ground floor before the concrete screed goes down, when every pipe and cable position stops being changeable.

How a measurement becomes a checked roomA handful of measurements taken on site become the whole layout, since walls and rooms are derived from them rather than drawn by hand. The same model is checked against a set of rules — drain slope, stair norms, floor clearances — and a render of the room is generated for a sanity check before anything gets built.MeasurementsModelRulesReportDoors, windows, stack and stairs, measured on siteWalls, rooms and pipe runs derived from the layoutChecked: drain slope, stair norms, floor clearancesRoom rendered for review
A checking pipeline, drawn the same way as a conversation.Message between systemsThe AI model decides

The problem

Once a concrete floor is poured, the position of every pipe, sleeve, drain and cable inside it is fixed. A mistake found after the pour means breaking concrete, not editing a drawing. I needed one model of the ground floor that every trade’s plan — plumbing, underfloor heating, electrics — could be checked against before that happened, not a stack of separate sketches that could quietly disagree with each other.

What I built

A browser-based planner where the floor is data, not a drawing. A handful of real measurements — door and window positions, the sewage stack, the existing staircase — anchor the model, and the walls, rooms, pipe runs and heating loops are all derived from it rather than drawn by hand. Anything not yet measured is marked as an assumption rather than presented as fact. A rules panel checks the whole model before the pour: drain slope, stair geometry, floor buildup clearance, heating loop length, and more.

Try it

The planner runs in the browser at floor-planner-4cg.pages.dev, and the source is public at github.com/tdoozer/floor-planner. The interface is in English, translated from the Russian I first built it in for myself. The sample project is my real house with the location details removed, and state lives in the browser’s local storage, so there is no account and no backend. Only the AI render step calls out, through a small Cloudflare Pages Function. The norms and thresholds in the calculations are my engineering assumptions, not certified design values, and the repository says so.

Architecture

The diagram above shows the checking pipeline rather than a conversation: measurements go in, the model derives geometry from them, that geometry is checked against a fixed set of rules, and the result — including a rendered view of the room — lands in a single report.

Key decisions

The house is data; every drawing is derived from it. The layout is defined by a small number of measured values, and walls, rooms and pipe runs are computed from them rather than stored as shapes. That means moving a partition or adjusting a room recomputes everything downstream instead of leaving stale drawings that have to be fixed by hand.

Measured facts are kept separate from assumptions, and the assumptions are counted. Concrete doesn’t forgive a guess. Anything not confirmed by an actual measurement is flagged in the model and shown with a distinct marker in the UI, with a running count of how many unconfirmed positions remain — so it’s never possible to mistake a placeholder for a fact.

The rules are tests, not a checklist I read by eye. Drain slope, stair proportions, floor buildup clearance and the rest are encoded as pure functions with their own test coverage, so a change to the layout that breaks the drain slope fails the test suite before it fails in concrete.

Layers came from an earlier project, not from scratch. I’d already built a similar tool for planning the plot around this same house, and its layer pattern — visibility and lock state per layer, persisted locally — along with its drag-and-drop and PNG/PDF export, carried over directly. Reusing it meant this tool started from a working interaction model instead of reinventing one.

Three documents, each answering a different question. After a few dozen releases I noticed the project kept losing one kind of knowledge: what had been rejected. The changelog says what changed in the code, and the project brief says what is true right now, but neither records the options I’d already thrown out. So a third file, a decision log, holds the revised decisions, the rejected alternatives with the reason, and the open questions grouped by the irreversible job they block, such as the screed pour. Every revised decision must state what evidence would reopen it, so a decision without a way to be wrong doesn’t survive. The log also earned its keep immediately: reconciling the brief against the code turned up two stale numbers, such as a worktop thickness the code had long since changed.

How Claude was used

I wrote down the domain facts and rules first — which positions are measured versus assumed, which checks a layout has to pass before a pour — and kept that written down as the source of truth across sessions. Claude wrote most of the calculation code and the UI against it; I decided which assumptions were safe to default and which had to be flagged rather than silently accepted, and the test suite gated every change to the geometry. Those three documents are what carry the project from one session to the next, so Claude starts each session from the current facts and the list of rejected ideas instead of proposing them again. More on that in how I build with Claude.

Results

The planner is at v0.56.1, with 565 tests covering the geometry, the rule checks and the app itself. It shipped in 59 feature releases over four weeks, from late July to late August 2026 — small, frequent changes rather than a few large ones, which suited a tool where every geometry change needs its own verification. It’s in active personal use for planning the actual floor before the pour, and anyone can open the live version or read the code.

What I’d do next

The tool itself covers the full path now — layout, heating, wiring, panel schedules, fabrication drawings and a cost estimate — but a meaningful list of positions in the model are still marked as assumptions rather than measurements: the boiler, both gas inlets, the stack’s invert level, the water inlet, the panel, the chimney. Those are exactly the kind of thing concrete doesn’t forgive getting wrong, so the actual next step isn’t more software — it’s going back with a tape measure and closing that list to zero before the pour.