Case Study
A mobile-first invoicing PWA for a trades sub-contractor. Vue, Java Spring Boot, and PostgreSQL, with hard lessons in scope creep and security architecture.












A sub-contractor friend was drowning in manual admin work between jobs: Manual invoicing, no tax tracking, no structure.
The goal: Build a mobile-first tool for job tracking, invoice generation, and basic financial calculations. Less admin, more living.
AWS Cognito was the initial auth choice. It conflicted with Spring Security's session handling in a browser-based SPA, JWTs were lost on page reload, sessions were unreliable at best. The backend was scrapped and rebuilt from scratch with Firebase Authentication, security-first: test controller, confirmed auth, then everything else.
The billables enum was the wrong abstraction. A hardcoded list requiring a code change to update and the client's billables changed the moment the app launched.
The UI prioritised function over form:
The application shipped as a functioning full-stack PWA. A user could:
The friend ultimately abandoned the application. Unconfirmed requirements and constant scope creep made continued development unsustainable and over 100 hours invested, no compensation, project frozen.
The application remains intact. The path to revitalizing it is clear.
IPD Buddy was the most instructive project I've built.
Not because everything went well, but because of what went wrong and why.
Scope creep is a requirements problem first. The billables enum issue wasn't a technical mistake, it was the consequence of building against unconfirmed requirements. No amount of good engineering compensates for a spec that keeps moving.
Security architecture belongs at the start. The Cognito detour proved it for me. The rebuild started from a security-first foundation and that's now the default starting point for any new backend.
The application remains frozen, not abandoned. The path forward is clear:
enum with user-owned templates (coined Jigs at the moment) The foundation is solid enough to build on.