Private Equity Operations
Cloud-Native Multi-Entity Finance Management Application
A serverless, multi-entity financial management application — Vue 3 front-end, FastAPI on AWS Lambda, PostgreSQL — built for the operations side of a private investment portfolio.
- Role
- Architecture, full-stack engineering, AWS infrastructure
- Duration
- Ongoing
- Sector
- Private Equity Operations
What was on the table
The strategic partner — a private investment equity company — was running portfolio-company finance on a mix of QuickBooks instances, NetSuite for the larger holdings, and an uncomfortable volume of spreadsheets bridging them. Consolidated reporting required a finance manager to manually reconcile cross-entity entries every month.
They needed a purpose-built application: multi-entity, role-scoped per portfolio company, serverless (because portfolio-wide usage varies wildly), and ergonomic enough that operators in non-engineering portfolio companies could use it daily.
What we built
A Vue 3 + TypeScript single-page application sits on top of a FastAPI backend deployed on AWS Lambda behind API Gateway. PostgreSQL — RDS — holds the books.
The data model is multi-entity from the ground up: every transaction, account, and journal entry is scoped to an entity (portfolio company), with explicit support for inter-company transactions. Consolidated reporting runs against the canonical model rather than reconstructing relationships post-hoc.
Authentication and authorization are role-scoped per entity — a finance manager at one portfolio company sees only that company’s books, while a portfolio-level controller sees the consolidated view. Role assignments are auditable and time-bounded.
The reporting layer connects out to NetSuite (for portfolio companies running NetSuite as their primary ERP) and to banking partners via direct API integration. A scheduled reconciliation pipeline matches bank-side transactions against the in-app journal and surfaces discrepancies for review.
How we got there
The serverless choice was deliberate. Some portfolio companies are small and use the application a few times a month; others run hundreds of transactions a day. A traditional always-on server tier was the wrong cost shape. AWS Lambda gives us per-request scaling and idle cost near zero.
The trade-off is that Lambda imposes architectural discipline: cold starts must be acceptable, package size must stay small, and connection pooling against RDS requires explicit handling. We invested in those constraints upfront — pooled connections via RDS Proxy, layered Lambda packages, and provisioned concurrency on the most-hit endpoints.
The Vue 3 SPA is uncompromising on TypeScript discipline. Every store, every API call, every component prop is typed. Type-safe contracts are generated from the FastAPI OpenAPI spec, so a backend route change that breaks the front-end is caught at compile time, not at runtime.
What changed for the business
Consolidated reporting now runs in seconds against the canonical multi-entity model. Inter-company transactions are first-class records rather than spreadsheet annotations. Bank-to-book reconciliation runs nightly with exception escalation, replacing what used to be a multi-hour monthly task.
The serverless cost model is doing its job: portfolio companies that use the app intensively pay (in compute time) for what they use, and quiet portfolio companies cost effectively nothing.
What this looks like as a service
If you operate a portfolio of businesses and your “system” is a folder of Excel files held together by one finance manager’s institutional memory — there is a better answer. We have built it.
Have a system that needs this kind of work?
We take on a small number of engagements at a time. If your problem rhymes with what's above, get in touch.
Start a conversation