Case study
GetPosals
A proposal tool I designed and built at CodeBuddy. Thirty flows, twelve days.
- Role
- Design and build, solo
- Company
- CodeBuddy
- Dates
- 24 Feb to 11 Mar 2026
The brief
The brief
The CEO had seen what I was shipping with AI tools, so he handed me a product and asked me to lead it. Design and build, both.
Thirty flows. Seventy-two hours of work. Twelve days.
I said yes before I did the maths.
The brief
The raw input a proposal starts from
The person building the proposal already has useful context in the lead: the company, contact, value, and source material.
The product had to turn that context into a working document without making them enter it all again.

Deciding the foundations once
Deciding the foundations once
You cannot design thirty flows in twelve days by starting each one fresh.
The shell and tokens came from IntelBuddy, a product we already had. I pulled brand values straight out of Figma instead of reading hex off a screen, so Brand/800 was #5124B4 because Figma said so, not because it looked close.
What I saved on foundations, I spent on the four screens that actually needed thinking.

Part one
The ProGenie argument
A split panel versus full-screen chat, settled in one meeting.
The argument
The argument
The real question was how much of the source material you should see while the AI writes.
I designed a split panel. The CEO wanted full-screen chat. Cleaner, fewer distractions, and he was not wrong about that.
So I built both.
The argument
Chat on the left, the documents on the right, live

The argument
How it landed
I walked him through one scenario and stopped at the moment the full-screen version produces a budget figure the user does not recognise.
In mine, you glance right and see which document it came from. In his, there is nowhere to look.
He changed his mind in that meeting, and gave me decision authority over the rest of the product.
The rule that came out of it
The rule that came out of it
The AI can draft. It does not decide.
ProGenie takes files, pasted text, links and custom instructions, and every one of them stays visible beside the conversation. What comes out is editable sections, not locked copy you accept or regenerate.
AI is very good at removing the blank page. It should not also remove your ownership of the document.

Do not ask twice
Do not ask twice
A proposal started from a lead already knows the company, the contact, the value, the documents.
So creation asks one question: do you want help, or a blank page.
Not a form. You already told us this.

Moving my own favourite thing out of the way
Moving my own favourite thing out of the way
On 30 March I demoted the feature I was proudest of.
The overview opened with the AI summary and a row of insight cards. It was the most impressive thing on the page, which is why I had put it first.
Sitting with it, the order was wrong. Someone opening a proposal wants the lead, the scope, the team, the money.
The best part of the page was not the part anyone needed first.
Moving my own favourite thing out of the way
Before and after: the assistant moves into its own tab

Part two
Shipping the back end
Real data, real bugs, and a mobile width that had to hold.
I built the back end too
I built the back end too
Hono on Cloudflare Workers, D1 across nine tables, R2 for files, Gemini for generation.
These figures are computed from real proposal and lead data. Nothing on this screen is mocked.

I built the back end too
Two decisions I would defend
Two decisions I would defend.
The data layer tries D1 and falls back to localStorage, so the interface survives the API being down.
And on 11 March the Gemini key moved out of the source and into a Worker secret. Quiet to fix early, embarrassing to fix late.

Then I broke it on purpose
Then I broke it on purpose
A race condition sending anyone who opened a deck straight back to onboarding. A hooks-order crash in the proposal detail. Statistics falling over on a proposal nobody had viewed yet.
Five bugs, fixed, with a 53-test automated pass behind them.
There was nobody to hand it to, so I kept going.
Then I broke it on purpose
It had to hold at 390 pixels too

Proposal workspace at 390

ProGenie at 390
What I took from it
Thirty flows became one working product
In twelve days, the work moved from a lead brief to a connected proposal product with a real Cloudflare data layer, Gemini generation, responsive mobile flows and a 53-test pass.
The clearest qualitative outcome was trust: after the ProGenie review, the CEO gave me decision authority over the rest of the product.

What I took from it
What I took from it
Fast projects make it easy to polish one screen at a time.
The quality lives between the screens. What context survives the jump, what you are offered next, and whether the document still feels like yours.
The CEO scenario review validated the product direction, and 53 automated tests validated technical behaviour. I did not run an end-user usability study in the twelve-day build; that is the next evidence I would add.
Stack
Built with
- Frontend
- React, Vite, TypeScript
- Styling
- Tailwind CSS
- Back end
- Hono on Cloudflare Workers, D1, R2
- AI
- Gemini
- Export
- pdf-lib
- Made with
- Figma and Figma Make, Codex, Cursor, GitHub Copilot, Claude Code. I pick the tool per phase, not per project.