kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 98 lines 2.4 kB view raw
1import { and, eq, max } from "drizzle-orm"; 2import { HTTPException } from "hono/http-exception"; 3import db from "../../database"; 4import { columnTable, taskTable, userTable } from "../../database/schema"; 5import { publishEvent } from "../../events"; 6import { assertValidTaskStatus } from "../validate-task-fields"; 7import getNextTaskNumber from "./get-next-task-number"; 8 9async function createTask({ 10 projectId, 11 userId, 12 title, 13 status, 14 startDate, 15 dueDate, 16 description, 17 priority, 18}: { 19 projectId: string; 20 userId?: string; 21 title: string; 22 status: string; 23 startDate?: Date; 24 dueDate?: Date; 25 description?: string; 26 priority?: string; 27}) { 28 const resolvedStatus = status || "to-do"; 29 const resolvedPriority = priority || "no-priority"; 30 31 await assertValidTaskStatus(resolvedStatus, projectId); 32 33 const [assignee] = await db 34 .select({ name: userTable.name }) 35 .from(userTable) 36 .where(eq(userTable.id, userId ?? "")); 37 38 const nextTaskNumber = await getNextTaskNumber(projectId); 39 40 const column = await db.query.columnTable.findFirst({ 41 where: and( 42 eq(columnTable.projectId, projectId), 43 eq(columnTable.slug, resolvedStatus), 44 ), 45 }); 46 47 const [maxPositionResult] = await db 48 .select({ maxPosition: max(taskTable.position) }) 49 .from(taskTable) 50 .where( 51 and( 52 eq(taskTable.projectId, projectId), 53 column?.id 54 ? eq(taskTable.columnId, column.id) 55 : eq(taskTable.status, resolvedStatus), 56 ), 57 ); 58 59 const nextPosition = (maxPositionResult?.maxPosition ?? 0) + 1; 60 61 const [createdTask] = await db 62 .insert(taskTable) 63 .values({ 64 projectId, 65 userId: userId || null, 66 title: title || "", 67 status: resolvedStatus, 68 columnId: column?.id ?? null, 69 startDate: startDate || null, 70 dueDate: dueDate || null, 71 description: description || "", 72 priority: resolvedPriority, 73 number: nextTaskNumber + 1, 74 position: nextPosition, 75 }) 76 .returning(); 77 78 if (!createdTask) { 79 throw new HTTPException(500, { 80 message: "Failed to create task", 81 }); 82 } 83 84 await publishEvent("task.created", { 85 ...createdTask, 86 taskId: createdTask.id, 87 userId: createdTask.userId ?? "", 88 type: "task", 89 content: null, 90 }); 91 92 return { 93 ...createdTask, 94 assigneeName: assignee?.name, 95 }; 96} 97 98export default createTask;