# Budget Phase 1.2 — Excel Seed Candidate Review Workflow

Use this reference when extending the FinanceManager Budget/Cashflow module from workbook dry-run analysis into persistent review candidates and a Vue/FastAPI review UI.

## Durable workflow pattern

- Keep the Excel workbook outside Git and treat it as temp/runtime-only input.
- Parse workbook structure first and report only aggregate counts; never echo real budget amounts or raw rows in chat.
- Persist workbook-derived rows into a dedicated candidate table, not productive budget tables.
- Preserve the write boundary:
  - Seed/dry-run: may create `budget_seed_candidates` only.
  - Preview/Review: may show proposed category/plan rows and unclean ranges.
  - Confirm: only then creates/updates productive `budget_categories` / `budget_plan_items` and writes audit.
  - Ignore: marks the candidate ignored and writes audit.
- Verify that seed persistence causes **zero** productive `budget_plan_items` mutation before confirm.
- Keep unclean or ambiguous rows visible as review items; do not silently drop them.
- If the accepted dry-run analyzer already has validated aggregate counts, align the persistent seed parser to those counts. Any mismatch is a safety signal, not a cosmetic issue.

## Excel parsing lessons

- `.xls` support may require `xlrd`; keep this optional and fail with a clear dependency message when absent.
- Budget sheets may use `Monatlich`/`Jahr` style columns rather than explicit `Kategorie` headers; reuse the same structural heuristics as the validated dry-run analyzer where possible.
- Section/category rows can look like normal rows but lack amounts. Persist them as category candidates and/or unclean ranges requiring review.
- Monthly-only source rows from broad workbook columns may be safer as unclean/review-required unless the existing dry-run semantics classify them as seed-suitable.
- Do not treat workbook formulas, totals, and rest/net rows as automatically clean imports; they need review semantics unless explicitly classified.

## Frontend/API pattern

- Add a dedicated Budget Setup / Excel übernehmen page instead of hiding this inside the normal overview.
- Display aggregate candidate counts, candidate type/status/confidence, and unclean ranges.
- User Mode should avoid raw technical IDs; Review/Admin UI may expose source sheet/range enough to identify the Excel row.
- Add API helpers for list/confirm/ignore seed candidates.
- Keep confirm/ignore buttons explicit and show errors without leaking raw provider/secret details.

## Phase 1.3 — Seed Review UAT / controlled takeover additions

When moving from review-only seed candidates into controlled productive takeover:

- Create a Runtime DB backup before any productive confirm/UAT with side effects.
- Keep report output aggregate-only; local dashboard may show values for review, chat must not echo real amounts.
- Add explicit status recovery actions for all candidate types: reopen, set pending, set needs_review/later, ignore; every status change writes audit.
- Treat `unclean_range` as a first-class review object: detail view with sheet/range/reason/proposal and conversion actions to category or budget-plan candidate.
- Income candidates from the 2026 sheet should be extracted from the user-specified income area (roughly rows 37-45, B-E) as review candidates only; categorize as `income` under Einnahmen buckets (Lohn Marcel, Lohn Melanie, Gratifikation, Sonstige Einnahmen). No productive write without confirm.
- Bulk takeover actions must be preview -> confirm -> audit and idempotent. Existing categories/budget plans must be linked/skipped, never duplicated.
- Use a temporary Runtime DB copy for manual UAT test bookings where possible, so income/expense/transfer/audit behavior is verified without polluting the real Runtime DB.
- If the original budget workbook is absent and only already-persisted candidates exist, report that income extraction cannot be regenerated from the real workbook until the workbook path/input is supplied.

## Verification gate

Run and record, in this order:

1. Backend focused tests for seed candidates, confirm/ignore/reopen/status, unclean conversion, income extraction, idempotent bulk takeover, audit, and no productive mutation on seed.
2. Frontend focused tests for Budget Setup render/actions.
3. Runtime seed against the real workbook with aggregate-only output: candidate counts, unclean count, and `productive_budget_plan_mutation=false`.
4. Full backend compile/pytest with `JARVIS_FINANCE_DB_PATH` unset unless a test explicitly needs runtime DB.
5. Frontend `npm test` and `npm run build` from `frontend/`.
6. Build-artifact secret scan before deleting `frontend/dist`.
7. Remove generated `frontend/dist`, `frontend/node_modules`, `.pytest_cache`, `.ruff_cache`, and similar caches before Git-safety.
8. `ruff check` on changed Python files, `git diff --check`, Git-safety, source diff secret scan.
9. Commit/push and verify local hash equals remote branch hash.

## Tooling pitfall

If a shell cleanup such as `rm -rf frontend/node_modules frontend/dist .ruff_cache` is blocked by an agent process guard, perform the cleanup with a short Python script using `shutil.rmtree`. Capture the cleanup pattern, not a claim that shell cleanup is generally broken.
