kaneo (minimalist kanban) fork to experiment adding a tangled integration
github.com/usekaneo/kaneo
1import { and, eq } from "drizzle-orm";
2import { HTTPException } from "hono/http-exception";
3import db from "../../database";
4import { columnTable, projectTable, taskTable } from "../../database/schema";
5import { publishEvent } from "../../events";
6import getNextTaskNumber from "./get-next-task-number";
7
8type ImportTask = {
9 title: string;
10 description?: string;
11 status: string;
12 priority?: string;
13 dueDate?: string;
14 userId?: string | null;
15};
16
17async function importTasks(projectId: string, tasksToImport: ImportTask[]) {
18 const project = await db.query.projectTable.findFirst({
19 where: eq(projectTable.id, projectId),
20 });
21
22 if (!project) {
23 throw new HTTPException(404, {
24 message: "Project not found",
25 });
26 }
27
28 const nextTaskNumber = await getNextTaskNumber(projectId);
29 let taskNumber = nextTaskNumber;
30
31 const results = [];
32
33 for (const taskData of tasksToImport) {
34 try {
35 const column = await db.query.columnTable.findFirst({
36 where: and(
37 eq(columnTable.projectId, projectId),
38 eq(columnTable.slug, taskData.status),
39 ),
40 });
41
42 const [createdTask] = await db
43 .insert(taskTable)
44 .values({
45 projectId,
46 userId: taskData.userId || null,
47 title: taskData.title,
48 status: taskData.status,
49 columnId: column?.id ?? null,
50 dueDate: taskData.dueDate ? new Date(taskData.dueDate) : null,
51 description: taskData.description || "",
52 priority: taskData.priority || "low",
53 number: ++taskNumber,
54 })
55 .returning();
56
57 if (createdTask) {
58 await publishEvent("task.created", {
59 taskId: createdTask.id,
60 userId: createdTask.userId ?? "",
61 type: "create",
62 content: "imported the task",
63 });
64
65 results.push({
66 success: true,
67 task: createdTask,
68 });
69 } else {
70 results.push({
71 success: false,
72 error: "Failed to create task",
73 task: taskData,
74 });
75 }
76 } catch (error) {
77 results.push({
78 success: false,
79 error: error instanceof Error ? error.message : "Unknown error",
80 task: taskData,
81 });
82 }
83 }
84
85 return {
86 importedAt: new Date().toISOString(),
87 project: {
88 id: project.id,
89 name: project.name,
90 slug: project.slug,
91 },
92 results: {
93 total: tasksToImport.length,
94 successful: results.filter((r) => r.success).length,
95 failed: results.filter((r) => !r.success).length,
96 tasks: results,
97 },
98 };
99}
100
101export default importTasks;