Files
triggerdotdev--trigger.dev/apps/webapp/app/routes/admin.api.v1.orgs.$organizationId.stream-basin.ts
2026-07-13 13:32:57 +08:00

49 lines
1.6 KiB
TypeScript

import type { ActionFunctionArgs } from "@remix-run/server-runtime";
import { json } from "@remix-run/server-runtime";
import { z } from "zod";
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
import { isValidDuration } from "~/services/realtime/duration.server";
import {
deprovisionBasinForOrg,
ensureBasinForOrg,
} from "~/services/realtime/streamBasinProvisioner.server";
const ParamsSchema = z.object({ organizationId: z.string() });
const BodySchema = z.discriminatedUnion("action", [
z.object({
action: z.literal("ensure"),
retention: z
.string()
.refine(isValidDuration, "retention must be a duration like 7d, 30d, 365d, 1h, 1y"),
}),
z.object({ action: z.literal("deprovision") }),
]);
export async function action({ request, params }: ActionFunctionArgs) {
await requireAdminApiRequest(request);
const { organizationId } = ParamsSchema.parse(params);
let parsed: z.infer<typeof BodySchema>;
try {
const text = await request.text();
const raw = text.length > 0 ? JSON.parse(text) : {};
const result = BodySchema.safeParse(raw);
if (!result.success) {
return json({ ok: false, error: result.error.flatten() }, { status: 400 });
}
parsed = result.data;
} catch {
return json({ ok: false, error: "Invalid JSON body" }, { status: 400 });
}
if (parsed.action === "ensure") {
const result = await ensureBasinForOrg(organizationId, parsed.retention);
return json({ ok: true, ...result });
}
const result = await deprovisionBasinForOrg(organizationId);
return json({ ok: true, ...result });
}