SaveMyMoneyNow
Import statements without tying the product to one template
In one line
SaveMyMoneyNow turns statements into a spending dashboard. It finds the header row, proposes a column mapping and waits for the user to confirm before importing.

The problem
SaveMyMoneyNow receives spreadsheets where the header can appear after several information rows. Column names, dates and decimal formats also change between files.
A dedicated reader for each layout would mean maintaining the same logic several times. The wizard looks for the file structure and lets the user correct its proposal.
How it works
The header is detected from its content
A wizard scores the first rows, keeps the one that looks like the header and proposes which column is Date, which is Description and which is Amount, reading both the name and what sits underneath. You confirm or correct.
The duplicate fingerprint leaves the amount out
The fingerprint uses date and description. This keeps a purchase corrected after a partial refund from becoming a new movement when the month is imported again. The amount stays separate for auditing.
Import batches expire on their own
What the wizard produces lives two days and Mongo deletes it; the final movements never expire. Picking the wizard back up too late returns a 410 with its explanation, rather than working on half-finished data.
The PDF has a cap and the spreadsheet doesn't
PDF exports accept up to five thousand rows because the library builds the whole document in memory. Spreadsheet exports write as they go and can handle larger histories.
The tests build the statements they are going to read
They spin up Mongo in memory and build statements with different layouts during the test. Each case declares the structure it expects to read.
Where the bar sits
- 21 endpoints
- 113 test cases
- 9 wizard steps
React, Node, Express and MongoDB. Tests with Vitest and in-memory Mongo.