Instead of maintaining a YAML file per language, German (de.yaml) is the
single source of truth. For any other language, the label strings are
translated on demand via an LLM call and cached in memory — no static
files to maintain, any language the parent writes in is served
automatically.
- Add src/notifications/i18n.py: get_strings(), _translate() via
litellm.completion, in-memory cache, clear_cache() for tests
- Passthrough keys (reg_fee_amount, deposit_amount) are never sent to
the LLM so currency amounts are guaranteed to be unchanged
- Falls back to German silently if the LLM call fails
- Remove src/notifications/i18n/en.yaml (no longer needed)
- Remove load_strings() from context.py (moved to i18n.py)
- Add model parameter to AdminNotifier (defaults to claude-haiku)
- Add TestGetStrings suite covering: no LLM for German, LLM called for
others, caching, fallback, passthrough key preservation
- Add autouse reset_translation_cache fixture to isolate tests
https://claude.ai/code/session_01LjjK7RjKVnC8bETtccfgna