Files
fuj-management/CHANGELOG.md
Jan Novak fa853780db
All checks were successful
Deploy to K8s / deploy (push) Successful in 8s
chore: tick M2.3 + M2.4 in progress tracker + CHANGELOG entry
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 09:25:45 +02:00

4.6 KiB
Raw Blame History

Changelog

2026-05-06 09:24 CEST — feat(go/M2.3+M2.4): port domain/fees.CalculateFee and CalculateJuniorFee

  • New go/internal/domain/fees package with adult and junior fee calculators ported from scripts/attendance.py.
  • CalculateFee(count, monthKey) int0→0, 1→200, 2+→AdultFeeMonthlyRate[month] (fallback 700 CZK).
  • CalculateJuniorFee(count, monthKey) Expected0→{0}, 1→{Unknown:true} (the "?" sentinel, now strictly typed), 2+→JuniorFeeMonthlyRate[month] (fallback 500 CZK).
  • 20 table-driven tests, all verified against live Python; -race clean; golangci-lint clean.

2026-05-06 00:07 CEST — feat(go/M2.2): port czech.ParseMonthReferences

  • internal/domain/czech.ParseMonthReferences: three-pass regex (numeric slash, dot, Czech month names) with range wrap-around and m≥10 → previousYear heuristic, byte-equivalent to Python.
  • 35 table-driven tests; all expected outputs verified against live Python before locking (addresses risk #4 from the rewrite plan).

2026-05-05 23:33 CEST — feat(go/M2.1): port czech.Normalize

  • First M2 pure-domain task: internal/domain/czech.Normalize (NFKD + Mn-strip + lowercase), byte-equivalent to Python czech_utils.normalize.
  • Adds golang.org/x/text v0.36.0 as first external Go dependency.
  • 13-case table-driven test, all spot-checked against Python before locking.

2026-05-04 23:08 CEST — fix: payment inference exact-match short-circuit

  • match_members() now short-circuits on whole-word full-name hits; nickname/partial checks only run when no full name is present.
  • Replaced bare in substring checks with _word_in() word-boundary regex throughout, closing the class of bugs where a short nickname (e.g. tov) matches inside another member's surname (ottova).
  • Added tests/test_match_members.py (6 cases). Affects scripts/match_payments.py.

2026-05-04 23:08 CEST — feat: lower adult monthly fee to 700 CZK from April 2026

  • ADULT_FEE_DEFAULT reduced from 750 → 700 CZK.
  • ADULT_FEE_MONTHLY_RATE now pins Sep 2025 Feb 2026 at 750 to preserve historical billing; Mar 2026 stays 350; AprMay 2026 at 700. Affects scripts/attendance.py.

2026-05-04 12:02 CEST — Go rewrite M1: skeleton + tooling

  • Created go/ tree with module fuj-management/go (Go 1.26).
  • cmd/fuj: stdlib-flag subcommand dispatcher; server and version implemented, stubs for M2/M4 commands.
  • internal/config: env loader mirroring scripts/config.py (same env var names and defaults).
  • internal/logging: slog setup accepting log level from config.
  • internal/web: net/http ServeMux on :8080; middleware/timer.go logs method/path/status/ms.
  • go/build/Dockerfile: multi-stage (golang:1.26alpine:3) producing a static binary image.
  • Makefile: webweb-py alias; added web-go, go-build, go-test, go-run, go-lint.
  • .gitea/workflows/build.yaml: parallel build-go job pushing <tag>-go image.
  • Gate: make go-build, make go-lint, make go-test, curl :8080 all pass.

2026-05-03 20:37 CEST — Fix Balance column to correctly reflect past-month debt

  • Balance (and Pay-All) are now computed as sum(paid expected) over past months only, iterating directly over the ledger entries from reconcile().
  • Previously the balance used total_balance (which includes current/future-month activity and out-of-window credits) plus a one-sided current-month debt adjustment. Current-month surplus leaked through, making the balance appear less negative than the actual past-month debt.
  • Pay-All is now max(0, balance) so the two values are derived from a single source and can never disagree.
  • Affected: adults_view() and juniors_view() in app.py.

2026-05-03 19:26 CEST — Fee-aware allocation for multi-month payments

  • reconcile() no longer splits a multi-month payment evenly. Allocation is now per-member with two phases: greedy (if amount ≥ total expected, each month gets exactly its expected fee and overflow → credit) and proportional (otherwise distribute by each month's expected). Fixes the case where e.g. 1250 CZK covering 3 months with mixed fees (750/350/150) marked two months red.
  • Out-of-window months keep the previous even-split-to-credit behavior. Fallback to even split when all matched months have expected = 0 (prepayment before attendance is recorded).
  • Display layer only — no changes to how payments are stored in Google Sheets; Inferred Amount still holds the full bank amount.
  • Files: scripts/match_payments.py, tests/test_reconcile_exceptions.py (6 new test cases).