A small business goes to a bank, a leasing company or a tender with one question: what does its trading look like to whoever decides. The answer is scattered across account movement, lease agreements, loan schedules, card acquiring, cash collection, payroll and tax load, and it is nowhere assembled. The system assembles it into one working model — who pays whom, for what, on what schedule — runs that model month by month against limits, contractual dates and taxes, and answers three practical questions: where the risk is, where headroom is left, and what a credit analyst will see.
The hard part is placing a flow of payments so that five constraints hold at once: the balance reconciles every day, no counterparty exceeds its limit or its share of turnover, the month stays under its ceiling, and the period closes on exactly the balance asked for. It is solved in layers — a plan, a check against the daily calendar, a sweep of the remainders, and a final pass that distributes the gap across whoever still has headroom, or says plainly that there is nothing left to close it with.
One principle holds the rest up: the model is the source. Monthly cash flow, analytics, the tax return and the note you carry into the bank meeting are derivatives — throw them away and they rebuild; the model cannot. Money moves as strings and is computed on Decimal, never through a float. The frontend's API types are generated from the backend's own OpenAPI contract, so a version bump breaks the build instead of someone's screen. Progress on long jobs goes over SSE rather than WebSocket, because a WebSocket would have needed the token in a query string, and from there it lands in the logs. A year of work; an internal product, in production on two stands, with no public sign-up.
Next.js 16 · React 19 · TypeScript strict · Tailwind v4 · Zustand · FastAPI · PostgreSQL · Redis · object storage · Docker