Waiver
A liability waiver that families sign at a soft-play centre. Typed in, signed on screen, saved as a PDF. It began as one HTML page and ended up a .NET desktop application on SQL Server.
- HTML
- JavaScript
- .NET
- WinForms
- SQL Server
- ChatGPT
Where It Started
The first version was a single HTML page. Participant and guardian details, a date, an emergency contact with a country-code picker, the liability text itself, and a signature box you drew into with a mouse or finger. Generate the waiver, save the PDF, done.
It was multi-language from the very first version. The language dropdown sits at the top, because the centre’s customers didn’t all read English.
The signature itself was drawn straight into the page and cleared if it went wrong, then Generate Waiver assembled the document and Save PDF handed the visitor their copy.
Crude, and it stored nothing. Every waiver was a PDF someone had to file. But it proved the idea worked, which is the only thing a first version has to do.
Into a Real Application
The obvious next problem was the filing. A PDF per visitor is fine until you need to find one. So the second version moved to a .NET WinForms desktop app with a SQL Server backend, so waivers were records you could search rather than files in a folder.
That meant it needed the things a real application needs: accounts and a login, user management, configuration, and maintenance screens. I gave it a name and an identity along the way. KAPADEV Tech, picked more or less at random, but it made the thing feel like a product rather than a script.
What I Was Actually Testing
The waiver was the excuse. What I wanted to know was how far ChatGPT could carry a real product. Not a snippet or a demo, but something with a database behind it, a backlog in front of it, and a person who would eventually have to use it.
The answer was: comfortably to a working MVP. Getting from nothing to something that ran, stored data and looked deliberate was genuinely fast.
Past a certain backlog size, every new feature started costing me a working one.
The ceiling showed up later. As the backlog grew and each iteration carried more context, changes started arriving that quietly broke things I was already happy with. A screen redesigned when I’d asked for a field, behaviour changed in a part I hadn’t mentioned. The failure wasn’t that it couldn’t write the code. It was that it had no stake in protecting what already worked.
That is the finding I actually took away, and it changed how I work: scope each iteration small enough to verify, keep the backlog prioritised rather than merely long, and treat “what must not change” as part of the requirement rather than something the tool will infer.
Where It Is Now
A developer friend was interested enough to take it on, so it is his to carry forward. It had gone as far as I wanted to take it as an experiment, and the thing I built it to learn, I had learned.