chore: update src/pages/api/repos/[owner]/[repo]/queue/join.ts
swadhinbiswas committed 8 months ago
7c6c2d9
1 parent c712762
commit 7c6c2d9
1 file changed
+36 -37
Showing 1 changed file+36-37
▼src/pages/api/repos/[owner]/[repo]/queue/join.ts
+36-37
| @@ -1,11 +1,11 @@ | ||
1 | 1 | import { getDatabase, schema } from "@/db"; |
2 | 2 | import { error, success, unauthorized } from "@/lib/api"; |
3 | 3 | import { withErrorHandler } from "@/lib/errors"; |
4 | -import { queueWorker } from "@/lib/queue-worker"; | |
4 | +import { canWriteRepo } from "@/lib/permissions"; | |
5 | +import { addToMergeQueue, processNextInQueue } from "@/lib/merge-queue"; | |
5 | 6 | import { and, eq } from "drizzle-orm"; |
6 | 7 | import type { NodePgDatabase } from "drizzle-orm/node-postgres"; |
7 | 8 | import type { APIContext } from "astro"; |
8 | -import { v4 as uuidv4 } from "uuid"; | |
9 | 9 | |
10 | 10 | export const POST = withErrorHandler(async ({ params, request, locals }: APIContext) => { |
11 | 11 | const user = locals.user; |
| @@ -22,51 +22,50 @@ export const POST = withErrorHandler(async ({ params, request, locals }: APICont | ||
22 | 22 | |
23 | 23 | const db = getDatabase() as NodePgDatabase<typeof schema>; |
24 | 24 | |
25 | - // 1. Verify Repository | |
26 | - const repository = await db.query.repositories.findFirst({ | |
27 | - where: and(eq(schema.repositories.name, repo!), eq(schema.repositories.ownerId, user.id)), // basic check, refine for orgs | |
28 | - with: { owner: true } | |
25 | + const ownerUser = await db.query.users.findFirst({ | |
26 | + where: eq(schema.users.username, owner!), | |
29 | 27 | }); |
30 | - | |
31 | - if (!repository || repository.owner.username !== owner) { | |
32 | - const repoByOwner = await db.query.repositories.findFirst({ | |
33 | - where: eq(schema.repositories.name, repo!), | |
34 | - with: { owner: true } | |
35 | - }); | |
36 | - if (!repoByOwner || repoByOwner.owner.username !== owner) { | |
37 | - return error("NOT_FOUND", "Repository not found", 404); | |
38 | - } | |
39 | - // Check basic permissions here... | |
28 | + if (!ownerUser) { | |
29 | + return error("NOT_FOUND", "Repository not found", 404); | |
40 | 30 | } |
41 | 31 | |
42 | - // 2. Add to Queue | |
43 | - const queueItem = { | |
44 | - id: uuidv4(), | |
45 | - repositoryId: repository!.id, // Need to fetch correct repo ID if permission check passes | |
46 | - pullRequestId, | |
47 | - status: "queued", | |
48 | - attemptCount: 0, | |
49 | - queuedAt: new Date(), | |
50 | - }; | |
51 | - | |
52 | - // Fix repo id fetching above or assume owner/repo is correct: | |
53 | - const targetRepo = await db.query.repositories.findFirst({ | |
32 | + const repository = await db.query.repositories.findFirst({ | |
54 | 33 | where: and( |
34 | + eq(schema.repositories.ownerId, ownerUser.id), | |
55 | 35 | eq(schema.repositories.name, repo!), |
56 | - eq(schema.repositories.ownerId, (await db.query.users.findFirst({ where: eq(schema.users.username, owner!) }))!.id) | |
57 | - ) | |
36 | + ), | |
58 | 37 | }); |
38 | + if (!repository) { | |
39 | + return error("NOT_FOUND", "Repository not found", 404); | |
40 | + } | |
59 | 41 | |
60 | - if (!targetRepo) return error("NOT_FOUND", "Repo not found", 404); | |
42 | + if (!(await canWriteRepo(user.id, repository, { isAdmin: user.isAdmin ?? undefined }))) { | |
43 | + return error("FORBIDDEN", "Access denied", 403); | |
44 | + } | |
61 | 45 | |
62 | - await db.insert(schema.mergeQueueItems).values({ | |
63 | - ...queueItem, | |
64 | - repositoryId: targetRepo.id | |
46 | + const pr = await db.query.pullRequests.findFirst({ | |
47 | + where: and( | |
48 | + eq(schema.pullRequests.id, pullRequestId), | |
49 | + eq(schema.pullRequests.repositoryId, repository.id), | |
50 | + ), | |
51 | + }); | |
52 | + if (!pr) { | |
53 | + return error("NOT_FOUND", "Pull request not found", 404); | |
54 | + } | |
55 | + if (pr.state !== "open" || pr.isMerged) { | |
56 | + return error("BAD_REQUEST", "Pull request is not open", 400); | |
57 | + } | |
58 | + | |
59 | + const queueItem = await addToMergeQueue({ | |
60 | + repositoryId: repository.id, | |
61 | + pullRequestId, | |
62 | + addedById: user.id, | |
65 | 63 | }); |
66 | 64 | |
67 | - // 3. Trigger Worker (Async) | |
68 | - // In production, this might be a cron or event queue. For now, we trigger immediately. | |
69 | - queueWorker.processQueue(targetRepo.id).catch(console.error); | |
65 | + // Kick processing asynchronously, but do not block request lifecycle. | |
66 | + setTimeout(() => { | |
67 | + processNextInQueue(repository.id).catch(console.error); | |
68 | + }, 0); | |
70 | 69 | |
71 | 70 | return success({ message: "Added to merge queue", queueId: queueItem.id }); |
72 | 71 | }); |
73 | 72 | |