34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import type { FastifyPluginAsync } from "fastify";
|
|
import { z } from "zod";
|
|
import { rolloverFixedPlans } from "../jobs/rollover.js";
|
|
|
|
type AdminRoutesOptions = {
|
|
authDisabled: boolean;
|
|
isInternalClientIp: (ip: string) => boolean;
|
|
};
|
|
|
|
const adminRoutes: FastifyPluginAsync<AdminRoutesOptions> = async (app, opts) => {
|
|
app.post("/admin/rollover", async (req, reply) => {
|
|
if (!opts.authDisabled) {
|
|
return reply.code(403).send({ ok: false, message: "Forbidden" });
|
|
}
|
|
if (!opts.isInternalClientIp(req.ip || "")) {
|
|
return reply.code(403).send({ ok: false, message: "Forbidden" });
|
|
}
|
|
const Body = z.object({
|
|
asOf: z.string().datetime().optional(),
|
|
dryRun: z.boolean().optional(),
|
|
});
|
|
const parsed = Body.safeParse(req.body);
|
|
if (!parsed.success) {
|
|
return reply.code(400).send({ ok: false, message: "Invalid payload" });
|
|
}
|
|
const asOf = parsed.data.asOf ? new Date(parsed.data.asOf) : new Date();
|
|
const dryRun = parsed.data.dryRun ?? false;
|
|
const results = await rolloverFixedPlans(app.prisma, asOf, { dryRun });
|
|
return { ok: true, asOf: asOf.toISOString(), dryRun, processed: results.length, results };
|
|
});
|
|
};
|
|
|
|
export default adminRoutes;
|