# Budget Import Review Production v1

Use this reference for Budget/Cashflow work that turns import-review candidates into a safe productive workflow with Merchant/Alias rules, duplicate handling, split booking, and PrimeVue review UX.

## Scope and invariants

- Keep **Buchungen prüfen** as the central review surface for import candidates.
- Preserve Preview → Confirm → Audit as the only productive write boundary.
- Merchant/Alias and Rule Manager actions may update candidate metadata/suggestions only; they must not create `budget_transactions`.
- Bulk tooling is allowed only behind Batch Preview and explicit Confirm, with partial-success/error feedback.
- Real runtime candidates must not be mass-confirmed during implementation unless the current turn explicitly authorizes that production action.
- Report only aggregate counts/statuses in chat; do not print raw rows, real amounts, secrets, DB paths with sensitive data, or source file contents.

## Backend pattern

- Add Merchant/Alias tables via migrations, typically:
  - `budget_merchants`
  - `budget_merchant_aliases`
- Store merchant/category/audit metadata on candidates, e.g. `merchant_id`, `merchant_display_name`, `proposed_category_id`, `review_reason`, `rule_id`, `rule_name`, `confidence`.
- Alias match modes should be explicit and tested: `contains`, `exact`, `regex`.
- Apply-to-candidates should target only open candidates and exclude protected/final statuses such as `confirmed`, `ignored`, `covered_by_migros`, `covered_by_source`, `superseded`, `reference_2025`, `archived_reference`.
- Rule Manager v1 should support create/list/test/apply/deactivate/update/prioritize. Rule test returns match counts and candidate IDs/status preview; apply sets suggestions only.
- Sort active rules by priority before created date so high-priority rules win deterministically.

## Duplicate MVP pattern

- Detect likely duplicates with a conservative heuristic:
  - same/similar merchant text,
  - same currency,
  - same amount,
  - date within a small tolerance, e.g. ±2 days,
  - match against confirmed transactions and/or open candidates depending on context.
- Mark candidates as `duplicate_candidate`, not confirmed/ignored automatically.
- Normal Confirm should block duplicates.
- Provide an explicit `allow_duplicate`/`Trotzdem bestätigen` path with ConfirmDialog and audit.
- Protected statuses such as `covered_by_source` and `covered_by_migros` remain non-confirmable.

## Frontend PrimeVue review pattern

- Use Toast for success/error feedback and ConfirmDialog for risky write actions.
- Risky actions include single Confirm, Bulk Confirm, Ignore, Reopen, Transfer marking, Split Confirm, and duplicate force-confirm.
- Split UI must show:
  - multiple split rows,
  - category per row,
  - amount per row,
  - optional tag/note,
  - split total and difference,
  - disabled Confirm unless the split total exactly matches candidate amount and at least two valid rows exist.
- Batch Confirm flow:
  1. select candidates,
  2. choose account/year/category as needed,
  3. generate Batch Preview,
  4. explicit ConfirmDialog,
  5. show partial-success/error count and audit feedback.
- User Mode must display plain status labels instead of raw enums:
  - `needs_review` → `Prüfung nötig`
  - `auto_categorized` → `Vorgeschlagen`
  - `duplicate_candidate` → `Mögliches Duplikat`
  - `transfer_candidate` → `Möglicher Transfer`
  - `covered_by_source` → `Durch Quelle abgedeckt`
- Keep raw technical IDs/fingerprints/hashes out of normal user-facing drawers; reserve for admin/debug views.

## Testing pattern

- Add RED tests first for:
  - Merchant/Alias create/apply/merge,
  - duplicate detection and confirm blocking,
  - explicit duplicate force-confirm with category/account/year,
  - Rule Manager create/test/apply/update/prioritize/deactivate,
  - Toast/ConfirmDialog integration,
  - split exact-match guard,
  - user-facing labels not raw enums.
- If importing service functions named like `test_budget_rule` into pytest modules, alias them (for example `service_test_budget_rule`) so pytest does not collect them as tests.
- When Vue tests call API wrappers with reactive form objects, snapshot payloads before the API call (`const payload = { ...form }`) so later form resets do not mutate what mocks/assertions observe.
- Mock PrimeVue `useToast` and `useConfirm` in unit tests rather than weakening production code.

## Verification and operations

- Run Python compile, full pytest, full Vitest, Vue build, `git diff --check`, Git-safety, source secret scan, and frontend build secret scan.
- Secret scans should inspect changed source and build artifacts, but avoid false positives from approved synthetic fixtures.
- After restart, verify both backend and frontend through the browser-visible Tailscale URL, not only localhost.
- Browser-sanity should check `/planning/budget/expenses/review`, `/planning/budget/rules`, candidate APIs, merchant APIs, and rule APIs.
- Before final report, verify no raw workflow enums remain visible in User Mode and no browser console errors appear.
