feat(go): port matching helpers (M2.7-2.9) #9

Merged
kacerr merged 2 commits from feat/m2-7-2-9-matching-package into main 2026-05-06 15:58:27 +02:00
Owner

Summary

  • New go/internal/domain/matching package porting three tightly coupled helpers from scripts/match_payments.py.
  • BuildNameVariants — extracts normalized ASCII search variants (full name, nickname, last/first); filters variants <3 chars; variants[0] is always the full base (load-bearing invariant for MatchMembers).
  • MatchMembers — auto/review confidence matching with an exact-name short-circuit that prevents nickname substrings (e.g. tov) from firing inside longer surnames (e.g. ottova); common-surname filter for the review tier (novak, novakova, prach).
  • FormatDate — nil/empty/serial int/float64 (since 1899-12-30, fractional days supported)/YYYY-MM-DD passthrough/garbage → never errors. Fractional serials computed via time.Duration to preserve Python timedelta(days=float) sub-day precision.
  • InferTransactionDetails — composes name + month matching over sender/message/user_id; falls back to sender-only member match and date-derived month when text carries no signal. SearchText key matches what the Python code actually returns (not the misleading matched_text docstring).
  • 21 table-driven tests; all expected values verified against live Python on 2026-05-06. go-build, go-test, go-lint all clean.

Done together per plan since the three functions form a tight dependency chain: InferTransactionDetailsMatchMembersBuildNameVariants + FormatDate.

Ticks M2.7, M2.8, M2.9 in the progress tracker. Next up: M2.10 domain/reconcile.Reconcile.

## Summary - New `go/internal/domain/matching` package porting three tightly coupled helpers from `scripts/match_payments.py`. - **`BuildNameVariants`** — extracts normalized ASCII search variants (full name, nickname, last/first); filters variants <3 chars; `variants[0]` is always the full base (load-bearing invariant for `MatchMembers`). - **`MatchMembers`** — auto/review confidence matching with an exact-name short-circuit that prevents nickname substrings (e.g. `tov`) from firing inside longer surnames (e.g. `ottova`); common-surname filter for the review tier (`novak`, `novakova`, `prach`). - **`FormatDate`** — nil/empty/serial int/float64 (since 1899-12-30, fractional days supported)/YYYY-MM-DD passthrough/garbage → never errors. Fractional serials computed via `time.Duration` to preserve Python `timedelta(days=float)` sub-day precision. - **`InferTransactionDetails`** — composes name + month matching over sender/message/user_id; falls back to sender-only member match and date-derived month when text carries no signal. `SearchText` key matches what the Python code actually returns (not the misleading `matched_text` docstring). - 21 table-driven tests; all expected values verified against live Python on 2026-05-06. `go-build`, `go-test`, `go-lint` all clean. Done together per plan since the three functions form a tight dependency chain: `InferTransactionDetails` → `MatchMembers` → `BuildNameVariants` + `FormatDate`. Ticks M2.7, M2.8, M2.9 in the progress tracker. Next up: M2.10 `domain/reconcile.Reconcile`.
kacerr added 2 commits 2026-05-06 15:25:56 +02:00
New go/internal/domain/matching package porting three helpers from
scripts/match_payments.py:

- BuildNameVariants: normalized ASCII variants from a member name (nickname
  in parens, last/first split, len<3 filtered); variants[0] is always the
  full base name — MatchMembers relies on this invariant.
- MatchMembers: auto/review confidence matching with an exact-name
  short-circuit pass that prevents nickname substrings (tov) from firing
  inside longer surnames (ottova); common-surname filter for review tier.
- FormatDate: nil/empty/""/serial int/float64 (since 1899-12-30, fractional
  days supported)/YYYY-MM-DD passthrough/garbage → never errors.
- InferTransactionDetails: composes BuildNameVariants+MatchMembers+
  ParseMonthReferences; falls back to sender-only member match and
  date-derived month when text carries no signal.

21 table-driven tests; all expected values verified against live Python
on 2026-05-06. go-build, go-test, go-lint all clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
chore: tick M2.7-2.9 in progress tracker + CHANGELOG entry
All checks were successful
Deploy to K8s / deploy (push) Successful in 7s
7232697e9c
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
kacerr merged commit 3e597242eb into main 2026-05-06 15:58:27 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kacerr/fuj-management#9