refactor(api): extract blueprint router support
This commit is contained in:
@@ -1,9 +1,34 @@
|
||||
import { BlueprintTarget, CreateBlueprintSchema, UpdateBlueprintSchema, type BlueprintFieldDefinition } from "@capakraken/shared";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { BlueprintTarget, CreateBlueprintSchema, UpdateBlueprintSchema } from "@capakraken/shared";
|
||||
import { z } from "zod";
|
||||
import { findUniqueOrThrow } from "../db/helpers.js";
|
||||
import { adminProcedure, createTRPCRouter, planningReadProcedure, protectedProcedure } from "../trpc.js";
|
||||
import { createAuditEntry } from "../lib/audit.js";
|
||||
import {
|
||||
buildBlueprintCreateData,
|
||||
buildBlueprintRolePresetsUpdateData,
|
||||
buildBlueprintUpdateData,
|
||||
expandGlobalBlueprintFieldDefs,
|
||||
findBlueprintByIdentifier,
|
||||
} from "./blueprint-support.js";
|
||||
|
||||
type BlueprintIdentifierReadModel = {
|
||||
id: string;
|
||||
name: string;
|
||||
target: BlueprintTarget;
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
type BlueprintDetailReadModel = {
|
||||
id: string;
|
||||
name: string;
|
||||
target: BlueprintTarget;
|
||||
description: string | null;
|
||||
fieldDefs: unknown;
|
||||
defaults: unknown;
|
||||
validationRules: unknown;
|
||||
rolePresets: unknown;
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
export const blueprintRouter = createTRPCRouter({
|
||||
listSummaries: planningReadProcedure
|
||||
@@ -48,79 +73,27 @@ export const blueprintRouter = createTRPCRouter({
|
||||
resolveByIdentifier: protectedProcedure
|
||||
.input(z.object({ identifier: z.string().trim().min(1) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const identifier = input.identifier.trim();
|
||||
const select = {
|
||||
id: true,
|
||||
name: true,
|
||||
target: true,
|
||||
isActive: true,
|
||||
} as const;
|
||||
|
||||
let blueprint = await ctx.db.blueprint.findUnique({
|
||||
where: { id: identifier },
|
||||
select,
|
||||
return findBlueprintByIdentifier<BlueprintIdentifierReadModel>(ctx.db, input.identifier, {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
target: true,
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!blueprint) {
|
||||
blueprint = await ctx.db.blueprint.findFirst({
|
||||
where: { name: { equals: identifier, mode: "insensitive" } },
|
||||
select,
|
||||
});
|
||||
}
|
||||
|
||||
if (!blueprint) {
|
||||
blueprint = await ctx.db.blueprint.findFirst({
|
||||
where: { name: { contains: identifier, mode: "insensitive" } },
|
||||
select,
|
||||
});
|
||||
}
|
||||
|
||||
if (!blueprint) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: `Blueprint not found: ${identifier}` });
|
||||
}
|
||||
|
||||
return blueprint;
|
||||
}),
|
||||
|
||||
getByIdentifier: planningReadProcedure
|
||||
.input(z.object({ identifier: z.string().trim().min(1) }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const identifier = input.identifier.trim();
|
||||
let blueprint = await ctx.db.blueprint.findUnique({
|
||||
where: { id: identifier },
|
||||
});
|
||||
|
||||
if (!blueprint) {
|
||||
blueprint = await ctx.db.blueprint.findFirst({
|
||||
where: { name: { equals: identifier, mode: "insensitive" } },
|
||||
});
|
||||
}
|
||||
|
||||
if (!blueprint) {
|
||||
blueprint = await ctx.db.blueprint.findFirst({
|
||||
where: { name: { contains: identifier, mode: "insensitive" } },
|
||||
});
|
||||
}
|
||||
|
||||
if (!blueprint) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: `Blueprint not found: ${identifier}` });
|
||||
}
|
||||
|
||||
return blueprint;
|
||||
return findBlueprintByIdentifier<BlueprintDetailReadModel>(ctx.db, input.identifier, {});
|
||||
}),
|
||||
|
||||
create: adminProcedure
|
||||
.input(CreateBlueprintSchema)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const blueprint = await ctx.db.blueprint.create({
|
||||
data: {
|
||||
name: input.name,
|
||||
target: input.target,
|
||||
description: input.description,
|
||||
fieldDefs: input.fieldDefs as unknown as import("@capakraken/db").Prisma.InputJsonValue,
|
||||
defaults: input.defaults as unknown as import("@capakraken/db").Prisma.InputJsonValue,
|
||||
validationRules: input.validationRules as unknown as import("@capakraken/db").Prisma.InputJsonValue,
|
||||
} as unknown as Parameters<typeof ctx.db.blueprint.create>[0]["data"],
|
||||
data: buildBlueprintCreateData(input),
|
||||
});
|
||||
|
||||
void createAuditEntry({
|
||||
@@ -147,13 +120,7 @@ export const blueprintRouter = createTRPCRouter({
|
||||
|
||||
const updated = await ctx.db.blueprint.update({
|
||||
where: { id: input.id },
|
||||
data: {
|
||||
...(input.data.name !== undefined ? { name: input.data.name } : {}),
|
||||
...(input.data.description !== undefined ? { description: input.data.description } : {}),
|
||||
...(input.data.fieldDefs !== undefined ? { fieldDefs: input.data.fieldDefs as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
|
||||
...(input.data.defaults !== undefined ? { defaults: input.data.defaults as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
|
||||
...(input.data.validationRules !== undefined ? { validationRules: input.data.validationRules as unknown as import("@capakraken/db").Prisma.InputJsonValue } : {}),
|
||||
} as unknown as Parameters<typeof ctx.db.blueprint.update>[0]["data"],
|
||||
data: buildBlueprintUpdateData(input.data),
|
||||
});
|
||||
|
||||
void createAuditEntry({
|
||||
@@ -181,7 +148,7 @@ export const blueprintRouter = createTRPCRouter({
|
||||
);
|
||||
const updated = await ctx.db.blueprint.update({
|
||||
where: { id: input.id },
|
||||
data: { rolePresets: input.rolePresets as unknown as import("@capakraken/db").Prisma.InputJsonValue },
|
||||
data: buildBlueprintRolePresetsUpdateData(input.rolePresets),
|
||||
});
|
||||
|
||||
void createAuditEntry({
|
||||
@@ -254,13 +221,7 @@ export const blueprintRouter = createTRPCRouter({
|
||||
where: { target: input.target, isGlobal: true, isActive: true },
|
||||
select: { id: true, name: true, fieldDefs: true },
|
||||
});
|
||||
return blueprints.flatMap((b) =>
|
||||
(b.fieldDefs as unknown as BlueprintFieldDefinition[]).map((f) => ({
|
||||
...f,
|
||||
blueprintId: b.id,
|
||||
blueprintName: b.name,
|
||||
})),
|
||||
);
|
||||
return expandGlobalBlueprintFieldDefs(blueprints);
|
||||
}),
|
||||
|
||||
setGlobal: adminProcedure
|
||||
|
||||
Reference in New Issue
Block a user