The brief
Replace a spreadsheet-and-email invoicing workflow with a real application: quotes, invoices, and delivery notes that generate as clean PDFs, a client and product catalog, multi-currency support, and eventually a full finance module — payments, bank reconciliation, statements of account, and tax compliance reporting.
No off-the-shelf SaaS tool fit the exact document formats and tax rules required, so the decision was to build it: FastAPI for the backend, server-rendered Jinja2 templates (deliberately not a JS framework, after an earlier round of instability from adding one), PostgreSQL for storage, and WeasyPrint turning HTML templates into the actual PDF documents clients receive.
What got built
Quotes, invoices, and delivery notes as generated PDFs with consistent numbering and branding.
Exchange rates applied consistently across documents and reports, not just at entry time.
Reusable records that documents are built from, instead of retyped every time.
Payments tracking, bank accounts, credit/debit notes, and a statement-of-account view per client.
VAT summary and owed-tax reporting built to match the actual local filing requirements.
Documents move through explicit states so a draft can be revised, but a finalized invoice can't quietly change.
How it actually got tested
This runs against a live database with real client invoices and payments, so every round of changes followed the same pattern: create disposable, clearly-prefixed test records, exercise the new feature against them, and verify every number back to the exact pre-round baseline before calling a round done. No feature shipped without that check.
One thing that came out of this discipline: testing purely by calling backend functions directly missed real bugs twice — both were only visible when a form was actually submitted through a browser, because the failure was in the client-side interaction, not the backend logic. Since then, anything touching form submission or numbering logic gets a real browser click test, not just an in-process call.