# Budget/Cashflow Phase 1.9 — Review Productivity, Split UI, Rule MVP-light

Use this reference when extending the FinanceManager Budget/Cashflow review surfaces after the core Confirm flow is already accepted.

## Scope boundary

- This is a tools/review-productivity sprint, not an import sprint.
- Do not add new import sources, OCR/camera/vision, or automatic blind booking.
- Do not productively mass-confirm real candidates without an explicit user approval in the current turn.
- Runtime writes are limited to schema migration, backup/audit, and tightly controlled single/synthetic UAT that is cleaned up afterwards.
- Chat reports stay aggregate-only; never include real amounts or raw candidate rows.

## Backend pattern

Add tests first for:

- candidate summary counts
- candidate filters and sorting
- batch action selection and Preview-before-Confirm
- split sum validation
- review-created category assignment and audit
- rules that only set candidate suggestions
- effective expenses and budgetstatus recategorisation paths

Useful service primitives:

- `review_candidate_summary(conn)` for cards: open total, auto, review, Galaxus/Digitec, Migros threshold, covered_by_migros, unclear, possible duplicates.
- Extended `list_transaction_candidates(...)` with filters: source, status, category proposal, merchant, rule, confidence, date range, local amount range; sort by date/merchant/category/confidence/source/status.
- `preview_batch_confirm_candidates(...)` must create an audit event and return `preview_id`, count, categories and conflicts. It must not create transactions.
- `batch_mark_candidates(...)` supports category, confirm, ignore, reopen, transfer and covered_by_migros. For `action='confirm'`, require `preview_id` or reject.
- `confirm_candidate_split(...)` validates split total exactly against candidate amount using Decimal text, then creates multiple linked confirmed budget transactions and an audit event.
- `create_review_category_for_candidate(...)` creates a category and immediately assigns it to the candidate with audit.
- Rule MVP functions should create/list/deactivate/test/apply rules, but applying a rule must only update open candidates' proposed category/status/confidence/rule metadata. It must return/productively verify `productive_transaction_count=0`.

## UI pattern

### Buchungen prüfen

- Make it the central candidate workbench.
- Add summary cards at top.
- Add filters for source, status, category proposal, merchant, rule, confidence, date range and amount range. Amounts may be visible in the local dashboard but not in chat summaries.
- Add sorting controls for date, merchant, category, confidence, source and status.
- Support multi-select batch actions.
- Batch Confirm UI must show preview count, categories and conflicts before showing the final Confirm button.
- Split UI should live in a candidate detail/drawer: category, amount, optional note, optional tag per row; block confirm when totals mismatch.
- Category creation from review should hide technical IDs in User Mode and assign the new category to the candidate.

### Regeln

- Build an MVP-light Rule Manager page, not a full rule engine.
- Expose: merchant contains text, source, category, target status `auto`/`review`, active flag.
- Actions: create, deactivate, test against open candidates, apply as suggestions.
- Clearly state in UI that rules do not create productive bookings.

### Effektive Ausgaben

- Treat it as an actual work page over confirmed expense transactions.
- Add summary cards: current month, year-to-date, count, top category.
- Keep filters for date/month, category, merchant, account and source.
- Row click opens detail drawer with category/tag/description edits, audit note, and explicit reversal/adjustment guidance rather than silent amount overwrites.

### Budgetstatus

- Rows should show Budget month/year, actual YTD, average month, forecast year, deviation and traffic-light status.
- Row click opens confirmed transactions for that category; allow audited recategorisation and refresh status afterwards.

### Income

- Show planned, actual, forecast, deviation and status.
- If no income candidates/transactions exist, show a calm empty state: `Noch keine Einnahmen importiert/erfasst.` No fake data and no error.

## SQLite migration pitfall

If adding split/rule tables after Phase 1.8, re-run full tests and inspect schema for any lingering `__phase*` foreign-key references from earlier table rebuilds. Budget split confirmation can fail if `confirmed_transaction_id` is constrained to a synthetic group ID; prefer linking the candidate to the first created transaction and keep the split group ID as audit/split metadata unless a real parent table exists.

## Verification gate

Before commit/push:

1. `unset JARVIS_FINANCE_DB_PATH`
2. `python -m compileall src tests`
3. full `pytest`
4. `npm test -- --run`
5. `npm run build`
6. source changed-file secret scan
7. frontend build secret scan
8. remove `frontend/dist`, `frontend/node_modules/.vite`, `.pytest_cache`, `__pycache__`
9. `git diff --check`
10. ensure no DB/CSV/XLSX/PDF/image/runtime artifacts are staged
11. commit, push, and verify remote branch hash — do not compare against `origin HEAD` unless the branch is the default branch.
