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

@@ -78,3 +78,16 @@ class TransactionPage(BaseModel):
total: int
page: int
page_size: int
class TransactionBulkCreate(BaseModel):
"""CSV import (see routes/transactions.py's /bulk): the frontend parses
the file and maps its columns client-side, then sends already-shaped
rows here. All-or-nothing — same failure semantics as backup restore, so
a single bad row never leaves a partial import behind."""
items: list[TransactionCreate] = Field(min_length=1, max_length=5000)
class TransactionBulkCreateResult(BaseModel):
created: int