My partner and I have separate bank accounts and credit cards. We split a mortgage and a few bills through a shared account, but most of our day-to-day spending happens independently, and we've always just sort of kept a mental tally and periodically reconciled. We hadn't done it since 2023, so it was time to sit down and actually figure out who owes whom what.

The problem is that, while my financial data lives in a Firefly III instance I self-host, where I upload CSVs from the bank and everything gets neatly auto-categorized, my partner's lives across a patchwork of CSV exports and PDF bank statements. I had actually started this project about a year ago -- I got as far as extracting all the data from the PDFs and then ran out of steam. So I was picking up a half-finished mess that past-me had left behind, which is always fun.

I used Claude as an assistant for the whole thing, and it was genuinely great. I had it start by reading through everything from my first attempt and making sense of what was already there, and then I had it keep a running journal of everything we did together. This turned out to be a great idea. Whenever I had an hour or two, I'd just ask it to re-read the journal and we'd pick up right where we left off. Once we got to a comfortable stopping point, I would just tell Claude to log everything in the journal, and go to bed.

The first chunk of work was building a transaction merger that could take the mix of PDFs and CSVs and combine them into one unified file. Claude was actually quite messy here. It wasn't dropping transactions or anything, but it would do weird things like not make sure that dates were properly sorted. This is when I had to be very explicit about telling it to check before/after counts at every step, making sure date formats were consistent, everything was sorted, and that each source file's date range was fully accounted for.

After that, Claude and I built a labelling tool for my partner to go through their transactions and mark everything that counted as a shared expense. This was quite fun, and basically a miniature UX + product design session. The tool is a single-file static HTML page (Bootstrap CSS, vanilla JS, no build step) that you can open in the browser, then load a transaction CSV and start going through.

It ended up with a pretty solid feature set:

Then a script to pull my transactions out of Firefly into a matching CSV format. This one was straightforward -- it hits the Firefly API, paginates through everything, skips transfers and reconciliation entries, and spits out a CSV with the same schema as my partner's file, except with a category column instead of shared. I already had all my transactions categorized in Firefly, so instead of labelling individual transactions I could just pick which categories count as shared spending.

Then I brought it all together into a LibreOffice spreadsheet. My partner's labelled transactions on one sheet, my Firefly export on another, and a summary sheet that computes monthly totals side by side, calculates each person's fair share based on our agreed split ratio, and tells us who owes whom. I don't use Excel & Co. enough to remember all the weird paradigms for conditional selection, etc., so Claude was immensely helpful here.

And then comes the fun part: Amazon.

We had deliberately left all Amazon transactions out of everything above, because they're a nightmare. The charges on your credit card are essentially random amounts that may or may not correspond to a full order, a single item, shipping, or some combination thereof.

Amazon does offer a data export function where you can request all your order history as a CSV. The CSV they send you has 28 columns, at least six of which contain dollar amounts: Unit Price, Unit Price Tax, Shipment Item Subtotal, Shipment Item Subtotal Tax, Shipping Charge, Total Amount, Total Discounts. Which one is the correct one to use if you want to know what you paid for each item? Great question.

I spent a painful session getting Claude to cross-reference that CSV against actual credit card charges and a handful of PDF invoices downloaded from Amazon, trying to figure out which column actually represents "what I paid for this thing." If you're curious, it turns out that Total Amount is the one you want -- it's per-item, post-discount, post-tax. And then there's a whole zoo of edge cases: multi-shipment orders producing multiple credit card charges, quantity-2 items split across packages with concatenated tracking numbers, orders from a different Amazon regional store where some fields are in a different currency, numeric fields containing the string "Not Available," discount values wrapped in extra quotes. I remember starting to figure this out last year and giving up very quickly. The journal has a section titled "Amazon data oddities," which should tell you everything you need to know about how that went.

But we got there. The extraction script filters to the right date range, maps each payment method to a person (we have separate cards on the same Amazon account), runs a sanity check per shipment, and produces a clean CSV with one line per purchased item.

Then we expanded the labelling tool to support this new format: it auto-detects which CSV schema it receives and switches modes. After loading it I immediately closed it: Amazon product names are completely unhinged. You're scrolling through hundreds of entries like "Sleek Socket Ultra-Thin Child Proofing Electrical Outlet Cover with 3 Outlet Power Strip and Protective Cord Cover Kit, 8-Foot, Universal Size, UL/CSA Certified," which are impossible to skim.

So we built one last tool: a little script that feeds each product name to a small local LLM and asks it to extract a brand name and a sensible short description. It deduplicates by product name first so each unique title only gets sent to the model once, then writes out a new CSV with the brand as a separate column. That monstrosity then becomes "[Sleek Socket] Outlet Cover with Power Strip" in the tool. A smart plug with a 60-word name becomes "[SONOFF] ZigBee Smart Plug (4-pack)." The labelling tool renders the brand dimmed and smaller before the product name, so you can scan through quickly without your brain melting.

After all that work over many weeks, I tallied everything up and discovered that I owe my partner about twenty thousand dollars. Most expensive Claude subscription ever.