Skip to content

Commit 4c2890a

Browse files
committed
Test page uses the taskIdentifier in the path
1 parent 19aa804 commit 4c2890a

File tree

5 files changed

+192
-97
lines changed

5 files changed

+192
-97
lines changed

apps/webapp/app/presenters/v3/TestPresenter.server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ export class TestPresenter extends BasePresenter {
113113
triggerSource: TaskTriggerSource;
114114
}[]
115115
>`WITH workers AS (
116-
SELECT
116+
SELECT
117117
bw.*,
118118
ROW_NUMBER() OVER(ORDER BY string_to_array(bw.version, '.')::int[] DESC) AS rn
119-
FROM
119+
FROM
120120
${sqlDatabaseSchema}."BackgroundWorker" bw
121121
WHERE "runtimeEnvironmentId" = ${envId}
122122
),

apps/webapp/app/presenters/v3/TestTaskPresenter.server.ts

Lines changed: 112 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { ScheduledTaskPayload, parsePacket, prettyPrintPacket } from "@trigger.dev/core/v3";
2-
import { RuntimeEnvironmentType, TaskRunStatus } from "@trigger.dev/database";
2+
import { BackgroundWorkerTask, RuntimeEnvironmentType, TaskRunStatus } from "@trigger.dev/database";
33
import { PrismaClient, prisma, sqlDatabaseSchema } from "~/db.server";
44
import { getTimezones } from "~/utils/timezones.server";
55
import { getUsername } from "~/utils/username";
6+
import { findCurrentWorkerDeployment } from "~/v3/models/workerDeployment.server";
67

78
type TestTaskOptions = {
89
userId: string;
910
projectSlug: string;
10-
taskFriendlyId: string;
11+
environmentSlug: string;
12+
taskIdentifier: string;
1113
};
1214

1315
type Task = {
@@ -37,6 +39,15 @@ export type TestTask =
3739
runs: ScheduledRun[];
3840
};
3941

42+
export type TestTaskResult =
43+
| {
44+
foundTask: true;
45+
task: TestTask;
46+
}
47+
| {
48+
foundTask: false;
49+
};
50+
4051
type RawRun = {
4152
id: string;
4253
number: BigInt;
@@ -71,55 +82,79 @@ export class TestTaskPresenter {
7182
this.#prismaClient = prismaClient;
7283
}
7384

74-
public async call({ userId, projectSlug, taskFriendlyId }: TestTaskOptions): Promise<TestTask> {
75-
const task = await this.#prismaClient.backgroundWorkerTask.findFirstOrThrow({
85+
public async call({
86+
userId,
87+
projectSlug,
88+
environmentSlug,
89+
taskIdentifier,
90+
}: TestTaskOptions): Promise<TestTaskResult> {
91+
const environment = await this.#prismaClient.runtimeEnvironment.findFirstOrThrow({
92+
where: {
93+
slug: environmentSlug,
94+
project: {
95+
slug: projectSlug,
96+
},
97+
orgMember: environmentSlug === "dev" ? { userId } : undefined,
98+
},
7699
select: {
77100
id: true,
78-
filePath: true,
79-
exportName: true,
80-
slug: true,
81-
triggerSource: true,
82-
runtimeEnvironment: {
101+
type: true,
102+
orgMember: {
83103
select: {
84-
id: true,
85-
type: true,
86-
orgMember: {
104+
user: {
87105
select: {
88-
user: {
89-
select: {
90-
id: true,
91-
name: true,
92-
displayName: true,
93-
},
94-
},
106+
id: true,
107+
name: true,
108+
displayName: true,
95109
},
96110
},
97111
},
98112
},
99113
},
100-
where: {
101-
friendlyId: taskFriendlyId,
102-
},
103114
});
104115

116+
let task: BackgroundWorkerTask | null = null;
117+
if (environment.type !== "DEVELOPMENT") {
118+
const deployment = await findCurrentWorkerDeployment(environment.id);
119+
if (deployment) {
120+
task = deployment.worker?.tasks.find((t) => t.slug === taskIdentifier) ?? null;
121+
}
122+
} else {
123+
task = await this.#prismaClient.backgroundWorkerTask.findFirst({
124+
where: {
125+
slug: taskIdentifier,
126+
runtimeEnvironmentId: environment.id,
127+
},
128+
orderBy: {
129+
createdAt: "desc",
130+
},
131+
});
132+
}
133+
134+
if (!task) {
135+
return {
136+
foundTask: false,
137+
};
138+
}
139+
105140
const latestRuns = await this.#prismaClient.$queryRaw<RawRun[]>`
106141
WITH taskruns AS (
107-
SELECT
108-
tr.*
109-
FROM
142+
SELECT
143+
tr.*
144+
FROM
110145
${sqlDatabaseSchema}."TaskRun" as tr
111146
JOIN
112147
${sqlDatabaseSchema}."BackgroundWorkerTask" as bwt
113148
ON
114149
tr."taskIdentifier" = bwt.slug
115150
WHERE
116-
bwt."friendlyId" = ${taskFriendlyId} AND
117-
tr."runtimeEnvironmentId" = ${task.runtimeEnvironment.id}
118-
ORDER BY
151+
bwt."friendlyId" = ${task.friendlyId} AND
152+
tr."runtimeEnvironmentId" = ${environment.id}
153+
ORDER BY
119154
tr."createdAt" DESC
120155
LIMIT 5
121156
)
122-
SELECT
157+
SELECT
123158
taskr.id,
124159
taskr.number,
125160
taskr."friendlyId",
@@ -131,7 +166,7 @@ export class TestTaskPresenter {
131166
taskr."seedMetadata",
132167
taskr."seedMetadataType",
133168
taskr."runtimeEnvironmentId"
134-
FROM
169+
FROM
135170
taskruns AS taskr
136171
WHERE
137172
taskr."payloadType" = 'application/json' OR taskr."payloadType" = 'application/super+json'
@@ -143,58 +178,64 @@ export class TestTaskPresenter {
143178
taskIdentifier: task.slug,
144179
filePath: task.filePath,
145180
exportName: task.exportName,
146-
friendlyId: taskFriendlyId,
181+
friendlyId: task.friendlyId,
147182
environment: {
148-
id: task.runtimeEnvironment.id,
149-
type: task.runtimeEnvironment.type,
150-
userId: task.runtimeEnvironment.orgMember?.user.id,
151-
userName: getUsername(task.runtimeEnvironment.orgMember?.user),
183+
id: environment.id,
184+
type: environment.type,
185+
userId: environment.orgMember?.user.id,
186+
userName: getUsername(environment.orgMember?.user),
152187
},
153188
};
154189

155190
switch (task.triggerSource) {
156191
case "STANDARD":
157192
return {
158-
triggerSource: "STANDARD",
159-
task: taskWithEnvironment,
160-
runs: await Promise.all(
161-
latestRuns.map(async (r) => {
162-
const number = Number(r.number);
163-
164-
return {
165-
...r,
166-
number,
167-
payload: await prettyPrintPacket(r.payload, r.payloadType),
168-
metadata: r.seedMetadata
169-
? await prettyPrintPacket(r.seedMetadata, r.seedMetadataType)
170-
: undefined,
171-
};
172-
})
173-
),
174-
};
175-
case "SCHEDULED":
176-
const possibleTimezones = getTimezones();
177-
return {
178-
triggerSource: "SCHEDULED",
179-
task: taskWithEnvironment,
180-
possibleTimezones,
181-
runs: (
182-
await Promise.all(
193+
foundTask: true,
194+
task: {
195+
triggerSource: "STANDARD",
196+
task: taskWithEnvironment,
197+
runs: await Promise.all(
183198
latestRuns.map(async (r) => {
184199
const number = Number(r.number);
185200

186-
const payload = await getScheduleTaskRunPayload(r);
187-
188-
if (payload.success) {
189-
return {
190-
...r,
191-
number,
192-
payload: payload.data,
193-
};
194-
}
201+
return {
202+
...r,
203+
number,
204+
payload: await prettyPrintPacket(r.payload, r.payloadType),
205+
metadata: r.seedMetadata
206+
? await prettyPrintPacket(r.seedMetadata, r.seedMetadataType)
207+
: undefined,
208+
};
195209
})
196-
)
197-
).filter(Boolean),
210+
),
211+
},
212+
};
213+
case "SCHEDULED":
214+
const possibleTimezones = getTimezones();
215+
return {
216+
foundTask: true,
217+
task: {
218+
triggerSource: "SCHEDULED",
219+
task: taskWithEnvironment,
220+
possibleTimezones,
221+
runs: (
222+
await Promise.all(
223+
latestRuns.map(async (r) => {
224+
const number = Number(r.number);
225+
226+
const payload = await getScheduleTaskRunPayload(r);
227+
228+
if (payload.success) {
229+
return {
230+
...r,
231+
number,
232+
payload: payload.data,
233+
};
234+
}
235+
})
236+
)
237+
).filter(Boolean),
238+
},
198239
};
199240
}
200241
}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.test.tasks.$taskParam/route.tsx

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Form, useActionData, useSubmit } from "@remix-run/react";
55
import { ActionFunction, LoaderFunctionArgs, json } from "@remix-run/server-runtime";
66
import { TaskRunStatus } from "@trigger.dev/database";
77
import { useCallback, useEffect, useRef, useState } from "react";
8-
import { typedjson, useTypedLoaderData } from "remix-typedjson";
8+
import { redirect, typedjson, useTypedLoaderData } from "remix-typedjson";
99
import { JSONEditor } from "~/components/code/JSONEditor";
1010
import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel";
1111
import { Button } from "~/components/primitives/Buttons";
@@ -32,7 +32,11 @@ import { TextLink } from "~/components/primitives/TextLink";
3232
import { TaskRunStatusCombo } from "~/components/runs/v3/TaskRunStatus";
3333
import { TimezoneList } from "~/components/scheduled/timezones";
3434
import { useSearchParams } from "~/hooks/useSearchParam";
35-
import { redirectBackWithErrorMessage, redirectWithSuccessMessage } from "~/models/message.server";
35+
import {
36+
redirectBackWithErrorMessage,
37+
redirectWithErrorMessage,
38+
redirectWithSuccessMessage,
39+
} from "~/models/message.server";
3640
import {
3741
ScheduledRun,
3842
StandardRun,
@@ -42,7 +46,7 @@ import {
4246
import { logger } from "~/services/logger.server";
4347
import { requireUserId } from "~/services/session.server";
4448
import { cn } from "~/utils/cn";
45-
import { docsPath, v3RunSpanPath, v3TaskParamsSchema } from "~/utils/pathBuilder";
49+
import { docsPath, v3RunSpanPath, v3TaskParamsSchema, v3TestPath } from "~/utils/pathBuilder";
4650
import { TestTaskService } from "~/v3/services/testTask.server";
4751
import { OutOfEntitlementError } from "~/v3/services/triggerTask.server";
4852
import { TestTaskData } from "~/v3/testTask";
@@ -51,14 +55,30 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
5155
const userId = await requireUserId(request);
5256
const { projectParam, organizationSlug, taskParam } = v3TaskParamsSchema.parse(params);
5357

54-
const presenter = new TestTaskPresenter();
55-
const result = await presenter.call({
56-
userId,
57-
projectSlug: projectParam,
58-
taskFriendlyId: taskParam,
59-
});
58+
//need an environment
59+
const searchParams = new URL(request.url).searchParams;
60+
const environment = searchParams.get("environment");
61+
if (!environment) {
62+
return redirect(v3TestPath({ slug: organizationSlug }, { slug: projectParam }));
63+
}
6064

61-
return typedjson(result);
65+
const presenter = new TestTaskPresenter();
66+
try {
67+
const result = await presenter.call({
68+
userId,
69+
projectSlug: projectParam,
70+
taskIdentifier: taskParam,
71+
environmentSlug: environment,
72+
});
73+
74+
return typedjson(result);
75+
} catch (error) {
76+
return redirectWithErrorMessage(
77+
v3TestPath({ slug: organizationSlug }, { slug: projectParam }, environment),
78+
request,
79+
`Couldn't load test page for ${taskParam}`
80+
);
81+
}
6282
};
6383

6484
export const action: ActionFunction = async ({ request, params }) => {
@@ -113,16 +133,20 @@ export const action: ActionFunction = async ({ request, params }) => {
113133
export default function Page() {
114134
const result = useTypedLoaderData<typeof loader>();
115135

116-
switch (result.triggerSource) {
136+
if (!result.foundTask) {
137+
return <div></div>;
138+
}
139+
140+
switch (result.task.triggerSource) {
117141
case "STANDARD": {
118-
return <StandardTaskForm task={result.task} runs={result.runs} />;
142+
return <StandardTaskForm task={result.task.task} runs={result.task.runs} />;
119143
}
120144
case "SCHEDULED": {
121145
return (
122146
<ScheduledTaskForm
123-
task={result.task}
124-
runs={result.runs}
125-
possibleTimezones={result.possibleTimezones}
147+
task={result.task.task}
148+
runs={result.task.runs}
149+
possibleTimezones={result.task.possibleTimezones}
126150
/>
127151
);
128152
}

0 commit comments

Comments
 (0)