feat: create new checklist item
This commit is contained in:
@@ -12,6 +12,12 @@ const checklistSchema = z.object({
|
||||
name: z.string().min(1).max(255),
|
||||
});
|
||||
|
||||
const checklistItemSchema = z.object({
|
||||
publicId: z.string().length(12),
|
||||
title: z.string().min(1).max(500),
|
||||
completed: z.boolean(),
|
||||
});
|
||||
|
||||
export const checklistRouter = createTRPCRouter({
|
||||
create: protectedProcedure
|
||||
.meta({
|
||||
@@ -75,6 +81,64 @@ export const checklistRouter = createTRPCRouter({
|
||||
|
||||
return newChecklist;
|
||||
}),
|
||||
createItem: protectedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
summary: "Add an item to a checklist",
|
||||
method: "POST",
|
||||
path: "/checklists/{checklistPublicId}/items",
|
||||
description: "Adds an item to a checklist",
|
||||
tags: ["Cards"],
|
||||
protect: true,
|
||||
},
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
checklistPublicId: z.string().length(12),
|
||||
title: z.string().min(1).max(500),
|
||||
}),
|
||||
)
|
||||
.output(checklistItemSchema)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId)
|
||||
throw new TRPCError({
|
||||
message: `User not authenticated`,
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const checklist = await checklistRepo.getChecklistByPublicId(
|
||||
ctx.db,
|
||||
input.checklistPublicId,
|
||||
);
|
||||
|
||||
if (!checklist)
|
||||
throw new TRPCError({
|
||||
message: `Checklist with public ID ${input.checklistPublicId} not found`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
|
||||
await assertUserInWorkspace(
|
||||
ctx.db,
|
||||
userId,
|
||||
checklist.card.list.board.workspace.id,
|
||||
);
|
||||
|
||||
const newChecklistItem = await checklistRepo.createItem(ctx.db, {
|
||||
title: input.title,
|
||||
createdBy: userId,
|
||||
checklistId: checklist.id,
|
||||
});
|
||||
|
||||
if (!newChecklistItem?.id)
|
||||
throw new TRPCError({
|
||||
message: `Failed to create checklist item`,
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
});
|
||||
|
||||
return newChecklistItem;
|
||||
}),
|
||||
// update: protectedProcedure
|
||||
// .meta({
|
||||
// openapi: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { and, desc, eq, isNull } from "drizzle-orm";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import { checklists } from "@kan/db/schema";
|
||||
import { checklistItems, checklists } from "@kan/db/schema";
|
||||
import { generateUID } from "@kan/shared/utils";
|
||||
|
||||
export const create = async (
|
||||
@@ -39,3 +39,70 @@ export const create = async (
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
export const createItem = async (
|
||||
db: dbClient,
|
||||
checklistItemInput: {
|
||||
checklistId: number;
|
||||
title: string;
|
||||
createdBy: string;
|
||||
},
|
||||
) => {
|
||||
return db.transaction(async (tx) => {
|
||||
const lastItem = await tx.query.checklistItems.findFirst({
|
||||
where: and(
|
||||
eq(checklistItems.checklistId, checklistItemInput.checklistId),
|
||||
isNull(checklistItems.deletedAt),
|
||||
),
|
||||
orderBy: desc(checklistItems.index),
|
||||
});
|
||||
|
||||
const [result] = await tx
|
||||
.insert(checklistItems)
|
||||
.values({
|
||||
publicId: generateUID(),
|
||||
title: checklistItemInput.title,
|
||||
createdBy: checklistItemInput.createdBy,
|
||||
checklistId: checklistItemInput.checklistId,
|
||||
index: lastItem ? lastItem.index + 1 : 0,
|
||||
completed: false,
|
||||
})
|
||||
.returning({
|
||||
id: checklistItems.id,
|
||||
publicId: checklistItems.publicId,
|
||||
title: checklistItems.title,
|
||||
completed: checklistItems.completed,
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
export const getChecklistByPublicId = async (
|
||||
db: dbClient,
|
||||
checklistPublicId: string,
|
||||
) => {
|
||||
const checklist = await db.query.checklists.findFirst({
|
||||
where: and(
|
||||
eq(checklists.publicId, checklistPublicId),
|
||||
isNull(checklists.deletedAt),
|
||||
),
|
||||
with: {
|
||||
card: {
|
||||
with: {
|
||||
list: {
|
||||
with: {
|
||||
board: {
|
||||
with: {
|
||||
workspace: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return checklist;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user