kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 124 lines 3.0 kB view raw
1import { and, eq } from "drizzle-orm"; 2import db from "../../../database"; 3import { 4 columnTable, 5 integrationTable, 6 taskTable, 7} from "../../../database/schema"; 8 9const NON_COLUMN_STATUSES = new Set(["planned", "archived"]); 10 11export async function findTaskByNumber(projectId: string, taskNumber: number) { 12 return db.query.taskTable.findFirst({ 13 where: and( 14 eq(taskTable.projectId, projectId), 15 eq(taskTable.number, taskNumber), 16 ), 17 }); 18} 19 20export async function findTaskById(taskId: string) { 21 return db.query.taskTable.findFirst({ 22 where: eq(taskTable.id, taskId), 23 }); 24} 25 26export async function updateTaskStatus(taskId: string, newStatus: string) { 27 const task = await db.query.taskTable.findFirst({ 28 where: eq(taskTable.id, taskId), 29 }); 30 31 if (!task) { 32 return; 33 } 34 35 let columnId: string | null = null; 36 37 const column = await db.query.columnTable.findFirst({ 38 where: and( 39 eq(columnTable.projectId, task.projectId), 40 eq(columnTable.slug, newStatus), 41 ), 42 }); 43 44 if (column) { 45 columnId = column.id; 46 } else if (!NON_COLUMN_STATUSES.has(newStatus)) { 47 console.warn( 48 `[GitHub] Skipping status update for task ${taskId}: column "${newStatus}" not found in project ${task.projectId}`, 49 ); 50 return; 51 } 52 53 await db 54 .update(taskTable) 55 .set({ status: newStatus, columnId }) 56 .where(eq(taskTable.id, taskId)); 57} 58 59export async function isTaskInFinalState(task: { 60 projectId: string; 61 status: string; 62 columnId: string | null; 63}): Promise<boolean> { 64 if (task.columnId) { 65 const columnById = await db.query.columnTable.findFirst({ 66 where: and( 67 eq(columnTable.id, task.columnId), 68 eq(columnTable.projectId, task.projectId), 69 ), 70 }); 71 72 if (columnById) { 73 return columnById.isFinal; 74 } 75 } 76 77 const columnByStatus = await db.query.columnTable.findFirst({ 78 where: and( 79 eq(columnTable.projectId, task.projectId), 80 eq(columnTable.slug, task.status), 81 ), 82 }); 83 84 if (columnByStatus) { 85 return columnByStatus.isFinal; 86 } 87 88 return task.status === "done"; 89} 90 91export async function getIntegrationWithProject(integrationId: string) { 92 return db.query.integrationTable.findFirst({ 93 where: eq(integrationTable.id, integrationId), 94 with: { 95 project: true, 96 }, 97 }); 98} 99 100export async function findIntegrationByRepo(owner: string, repo: string) { 101 const integrations = await findAllIntegrationsByRepo(owner, repo); 102 return integrations[0] || null; 103} 104 105export async function findAllIntegrationsByRepo(owner: string, repo: string) { 106 const integrations = await db.query.integrationTable.findMany({ 107 where: and( 108 eq(integrationTable.type, "github"), 109 eq(integrationTable.isActive, true), 110 ), 111 with: { 112 project: true, 113 }, 114 }); 115 116 return integrations.filter((integration) => { 117 try { 118 const config = JSON.parse(integration.config); 119 return config.repositoryOwner === owner && config.repositoryName === repo; 120 } catch { 121 return false; 122 } 123 }); 124}