144 lines
4.4 KiB
TypeScript
144 lines
4.4 KiB
TypeScript
import { type TemplateVariable } from "@prisma/client";
|
|
import { sql } from "kysely";
|
|
import { z } from "zod";
|
|
import { createTRPCRouter, protectedProcedure, publicProcedure } from "~/server/api/trpc";
|
|
import { kysely, prisma } from "~/server/db";
|
|
import { error, success } from "~/utils/errorHandling/standardResponses";
|
|
import { requireCanModifyExperiment, requireCanViewExperiment } from "~/utils/accessControl";
|
|
|
|
export const scenarioVarsRouter = createTRPCRouter({
|
|
create: protectedProcedure
|
|
.input(z.object({ experimentId: z.string(), label: z.string() }))
|
|
.mutation(async ({ input, ctx }) => {
|
|
await requireCanModifyExperiment(input.experimentId, ctx);
|
|
|
|
// Make sure there isn't an existing variable with the same name
|
|
const existingVariable = await prisma.templateVariable.findFirst({
|
|
where: {
|
|
experimentId: input.experimentId,
|
|
label: input.label,
|
|
},
|
|
});
|
|
if (existingVariable) {
|
|
return error(`A variable named ${input.label} already exists.`);
|
|
}
|
|
|
|
await prisma.templateVariable.create({
|
|
data: {
|
|
experimentId: input.experimentId,
|
|
label: input.label,
|
|
},
|
|
});
|
|
|
|
return success();
|
|
}),
|
|
|
|
rename: protectedProcedure
|
|
.input(z.object({ id: z.string(), label: z.string() }))
|
|
.mutation(async ({ input, ctx }) => {
|
|
const templateVariable = await prisma.templateVariable.findUniqueOrThrow({
|
|
where: { id: input.id },
|
|
});
|
|
await requireCanModifyExperiment(templateVariable.experimentId, ctx);
|
|
|
|
// Make sure there isn't an existing variable with the same name
|
|
const existingVariable = await prisma.templateVariable.findFirst({
|
|
where: {
|
|
experimentId: templateVariable.experimentId,
|
|
label: input.label,
|
|
},
|
|
});
|
|
if (existingVariable) {
|
|
return error(`A variable named ${input.label} already exists.`);
|
|
}
|
|
|
|
await renameTemplateVariable(templateVariable, input.label);
|
|
return success();
|
|
}),
|
|
|
|
delete: protectedProcedure
|
|
.input(z.object({ id: z.string() }))
|
|
.mutation(async ({ input, ctx }) => {
|
|
const { experimentId } = await prisma.templateVariable.findUniqueOrThrow({
|
|
where: { id: input.id },
|
|
});
|
|
|
|
await requireCanModifyExperiment(experimentId, ctx);
|
|
|
|
await prisma.templateVariable.delete({ where: { id: input.id } });
|
|
}),
|
|
|
|
list: publicProcedure
|
|
.input(z.object({ experimentId: z.string() }))
|
|
.query(async ({ input, ctx }) => {
|
|
await requireCanViewExperiment(input.experimentId, ctx);
|
|
return await prisma.templateVariable.findMany({
|
|
where: {
|
|
experimentId: input.experimentId,
|
|
},
|
|
orderBy: {
|
|
createdAt: "asc",
|
|
},
|
|
select: {
|
|
id: true,
|
|
label: true,
|
|
},
|
|
});
|
|
}),
|
|
});
|
|
|
|
export const renameTemplateVariable = async (
|
|
templateVariable: TemplateVariable,
|
|
newLabel: string,
|
|
) => {
|
|
const { experimentId } = templateVariable;
|
|
|
|
await kysely.transaction().execute(async (trx) => {
|
|
await trx
|
|
.updateTable("TemplateVariable")
|
|
.set({
|
|
label: newLabel,
|
|
})
|
|
.where("id", "=", templateVariable.id)
|
|
.execute();
|
|
|
|
await sql`
|
|
CREATE TEMP TABLE "TempTestScenario" AS
|
|
SELECT *
|
|
FROM "TestScenario"
|
|
WHERE "experimentId" = ${experimentId}
|
|
|
|
-- Only copy the rows that actually have a value for the variable, no reason to churn the rest and simplifies the update.
|
|
AND "variableValues"->${templateVariable.label} IS NOT NULL
|
|
`.execute(trx);
|
|
|
|
await sql`
|
|
UPDATE "TempTestScenario"
|
|
SET "variableValues" = jsonb_set(
|
|
"variableValues",
|
|
${`{${newLabel}}`},
|
|
"variableValues"->${templateVariable.label}
|
|
) - ${templateVariable.label},
|
|
"updatedAt" = NOW(),
|
|
"id" = uuid_generate_v4()
|
|
`.execute(trx);
|
|
|
|
// Print the contents of the temp table
|
|
const results = await sql`SELECT * FROM "TempTestScenario"`.execute(trx);
|
|
console.log(results.rows);
|
|
|
|
await trx
|
|
.updateTable("TestScenario")
|
|
.set({
|
|
visible: false,
|
|
})
|
|
.where("experimentId", "=", experimentId)
|
|
.execute();
|
|
|
|
await sql`
|
|
INSERT INTO "TestScenario" (id, "variableValues", "uiId", visible, "sortIndex", "experimentId", "createdAt", "updatedAt")
|
|
SELECT * FROM "TempTestScenario";
|
|
`.execute(trx);
|
|
});
|
|
};
|