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 39e2dfae265f26c8d6d888a560f50ab2d5d58b3f 100 lines 2.6 kB view raw
1import { and, eq } from "drizzle-orm"; 2import db from "../../../database"; 3import { externalLinkTable } from "../../../database/schema"; 4import type { GitHubConfig } from "../config"; 5import { updateExternalLink } from "../services/link-manager"; 6import { 7 findAllIntegrationsByRepo, 8 findTaskById, 9 updateTaskStatus, 10} from "../services/task-service"; 11import { resolveTargetStatus } from "../utils/resolve-column"; 12 13type PRClosedPayload = { 14 action: string; 15 pull_request: { 16 number: number; 17 title: string; 18 html_url: string; 19 state: string; 20 merged: boolean; 21 merged_at: string | null; 22 head: { 23 ref: string; 24 }; 25 }; 26 repository: { 27 owner: { login: string }; 28 name: string; 29 }; 30}; 31 32export async function handlePullRequestClosed(payload: PRClosedPayload) { 33 const { pull_request, repository } = payload; 34 35 const integrations = await findAllIntegrationsByRepo( 36 repository.owner.login, 37 repository.name, 38 ); 39 40 for (const integration of integrations) { 41 const config = JSON.parse(integration.config) as GitHubConfig; 42 43 const externalLink = await db.query.externalLinkTable.findFirst({ 44 where: and( 45 eq(externalLinkTable.integrationId, integration.id), 46 eq(externalLinkTable.resourceType, "pull_request"), 47 eq(externalLinkTable.externalId, pull_request.number.toString()), 48 ), 49 }); 50 51 if (!externalLink) { 52 continue; 53 } 54 55 const task = await findTaskById(externalLink.taskId); 56 57 if (!task) { 58 continue; 59 } 60 61 const existingMetadata = externalLink.metadata 62 ? JSON.parse(externalLink.metadata) 63 : {}; 64 65 await updateExternalLink(externalLink.id, { 66 metadata: { 67 ...existingMetadata, 68 state: "closed", 69 merged: pull_request.merged, 70 mergedAt: pull_request.merged_at, 71 }, 72 }); 73 74 if (pull_request.merged) { 75 const allTaskPRs = await db.query.externalLinkTable.findMany({ 76 where: and( 77 eq(externalLinkTable.taskId, task.id), 78 eq(externalLinkTable.resourceType, "pull_request"), 79 ), 80 }); 81 82 const hasOpenPRs = allTaskPRs.some((pr) => { 83 if (pr.id === externalLink.id) return false; 84 const metadata = pr.metadata ? JSON.parse(pr.metadata) : {}; 85 return metadata.state === "open"; 86 }); 87 88 if (!hasOpenPRs) { 89 const targetStatus = await resolveTargetStatus( 90 integration.projectId, 91 "pr_merged", 92 config.statusTransitions?.onPRMerge || "done", 93 ); 94 await updateTaskStatus(task.id, targetStatus); 95 } 96 } 97 98 return; 99 } 100}