← All projects
Case study · Personal finance · Risk assessment

Netted

A personal-finance app for realized trade profit, shared investment funds and budgeting. I wrote the accounting rules before any code, enforced MFA inside the database, and wrote a security assessment for non-technical decision makers.

Status
Deployed beta, private source
Timeline
September 2026
Stack
Next.js, TypeScript
Works with
Supabase (PostgreSQL, Auth), Vercel
Netted sample workspace: a realized-profit chart and a contribution split, all fictional data
The public sample workspace runs on fictional data that never leaves your browser.

Key decisionFix each contributor's share at purchase time and keep corrections as reversals, so every number can be traced back without rewriting history.

What it shows

Risk written for decision makers

An assessment that explains each control in business terms, with a scorecard and a 7-item risk register.

MFA the API can't skip

A Google password alone doesn't open financial records. Database functions require a verified identity, a live session and an authenticator code.

Exact accounting

Integer cents and exact share quantities. A missing cost basis goes to review instead of being guessed.

A recovery drill

An encrypted backup restored into an isolated database, with every journal record and cent total matched.

Security assessment

I wrote the assessment for people who decide whether a product ships, not for engineers. It explains each control in plain terms, says what the evidence shows, and concludes that the protections work but the app isn't ready for release yet.

Assessment scorecard: measure, result and what it means
MeasureResultWhat it means
Live site checks26 passedIncluding 5 forged-origin and 5 signed-out requests, all refused
Security and recovery tests18 passed17 security regressions and a schema rollback
Dependency advisories0 across 520No published flaw in any dependency at review time
Release conditions0 of 4 closedAdmin access review, backups, hosting eligibility and an outside review

The risk register tracks 7 open items: 4 high-priority release conditions and 3 medium operating ones. Each has an owner, a deliverable, a measurable acceptance test and a due date, such as "100% of privileged accounts have MFA" and "1 successful full restore with record counts and cent totals reconciled."

Controls

Imports stay on the device

Brokerage CSV and PDF files are parsed in the browser, and only the trades the user reviews are saved. Files are capped at 2 MB and 2,000 rows; PDFs at 20 pages and 15 seconds, read as text only.

No local copies

Financial records never go to browser storage or offline caches. Signing out clears private state, and responses tell browsers and shared caches not to keep copies.

Ownership checked on every write

Direct table writes are denied, and tests confirm one user can't read or reference another user's records.

Isolated from my other apps

Its own hosting project, database and sign-in. The build refuses any other database host and rejects secret keys in public settings.

Recovery drill

I restored the encrypted backup into an isolated local database and compared it with the original. All 506 journal records, 8 corrections and 280 current records matched, cent totals and hashes included. The release migrations changed none of the original records.

Accounting rules

Netted started as an Excel budget. Before building it, I wrote down the rules the spreadsheet had been applying informally:

Example. Buy 10 shares at $100 with a $5 fee, then sell 4 at $120 with a $2 fee. The cost basis of the 4 shares is $402, net proceeds are $478, and realized profit is $76. Split 60/40, that's $45.60 and $30.40.

Limits

Discuss Netted

Ask about the risk register, MFA in the database or how a spreadsheet's rules became a web app. Email me at aagarwalcollege@gmail.com.

Project screenshot

Open original ↗

View full size to read details. Scroll or swipe to move around the enlarged image.