feat: Phase 4 – CSV-Import (Templates, Prüfansicht, Duplikat/Transfer-Erkennung, Undo)

Backend:
- Modelle + Migration 0005: import_templates, import_batches, categorization_rules;
  transactions um import_batch_id + import_hash erweitert.
- services/csv_import: Datei parsen (Trennzeichen, Dezimal-/Datumsformat, Kodierung,
  Header/Skip, Vorzeichen vs. Soll/Haben), Vorschau mit Duplikat-Erkennung (Hash),
  interner-Transfer-Erkennung via IBAN, lernender Auto-Kategorisierung; Buchen mit
  Batch und Undo.
- routers/imports: Templates (CRUD), Roh-Vorschau, Prüf-Vorschau, Buchen, Verlauf,
  Rückgängig. pytest: Parsing, Duplikate, Transfer, Buchen, Undo, Lernen.

Frontend:
- Import-Seite: Konto+Datei, Format/Spaltenzuordnung (mit Roh-Vorschau),
  editierbare Prüfansicht (Kategorie/Typ/Zielkonto, Duplikate markiert),
  Buchen, Import-Verlauf mit Undo; Vorlagen speichern; i18n DE/EN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-19 20:06:50 +02:00
co-authored by Claude Opus 4.8
parent a31ba0c785
commit 1381967aae
14 changed files with 1366 additions and 2 deletions
+3
View File
@@ -11,6 +11,7 @@ import Accounts from "./pages/Accounts";
import Categories from "./pages/Categories";
import Transactions from "./pages/Transactions";
import Budget from "./pages/Budget";
import Import from "./pages/Import";
import Users from "./pages/Users";
import Settings from "./pages/Settings";
@@ -46,6 +47,7 @@ function Sidebar() {
<NavItem to="/kategorien" icon="list" label={t("nav.categories")} />
<NavItem to="/buchungen" icon="arrow-left-right" label={t("nav.transactions")} />
<NavItem to="/budget" icon="pie-chart" label={t("nav.budget")} />
<NavItem to="/import" icon="download" label={t("nav.import")} />
<NavItem to="/settings" icon="settings" label={t("nav.settings")} />
{isAdmin && (
<>
@@ -131,6 +133,7 @@ export default function App() {
<Route path="/kategorien" element={<Protected><Categories /></Protected>} />
<Route path="/buchungen" element={<Protected wide><Transactions /></Protected>} />
<Route path="/budget" element={<Protected wide><Budget /></Protected>} />
<Route path="/import" element={<Protected wide><Import /></Protected>} />
<Route path="/settings" element={<Protected><Settings /></Protected>} />
<Route path="/users" element={<Protected adminOnly><Users /></Protected>} />
<Route path="*" element={<Navigate to="/" replace />} />