kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 71 lines 1.5 kB view raw
1import { eq, sql } from "drizzle-orm"; 2import { HTTPException } from "hono/http-exception"; 3import db from "../../database"; 4import { columnTable } from "../../database/schema"; 5 6function toSlug(name: string): string { 7 return name 8 .toLowerCase() 9 .trim() 10 .replace(/[^a-z0-9]+/g, "-") 11 .replace(/^-+|-+$/g, ""); 12} 13 14async function createColumn({ 15 projectId, 16 name, 17 icon, 18 color, 19 isFinal, 20}: { 21 projectId: string; 22 name: string; 23 icon?: string; 24 color?: string; 25 isFinal?: boolean; 26}) { 27 const slug = toSlug(name); 28 29 const existing = await db 30 .select({ id: columnTable.id }) 31 .from(columnTable) 32 .where( 33 sql`${columnTable.projectId} = ${projectId} AND ${columnTable.slug} = ${slug}`, 34 ); 35 36 if (existing.length > 0) { 37 throw new HTTPException(409, { 38 message: `Column with slug "${slug}" already exists in this project`, 39 }); 40 } 41 42 const [maxPos] = await db 43 .select({ 44 maxPosition: sql<number>`COALESCE(MAX(${columnTable.position}), -1)`, 45 }) 46 .from(columnTable) 47 .where(eq(columnTable.projectId, projectId)); 48 49 const position = (maxPos?.maxPosition ?? -1) + 1; 50 51 const [created] = await db 52 .insert(columnTable) 53 .values({ 54 projectId, 55 name, 56 slug, 57 position, 58 icon: icon || null, 59 color: color || null, 60 isFinal: isFinal ?? false, 61 }) 62 .returning(); 63 64 if (!created) { 65 throw new HTTPException(500, { message: "Failed to create column" }); 66 } 67 68 return created; 69} 70 71export default createColumn;