# Budget CSV Import Production v2

Use this for FinanceManager Budget/Cashflow CSV-import sprints after the basic review workflow exists.

## Scope guard

- Build regular **budget** CSV imports only: VISA credit card, Migros receipts, Raiffeisen bank, AKB bank.
- Do not add portfolio/investment imports, OCR/camera, data explorer, Sankey, tax reports, or new provider features unless explicitly requested.
- Never copy real CSV/XLS/PDF/DB files into the repo; read Google Drive files via temp dirs only.
- Never print real amounts/raw rows in chat or final reports; report aggregate counts and status only.
- Productive writes require a verified runtime backup first.

## Required workflow

1. Create a feature branch from current `main`/release baseline.
2. Preflight Google Drive folder `Finanzen/03 Budget` structurally only:
   - find CSVs by source,
   - detect encoding/delimiter/header/profile,
   - count rows and date coverage,
   - report blockers aggregate-only,
   - no DB mutation.
3. Write RED tests first for:
   - profile detection,
   - idempotency,
   - Migros receipt/article grouping,
   - VISA Migros coverage,
   - AKB/Raiffeisen transfers,
   - True Wealth/investment transfer,
   - credit-card settlement,
   - income detection,
   - source-aware review tabs/actions,
   - safety/Git checks.
4. Implement import profiles:
   - `visa_credit_card`
   - `migros_receipts`
   - `raiffeisen_bank`
   - `akb_bank`
5. Keep imports as Dry Run → Candidates → Review → Confirm → Audit. Candidate creation is allowed after backup; confirming productive transactions is a separate explicit user approval.
6. Re-run the same import and prove idempotency: second run must create zero new candidates and zero productive transactions.
7. Verify full backend/frontend gates, restart dashboard, check Tailscale-visible routes/APIs, cleanup generated artifacts, Git-safety, commit, push, remote-hash verify.

## Import semantics

### VISA

- Credit-card line items are ordinary expense candidates except where covered/transfer logic applies.
- Migros credit-card rows are not budget expenses; mark as `covered_by_migros`/covered by source because Migros CSV is primary.
- Bank payment to VISA is `credit_card_payment`, not an expense, when individual card rows are imported.

### Migros

- Treat Migros receipt/transaction as the main candidate.
- Store article rows only as detail data; do not create one budget candidate per article line.
- Default category can be `Essen & Haushalt` if active.
- Use receipt-level fingerprinting so re-imports do not duplicate receipts.

### Raiffeisen / AKB

- Parse Soll/Haben or signed amount into explicit direction.
- Detect own-account transfers AKB ↔ Raiffeisen as `transfer_candidate`; they must not count as income or expense.
- Detect Raiffeisen/AKB → True Wealth as `investment_transfer`; it must not count as consumption expense.
- Detect VISA/card-settlement payments as `credit_card_payment`; avoid double counting.
- Detect clear salary/bonus/refund income, but prioritize clear income tokens before generic own-account names like Marcel/Melanie.
- Ambiguous positive bank rows stay in review rather than being auto-income.

## Fingerprints and duplicate handling

- Build stable `source_fingerprint` from source profile, source file/row or receipt key, account/card reference when non-sensitive, date, currency, amount, and normalized description/merchant.
- Do not store sensitive card/account numbers raw; omit or hash if needed.
- If fingerprint already exists in confirmed/imported/ignored/candidate state, mark/report `already_processed` rather than inserting.
- Similar manually-entered confirmed transactions should become `duplicate_candidate`, not silently blocked or confirmed.
- Avoid relying on `INSERT OR IGNORE` alone; return status counts: created, already_processed, duplicates, transfers, income, line_items.

## Review UI/API expectations

Review tabs should include:

- Alle neuen
- VISA
- Migros
- Raiffeisen
- AKB
- Einnahmen
- Transfers
- Kreditkartenausgleich
- True Wealth / Investment Transfers
- Duplikate
- Review nötig
- Ignoriert / bereits verarbeitet

Each candidate should expose source, date, local amount in dashboard only, currency, merchant/description, proposed category, type/classification, confidence, rule/reason, duplicate status, and audited actions: confirm, change category, mark transfer, mark investment transfer, mark credit-card payment, ignore/reopen, split.

## Verification checklist

- `python -m compileall -q src tests`
- full `pytest`
- full frontend `npm test -- --run`
- `npm run build`
- changed-source secret scan
- frontend build secret scan before deleting build artifacts
- Git-safety scan after deleting `frontend/dist`, `.pytest_cache`, `__pycache__`, `.vite`, generated caches
- `git diff --check`
- dashboard restart from current branch
- Tailscale-visible checks for `/api/budget/import-profiles`, `/api/budget/transaction-candidates?...`, and key Budget pages
- commit, push, remote-hash equality

## Reporting

Report only aggregate source counts and statuses. Include yes/no for profile support, idempotency, transfer detection, True Wealth, card settlement, income, rules/review UI, productive bookings, tests, Git-safety, commit hash, push status, and open limits. Never include real amounts, raw rows, secrets, or source file contents.