Investment Intelligence Dashboard
Problem
The family office invests in everything: public stocks across several brokerages, interests in private equity and venture funds, and stakes in operating companies. Each one reports in its own format. Capital account statements, capital call notices, K-1s, fund financial statements, brokerage statements and investor letters arrived by email or sat behind fund portals.
The family office paid several people to keep several spreadsheets up to date, and even then the spreadsheets didn't capture everything. Nobody could see the whole picture. Answering "how is the portfolio doing?" or "which companies are inside this fund?" meant opening PDFs. Keeping current meant someone downloading statements, sometimes signing into portals to get them, and typing numbers somewhere.
Approach
The core problem was reading the documents reliably. Financial PDFs come in dozens of layouts, so I didn't write a parser for each one. Claude reads each PDF directly and has to choose one of eight extraction formats: capital account statement, account summary, capital call or distribution notice, K-1, fund financial statement, brokerage statement, performance report, or narrative (letters and decks). Choosing the format is the classification. The output is validated before anything is written. In the first batch run, 87 documents went in with no errors and none misclassified.
Two rules shaped everything else:
- Every number knows where it came from. Each figure in the database links back to the source document, so any number on the dashboard can be traced to a page.
- Automate what's clean, queue what isn't. The nightly run ingests clean PDFs on its own. Anything it can't handle safely goes in front of a person: a password-protected file, a link to a portal, figures written in an email body.
How it works
Every night, while everyone's asleep:
- Read the inbox. The system reads the principal's Outlook mailbox since the last run. Claude sorts each investment email: an update on a known holding, a new investment, a pitch, or not investment-related.
- Ingest what it can. Clean PDF attachments go straight through extraction. Files it has already seen are skipped by fingerprint, so a statement forwarded twice isn't counted twice.
- Queue what it can't. Portal links, protected PDFs, other attachments, and numbers in an email body go to a review queue, with instructions for what to do. A document uploaded from the queue is processed in a minute or two through the same pipeline.
- Pull from Carta. The newest piece. The system checks Carta for new fund documents, pulls them in, and clears the Carta notification emails that were waiting in the queue. Before, someone had to sign into Carta, download each document, and upload it by hand.
- Refresh and recompute. Closing prices for every public holding are refreshed, then performance is recalculated.
- Check for problems. A Claude agent with a short list of narrow tools runs three checks and posts anything it finds to "Needs attention": an operating company's revenue or EBITDA down more than 10% from the prior period, a fund more than 20% below cost, and data going stale (a fund with no statement in 150 days).
What I shipped
The breakdown
The overview shows total value and gain or loss across about two hundred holdings, by asset class. The breakdown goes one level down. Public securities are grouped by brokerage, with what was invested, current value, the one-day change, and total gain or loss for each position.
Fund pages and tear sheets
Each fund has its own page: what's been contributed, the latest value from the capital account statement, the whole fund's NAV (kept separate, because it's not this investor's money), series, positions and metrics. From there, one button builds an investor tear sheet. It's a two-page report modeled on the ones the family office used to make by hand, with performance metrics, a capital account summary, transaction history, and a NAV chart. The tear sheet is plain code and math, not AI. The template is fixed and the return figures (IRR, DPI, TVPI) are calculated, so the same inputs always produce the same report. It previews instantly and prints to PDF.
Ask Your Portfolio
The chat answers questions about the whole portfolio, typed or spoken: which companies sit inside a given fund, what was called last quarter, which holdings are behind. Claude writes its own database queries, but only through a read-only connection with a time limit, so it can look and never change anything. It's told never to add the whole fund's value to the family's share of it, and to ask one clarifying question instead of guessing. It can also generate a tear sheet on request.
Under the hood
Vue on the front end, installable as an app on a phone. Supabase for the database, sign-in, document storage, and the chat's backend. The nightly run and on-demand uploads are GitHub Actions, and the reading, sorting, checking, and chat all run on Claude.
Outcome
Instead of several people keeping spreadsheets that still missed things, the family office has one current view of the entire portfolio, rebuilt every night from the documents themselves. Statements that arrive by email are in by morning. The ones that need a person are waiting in a queue with instructions, and Carta documents no longer need anyone at all. Questions that used to mean opening a stack of PDFs now take one sentence.