# Changelog ## 2026-05-24 21:58 CEST — feat(fees): update adult monthly rates for 2026-05 through 2026-08 - 2026-05: 700 → 450 CZK; 2026-06/07/08: 600 CZK (new months added). - Mirrored in both `scripts/attendance.py` and `go/internal/domain/fees/fees.go`. ## 2026-05-24 21:42 CEST — feat: multi-account Fio sync + switch QR default to 2502035405/2010 - Added second bank account `2502035405/2010` (IBAN `CZ0820100000002502035405`) to sync. - Both accounts are fetched on every sync; dedup by existing sync_id keeps the payments sheet clean. - QR codes now default to the new account (`CZ0820100000002502035405`). - Go: `config.go` gains hardcoded `Accounts`/`LoadedAccount` slice; `Config.BankAccount` renamed to `Config.QRAccount`; `FioAPIToken` removed (tokens are per-account via `FIO_API_TOKEN_NEW` / `FIO_API_TOKEN_OLD`). - Go: `SyncToSheets` now accepts `[]fio.Client`; new `TestSyncToSheets_MultiAccount` test. - Python: `config.py` gains `ACCOUNTS` / `LOADED_ACCOUNTS`; `fio_utils.py` adds `fetch_transactions_for` and `fetch_transactions_all`; `sync_fio_to_sheets.py` uses `fetch_transactions_all`. - Key files: `go/internal/config/config.go`, `go/internal/services/banksync/sync.go`, `go/cmd/fuj/main.go`, `scripts/config.py`, `scripts/fio_utils.py`, `scripts/sync_fio_to_sheets.py`. ## 2026-05-11 23:58 CEST — fix(reconcile): fill earliest month deficit first in multi-month allocations - Multi-month payment allocation now fills the earliest in-window deficit first and spills any remainder to later months, accounting for prior transactions' contributions to each month. Previously a single transaction was split proportionally to each month's total expected fee, ignoring what earlier transactions had already paid — surfaced by Matyáš Thér's 200+550 case showing 566/183 instead of 500/250. - Files: `scripts/match_payments.py`, `go/internal/domain/reconcile/reconcile.go`, tests, parity fixtures. ## 2026-05-11 22:56 CEST — fix(python): parse Fio 2-digit-year dates + add `make sync-debug` dry-run tool - Fix: `scripts/fio_utils.py` `parse_czech_date` now accepts `DD.MM.YY` / `D.M.YY` in addition to the 4-digit-year variants. Fio's transparent page now mixes both forms in the same response; the 2-digit rows were being silently dropped, which caused `make sync-2026` to miss every recent transfer. Mirrors the Go-side fix from 2026-05-07 (CHANGELOG entry below). - Added `--dry-run` and `--print-fio-table` flags to `scripts/sync_fio_to_sheets.py`, plus a `make sync-debug [DAYS=N]` Makefile target. Mirrors `make go-sync-debug`: fetches from Fio and dedupes against the sheet, prints `STATUS=NEW/DUP` per transaction, and prints per-row `Dry run: would append …` lines + `would sort by date` instead of touching the sheet. - Added always-on stderr diagnostics in `scripts/fio_utils.py`: which fetcher was selected (authenticated API vs. transparent-page scraper with `FIO_API_TOKEN`-unset warning), and raw-vs-after-filter transaction counts on both paths — so this class of "scraper drops everything" bug surfaces immediately. ## 2026-05-08 15:24 CEST — feat(go): M6.7 — single-binary embed verification - Confirmed `embed.FS` wiring is complete: templates parsed via `template.ParseFS(templateFS, ...)`, static assets served via `http.FileServerFS(fs.Sub(staticFS, "static"))`. - Added `go/internal/web/assets_test.go` with two tests: `TestEmbedCompleteness` (walks disk vs embed.FS to catch forgotten files) and `TestStaticAssetsServed` (hits `/static/css/app.css` and all JS files through the mux, asserts 200 + Content-Type + non-empty body + 404 for unknown paths). - Closes M6; single binary confirmed self-contained with no adjacent `templates/` or `static/` required at runtime. - Key files: `go/internal/web/assets_test.go` (new). ## 2026-05-08 14:55 CEST — feat(go): M6.6.1 — Pay-button QR popup modal - Restored the Python `showPayQR` in-page modal UX that was lost in M6.6 (Pay buttons were navigating the tab to the raw `/qr` PNG). - Replaced `Pay` with `