feat(sprint10): Phase 4+5 — Frontend import wizard + integration testing
Phase 4 — Frontend Import Wizard:
- bank-import.ts service: types (BankImportSession, BankTransaction,
CsvColumnMapping, ImportSessionStatus, MatchStatus) + 12 React Query hooks
(sessions, transactions, mappings, upload/confirm/skip/assign/complete)
- /finance/import page: 4-step wizard (Upload -> Map -> Review -> Confirm)
* Drag-and-drop upload with bank format auto-detect (MT940/CAMT.053/CSV)
* CSV column mapping editor (saves as reusable mapping)
* Review table with color-coded MATCHED/SUGGESTED/UNMATCHED/CONFIRMED rows,
confidence % badges, member-assign Combobox, skip/confirm/bulk-confirm
* Completion summary + import history table with resume action
- de.json + en.json: full bankImport.* namespace (steps, upload, map, review,
complete, history, status, sessionStatus, actions, errors)
- Navigation: Finanzen converted to nested submenu (Uebersicht + Import)
Phase 5 — Integration Testing:
- docker compose down -v + up -d --build (clean rebuild)
- Playwright e2e/sprint10-system-test.spec.ts: verifies /finance/import
unauthenticated -> /login?callbackUrl=%2Ffinance%2Fimport (PASS)
- Backend health + frontend route registration verified
Bugfix bundled (blocked backend startup):
- PaymentRepository: countOverdueByClubId* queries referenced non-existent
Payment.dueDate column (regression from Sprint 9 Phase 6, commit 57f418f).
Switched to Payment.periodTo (the implicit due date for billing periods).
This commit is contained in:
@@ -958,6 +958,117 @@
|
||||
"noPayments": "No payments yet"
|
||||
}
|
||||
},
|
||||
"bankImport": {
|
||||
"title": "Bank Statement Import",
|
||||
"subtitle": "Import bank statements, match transactions to members, and confirm fee payments",
|
||||
"steps": {
|
||||
"upload": "Upload",
|
||||
"map": "Map Columns",
|
||||
"review": "Review",
|
||||
"complete": "Complete"
|
||||
},
|
||||
"upload": {
|
||||
"title": "Upload bank statement",
|
||||
"description": "Supported formats: MT940 (.sta, .mt940, .txt), CAMT.053 (.xml), CSV (.csv)",
|
||||
"dropzone": "Drag a file here or click to select",
|
||||
"selectFile": "Select file",
|
||||
"format": "Format",
|
||||
"mapping": "CSV Template (optional)",
|
||||
"noMapping": "Auto-detect",
|
||||
"upload": "Upload",
|
||||
"uploading": "Uploading…"
|
||||
},
|
||||
"map": {
|
||||
"title": "Map CSV columns",
|
||||
"description": "Specify which columns contain which data",
|
||||
"dateColumn": "Date column",
|
||||
"amountColumn": "Amount column",
|
||||
"referenceColumn": "Reference column",
|
||||
"counterpartyColumn": "Counterparty column",
|
||||
"delimiter": "Delimiter",
|
||||
"dateFormat": "Date format",
|
||||
"saveAsTemplate": "Save as default template",
|
||||
"templateName": "Template name",
|
||||
"continue": "Continue",
|
||||
"saving": "Saving…"
|
||||
},
|
||||
"review": {
|
||||
"title": "Review transactions",
|
||||
"description": "Confirm matches or assign members manually",
|
||||
"matched": "Matched",
|
||||
"suggested": "Suggested",
|
||||
"unmatched": "Unmatched",
|
||||
"skipped": "Skipped",
|
||||
"total": "Total",
|
||||
"progress": "Review progress",
|
||||
"confirmAll": "Confirm all matched",
|
||||
"confirmingAll": "Confirming…",
|
||||
"sortBy": "Sort by",
|
||||
"sortConfidence": "Confidence",
|
||||
"sortAmount": "Amount",
|
||||
"sortDate": "Date",
|
||||
"date": "Date",
|
||||
"amount": "Amount",
|
||||
"counterparty": "Counterparty",
|
||||
"reference": "Reference",
|
||||
"match": "Match",
|
||||
"actions": "Actions",
|
||||
"noTransactions": "No transactions found",
|
||||
"resume": "Resume"
|
||||
},
|
||||
"complete": {
|
||||
"title": "Complete session",
|
||||
"description": "Seal the session — sealed sessions are immutable (GoBD §147 AO)",
|
||||
"summary": "Summary",
|
||||
"confirmed": "Confirmed",
|
||||
"skipped": "Skipped",
|
||||
"open": "Open",
|
||||
"seal": "Seal session",
|
||||
"sealing": "Sealing…",
|
||||
"sealed": "Session sealed",
|
||||
"sealedDescription": "This session is now immutable and audit-proof.",
|
||||
"back": "Back to Finance"
|
||||
},
|
||||
"history": {
|
||||
"title": "Import history",
|
||||
"description": "Previous import sessions",
|
||||
"noSessions": "No imports yet",
|
||||
"filename": "Filename",
|
||||
"uploaded": "Uploaded",
|
||||
"status": "Status",
|
||||
"resume": "Resume"
|
||||
},
|
||||
"status": {
|
||||
"MATCHED": "Matched",
|
||||
"SUGGESTED": "Suggested",
|
||||
"UNMATCHED": "Unmatched",
|
||||
"CONFIRMED": "Confirmed",
|
||||
"SKIPPED": "Skipped"
|
||||
},
|
||||
"sessionStatus": {
|
||||
"PENDING": "Pending",
|
||||
"IN_REVIEW": "In Review",
|
||||
"COMPLETED": "Completed",
|
||||
"FAILED": "Failed",
|
||||
"CANCELLED": "Cancelled"
|
||||
},
|
||||
"actions": {
|
||||
"confirm": "Confirm",
|
||||
"assign": "Assign",
|
||||
"skip": "Skip",
|
||||
"searchMember": "Search member…",
|
||||
"noMembersFound": "No members found",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"errors": {
|
||||
"uploadFailed": "Upload failed",
|
||||
"noFile": "Please select a file",
|
||||
"confirmFailed": "Confirm failed",
|
||||
"assignFailed": "Assign failed",
|
||||
"skipFailed": "Skip failed",
|
||||
"completeFailed": "Complete failed"
|
||||
}
|
||||
},
|
||||
"documents": {
|
||||
"title": "Document Archive",
|
||||
"description": "Manage and archive club documents",
|
||||
|
||||
Reference in New Issue
Block a user