Client Report Portal

Context
Time-boxed build against a fixed written specification (technical assessment)
Objective
Deliver a working client report portal from a requirements document
Stack
FastAPI, htmx, SQLite, CairoSVG. Deployed on Railway.
Testing
700+ automated tests
Duration
About 24 hours from spec to submission, AI-assisted build
Status
Code available on request

The brief

The starting point was a written specification, not a conversation. The task was to read a requirements document, decide what it actually meant, and deliver a working system inside a fixed window. The specification asked for a portal where a small financial planning team enters client financial data into structured forms and generates fixed-layout quarterly cash-flow and net-worth reports as PDFs, replacing a manual preparation process that took a full day per client meeting.

About 24 hours means exactly that, and it was an AI-assisted build: roughly five hours of system architecture first, then an overnight build with the specification as the contract. The speed did not come from skipping verification. The test suite was AI-generated and human-reviewed, and the build was not submitted until it passed. Before submission I personally verified the calculation rules against the specification, reviewed the generated report PDFs against the required layout, ran the full test suite, and walked the entire flow end to end as a user.

This is a different problem from the Gold Trading engagement. There, the work was discovering requirements that nobody had written down. Here, the work was interpreting requirements that someone else had written, filling the gaps deliberately, and proving the result correct.

Interpreting the requirements

A written spec is never complete. Every gap is a decision: guess silently, ask, or make an assumption and document it. Two features sat in exactly that zone here: the specification recorded a Canva export as proposed but never firmly confirmed, and a Dropbox auto-save as mentioned without commitment. Both were treated as in scope and delivered, so the ambiguity cost the client nothing either way.

Assumptions were logged rather than buried, so the reviewer could see not only what was built but what was decided along the way.

Architecture decisions

Decision

Server-rendered UI with htmx instead of a JavaScript SPA.

Why

Fewer moving parts inside a fixed delivery window. The interaction model, forms, tables, and report views, did not justify a client-side framework.

Decision

SQLite as the datastore.

Why

Single-tenant scope with modest concurrency. Zero-operations persistence beats infrastructure ceremony at this footprint.

Decision

Server-side PDF generation with CairoSVG.

Why

Report output must be deterministic and reproducible. Rendering on the server removes browser variability from the deliverable.

Decision

Tests before polish: 700+ automated tests.

Why

A report portal produces trusted output. Correctness had to be provable rather than assumed, especially in a time-boxed build.

Report pipeline

Report generation

  1. Generate Report from the client profile
  2. Form pre-filled with static data and last quarter's values
  3. Current balances entered
  4. Calculations run automatically
  5. Completeness validation
  6. Fixed-layout render (CairoSVG)
  7. PDF download, stored in report history
Deterministic output. The same inputs produce the same report every time.

What shipped

The delivered system covered client profile management (household structure, accounts, static financial data), quarterly report data entry pre-filled from the profile and the previous quarter, automatic calculation of all totals, and generation of both fixed-layout report PDFs. Reports could be downloaded directly, re-downloaded from a report history, exported to Canva, and saved automatically to the client's Dropbox folder.

The system was deployed to Railway as a running application, not submitted as a zip of source code.

Testing philosophy

The test count matters less than what the tests assert. The tests cover the calculation rules (per-spouse retirement totals, non-retirement totals excluding the trust, liabilities reported separately from net worth), form validation and completeness checks, API behavior, and the stability of the fixed-layout PDF output. The principle was the same one that runs through every system documented on this site: output that people will trust has to be validated by the system itself, not by hoping the author was careful.

What this demonstrates

Requirements interpretation. Scope discipline inside a fixed window. Architecture matched to the footprint of the problem rather than to fashion. Engineering rigor that can be inspected, not asserted. Deployment to production infrastructure.

Reflection

The specification was the starting point, not the work. The work was deciding what the specification meant, choosing an architecture proportionate to the problem, and proving the result correct before calling it done. A time-boxed build makes those trade-offs visible in a way that open-ended projects never do.