feat: import transactions from a CSV bank statement

Fourth of the four ideas picked from the Maybe/Sure feature audit, and the
last one queued up. A 3-step wizard (account -> column mapping -> preview)
at /transactions/import, parsed entirely client-side (new lib/csv.ts —
delimiter auto-detect, 5 date formats, thousands/decimal-separator-aware
amounts) and submitted through a new all-or-nothing POST /transactions/bulk
endpoint, mirroring backup restore's validate-everything-before-touching-
anything approach.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ZProger
2026-08-25 02:44:30 +03:00
parent 94782ee073
commit 19f5cfa429
11 changed files with 706 additions and 8 deletions

View File

@@ -37,6 +37,12 @@ export function createTransaction(input: TransactionInput) {
return api.post<Transaction>("/transactions", input);
}
/** CSV import — see pages/CsvImportPage.tsx. All-or-nothing on the backend:
* either every row is created, or (on a validation error) none are. */
export function bulkCreateTransactions(items: TransactionInput[]) {
return api.post<{ created: number }>("/transactions/bulk", { items });
}
export function updateTransaction(id: number, input: Partial<TransactionInput>) {
return api.patch<Transaction>(`/transactions/${id}`, input);
}