shouldivibecodeit

Should I vibe codeAuritrack?

AI-native expense tracker that does your bookkeeping from chat messages and bank statements

A tracker that is 97% right is worse than none, because you will trust the total and stop checking.

?

Their verdict, the Plus price and the build-time estimate come from their entry, MIT-licensed. Checked 2026-08-04.

Can you build it?asked by canivibecodeit.com ↗KINDAweekend project · weekend
?

Our verdict, the regret score and everything below it. Editorial and unsponsored — nobody can pay to be moved.

Should you ship it?asked by usDEMO ONLYvibe the v0, throw it away.

The honest answer

why the verdict is what it is

A Telegram bot that turns "spent 42 on lunch" into a row in SQLite is a genuinely delightful Saturday, and for a week it will feel better than any commercial app. Then the arithmetic starts drifting. Extraction gets confidently wrong on the cases you cannot see: a European statement where 1.234,56 means one thousand and not one, a receipt in a second currency logged at today's rate, a date parsed as the fourth of December when the bank meant the twelfth of April, a re-uploaded PDF that duplicates six weeks of transactions because nothing enforced idempotency. None of these throw an error. They produce a total, and the entire point of a tracker is that you stop checking the total. The other half is what you feed it: a bank statement PDF is not an expense list, it is your account number, your balance, your salary, your landlord and every counterparty you have, and the naive build posts the whole thing to a model provider to recover three fields. Build it, use it, enjoy it — just decide up front whether you are willing to file a tax return off numbers you have not reconciled against anything.

What actually breaks

not "if". the specific failures.

  • Number extraction, silently. 1.234,56 in a European statement, a trailing CR for credit, a negative in parentheses, a currency symbol the model helpfully drops — each produces a plausible figure and no error
  • Date parsing, where 04/12 is the fourth of December to your bank and the twelfth of April to the model, and the mistake only surfaces when a month's total looks slightly off a year later
  • Duplicate imports, because re-uploading a statement that overlaps the last one is the most natural thing a user does and nothing in the naive build makes a transaction unique
  • The privacy trade you did not consciously make: the whole statement page goes to a model provider to extract three fields, carrying your account number, your balance, your employer and every counterparty on it
  • The Telegram bot token, which is a credential that lets anyone holding it read and write the chat where your entire financial history is being typed
  • Reconciliation, or rather its absence — with no bank connection there is nothing to check your ledger against, so an error introduced in March is still there in December
  • Category drift, since an LLM classifying free-text will invent "Groceries", "Food", "Food & Drink" and "groceries" over six months unless the categories are a closed list
  • Multi-currency, which is where homemade trackers universally cheat: storing a converted number instead of the original amount, currency and rate makes every historical figure unrecoverable
  • The tax story, if this is business bookkeeping. A categorised total with no link back to the source document is a summary, not a record, and the substantiation requirement is about the record

Is that you?

the verdict is a default, not a law

ship it if
  • It is your own spending, in one currency, and you look at the numbers often enough to notice a wrong one
  • Every extracted transaction keeps the raw source text and a link to the document it came from
  • Statements are parsed locally, or redacted before anything leaves your machine
  • You are using it to see patterns rather than to produce a figure anyone else relies on
don’t ship it if
  • A tax return, an expense claim or an invoice to a client will be computed from these numbers without a human reconciling them
  • You are uploading full bank statements to a model provider without having read what that provider retains and for how long
  • Anyone else's finances go in, at which point you are holding somebody else's bank data in a weekend project
  • There is no export and no backup, because a personal ledger with no second copy is one dropped volume from starting over
  • Amounts are stored as floats, or as a single converted number with the original currency thrown away

If you build it anyway

the checklist, then the prompt that enforces it

  1. Store money as integer minor units with an explicit currency code, never as a float and never pre-converted. If a conversion happened, keep the original amount, the currency and the rate as separate columns.
  2. Make every transaction idempotent on a natural key — date, amount, normalised description, account — so re-importing an overlapping statement is a no-op rather than a doubling.
  3. Keep the raw input next to every extracted row: the original message text or the source page and line. Without it you cannot ever audit a number, and auditing is the only defence against silent drift.
  4. Extract with a strict schema and reject anything that does not fit. A model returning a number it is unsure about should return null and queue the item for review, not guess.
  5. Redact before the model call. Account numbers, balances and names are not needed to categorise a transaction, and Article 5's minimisation principle is a good instinct even when nobody is enforcing it against you.
  6. Fix the categories as a closed enum and force the model to choose from it. Free-text categorisation produces four spellings of Groceries and no usable report.
  7. Run a reconciliation check even without a bank connection: assert that the opening balance plus the parsed transactions equals the closing balance printed on the statement. It is one line and it catches most extraction failures.
  8. Rotate and scope the bot token, and keep it out of the repository. The chat log is a complete financial history in a place with no access control of its own.
  9. Export to CSV on a schedule and keep it somewhere else. The ledger is the asset; the app is not.
the guardrail prompt
I am building a personal expense tracker that takes free-text messages and bank
statement files and turns them into ledger entries with an LLM. Silent numerical
error is the failure I care about, not a crash. Build in this order.

1. Set the money model first: integer minor units plus an ISO currency code. Never
   floats, never a pre-converted single number. If a rate was applied, store the
   original amount, currency and rate separately.
2. Every transaction row keeps its raw source — the exact message text, or the file,
   page and line it came from. Nothing is stored that cannot be traced back.
3. Make ingestion idempotent before it is clever: a natural key of date, amount,
   normalised description and account, with a unique constraint. Re-importing an
   overlapping statement must be a no-op, and I will do that on my first day.
4. Extraction returns a strict schema and is allowed to fail. Anything ambiguous
   returns null and lands in a review queue. Never let the model guess a number.
5. Redact before the model call — account numbers, balances, names, addresses. You
   only need date, description and amount to categorise. Tell me what you stripped.
6. Categories are a closed enum I define. The model picks from the list or returns
   unknown. Refuse to let it invent category names.
7. Add the reconciliation check: opening balance plus parsed transactions must equal
   the closing balance printed on the statement, and flag loudly when it does not.
   This is the single highest-value test here — write it before any UI.
8. Handle the parsing edge cases explicitly and show me the tests: 1.234,56 versus
   1,234.56, trailing CR/DR markers, negatives in parentheses, DD/MM versus MM/DD,
   and multi-line descriptions.
9. Secrets — bot token, model key — from the environment, never committed, and the
   chat surface treated as an untrusted public channel.
10. Ship a CSV export and a scheduled backup before any charts. Out of scope: bank
    connections, multi-user, sharing. If I am filing taxes off this, tell me to
    reconcile against the statements by hand and that Auritrack is $3 a month.
paste this before you build — not after something breaks29 lines · 2129 chars

That one keeps you out of trouble. For the prompt that actually builds it, canivibecodeit.com has one.

their build prompt ↗

Or don’t build it

the boring option, and the way back out

just pay for it

Three dollars a month is roughly the cost of thinking about this for ten minutes, and the free tier already covers manual tracking. The honest comparison is not price, it is who owns the extraction bugs. A commercial tracker has had its statement parsers broken by a thousand different banks and fixed; yours has been tested against one. Buy it if the numbers feed anything official. Build it if you want the Telegram bot, which really is the fun part and really is a weekend — and consider bolting it onto Firefly III's API rather than writing a ledger from scratch.

$3/mo is cheaper than your weekend.

your exit plan, if you already built it

The ledger is the only thing worth keeping, so make it portable from the first commit: one CSV per year with date, amount in minor units, currency, category, description and a reference to the source document, written on a schedule to somewhere that is not the app's own disk. That file imports into Firefly III, Actual Budget, a spreadsheet or an accountant's system without argument. If you have been sending statements to a model provider, go and check what that provider's retention policy actually says while you still care, and delete anything you can. And if the tracker is feeding a tax return, keep the source statements alongside the CSV — the summary is not the record, and the record is what gets asked for.

prior art · someone already did this
Firefly III

Mature self-hosted personal finance manager with a full API, a proper double-entry ledger and a CSV importer — the right base to bolt an LLM front end onto instead of inventing a ledger.

Actual Budget

Open-source local-first budgeting app with strong transaction import and reconciliation tooling.

Questions

Nothing here is dangerous. Why isn't this SHIP IT?

The verdict is not about danger, it is about the gap between the demo and the product. The demo — text a message, get a row — takes a weekend and works immediately. The product is a ledger you can still trust in eighteen months, and that needs idempotent imports, a reconciliation check, closed categories, currency handled properly and the raw source kept next to every number. None of that is hard; all of it is the part people skip, and skipping it is invisible until the totals are already wrong.

Is uploading a bank statement to an LLM actually a problem?

It is a choice, and most builds make it without noticing. A statement page carries your account number, running balance, employer, landlord and every counterparty — and categorising a transaction needs only the date, description and amount. Redact before the call and you keep the feature while giving away three fields instead of your financial life. Read the provider's retention terms too; "we do not train on it" and "we do not store it" are different sentences.

What's the single test worth writing?

Opening balance plus the transactions you parsed equals the closing balance printed on the statement. One assertion, and it catches missed rows, duplicated rows, sign errors and decimal-separator confusion in one go. If it fails, the import is rejected rather than partially applied. Most homemade importers have no equivalent, which is why they drift quietly.

Does the no-bank-connection design make this safer?

Safer in one direction and worse in another. Not holding bank credentials removes the scariest failure mode, which is why the product advertises it. But it also removes the thing that would catch your mistakes: with an API feed the numbers are authoritative, whereas a statement parsed by a model is a guess with no second opinion. That is exactly why the reconciliation check has to do the job the bank connection would have done.

sources
  • IRS — what kind of records should I keep
  • GDPR Art. 5 — principles relating to processing of personal data
did you build it?

Every week, someone ships something they shouldn’t have.

New verdicts, the worst thing that landed in the trap, and the occasional incident report. No other email, ever.

also on the regret index
YNABDEMO ONLY

Your own budget, your own rules, your own bug that told you you had money.

Monarch MoneyYOUR FUNERAL

Add a second person and "my risk, my problem" stops being true. You are now someone else's bank-data custodian.

Copilot MoneyYOUR FUNERAL

Your bank feed is read-only. Your database isn't — it's a map of everywhere you go and everyone you pay.

last reviewed 2026-08-04 · verdict is editorial and unsponsored · shared entry data from canivibecodeit under MIT · not legal advice