chore: feedback from pull request
This commit is contained in:
@@ -80,144 +80,144 @@ export class LocalJobProvider extends BaseJobProvider {
|
|||||||
|
|
||||||
public getApiHandler() {
|
public getApiHandler() {
|
||||||
return async (req: NextApiRequest, res: NextApiResponse) => {
|
return async (req: NextApiRequest, res: NextApiResponse) => {
|
||||||
if (req.method === 'POST') {
|
if (req.method !== 'POST') {
|
||||||
const jobId = req.headers['x-job-id'];
|
res.status(405).send('Method not allowed');
|
||||||
const signature = req.headers['x-job-signature'];
|
}
|
||||||
const isRetry = req.headers['x-job-retry'] !== undefined;
|
|
||||||
|
|
||||||
|
const jobId = req.headers['x-job-id'];
|
||||||
|
const signature = req.headers['x-job-signature'];
|
||||||
|
const isRetry = req.headers['x-job-retry'] !== undefined;
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
|
const options = await json(req)
|
||||||
|
.then(async (data) => ZSimpleTriggerJobOptionsSchema.parseAsync(data))
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||||
const options = await json(req)
|
.then((data) => data as SimpleTriggerJobOptions)
|
||||||
.then(async (data) => ZSimpleTriggerJobOptionsSchema.parseAsync(data))
|
.catch(() => null);
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
||||||
.then((data) => data as SimpleTriggerJobOptions)
|
|
||||||
.catch(() => null);
|
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
|
res.status(400).send('Bad request');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const definition = this._jobDefinitions[options.name];
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof jobId !== 'string' ||
|
||||||
|
typeof signature !== 'string' ||
|
||||||
|
typeof options !== 'object'
|
||||||
|
) {
|
||||||
|
res.status(400).send('Bad request');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!definition) {
|
||||||
|
res.status(404).send('Job not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition && !definition.enabled) {
|
||||||
|
console.log('Attempted to trigger a disabled job', options.name);
|
||||||
|
|
||||||
|
res.status(404).send('Job not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!signature || !verify(options, signature)) {
|
||||||
|
res.status(401).send('Unauthorized');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (definition.trigger.schema) {
|
||||||
|
const result = definition.trigger.schema.safeParse(options.payload);
|
||||||
|
|
||||||
|
if (!result.success) {
|
||||||
res.status(400).send('Bad request');
|
res.status(400).send('Bad request');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const definition = this._jobDefinitions[options.name];
|
console.log(`[JOBS]: Triggering job ${options.name} with payload`, options.payload);
|
||||||
|
|
||||||
if (
|
let backgroundJob = await prisma.backgroundJob
|
||||||
typeof jobId !== 'string' ||
|
.update({
|
||||||
typeof signature !== 'string' ||
|
where: {
|
||||||
typeof options !== 'object'
|
id: jobId,
|
||||||
) {
|
status: BackgroundJobStatus.PENDING,
|
||||||
res.status(400).send('Bad request');
|
},
|
||||||
return;
|
data: {
|
||||||
}
|
status: BackgroundJobStatus.PROCESSING,
|
||||||
|
retried: {
|
||||||
if (!definition) {
|
increment: isRetry ? 1 : 0,
|
||||||
res.status(404).send('Job not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (definition && !definition.enabled) {
|
|
||||||
console.log('Attempted to trigger a disabled job', options.name);
|
|
||||||
|
|
||||||
res.status(404).send('Job not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!signature || !verify(options, signature)) {
|
|
||||||
res.status(401).send('Unauthorized');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (definition.trigger.schema) {
|
|
||||||
const result = definition.trigger.schema.safeParse(options.payload);
|
|
||||||
|
|
||||||
if (!result.success) {
|
|
||||||
res.status(400).send('Bad request');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`[JOBS]: Triggering job ${options.name} with payload`, options.payload);
|
|
||||||
|
|
||||||
let backgroundJob = await prisma.backgroundJob
|
|
||||||
.update({
|
|
||||||
where: {
|
|
||||||
id: jobId,
|
|
||||||
status: BackgroundJobStatus.PENDING,
|
|
||||||
},
|
},
|
||||||
data: {
|
lastRetriedAt: isRetry ? new Date() : undefined,
|
||||||
status: BackgroundJobStatus.PROCESSING,
|
},
|
||||||
retried: {
|
})
|
||||||
increment: isRetry ? 1 : 0,
|
.catch(() => null);
|
||||||
},
|
|
||||||
lastRetriedAt: isRetry ? new Date() : undefined,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.catch(() => null);
|
|
||||||
|
|
||||||
if (!backgroundJob) {
|
if (!backgroundJob) {
|
||||||
res.status(404).send('Job not found');
|
res.status(404).send('Job not found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await definition.handler({
|
await definition.handler({
|
||||||
payload: options.payload,
|
payload: options.payload,
|
||||||
io: this.createJobRunIO(jobId),
|
io: this.createJobRunIO(jobId),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
backgroundJob = await prisma.backgroundJob.update({
|
||||||
|
where: {
|
||||||
|
id: jobId,
|
||||||
|
status: BackgroundJobStatus.PROCESSING,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: BackgroundJobStatus.COMPLETED,
|
||||||
|
completedAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[JOBS]: Job ${options.name} failed`, error);
|
||||||
|
|
||||||
|
const taskHasExceededRetries = error instanceof BackgroundTaskExceededRetriesError;
|
||||||
|
const jobHasExceededRetries =
|
||||||
|
backgroundJob.retried >= backgroundJob.maxRetries &&
|
||||||
|
!(error instanceof BackgroundTaskFailedError);
|
||||||
|
|
||||||
|
if (taskHasExceededRetries || jobHasExceededRetries) {
|
||||||
backgroundJob = await prisma.backgroundJob.update({
|
backgroundJob = await prisma.backgroundJob.update({
|
||||||
where: {
|
where: {
|
||||||
id: jobId,
|
id: jobId,
|
||||||
status: BackgroundJobStatus.PROCESSING,
|
status: BackgroundJobStatus.PROCESSING,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
status: BackgroundJobStatus.COMPLETED,
|
status: BackgroundJobStatus.FAILED,
|
||||||
completedAt: new Date(),
|
completedAt: new Date(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
|
||||||
console.error(`[JOBS]: Job ${options.name} failed`, error);
|
|
||||||
|
|
||||||
const taskHasExceededRetries = error instanceof BackgroundTaskExceededRetriesError;
|
res.status(500).send('Task exceeded retries');
|
||||||
const jobHasExceededRetries =
|
return;
|
||||||
backgroundJob.retried >= backgroundJob.maxRetries &&
|
|
||||||
!(error instanceof BackgroundTaskFailedError);
|
|
||||||
|
|
||||||
if (taskHasExceededRetries || jobHasExceededRetries) {
|
|
||||||
backgroundJob = await prisma.backgroundJob.update({
|
|
||||||
where: {
|
|
||||||
id: jobId,
|
|
||||||
status: BackgroundJobStatus.PROCESSING,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
status: BackgroundJobStatus.FAILED,
|
|
||||||
completedAt: new Date(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
res.status(500).send('Task exceeded retries');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
backgroundJob = await prisma.backgroundJob.update({
|
|
||||||
where: {
|
|
||||||
id: jobId,
|
|
||||||
status: BackgroundJobStatus.PROCESSING,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
status: BackgroundJobStatus.PENDING,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.submitJobToEndpoint({
|
|
||||||
jobId,
|
|
||||||
jobDefinitionId: backgroundJob.jobId,
|
|
||||||
data: options,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).send('OK');
|
backgroundJob = await prisma.backgroundJob.update({
|
||||||
} else {
|
where: {
|
||||||
res.status(405).send('Method not allowed');
|
id: jobId,
|
||||||
|
status: BackgroundJobStatus.PROCESSING,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
status: BackgroundJobStatus.PENDING,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.submitJobToEndpoint({
|
||||||
|
jobId,
|
||||||
|
jobDefinitionId: backgroundJob.jobId,
|
||||||
|
data: options,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res.status(200).send('OK');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import { sendConfirmationToken } from '../../server-only/user/send-confirmation-
|
|||||||
import type { JobDefinition } from '../client/_internal/job';
|
import type { JobDefinition } from '../client/_internal/job';
|
||||||
|
|
||||||
export const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION = {
|
export const SEND_CONFIRMATION_EMAIL_JOB_DEFINITION = {
|
||||||
id: 'send.confirmation.email',
|
id: 'send.signup.confirmation.email',
|
||||||
name: 'Send Confirmation Email',
|
name: 'Send Confirmation Email',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
trigger: {
|
trigger: {
|
||||||
name: 'send.confirmation.email',
|
name: 'send.signup.confirmation.email',
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
email: z.string().email(),
|
email: z.string().email(),
|
||||||
force: z.boolean().optional(),
|
force: z.boolean().optional(),
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ import { renderCustomEmailTemplate } from '../../utils/render-custom-email-templ
|
|||||||
import type { JobDefinition } from '../client/_internal/job';
|
import type { JobDefinition } from '../client/_internal/job';
|
||||||
|
|
||||||
export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
export const SEND_SIGNING_EMAIL_JOB_DEFINITION = {
|
||||||
id: 'send.signing.email',
|
id: 'send.signing.requested.email',
|
||||||
name: 'Send Signing Email',
|
name: 'Send Signing Email',
|
||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
trigger: {
|
trigger: {
|
||||||
name: 'send.signing.email',
|
name: 'send.signing.requested.email',
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
userId: z.number(),
|
userId: z.number(),
|
||||||
documentId: z.number(),
|
documentId: z.number(),
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = {
|
|||||||
DateTime.fromJSDate(mostRecentToken.createdAt).diffNow('minutes').minutes > -5
|
DateTime.fromJSDate(mostRecentToken.createdAt).diffNow('minutes').minutes > -5
|
||||||
) {
|
) {
|
||||||
await jobsClient.triggerJob({
|
await jobsClient.triggerJob({
|
||||||
name: 'send.confirmation.email',
|
name: 'send.signup.confirmation.email',
|
||||||
payload: {
|
payload: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export const sendDocument = async ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await jobsClient.triggerJob({
|
await jobsClient.triggerJob({
|
||||||
name: 'send.signing.email',
|
name: 'send.signing.requested.email',
|
||||||
payload: {
|
payload: {
|
||||||
userId,
|
userId,
|
||||||
documentId,
|
documentId,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export const verifyEmail = async ({ token }: VerifyEmailProps) => {
|
|||||||
DateTime.now().minus({ hours: 1 }).toJSDate() > mostRecentToken.createdAt
|
DateTime.now().minus({ hours: 1 }).toJSDate() > mostRecentToken.createdAt
|
||||||
) {
|
) {
|
||||||
await jobsClient.triggerJob({
|
await jobsClient.triggerJob({
|
||||||
name: 'send.confirmation.email',
|
name: 'send.signup.confirmation.email',
|
||||||
payload: {
|
payload: {
|
||||||
email: verificationToken.user.email,
|
email: verificationToken.user.email,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const authRouter = router({
|
|||||||
const user = await createUser({ name, email, password, signature, url });
|
const user = await createUser({ name, email, password, signature, url });
|
||||||
|
|
||||||
await jobsClient.triggerJob({
|
await jobsClient.triggerJob({
|
||||||
name: 'send.confirmation.email',
|
name: 'send.signup.confirmation.email',
|
||||||
payload: {
|
payload: {
|
||||||
email: user.email,
|
email: user.email,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ export const profileRouter = router({
|
|||||||
const { email } = input;
|
const { email } = input;
|
||||||
|
|
||||||
await jobsClient.triggerJob({
|
await jobsClient.triggerJob({
|
||||||
name: 'send.confirmation.email',
|
name: 'send.signup.confirmation.email',
|
||||||
payload: {
|
payload: {
|
||||||
email,
|
email,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user