-
-
Notifications
You must be signed in to change notification settings - Fork 918
feat(webapp): Add support for resetting idempotency keys #2777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add new action route for resetting idempotency keys via UI - Add reset button in Idempotency section of run detail view - Added API and SDK for resetting imdepotency - Updated docs page for this feature
🦋 Changeset detectedLatest commit: 277f04c The changes in this PR will be included in the next version bump. This PR includes changesets to release 26 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded@mpcgrid has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 44 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughAdds a complete idempotency key reset feature: a new server service (ResetIdempotencyKeyService) that clears idempotency keys on matching task runs; two routes (an API v1 POST-like route and a resource-scoped Remix action) that validate inputs, authenticate/authorize, and call the service; a UI integration to trigger resets with a toast on success; a path helper for the reset route; client SDK additions (API client method, schema, core helper, and trigger-sdk export); documentation for the feature; and a changeset bump. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Areas requiring additional attention:
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (3)
packages/core/src/v3/idempotencyKeys.ts (1)
1-1: Core helper forresetIdempotencyKeylooks correctThe new helper cleanly delegates to
apiClientManager.clientOrThrow().resetIdempotencyKey(...)and returns the correctly typed{ id: string }response. This matches how other v3 helpers wrap the API client.If you anticipate advanced usage, you could later add an optional
requestOptions?: ZodFetchOptionsparameter here to pass through to the client, but it’s fine to keep it simple for now.Also applies to: 136-145
apps/webapp/app/v3/services/resetIdempotencyKey.server.ts (1)
1-44: Avoid redundant read before update in ResetIdempotencyKeyServiceThe service behavior is correct, but it does a
findManyjust to checkruns.length === 0and then anupdateManywith the same where clause. You can save a round trip by using onlyupdateManyand checking the affected row count:- const runs = await this._prisma.taskRun.findMany({ - where: { - idempotencyKey, - taskIdentifier, - runtimeEnvironmentId: authenticatedEnv.id, - }, - select: { - id: true, - }, - }); - - if (runs.length === 0) { - throw new ServiceValidationError( - `No runs found with idempotency key: ${idempotencyKey} and task: ${taskIdentifier}`, - 404 - ); - } - - // Update all runs to clear the idempotency key - await this._prisma.taskRun.updateMany({ - where: { - idempotencyKey, - taskIdentifier, - runtimeEnvironmentId: authenticatedEnv.id, - }, - data: { - idempotencyKey: null, - idempotencyKeyExpiresAt: null, - }, - }); + const { count } = await this._prisma.taskRun.updateMany({ + where: { + idempotencyKey, + taskIdentifier, + runtimeEnvironmentId: authenticatedEnv.id, + }, + data: { + idempotencyKey: null, + idempotencyKeyExpiresAt: null, + }, + }); + + if (count === 0) { + throw new ServiceValidationError( + `No runs found with idempotency key: ${idempotencyKey} and task: ${taskIdentifier}`, + 404 + ); + }This keeps the same behavior with fewer queries.
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx (1)
105-109: Consider using plainjson()instead ofjsonWithSuccessMessage().The UI component already handles success feedback by checking
resetFetcher.data.success === trueand displaying a custom toast. UsingjsonWithSuccessMessage()sets an additional session-based message that might result in duplicate notifications if there's a global toast handler reading session messages.- return jsonWithSuccessMessage( - { success: true }, - request, - "Idempotency key reset successfully" - ); + return json({ success: true });If you want to keep the session message for consistency with other actions, ensure there's no global handler that would display it alongside the custom toast.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts(1 hunks)apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx(1 hunks)apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx(7 hunks)apps/webapp/app/utils/pathBuilder.ts(1 hunks)apps/webapp/app/v3/services/resetIdempotencyKey.server.ts(1 hunks)docs/idempotency.mdx(1 hunks)packages/core/src/v3/apiClient/index.ts(2 hunks)packages/core/src/v3/idempotencyKeys.ts(2 hunks)packages/core/src/v3/schemas/api.ts(1 hunks)packages/trigger-sdk/src/v3/idempotencyKeys.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tspackages/core/src/v3/schemas/api.tspackages/core/src/v3/idempotencyKeys.tspackages/trigger-sdk/src/v3/idempotencyKeys.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxpackages/core/src/v3/apiClient/index.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tspackages/core/src/v3/schemas/api.tspackages/core/src/v3/idempotencyKeys.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxpackages/core/src/v3/apiClient/index.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tspackages/core/src/v3/schemas/api.tspackages/core/src/v3/idempotencyKeys.tspackages/trigger-sdk/src/v3/idempotencyKeys.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxpackages/core/src/v3/apiClient/index.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
apps/webapp/app/v3/services/**/*.server.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Organize services in the webapp following the pattern
app/v3/services/*/*.server.ts
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tspackages/core/src/v3/schemas/api.tspackages/core/src/v3/idempotencyKeys.tspackages/trigger-sdk/src/v3/idempotencyKeys.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxpackages/core/src/v3/apiClient/index.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
packages/trigger-sdk/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
In the Trigger.dev SDK (packages/trigger-sdk), prefer isomorphic code like fetch and ReadableStream instead of Node.js-specific code
Files:
packages/trigger-sdk/src/v3/idempotencyKeys.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Scope idempotency keys globally or to current run using the scope parameter
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions
Applied to files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tspackages/core/src/v3/idempotencyKeys.tsdocs/idempotency.mdxpackages/trigger-sdk/src/v3/idempotencyKeys.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxpackages/core/src/v3/apiClient/index.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Export tasks with unique IDs within the project to enable proper task discovery and execution
Applied to files:
packages/core/src/v3/idempotencyKeys.tsdocs/idempotency.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Scope idempotency keys globally or to current run using the scope parameter
Applied to files:
packages/core/src/v3/idempotencyKeys.tsdocs/idempotency.mdxpackages/trigger-sdk/src/v3/idempotencyKeys.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/utils/pathBuilder.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeyTTL` option to define a time window during which duplicate triggers return the original run
Applied to files:
docs/idempotency.mdxpackages/trigger-sdk/src/v3/idempotencyKeys.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use the `task()` function from `trigger.dev/sdk/v3` to define tasks with id and run properties
Applied to files:
docs/idempotency.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Attach metadata to task runs using the metadata option when triggering, and access/update it inside runs using metadata functions
Applied to files:
docs/idempotency.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `trigger.dev/sdk/v3` for all imports in Trigger.dev tasks
Applied to files:
docs/idempotency.mdxpackages/trigger-sdk/src/v3/idempotencyKeys.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.batchTrigger()` to trigger multiple runs of a single task with different payloads
Applied to files:
docs/idempotency.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `tasks.trigger()` with type-only imports to trigger tasks from backend code without importing the task implementation
Applied to files:
docs/idempotency.mdx
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `yourTask.batchTrigger()` to trigger multiple runs of a task from inside another task
Applied to files:
docs/idempotency.mdx
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp
Applied to files:
apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tsapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx
📚 Learning: 2025-12-08T15:19:56.801Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.801Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.
Applied to files:
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsxapps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx
🧬 Code graph analysis (5)
packages/trigger-sdk/src/v3/idempotencyKeys.ts (2)
packages/core/src/v3/idempotencyKeys.ts (2)
createIdempotencyKey(89-98)resetIdempotencyKey(138-145)packages/core/src/v3/apiClient/index.ts (1)
resetIdempotencyKey(452-467)
apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts (2)
apps/webapp/app/v3/services/resetIdempotencyKey.server.ts (1)
ResetIdempotencyKeyService(4-44)packages/core/src/v3/apps/http.ts (1)
json(65-75)
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx (5)
apps/webapp/app/services/session.server.ts (1)
requireUserId(25-35)apps/webapp/app/utils/pathBuilder.ts (1)
v3RunParamsSchema(35-37)packages/core/src/v3/apps/http.ts (1)
json(65-75)apps/webapp/app/models/message.server.ts (2)
jsonWithErrorMessage(125-142)jsonWithSuccessMessage(106-123)apps/webapp/app/v3/services/resetIdempotencyKey.server.ts (1)
ResetIdempotencyKeyService(4-44)
packages/core/src/v3/apiClient/index.ts (2)
packages/core/src/v3/apiClient/core.ts (2)
ZodFetchOptions(31-39)zodfetch(71-78)packages/core/src/v3/schemas/api.ts (2)
ResetIdempotencyKeyResponse(721-723)ResetIdempotencyKeyResponse(725-725)
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx (2)
apps/webapp/app/components/primitives/Toast.tsx (1)
ToastUI(46-94)apps/webapp/app/utils/pathBuilder.ts (1)
v3RunIdempotencyKeyResetPath(332-341)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: typecheck / typecheck
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
🔇 Additional comments (7)
packages/trigger-sdk/src/v3/idempotencyKeys.ts (1)
1-6: SDK surface correctly exposes coreresetIdempotencyKeyThe
idempotencyKeysmap now forwardsresetdirectly to the core implementation, which is exactly what you want for SDK ergonomics. No issues here.apps/webapp/app/utils/pathBuilder.ts (1)
332-341: Reset path helper is consistent with existing routing
v3RunIdempotencyKeyResetPathcomposes the resource URL using the same helpers and conventions as other v3 paths; the shape matches the newresources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.resetroute. Looks good.packages/core/src/v3/schemas/api.ts (1)
721-725: ResetIdempotencyKeyResponse schema is consistent and sufficientThe new
ResetIdempotencyKeyResponseschema and inferred type mirror the other simple{ id: string }responses and align with what the service returns. No changes needed.apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route.tsx (2)
301-322: LGTM on the toast handling logic.The fetcher pattern and useEffect dependency array are correct. The success check properly waits for idle state before showing the toast.
573-603: LGTM on the reset UI implementation.The form correctly posts to the reset path with the task identifier, and the button properly reflects the submitting state. The layout adjustments appropriately accommodate the new reset functionality.
apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx (2)
13-15: LGTM on schema definition.Using zod for validation aligns with coding guidelines for
packages/coreandapps/webapp.
32-56: LGTM on authorization check.The query correctly validates that the user is a member of the organization owning this run, providing proper access control.
...rganizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx
Outdated
Show resolved
Hide resolved
|
@mpcgrid can you go through the CodeRabbit review and address their comments? |
|
This PR also needs a changeset, run the following command at the root of the repo: pnpm run changeset:addSelect the |
ran changeset
…cykey' into feat/tri-6733-reset-an-idempotencykey
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/webapp/app/v3/services/resetIdempotencyKey.server.ts (1)
4-30: Consider adding audit logging for idempotency key resets.For security and debugging purposes, it would be helpful to log when idempotency keys are reset, including who performed the action and how many runs were affected.
): Promise<{ id: string }> { const { count } = await this._prisma.taskRun.updateMany({ where: { idempotencyKey, taskIdentifier, runtimeEnvironmentId: authenticatedEnv.id, }, data: { idempotencyKey: null, idempotencyKeyExpiresAt: null, }, }); if (count === 0) { throw new ServiceValidationError( `No runs found with idempotency key: ${idempotencyKey} and task: ${taskIdentifier}`, 404 ); } + // Log the reset operation for audit trail + console.log(`Reset idempotency key: ${idempotencyKey} for task: ${taskIdentifier} in env: ${authenticatedEnv.id}, affected ${count} run(s)`); + return { id: idempotencyKey }; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.changeset/quick-plums-tan.md(1 hunks)apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts(1 hunks)apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx(1 hunks)apps/webapp/app/utils/pathBuilder.ts(1 hunks)apps/webapp/app/v3/services/resetIdempotencyKey.server.ts(1 hunks)packages/core/src/v3/apiClient/index.ts(2 hunks)packages/core/src/v3/idempotencyKeys.ts(2 hunks)packages/core/src/v3/schemas/api.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .changeset/quick-plums-tan.md
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/core/src/v3/idempotencyKeys.ts
- apps/webapp/app/utils/pathBuilder.ts
- apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.idempotencyKey.reset.tsx
- packages/core/src/v3/schemas/api.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tspackages/core/src/v3/apiClient/index.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use zod for validation in packages/core and apps/webapp
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tspackages/core/src/v3/apiClient/index.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use function declarations instead of default exports
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tspackages/core/src/v3/apiClient/index.ts
apps/webapp/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access all environment variables through the
envexport ofenv.server.tsinstead of directly accessingprocess.envin the Trigger.dev webapp
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
apps/webapp/**/*.{ts,tsx}: When importing from@trigger.dev/corein the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts
apps/webapp/app/v3/services/**/*.server.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Organize services in the webapp following the pattern
app/v3/services/*/*.server.ts
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.ts
**/*.{js,ts,jsx,tsx,json,md,css,scss}
📄 CodeRabbit inference engine (AGENTS.md)
Format code using Prettier
Files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tspackages/core/src/v3/apiClient/index.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Scope idempotency keys globally or to current run using the scope parameter
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Use `idempotencyKeys.create()` to create idempotency keys for preventing duplicate task executions
Applied to files:
apps/webapp/app/v3/services/resetIdempotencyKey.server.tsapps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.tspackages/core/src/v3/apiClient/index.ts
📚 Learning: 2025-11-27T16:27:35.304Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/writing-tasks.mdc:0-0
Timestamp: 2025-11-27T16:27:35.304Z
Learning: Applies to **/trigger/**/*.{ts,tsx,js,jsx} : Scope idempotency keys globally or to current run using the scope parameter
Applied to files:
apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts
📚 Learning: 2025-11-27T16:26:58.661Z
Learnt from: CR
Repo: triggerdotdev/trigger.dev PR: 0
File: .cursor/rules/webapp.mdc:0-0
Timestamp: 2025-11-27T16:26:58.661Z
Learning: Applies to apps/webapp/**/*.{ts,tsx} : Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp
Applied to files:
packages/core/src/v3/apiClient/index.ts
🧬 Code graph analysis (2)
apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts (2)
apps/webapp/app/v3/services/resetIdempotencyKey.server.ts (1)
ResetIdempotencyKeyService(4-31)packages/core/src/v3/apps/http.ts (1)
json(65-75)
packages/core/src/v3/apiClient/index.ts (2)
packages/core/src/v3/apiClient/core.ts (2)
ZodFetchOptions(31-39)zodfetch(71-78)packages/core/src/v3/schemas/api.ts (2)
ResetIdempotencyKeyResponse(798-800)ResetIdempotencyKeyResponse(802-802)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: typecheck / typecheck
🔇 Additional comments (3)
packages/core/src/v3/apiClient/index.ts (1)
665-680: LGTM! Well-implemented API client method.The implementation follows established patterns in the ApiClient class, properly encodes the idempotency key parameter, and correctly uses the ResetIdempotencyKeyResponse schema for type safety.
apps/webapp/app/routes/api.v1.idempotencyKeys.$key.reset.ts (2)
31-48: LGTM! Error handling correctly implemented.The error handling properly distinguishes between
ServiceValidationError(client errors) and unexpected errors (server errors), avoiding the previous issue of treating all errors as 404s. The structured logging for unexpected errors aids debugging without leaking sensitive details to clients.
16-27: This route configuration is intentionally designed for SDK access. ThecorsStrategy: "all"is consistent with other SDK-accessible endpoints, and the empty authorization resource is correct for an environment-scoped operation (the actual scope is validated viaauthentication.environmentand superScopes). No security concerns identified.
Add support for resetting idempotency keys both from ui and sdk
✅ Checklist
Testing
Changelog
Screenshots
[Screenshots]
