feat: Schlagwörter je Kategorie + auf-/zuklappbares Kategorie-Dropdown

- Manuelle Schlagwörter je Kategorie (Popup mit Chips, Doppelklick zum Bearbeiten)
- Treffer über Empfänger ODER Verwendungszweck; längstes Schlagwort gewinnt;
  Kind-Filter (Ausgabe/Einnahme); wirken nur bei künftigen Importen
- Lernende Korrektur-Erkennung: ab 5 Anwendungen und >= 1/3 Korrekturen
  erscheint eine Prüf-Meldung in den Einstellungen (Behalten/Entfernen)
- Neue CategorySelect-Komponente (Baum + Suche, per Portal) ersetzt die
  nativen optgroup-Selects in Buchungen und Import-Prüfansicht
- Migration 0006 (source/applied_count/overridden_count/confirmed, match_field any)
- Endpunkte, i18n DE/EN, Tests (test_keywords: 7 neu, gesamt 27 grün)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-19 21:31:29 +02:00
co-authored by Claude Opus 4.8
parent f375fc5eaa
commit 37f64999cd
17 changed files with 1137 additions and 45 deletions
+14 -2
View File
@@ -79,7 +79,12 @@
"exportTxnJson": "Buchungen (JSON)",
"exportAll": "Alle Daten (JSON)",
"dbBackup": "Komplettes DB-Backup herunterladen",
"dbBackupHint": "Vollständige Datenbank aller Nutzer (nur Admin) – zum Wiederherstellen sichern."
"dbBackupHint": "Vollständige Datenbank aller Nutzer (nur Admin) – zum Wiederherstellen sichern.",
"keywordReview": "Schlagwörter prüfen",
"keywordReviewHint": "Diese Schlagwörter werden auffällig oft wieder wegkorrigiert – stimmen sie vielleicht nicht mehr?",
"keywordCorrected": "{{overridden}} von {{applied}} Buchungen korrigiert",
"keep": "Behalten",
"remove": "Entfernen"
},
"dashboard": {
"title": "Übersicht",
@@ -153,7 +158,14 @@
"expense": "Ausgabe",
"emptyGroup": "Keine Kategorien in dieser Gruppe.",
"deleteConfirm": "Diese Kategorie löschen?",
"deleteGroupConfirm": "Diese Gruppe samt aller Kategorien löschen?"
"deleteGroupConfirm": "Diese Gruppe samt aller Kategorien löschen?",
"keywordsBtn": "Schlagwörter",
"keywordsTitle": "Schlagwörter – {{name}}",
"keywordsHint": "Buchungen, die eines dieser Wörter im Empfänger oder Verwendungszweck enthalten, werden bei künftigen Importen automatisch dieser Kategorie zugeordnet.",
"keywordAdd": "Wort eingeben und Enter",
"keywordEmpty": "Noch keine Schlagwörter.",
"keywordEditHint": "Doppelklick auf ein Schlagwort, um es zu bearbeiten.",
"searchPlaceholder": "Kategorie suchen …"
},
"transactions": {
"title": "Buchungen",