From 1cf5808ce742f258eaa73b64a5b2b2fa2aae6a28 Mon Sep 17 00:00:00 2001 From: Henry Date: Tue, 15 Jul 2025 14:01:46 +0100 Subject: [PATCH] feat: scaffold checklist router --- packages/api/src/routers/checklists.ts | 120 +++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 packages/api/src/routers/checklists.ts diff --git a/packages/api/src/routers/checklists.ts b/packages/api/src/routers/checklists.ts new file mode 100644 index 00000000..a3aac701 --- /dev/null +++ b/packages/api/src/routers/checklists.ts @@ -0,0 +1,120 @@ +import { TRPCError } from "@trpc/server"; +import { z } from "zod"; + +import * as cardRepo from "@kan/db/repository/card.repo"; +import * as checklistRepo from "@kan/db/repository/checklist.repo"; + +import { createTRPCRouter, protectedProcedure } from "../trpc"; +import { assertUserInWorkspace } from "../utils/auth"; + +const checklistSchema = z.object({ + publicId: z.string(), + title: z.string(), +}); + +export const checklistRouter = createTRPCRouter({ + create: protectedProcedure + .meta({ + openapi: { + summary: "Add a checklist to a card", + method: "POST", + path: "/cards/{cardPublicId}/checklists", + description: "Adds a checklist to a card", + tags: ["Cards"], + protect: true, + }, + }) + .input( + z.object({ + cardPublicId: z.string().min(12), + title: z.string().min(1), + }), + ) + .output(checklistSchema) + .mutation(async ({ ctx, input }) => { + const userId = ctx.user?.id; + + if (!userId) + throw new TRPCError({ + message: `User not authenticated`, + code: "UNAUTHORIZED", + }); + + const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId( + ctx.db, + input.cardPublicId, + ); + + if (!card) + throw new TRPCError({ + message: `Card with public ID ${input.cardPublicId} not found`, + code: "NOT_FOUND", + }); + + await assertUserInWorkspace(ctx.db, userId, card.workspaceId); + + const newChecklist = await checklistRepo.create(ctx.db, { + title: input.title, + createdBy: userId, + cardId: card.id, + }); + + if (!newChecklist?.id) + throw new TRPCError({ + message: `Failed to create checklist`, + code: "INTERNAL_SERVER_ERROR", + }); + + // await cardActivityRepo.create(ctx.db, { + // type: "card.updated.checklist.added" as const, + // cardId: card.id, + // checklistId: newChecklist.id, + // toChecklist: newChecklist.title, + // createdBy: userId, + // }); + + return newChecklist; + }), + // update: protectedProcedure + // .meta({ + // openapi: { + // summary: "Update a checklist", + // method: "PUT", + // path: "/cards/{cardPublicId}/checklists/{checklistPublicId}", + // description: "Updates a checklist", + // tags: ["Cards"], + // protect: true, + // }, + // }) + // .input( + // z.object({ + // cardPublicId: z.string().min(12), + // checklistPublicId: z.string().min(12), + // title: z.string().min(1), + // }), + // ) + // .output(checklistSchema) + // .mutation(async ({ ctx, input }) => { + + // }), + // delete: protectedProcedure + // .meta({ + // openapi: { + // summary: "Delete a checklist", + // method: "DELETE", + // path: "/cards/{cardPublicId}/checklists/{checklistPublicId}", + // description: "Deletes a checklist", + // tags: ["Cards"], + // }, + // }) + // .input( + // z.object({ + // cardPublicId: z.string().min(12), + // checklistPublicId: z.string().min(12), + // }), + // ) + // .output(checklistSchema) + // .mutation(async ({ ctx, input }) => { + + // }), +});