Victor Pasqualini
CV
All projects

The rule that defines the product

On a spreadsheet a contribution looks like money out and a yield looks like money in. That is correct bookkeeping and ruinous reporting: adding those rows to the cash flow inflates income and expense at once, and destroys any sense of what you actually spend and save. So every row falls into one of five buckets, and only two of them feed the cash flow.

src/lib/types.ts: the whole product in one union
export type Bucket =
  | "income"           // feeds the cash flow, as money in
  | "expense"          // feeds the cash flow, as money out
  | "invest_contrib"   // a contribution is not spending
  | "invest_withdraw"  // a withdrawal is not income
  | "invest_yield";    // a yield is not income either
The investments screen, where contributions and yields are the subject (demo data)

It reads your sheet, not a new format

Paste a OneDrive share link and the reader converts it into a download URL, guesses the header row and the columns by keyword, and shows you the first rows to confirm. .xlsx, .csv and .tsv all work; the .xlsx reader is written in-house on top of fflate, so the only real dependency is a zip decoder.

Brazilian formats are read as they are, with no configuration
date         description        amount        segment      asset
04/09/2026   Mercado            R$ 312,45     Mercado
05/09/2026   Aporte Tesouro     (R$ 500,00)   Investimento Tesouro Selic
10/09/2026   Salário            R$ 8.400,00   Renda

# dd/mm/yyyy, "R$ 1.234,56" and parentheses-as-negative are read as they are.
# The filled "asset" column is the strongest signal that a row is an investment.

No database, on purpose

Nothing is imported and nothing is stored: add a line in the sheet, click refresh, the dashboard moves. The fetch is cached for 60 seconds and guarded against SSRF, and the only persisted state is a local config file: the link, the tab, the column mapping and the classification rules. Delete it and the app is new again.

The month panel reading a spreadsheet straight from disk; the header names the file

Five screens, and charts that cannot go off-palette

A month panel, an investments screen where contributions and yields are the subject rather than noise, a credit-card screen, the full filterable ledger (including the rows the reader could not interpret) and the configuration. The charts are hand-written SVG and never read a hex value: every colour comes from a custom property, so light and dark themes cannot drift apart and no component can escape the palette.

The credit-card screen: hand-written SVG, and every colour from the palette
Next projectPouch

Almost nothing works; the hard part is telling which. Research first, testnet money only.