more ui fix for rebalance, and safegaurd as well.
All checks were successful
Deploy / deploy (push) Successful in 1m28s
Security Tests / security-non-db (push) Successful in 18s
Security Tests / security-db (push) Successful in 24s

This commit is contained in:
2026-03-11 22:24:20 -05:00
parent e6dac3f344
commit 234ecc56e9
3 changed files with 132 additions and 32 deletions

View File

@@ -3355,6 +3355,7 @@ const ManualRebalanceBody = z.object({
})
),
forceLowerSavings: z.boolean().optional(),
confirmOver80: z.boolean().optional(),
});
async function assertPercentTotal(
@@ -3606,8 +3607,13 @@ app.post("/variable-categories/manual-rebalance", async (req, reply) => {
.send({ ok: false, code: "SUM_MISMATCH", message: `Targets must sum to available (${availableCents}).` });
}
const maxAllowed = Math.floor(availableCents * 0.8);
if (availableCents > 0 && targets.some((t) => t.target > maxAllowed)) {
return reply.code(400).send({ ok: false, code: "OVER_80_PERCENT", message: "No category can exceed 80% of available." });
const over80 = availableCents > 0 && targets.some((t) => t.target > maxAllowed);
if (over80 && !parsed.data.confirmOver80) {
return reply.code(400).send({
ok: false,
code: "OVER_80_CONFIRM_REQUIRED",
message: "A category exceeds 80% of available. Confirm to proceed.",
});
}
const totalSavingsBefore = targets.filter((t) => t.isSavings).reduce((s, t) => s + t.currentBalance, 0);
const totalSavingsAfter = targets.filter((t) => t.isSavings).reduce((s, t) => s + t.target, 0);