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
▼src/pages/api/repos/[owner]/[repo]/queue/join.ts
+36-37
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
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