Aforro Tracker
A private web app for people in Portugal who hold savings certificates (Certificados de Aforro and do Tesouro), valued from public rates.
- Role
- Sole developer
- Year
- 2026
- Outcome
- A holder enters their own lots and sees what each is worth today and why, and how certificate types compare for new money, without ever handing over the login for the official portal.
- Built with
- Vue 3, TypeScript, Vite, PWA, Dexie (IndexedDB), vue-i18n, big.js, Vitest, fast-check, Playwright, axe-core, GitHub Actions

Why I built it
Savings certificates are popular in Portugal, but the official portal shows little history, and comparing the two kinds means doing the sums by hand. Some third-party tools ask for the portal password, which the issuer warns against.
What it does
Portfolio
The total held, interest earned this year and since the start, the split between Certificados de Aforro and Certificados do Tesouro, a filter per holder, and every lot with its next event. A What's new card is worked out on the device: a new month's rate, a lot that can now be redeemed, a coupon coming up, the minimum for Tesouro reached, or a change in which product leads.

Adding lots without a password
It never asks for the official portal's login. Lots are typed in with the same columns as the official statement, or pasted: you copy the balance table from your own portal session, and the app reads it on the device, with a preview that marks each row ready, a duplicate or a problem before anything is saved.

Each lot
Current value, the unit value to five decimals, gross and net interest, tax withheld, the current loyalty-premium tier and when the next one starts, the next capitalisation or coupon, and a redemption guard: "redeeming today loses about this much interest; the next value date is in N days".

Why this value?
Every figure can be opened to show how it was worked out: the inputs, the formula, every rate with its source and the date it was read, the tax and the rounding. If a month's rate is missing, it says which one and shows no number rather than a guess.

Decide
For new money, the two products side by side over a chosen horizon, under a scenario for the interest rates not yet published, with checkpoints at 1, 2, 5, 10 and 15 years, a chart with a table beside it, and every projection labelled as an estimate. For money already invested, each lot ranked by what moving it would cost today. Strategies compares three ways of saving the same amount every month. The wording is tested so that it never says "should".

Goals, holders and a page for the heirs
Goals with a target, a deadline and a reserve; one label per holder, never a tax number; and a printable page for the heirs with every lot valued today and plain guidance on what they need to do.

How it works
- Nothing leaves the browser
- Holdings live in the browser's own database. No accounts, no sync, no analytics, no outside fonts. The content security policy allows connections to its own address only, so the browser itself blocks anything else. A backup is a file you save, optionally encrypted with a passphrase.
- Rates as data
- The issuer has no public API. A scheduled job reads its public pages and the ECB's monthly Euribor, checks every record for changes in format, runs the engine's tests against the new data, and commits each rate with its source address, the time it was read and a hash, then rebuilds the app. Past values are never overwritten.
- A pure engine
- The valuation engine is plain TypeScript with no interface, no input or output and no clock: exact decimal money, calendar dates and a book of dated rates. It returns every value together with its explanation, which is what the "Why this value?" screen shows. The household finance app values certificates with the same engine.
How it is built and tested
- Tests
- About 150 tests. Golden tests reproduce 27 lots taken from the issuer's own simulator to the fifth decimal, and property tests check that removing any month the sum needs makes it fail and name that month. End-to-end runs in Chromium and WebKit go through every screen, with an accessibility scan that must find nothing.
- The rounding
- Rounding each lot to the cent reproduced none of the 27 captured lots. The rule that does (round the unit value to five decimals after every quarter, and show cents only at the end) was worked out from them.
- Decided before code
- The plan was settled in 38 recorded decisions and ten architecture records before any code was written. Research showed that several rules in the first brief were wrong, so every formula cites its source.
How Atta helped
- The plan was grilled before any code: 38 decisions settled one question at a time.
- The research became wiki pages (the rounding model, where the rates come from), so each later session starts from them instead of rediscovering them.
- Atta generated a team for the stack: Vue, TypeScript, Vitest, Playwright and accessibility.
- Its valuation engine was later reused unchanged by the household finance app.