@@ -6,16 +6,17 @@ import {
66} from "@trigger.dev/core/v3" ;
77import { TaskRun } from "@trigger.dev/database" ;
88import { z } from "zod" ;
9+ import { prisma } from "~/db.server" ;
910import { env } from "~/env.server" ;
1011import { EngineServiceValidationError } from "~/runEngine/concerns/errors" ;
11- import {
12- ApiAuthenticationResultSuccess ,
13- AuthenticatedEnvironment ,
14- getOneTimeUseToken ,
15- } from "~/services/apiAuth.server" ;
12+ import { ApiAuthenticationResultSuccess , getOneTimeUseToken } from "~/services/apiAuth.server" ;
1613import { logger } from "~/services/logger.server" ;
1714import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server" ;
1815import { resolveIdempotencyKeyTTL } from "~/utils/idempotencyKeys.server" ;
16+ import {
17+ handleRequestIdempotency ,
18+ saveRequestIdempotency ,
19+ } from "~/utils/requestIdempotency.server" ;
1920import { ServiceValidationError } from "~/v3/services/baseService.server" ;
2021import { OutOfEntitlementError , TriggerTaskService } from "~/v3/services/triggerTask.server" ;
2122
@@ -31,6 +32,7 @@ export const HeadersSchema = z.object({
3132 "x-trigger-worker" : z . string ( ) . nullish ( ) ,
3233 "x-trigger-client" : z . string ( ) . nullish ( ) ,
3334 "x-trigger-engine-version" : RunEngineVersionSchema . nullish ( ) ,
35+ "x-trigger-request-idempotency-key" : z . string ( ) . nullish ( ) ,
3436 traceparent : z . string ( ) . optional ( ) ,
3537 tracestate : z . string ( ) . optional ( ) ,
3638} ) ;
@@ -60,8 +62,34 @@ const { action, loader } = createActionApiRoute(
6062 "x-trigger-worker" : isFromWorker ,
6163 "x-trigger-client" : triggerClient ,
6264 "x-trigger-engine-version" : engineVersion ,
65+ "x-trigger-request-idempotency-key" : requestIdempotencyKey ,
6366 } = headers ;
6467
68+ const cachedResponse = await handleRequestIdempotency ( requestIdempotencyKey , {
69+ requestType : "trigger" ,
70+ findCachedEntity : async ( cachedRequestId ) => {
71+ return await prisma . taskRun . findFirst ( {
72+ where : {
73+ id : cachedRequestId ,
74+ } ,
75+ select : {
76+ friendlyId : true ,
77+ } ,
78+ } ) ;
79+ } ,
80+ buildResponse : ( cachedRun ) => ( {
81+ id : cachedRun . friendlyId ,
82+ isCached : false ,
83+ } ) ,
84+ buildResponseHeaders : async ( responseBody , cachedEntity ) => {
85+ return await responseHeaders ( cachedEntity , authentication , triggerClient ) ;
86+ } ,
87+ } ) ;
88+
89+ if ( cachedResponse ) {
90+ return cachedResponse ;
91+ }
92+
6593 const service = new TriggerTaskService ( ) ;
6694
6795 try {
@@ -104,6 +132,8 @@ const { action, loader } = createActionApiRoute(
104132 return json ( { error : "Task not found" } , { status : 404 } ) ;
105133 }
106134
135+ await saveRequestIdempotency ( requestIdempotencyKey , "trigger" , result . run . id ) ;
136+
107137 const $responseHeaders = await responseHeaders ( result . run , authentication , triggerClient ) ;
108138
109139 return json (
@@ -113,6 +143,7 @@ const { action, loader } = createActionApiRoute(
113143 } ,
114144 {
115145 headers : $responseHeaders ,
146+ status : 200 ,
116147 }
117148 ) ;
118149 } catch ( error ) {
@@ -132,7 +163,7 @@ const { action, loader } = createActionApiRoute(
132163) ;
133164
134165async function responseHeaders (
135- run : TaskRun ,
166+ run : Pick < TaskRun , "friendlyId" > ,
136167 authentication : ApiAuthenticationResultSuccess ,
137168 triggerClient ?: string | null
138169) : Promise < Record < string , string > > {
0 commit comments