# Variable Pool Rebalance / Transfer Feature ## Summary - Allow users to redistribute current variable pool (BudgetSession.availableCents) by setting per-category dollar targets, without changing future percent-based allocations. - Enforce guards: sum = available, savings floor confirm, non-negative, no single category >80%, warnings when lowering savings. - New backend endpoint performs atomic balance updates and audit logging; fixed expenses unaffected. ## API - `POST /variable-categories/manual-rebalance` - Body: `{ targets: [{ id, targetCents }], forceLowerSavings?: boolean }` - Uses latest BudgetSession by periodStart; availableCents is the pool to balance. - Validations: targets cover every category; non-negative; sum(targets)=available; each ≤80% of available; lowering savings or savings <20% requires `forceLowerSavings`. - Transaction: update category balanceCents to targets; insert transaction(kind=`rebalance`, note snapshot); fixed plans untouched. - Response: `{ ok: true, availableCents, categories: [{ id, balanceCents }] }`. ## UI/UX - New Rebalance page (Settings → Expenses tab entry point) showing availableCents and per-category balances. - Editable dollar inputs with live total meter and inline errors for rule violations. - Savings floor warning/confirm; optional helper to adjust one category and auto-scale others respecting floors. - Confirmation modal summarizing before/after deltas. ## Data / Logic - Active session = latest BudgetSession for user. - Rebalance acts on current variable pool only; future income remains percent-based. - Savings floor default 20% of available; lowering requires confirmation flag. ## Tests - Sum=available happy path; savings unchanged. - Lowering savings w/out flag → 400; with flag → OK. - Savings total <20% w/out flag → 400; with flag → OK. - >80% single category → 400. - Sum mismatch → 400; negative target → 400. - Negative existing balance allowed only if target >=0 (ending non-negative). - Adjust-one helper unit: scaling respects floors. - Audit entry created; fixed plans and percents unchanged. ## Assumptions - availableCents equals dashboard “Available” variable pool. - No localization requirements for new errors.