# Budget Monthly Import Workflow & Rule Learning v1

Use this reference for FinanceManager Budget/Cashflow sprints that productize a recurring monthly CSV workflow from the existing Google Drive Budget folder without creating productive bookings during import.

## Scope boundary

- Allowed sources only: AKB CSV, Raiffeisen CSV, VISA CSV, Migros CSV from `Finanzen/03 Budget`.
- Do not add portfolio imports, OCR/camera, new providers, Telegram alerts, reports, or Data Explorer v2 in the same sprint.
- No runtime DBs, real CSV files, credentials, or frontend build artifacts in Git.
- No real amounts in chat/report summaries; use aggregate counts/statuses only.
- Import is never the productive booking boundary. The write chain is: Drive scan/Dry Run -> candidates -> Review -> explicit Confirm -> Audit.

## Data model pattern

Add/import with append-only migrations and tests:

- `budget_import_sessions`: one row per file/session with source, file label, profile, file period, row totals, new/existing/duplicate/ignored/covered/error counts and status (`dry_run`, `candidates_created`, `reviewed`, `partial`, `failed`).
- `budget_import_line_items`: stable per-source fingerprint ledger for every parsed line/receipt, linked to the session and optionally to a candidate/transaction, so re-imports can classify rows as existing/processed/ignored/covered rather than creating duplicates.
- `budget_rule_suggestions`: suggestions derived from manual candidate category changes; suggestions may set candidate metadata/categories only, never create `budget_transactions`.
- Add an `import_session_id` or equivalent link on `budget_transaction_candidates` so Review can filter by source/session/new status.

## Fingerprint/idempotency rules

Normalize whitespace/case consistently and hash non-display-sensitive raw identifiers when necessary. Tests must prove same-file and re-upload idempotency.

- VISA: transaction id if present, card token/non-sensitive card id, date, amount, currency, merchant, original amount/currency when present.
- Migros: date, time, store/filiale, register/kasse, transaction/receipt number, receipt total, item-lines hash. Article lines are detail data; aggregate to receipt candidates.
- AKB/Raiffeisen: account source, booking date, valuta, amount, currency, booking text, counterparty if present, reference/transaction id if present.

Re-import behavior:

- confirmed rows -> `existing`/`processed`, not Review duplicates
- ignored rows -> stay ignored
- `covered_by_migros` rows -> stay covered/hidden from normal Review
- auto-ignored duplicates -> hidden from normal Review

## Classification at import time

Set candidate proposal metadata only:

- Migros receipts -> `Essen & Haushalt`, `ready_for_confirm`/`auto_categorized`; article lines detail-only.
- VISA Migros -> `covered_by_migros`.
- Apple/Google/Netflix/Disney/Amazon Prime etc. -> merchant/rule-derived proposal.
- Galaxus/Digitec -> `needs_review`, split may be needed.
- Salary/wages -> `income_candidate`.
- AKB <-> Raiffeisen own-account movement -> `transfer_candidate`.
- Credit-card settlement from bank CSV -> `credit_card_payment`.
- True Wealth transfer -> `investment_transfer` / True Wealth Cash, excluded from consumer spending.
- Unclear bank payment -> `needs_review`.

## Rule learning pattern

When a user manually categorizes a candidate, create a rule suggestion with:

- merchant/description pattern
- match type (`contains`, `exact`, optional `regex`)
- source scope (`all`, `VISA`, `AKB`, `Raiffeisen`, `Migros`)
- target category
- optional `recurring_type`
- optional amount range
- confidence
- preview count of affected open candidates

Actions:

- save rule
- save and apply to open candidates
- reject
- review later

Applying a rule suggestion must update only open candidates/proposals and audit the action. It must not create productive transactions, income bookings, transfer bookings, or bulk confirmations.

## UI pattern

Add `Budget > Monatsimport` (or `Transaktionen > Monatsimport`) with:

- Drive scan button (read-only metadata/file discovery)
- Dry Run action
- Import dashboard: latest import by source, open candidates by source, new since last import, duplicate/ignored, ready_for_confirm, needs_review, transfer_candidate, income_candidate
- Import history table/cards with session status and aggregate counts
- Review links to `Buchungen prüfen` with source/import-session/status filters

Extend `Budget > Regeln` with a `Regelvorschläge` section showing the suggested rule, trigger/example, category, affected candidates, source, confidence and actions.

## Verification gate

Run:

- Python compile
- full pytest
- full frontend Vitest
- `npm run build`
- changed-source secret scan
- frontend build secret scan
- Git-safety scan for runtime DB/CSV/secrets/build artifacts
- `git diff --check`
- restart backend/frontend with browser-visible Tailscale API base
- browser sanity for Monatsimport, Buchungen prüfen, Regeln, Effektive Ausgaben, Einkünfte
- commit, push, remote hash verification

If runtime browser sanity shows stale API behavior after a code fix, restart the backend bound to port 8000 before re-checking; stale uvicorn processes can mask fixed service code.
