After saving an expense, checks if the category budget reaches 75%,
90%, or 100% thresholds. Sends gio::Notification for each newly
crossed threshold. Tracks sent notifications in database to prevent
duplicates within the same month.
set/get/list/delete budgets per category per month. Budget progress
calculates spent vs budgeted percentage. Copy budgets from one month
to the next. Seven new unit tests covering all operations.
ExchangeRateService fetches rates from fawazahmed0/exchange-api with
Frankfurter API as fallback. Rates are cached in SQLite for 24 hours.
Includes response parsers, 30 supported currencies, and 8 unit tests
covering parsing, caching, and same-currency identity.