fix: fix no budget session in rebalance get route
This commit is contained in:
@@ -3395,6 +3395,27 @@ async function getLatestBudgetSession(app: any, userId: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function ensureBudgetSession(app: any, userId: string, fallbackAvailableCents = 0) {
|
||||||
|
const existing = await getLatestBudgetSession(app, userId);
|
||||||
|
if (existing) return existing;
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const start = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, 0, 0, 0, 0));
|
||||||
|
const end = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1, 0, 0, 0, 0));
|
||||||
|
|
||||||
|
return app.prisma.budgetSession.create({
|
||||||
|
data: {
|
||||||
|
userId,
|
||||||
|
periodStart: start,
|
||||||
|
periodEnd: end,
|
||||||
|
totalBudgetCents: BigInt(Math.max(0, fallbackAvailableCents)),
|
||||||
|
allocatedCents: 0n,
|
||||||
|
fundedCents: 0n,
|
||||||
|
availableCents: BigInt(Math.max(0, fallbackAvailableCents)),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.post("/variable-categories", mutationRateLimit, async (req, reply) => {
|
app.post("/variable-categories", mutationRateLimit, async (req, reply) => {
|
||||||
const parsed = CatBody.safeParse(req.body);
|
const parsed = CatBody.safeParse(req.body);
|
||||||
if (!parsed.success) {
|
if (!parsed.success) {
|
||||||
@@ -3527,14 +3548,13 @@ app.post("/variable-categories/rebalance", mutationRateLimit, async (req, reply)
|
|||||||
|
|
||||||
app.get("/variable-categories/manual-rebalance", async (req, reply) => {
|
app.get("/variable-categories/manual-rebalance", async (req, reply) => {
|
||||||
const userId = req.userId;
|
const userId = req.userId;
|
||||||
const session = await getLatestBudgetSession(app, userId);
|
|
||||||
if (!session) return reply.code(400).send({ ok: false, code: "NO_BUDGET_SESSION" });
|
|
||||||
|
|
||||||
const cats = await app.prisma.variableCategory.findMany({
|
const cats = await app.prisma.variableCategory.findMany({
|
||||||
where: { userId },
|
where: { userId },
|
||||||
orderBy: [{ priority: "asc" }, { name: "asc" }],
|
orderBy: [{ priority: "asc" }, { name: "asc" }],
|
||||||
select: { id: true, name: true, percent: true, isSavings: true, balanceCents: true },
|
select: { id: true, name: true, percent: true, isSavings: true, balanceCents: true },
|
||||||
});
|
});
|
||||||
|
const totalBalance = cats.reduce((s, c) => s + Number(c.balanceCents ?? 0n), 0);
|
||||||
|
const session = await ensureBudgetSession(app, userId, totalBalance);
|
||||||
|
|
||||||
return reply.send({
|
return reply.send({
|
||||||
ok: true,
|
ok: true,
|
||||||
@@ -3550,10 +3570,6 @@ app.post("/variable-categories/manual-rebalance", async (req, reply) => {
|
|||||||
return reply.code(400).send({ ok: false, code: "INVALID_BODY" });
|
return reply.code(400).send({ ok: false, code: "INVALID_BODY" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const session = await getLatestBudgetSession(app, userId);
|
|
||||||
if (!session) return reply.code(400).send({ ok: false, code: "NO_BUDGET_SESSION" });
|
|
||||||
const availableCents = Number(session.availableCents ?? 0n);
|
|
||||||
|
|
||||||
const cats = await app.prisma.variableCategory.findMany({
|
const cats = await app.prisma.variableCategory.findMany({
|
||||||
where: { userId },
|
where: { userId },
|
||||||
orderBy: [{ priority: "asc" }, { name: "asc" }],
|
orderBy: [{ priority: "asc" }, { name: "asc" }],
|
||||||
@@ -3561,6 +3577,10 @@ app.post("/variable-categories/manual-rebalance", async (req, reply) => {
|
|||||||
});
|
});
|
||||||
if (cats.length === 0) return reply.code(400).send({ ok: false, code: "NO_CATEGORIES" });
|
if (cats.length === 0) return reply.code(400).send({ ok: false, code: "NO_CATEGORIES" });
|
||||||
|
|
||||||
|
const totalBalance = cats.reduce((s, c) => s + Number(c.balanceCents ?? 0n), 0);
|
||||||
|
const session = await ensureBudgetSession(app, userId, totalBalance);
|
||||||
|
const availableCents = Number(session.availableCents ?? 0n);
|
||||||
|
|
||||||
const targetMap = new Map<string, number>();
|
const targetMap = new Map<string, number>();
|
||||||
for (const t of parsed.data.targets) {
|
for (const t of parsed.data.targets) {
|
||||||
if (targetMap.has(t.id)) return reply.code(400).send({ ok: false, code: "DUPLICATE_ID" });
|
if (targetMap.has(t.id)) return reply.code(400).send({ ok: false, code: "DUPLICATE_ID" });
|
||||||
|
|||||||
Reference in New Issue
Block a user