Inspiration
Every finance team eventually hits the same wall: a payment gateway settles ₹10L, but only ₹9.42L lands in the bank, and nobody can say why. The gap gets written off, buried in a spreadsheet, or chased for hours by a controller cross-referencing fees, refunds, and taxes by hand. We wanted to build something that treats that gap as a first-class problem, not a footnote and refuses to let a transaction get booked until the discrepancy is actually explained.
What it does
FINOVA reconciles payment-gateway payouts against real bank settlements using pure deterministic arithmetic — Expected Net Payout = Gross − Fees − Refunds − Taxes ± Adjustments, compared line-by-line against what actually landed. When the numbers match, it's reconciled automatically. When they don't, the payout is routed into the Controller Workbench, a guided, multi-stage workflow: Exception Queue → Investigation → Proposed Correction → Policy Proposal → Policy Backtest → Close Run → Audit Trail, that keeps a human controller in the approval loop and logs every decision to an immutable audit trail. Nothing gets booked that FINOVA can't explain.
How we built it
Next.js (App Router) + TypeScript end-to-end, API routes as the backend (no separate server), Prisma ORM on PostgreSQL for persistence. The reconciliation logic is kept as plain, testable TypeScript functions rather than an LLM call, since the one number a finance tool can't get wrong shouldn't be probabilistic. State that used to live only in memory — the Workbench's stage progression, the audit trail — was moved into real Prisma models so it survives restarts and works correctly on serverless infrastructure. The whole thing is deployed on Vercel.
Challenges we ran into
- Migrating off SQLite mid-build. The project started on a local SQLite file; moving to Postgres meant re-pointing the Prisma schema, re-seeding demo data, and making sure the Prisma Client singleton (globalForPrisma) was actually safe under Next.js's dev-mode hot reloading, which otherwise exhausts connections fast.
- A live Next.js CVE blocking deployment. Vercel started rejecting the build outright over a critical vulnerability in the pinned Next.js version. Fixing it meant carefully picking the smallest safe upgrade within the same major version, not just grabbing latest but checking React/Prisma compatibility first, and separately dealing with an unrelated build failure caused by Next's stricter workspace-root detection.
- Finding out our own architecture diagram was wrong. While screenshotting the app for documentation, we discovered /overview doesn't actually render an overview dashboard at all — it renders the Controller Workbench. The intended metrics dashboard component existed in the codebase but was never wired into any route. It was a good reminder that documentation drifts from reality fast, and the only way to catch it is to actually click through the running app, not just read the source.
Accomplishments that we're proud of
- Deterministic reconciliation math that actually catches real discrepancies (PO-1025's ₹18,000 gap flagged correctly, PO-1024 clears clean) — zero LLM in the arithmetic.
- Every decision is durable, not in-memory — the Workbench and audit trail are fully Postgres-backed via Prisma.
- The full approval chain works end-to-end: evidence → investigation → controller review → accounting entry → audit log.
- We caught and fixed a live Vercel deployment block (critical Next.js CVE) with a minimal, compatibility-checked upgrade verified with a real production build.
- We kept correcting the docs against the real running app instead of letting them drift.
What we learned
That deterministic-by-default is a feature, not a limitation — for a financial product, "we can't fully explain this number" is a worse failure mode than "this took longer to compute." And that keeping a paper trail of actual implementation status (what's live vs. placeholder) matters as much as building the features themselves, especially once the codebase is bigger than any one person holds in their head.
What's next for Finova
- Wire up the placeholder screens (Accounts, Transactions, Invoices, Payroll, Reports, Treasury, Settings) with real Prisma-backed data — they're scaffolded but not yet live.
- Turn the AI Agent Orchestrator from a UI mock into a real backend — actual agent calls instead of static demo data, still kept out of the financial-arithmetic path.
- Replace the demo evidence providers (gateway disputes, reserve withholding) with real integrations against RazorPay/Stripe APIs, so investigations pull live gateway data instead of seeded fixtures.
- Add real multi-tenant auth — today it's a single seeded company with no login; production use needs actual user accounts and org-scoped access.
- Expand reconciliation beyond payouts — the same deterministic-match-and-explain model applied to bank statements, invoices, and payroll, not just gateway settlements.
Built With
- css
- lucide-react
- modules
- next.js
- orm
- postgresql
- prisma
- react
- recharts
- router
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.