-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathapi.v1.orgs.$orgParam.projects.ts
More file actions
168 lines (145 loc) · 4.9 KB
/
Copy pathapi.v1.orgs.$orgParam.projects.ts
File metadata and controls
168 lines (145 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/server-runtime";
import { json } from "@remix-run/server-runtime";
import type { GetProjectResponseBody, GetProjectsResponseBody } from "@trigger.dev/core/v3";
import { CreateProjectRequestBody, tryCatch } from "@trigger.dev/core/v3";
import { z } from "zod";
import { prisma } from "~/db.server";
import { createProject } from "~/models/project.server";
import { logger } from "~/services/logger.server";
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
import { isCuid } from "cuid";
const ParamsSchema = z.object({
orgParam: z.string(),
});
export async function loader({ request, params }: LoaderFunctionArgs) {
logger.info("get projects", { url: request.url });
try {
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
if (!authenticationResult) {
return json({ error: "Invalid or Missing Access Token" }, { status: 401 });
}
const { orgParam } = ParamsSchema.parse(params);
const projects = await prisma.project.findMany({
where: {
organization: {
...orgParamWhereClause(orgParam),
deletedAt: null,
members: {
some: {
userId: authenticationResult.userId,
},
},
},
version: "V3",
deletedAt: null,
},
include: {
organization: true,
defaultWorkerGroup: { select: { name: true } },
},
});
if (!projects) {
return json({ error: "Projects not found" }, { status: 404 });
}
const result: GetProjectsResponseBody = projects.map((project) => ({
id: project.id,
externalRef: project.externalRef,
name: project.name,
slug: project.slug,
createdAt: project.createdAt,
defaultRegion: project.defaultWorkerGroup?.name ?? null,
organization: {
id: project.organization.id,
title: project.organization.title,
slug: project.organization.slug,
createdAt: project.organization.createdAt,
},
}));
return json(result);
} catch (error) {
if (error instanceof Response) throw error;
logger.error("Failed to list org projects", { error });
return json({ error: "Internal Server Error" }, { status: 500 });
}
}
export async function action({ request, params }: ActionFunctionArgs) {
try {
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
if (!authenticationResult) {
return json({ error: "Invalid or Missing Access Token" }, { status: 401 });
}
const { orgParam } = ParamsSchema.parse(params);
const organization = await prisma.organization.findFirst({
where: {
...orgParamWhereClause(orgParam),
deletedAt: null,
members: {
some: {
userId: authenticationResult.userId,
},
},
},
});
if (!organization) {
return json({ error: "Organization not found" }, { status: 404 });
}
const body = await request.json();
const parsedBody = CreateProjectRequestBody.safeParse(body);
if (!parsedBody.success) {
return json({ error: "Invalid request body" }, { status: 400 });
}
const [error, project] = await tryCatch(
createProject({
organizationSlug: organization.slug,
name: parsedBody.data.name,
userId: authenticationResult.userId,
version: "v3",
})
);
if (error) {
logger.error("Failed to create project", { error });
return json({ error: "Failed to create project" }, { status: 400 });
}
// Derive from the stored id rather than assuming new projects are unset,
// so this stays correct if project creation ever inherits a default region.
const defaultRegion = project.defaultWorkerGroupId
? ((
await prisma.workerInstanceGroup.findFirst({
where: { id: project.defaultWorkerGroupId },
select: { name: true },
})
)?.name ?? null)
: null;
const result: GetProjectResponseBody = {
id: project.id,
externalRef: project.externalRef,
name: project.name,
slug: project.slug,
createdAt: project.createdAt,
defaultRegion,
organization: {
id: project.organization.id,
title: project.organization.title,
slug: project.organization.slug,
createdAt: project.organization.createdAt,
},
};
return json(result);
} catch (error) {
if (error instanceof Response) throw error;
logger.error("Failed to create org project", { error });
return json({ error: "Internal Server Error" }, { status: 500 });
}
}
function orgParamWhereClause(orgParam: string) {
// If the orgParam is an ID, or if it's a slug
// IDs are cuid
if (isCuid(orgParam)) {
return {
id: orgParam,
};
}
return {
slug: orgParam,
};
}