250 tests, a plan validator and real-browser timing: what the work looked like, what it would cost by hand, and the metric we didn't tune away
Client: a carpentry workshop
Delivered by: Pablo Rosero (pablorosero.me), working with Claude Code
Stack: React 19, Tailwind 4, Vite, TypeScript, Vitest, Web Worker, localStorage only
1. The problem
A carpentry workshop loses money in three places before a saw ever turns on:
Cut lists are built by hand. A kitchen module turns into dozens of pieces, and one thickness mistake ruins a board.
Board layouts are guessed. Too many boards are bought, and offcuts pile up unrecorded.
Quotes and shop-floor schedules live in separate spreadsheets. The price quoted never quite matches the boards cut.
The workshop needed one tool to do all of it: parametric cut list, optimal layout, quote, panel-saw shifts and an admin area. It had to work on a phone in the workshop and print as a clean black-and-white plan.
2. What was delivered
LayerWhat it does1. Parametric cut listEnter a module (e.g. 800 × 720 × 560 under-counter unit, 18 mm melamine). It derives each piece, discounting thicknesses: sides 720 × 560, top and bottom 764 × 560, 3 mm back panel.2. Guillotine optimizerRuns in a Web Worker. Deterministic, 4 mm saw kerf, 10 mm edge trim, grain-aware (no rotation of grain-critical pieces), uses stored offcuts first. An independent validator re-checks every plan.3. Quote, shifts, adminQuote from the real board count, panel-saw shift scheduling, and a password-protected
/admin for materials, machines and VAT.Plan viewsOpticutter-style cut plans (a visualization reference only, no 3D), with numbered cuts, piece sizes and offcuts. They read clearly printed in black and white.DocsFull README in neutral Spanish: how to run, where everything is, which features are simulated, sample data and how to reset it, how to change the panel password.Size of the result (measured from the repo):
76 tracked files
about 7,400 lines of application code
about 4,400 lines of tests
250 automated tests, including real-Chromium tests that build the production app, install the service worker, test offline, and time the optimizer under CPU throttling
15 commits
a live production deployment
3. How the work was run
The client brief arrived as ten acceptance criteria. Examples: «exactly 4 mm of saw between pieces», «a piece bigger than the board shows an explanatory error», «120 pieces solved in under 3 s on a mid-range phone», «data survives a browser reload».
Instead of treating these as a checklist at the end, the process turned them into the spine of the project:
One test file per official criterion (
tests/criterios/c01…c10). The client can open the file named after the criterion they care about and see the proof.Build in layers. The cut list, then the optimizer, then the business layer. Each layer was committed and tested before the next one started.
Independent review passes. After the first build, several reviewer agents audited the code in parallel along different dimensions (optimizer correctness, print output, screens, storage, offline). Each finding was then checked by a separate agent trying to refute it. Confirmed findings were fixed in isolated git worktrees and merged. This produced real fixes, not noise. Examples:
an offcut assignment bug
cut lines drawn through the numbered circles in the plan
a password string visible in the compiled bundle (replaced with a salted hash)
small pieces losing their size labels
a utilization tile that misled users after approving other projects
Verification in a real browser. Criteria 1–9 were checked in Chromium at 360 px phone width, not just in jsdom. The phone-speed claim was measured with CPU throttling, and the report is honest about how: CDP throttling does not apply to workers, so the test runs the worker code on the throttled main thread. That is a conservative method.
Honest reporting. When a metric looked good but wasn’t (see §5), it was surfaced to the client as a decision rather than quietly tuned.
Commit timeline (from git): the first layered commits landed on 4 Nov 2026 at 16:24 and the last verified fix at 00:46 on 5 Nov. That is about 8 h 20 min of recorded commit time across all review rounds. It excludes the earlier unrecorded drafting and the conversation time on the client side. Everything was delivered within that two-day window.
Measured performance (real Chromium, throttled, tap to plan):
CaseTime120-piece project, 6× slowdownabout 1.0 s120-piece project, 10× slowdownabout 1.3 sFull rack of offcuts, 6× slowdownabout 1.1 sWorst case found, 6× slowdown0.77 s
The requirement was under 3 s.
4. Manual cost comparison
The numbers below are estimates with stated assumptions, not invoices. Adjust the rate and hours to your own market; the structure holds.
Assumptions: senior freelance full-stack developer, €50/h; a competent developer who does not already know the carpentry domain; same scope and same quality bar (tests, real-browser verification, printed plans, docs, deployment).
Work packageManual estimate (h)Domain research and requirements (cut-list rules, thickness discounting, kerf, trim, grain)24Parametric cut list and module editor24Guillotine optimizer, offcut logic, Web Worker, independent validator60Quote, expiry, VAT, panel-saw shifts, /admin with password48Mobile-first UI, plan drawings, print views (B/W-safe), PDF print test56Automated tests (≈4,400 lines, 250 tests) including Chromium harness56Spanish documentation (README + criteria map)12Deployment, SPA rewrite, service worker, offline8Review and fix rounds (the five-plus rounds actually run)40Real-device and phone-width QA16Total≈ 344 h
ManualWith AI-assisted deliveryEffort≈ 344 h (about 8.6 working weeks)≈ 8.3 h of recorded commit time, plus reviewing and decidingCost at €50/h≈ €17,200A small fraction of itCalendar time2 to 3 months part-time2 days
Even if the manual estimate is cut in half (a very fast developer, or smaller scope), the gap is more than an order of magnitude in calendar time. The savings are not the whole story, though, which is the next point.
What the manual path usually skips. At €17k, a manual project rarely includes all of: one test file per criterion, an independent validator that re-checks every cut plan, adversarial review rounds, a real-Chromium timing test, and a bilingual-quality README. In practice those are the first things cut when hours run out. Here they were part of the baseline.
5. A decision handled openly: the utilization metric
The 80 % utilization target (criterion 5) exposed a real trade-off. Counting every board and every offcut used in full, the seed project «Cocina en L» reached 81.6 %. After approving other sample projects the figure fell to about 75–80 %, because criterion 6 forces the optimizer to use offcuts first, and those offcuts are often awkward shapes.
A less careful delivery would have tuned the number or hidden the drop. Instead:
the plan tile was changed to show new boards % and offcuts % separately;
the issue was written up in the criteria document with the measured values;
the client was offered the industry-standard alternative, net utilization (offcuts that return to the shelf are not counted as waste, expected about 89–91 %);
the client chose net, and the switch was then made: the seed now reads 88.8 %, and all 16 approval orders stay between 87.9 % and 89.6 %.
The client got the decision, with the numbers, instead of a surprise.
6. Why work with me
Domain-aware, not just code-aware. Thickness discounting, saw kerf, trim, grain direction, offcut inventory and panel-saw shifts are modeled as the workshop actually uses them. Criteria were turned into tests before they were turned into promises.
Speed without the usual quality sacrifice. Days instead of months, and the extras that normally get cut (tests, validator, review rounds, docs) stay in.
Evidence, not claims. Each acceptance criterion maps to a named test. Performance was measured under throttling in a real browser and reported with its limits.
Honest scope handling. Simulated features (emails, payments, WhatsApp) are documented as simulated. Metrics are explained rather than massaged. Open decisions are put to you with numbers.
Security hygiene by default. No password text in the bundle (salted hash, set at build time), no secrets committed, deployment only after your explicit approval.
Handover-ready. You get a private repo shared with your team, a README in your language, preloaded sample data with a reset procedure, and a working preview URL.
Fast, cheap iteration. Change requests such as the third review pass, translating the docs, and the metric switch are hours, not sprints, because the test suite makes changes safe.
7. Honest limits
The cost comparison is an estimate built on stated assumptions. Your numbers will differ.
The app stores data in the browser only (localStorage), by design for this version. There is no multi-user backend.
Emails, payments and WhatsApp are simulated and documented as such.
The phone-speed test approximates a mid-range phone with CPU throttling; it is not a lab of physical devices.
The net-utilization change is applied locally and tested; it is not yet committed or deployed.
8. Takeaway
A workshop got a working, tested, printable cut optimizer with quoting and shift planning in roughly two days. The same scope done by hand is a two-to-three-month project at around €17k, and it would likely ship with fewer tests and no independent validator. The value is not only speed. It is the combination of speed, verified quality and transparent decisions.
0 likes · 1 view · Nov 13, 2026
250 tests, a plan validator and real-browser timing: what the work looked like, what it would cost by hand, and the metric we didn't tune away