diff --git a/apps/backend/src/app/api/v1/auth/passkey/register/verification-code-handler.tsx b/apps/backend/src/app/api/v1/auth/passkey/register/verification-code-handler.tsx index 906a725ef..1f31b447a 100644 --- a/apps/backend/src/app/api/v1/auth/passkey/register/verification-code-handler.tsx +++ b/apps/backend/src/app/api/v1/auth/passkey/register/verification-code-handler.tsx @@ -1,4 +1,4 @@ -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createVerificationCodeHandler } from "@/route-handlers/verification-code-handler"; import { VerificationCodeType } from "@prisma/client"; import { verifyRegistrationResponse } from "@simplewebauthn/server"; @@ -96,7 +96,7 @@ export const registerVerificationCodeHandler = createVerificationCodeHandler({ const registrationInfo = verification.registrationInfo; - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { const authMethodConfig = await tx.passkeyAuthMethodConfig.findMany({ where: { projectConfigId: project.config.id, diff --git a/apps/backend/src/app/api/v1/auth/password/set/route.tsx b/apps/backend/src/app/api/v1/auth/password/set/route.tsx index b9ed7f9b2..ebc9eb909 100644 --- a/apps/backend/src/app/api/v1/auth/password/set/route.tsx +++ b/apps/backend/src/app/api/v1/auth/password/set/route.tsx @@ -1,4 +1,4 @@ -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; import { KnownErrors } from "@stackframe/stack-shared"; import { getPasswordError } from "@stackframe/stack-shared/dist/helpers/password"; @@ -37,7 +37,7 @@ export const POST = createSmartRouteHandler({ throw passwordError; } - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { const authMethodConfig = await tx.passwordAuthMethodConfig.findMany({ where: { projectConfigId: project.config.id, diff --git a/apps/backend/src/app/api/v1/auth/password/update/route.tsx b/apps/backend/src/app/api/v1/auth/password/update/route.tsx index c47091157..489db10e5 100644 --- a/apps/backend/src/app/api/v1/auth/password/update/route.tsx +++ b/apps/backend/src/app/api/v1/auth/password/update/route.tsx @@ -1,4 +1,4 @@ -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; import { KnownErrors } from "@stackframe/stack-shared"; import { getPasswordError } from "@stackframe/stack-shared/dist/helpers/password"; @@ -40,7 +40,7 @@ export const POST = createSmartRouteHandler({ throw passwordError; } - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { const authMethods = await tx.passwordAuthMethod.findMany({ where: { projectId: project.id, diff --git a/apps/backend/src/app/api/v1/contact-channels/crud.tsx b/apps/backend/src/app/api/v1/contact-channels/crud.tsx index 4665989bd..2640ec618 100644 --- a/apps/backend/src/app/api/v1/contact-channels/crud.tsx +++ b/apps/backend/src/app/api/v1/contact-channels/crud.tsx @@ -1,5 +1,5 @@ import { ensureContactChannelDoesNotExists, ensureContactChannelExists } from "@/lib/request-checks"; -import { maybeTransactionWithRetry, prismaClient } from "@/prisma-client"; +import { prismaClient, retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { Prisma } from "@prisma/client"; import { KnownErrors } from "@stackframe/stack-shared"; @@ -62,7 +62,7 @@ export const contactChannelsCrudHandlers = createLazyProxy(() => createCrudHandl } } - const contactChannel = await maybeTransactionWithRetry(async (tx) => { + const contactChannel = await retryTransaction(async (tx) => { await ensureContactChannelDoesNotExists(tx, { projectId: auth.project.id, userId: data.user_id, @@ -145,7 +145,7 @@ export const contactChannelsCrudHandlers = createLazyProxy(() => createCrudHandl } } - const updatedContactChannel = await maybeTransactionWithRetry(async (tx) => { + const updatedContactChannel = await retryTransaction(async (tx) => { const existingContactChannel = await ensureContactChannelExists(tx, { projectId: auth.project.id, userId: params.user_id, @@ -209,7 +209,7 @@ export const contactChannelsCrudHandlers = createLazyProxy(() => createCrudHandl } } - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { await ensureContactChannelExists(tx, { projectId: auth.project.id, userId: params.user_id, diff --git a/apps/backend/src/app/api/v1/integrations/neon/oauth-providers/crud.tsx b/apps/backend/src/app/api/v1/integrations/neon/oauth-providers/crud.tsx index 77b5cc20e..7fb670d5e 100644 --- a/apps/backend/src/app/api/v1/integrations/neon/oauth-providers/crud.tsx +++ b/apps/backend/src/app/api/v1/integrations/neon/oauth-providers/crud.tsx @@ -1,4 +1,4 @@ -import { maybeTransactionWithRetry, prismaClient } from "@/prisma-client"; +import { prismaClient, retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { Prisma } from "@prisma/client"; import { CrudTypeOf, createCrud } from "@stackframe/stack-shared/dist/crud"; @@ -105,7 +105,7 @@ async function createOrUpdateProvider( throw new StatusError(StatusError.BadRequest, `${providerId} is not a shared provider`); } - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { if (oldProvider) { switch (oldProvider.type) { case 'shared': { diff --git a/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts b/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts index 5e9fa8561..0ac9e6318 100644 --- a/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts +++ b/apps/backend/src/app/api/v1/integrations/neon/oauth/idp/[[...route]]/idp.ts @@ -1,4 +1,4 @@ -import { maybeTransactionWithRetry, prismaClient } from '@/prisma-client'; +import { prismaClient, retryTransaction } from '@/prisma-client'; import { Prisma } from '@prisma/client'; import { decodeBase64OrBase64Url } from '@stackframe/stack-shared/dist/utils/bytes'; import { getEnvVariable } from '@stackframe/stack-shared/dist/utils/env'; @@ -94,7 +94,7 @@ function createAdapter(options: { function createPrismaAdapter(idpId: string) { return createAdapter({ async onUpdateUnique(model, idOrWhere, updater) { - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { const oldAll = await tx.idPAdapterData.findMany({ where: typeof idOrWhere === 'string' ? { idpId, diff --git a/apps/backend/src/app/api/v1/projects/current/crud.tsx b/apps/backend/src/app/api/v1/projects/current/crud.tsx index 07ab66ae9..236c38c28 100644 --- a/apps/backend/src/app/api/v1/projects/current/crud.tsx +++ b/apps/backend/src/app/api/v1/projects/current/crud.tsx @@ -1,7 +1,7 @@ import { isTeamSystemPermission, listTeamPermissionDefinitions, teamSystemPermissionStringToDBType } from "@/lib/permissions"; import { fullProjectInclude, projectPrismaToCrud } from "@/lib/projects"; import { ensureSharedProvider } from "@/lib/request-checks"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { projectsCrud } from "@stackframe/stack-shared/dist/interface/crud/projects"; import { yupObject } from "@stackframe/stack-shared/dist/schema-fields"; @@ -15,7 +15,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro onUpdate: async ({ auth, data }) => { const oldProject = auth.project; - const result = await maybeTransactionWithRetry(async (tx) => { + const result = await retryTransaction(async (tx) => { // ======================= update default team permissions ======================= const dbParams = [ @@ -479,7 +479,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro return auth.project; }, onDelete: async ({ auth }) => { - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { const configs = await tx.projectConfig.findMany({ where: { id: auth.project.config.id diff --git a/apps/backend/src/app/api/v1/team-invitations/crud.tsx b/apps/backend/src/app/api/v1/team-invitations/crud.tsx index 1ff7b3c12..07d534653 100644 --- a/apps/backend/src/app/api/v1/team-invitations/crud.tsx +++ b/apps/backend/src/app/api/v1/team-invitations/crud.tsx @@ -1,5 +1,5 @@ import { ensureTeamExists, ensureTeamMembershipExists, ensureUserTeamPermissionExists } from "@/lib/request-checks"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { KnownErrors } from "@stackframe/stack-shared"; import { teamInvitationCrud } from "@stackframe/stack-shared/dist/interface/crud/team-invitation"; @@ -16,7 +16,7 @@ export const teamInvitationsCrudHandlers = createLazyProxy(() => createCrudHandl id: yupString().uuid().defined(), }), onList: async ({ auth, query }) => { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { if (auth.type === 'client') { // Client can only: // - list invitations in their own team if they have the $read_members AND $invite_members permissions @@ -59,7 +59,7 @@ export const teamInvitationsCrudHandlers = createLazyProxy(() => createCrudHandl }); }, onDelete: async ({ auth, query, params }) => { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { if (auth.type === 'client') { // Client can only: // - delete invitations in their own team if they have the $remove_members permissions diff --git a/apps/backend/src/app/api/v1/team-invitations/send-code/route.tsx b/apps/backend/src/app/api/v1/team-invitations/send-code/route.tsx index 1716c4404..e8492d3b2 100644 --- a/apps/backend/src/app/api/v1/team-invitations/send-code/route.tsx +++ b/apps/backend/src/app/api/v1/team-invitations/send-code/route.tsx @@ -1,5 +1,5 @@ import { ensureUserTeamPermissionExists } from "@/lib/request-checks"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; import { KnownErrors } from "@stackframe/stack-shared"; import { adaptSchema, clientOrHigherAuthTypeSchema, teamIdSchema, teamInvitationCallbackUrlSchema, teamInvitationEmailSchema, yupBoolean, yupNumber, yupObject, yupString } from "@stackframe/stack-shared/dist/schema-fields"; @@ -32,7 +32,7 @@ export const POST = createSmartRouteHandler({ }).defined(), }), async handler({ auth, body }) { - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { if (auth.type === "client") { if (!auth.user) throw new KnownErrors.UserAuthenticationRequired; diff --git a/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx b/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx index 00f04bb6c..e2b309a39 100644 --- a/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx +++ b/apps/backend/src/app/api/v1/team-member-profiles/crud.tsx @@ -1,5 +1,5 @@ import { ensureTeamExists, ensureTeamMembershipExists, ensureUserExists, ensureUserTeamPermissionExists } from "@/lib/request-checks"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { Prisma } from "@prisma/client"; import { KnownErrors } from "@stackframe/stack-shared"; @@ -31,7 +31,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa user_id: userIdOrMeSchema.defined(), }), onList: async ({ auth, query }) => { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { if (auth.type === 'client') { // Client can only: // - list users in their own team if they have the $read_members permission @@ -85,7 +85,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa }); }, onRead: async ({ auth, params }) => { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { if (auth.type === 'client') { const currentUserId = auth.user?.id ?? throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); if (params.user_id !== currentUserId) { @@ -122,7 +122,7 @@ export const teamMemberProfilesCrudHandlers = createLazyProxy(() => createCrudHa }); }, onUpdate: async ({ auth, data, params }) => { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { if (auth.type === 'client') { const currentUserId = auth.user?.id ?? throwErr(new KnownErrors.CannotGetOwnUserWithoutUser()); if (params.user_id !== currentUserId) { diff --git a/apps/backend/src/app/api/v1/team-memberships/crud.tsx b/apps/backend/src/app/api/v1/team-memberships/crud.tsx index 2b0b97790..e5e4d6ebb 100644 --- a/apps/backend/src/app/api/v1/team-memberships/crud.tsx +++ b/apps/backend/src/app/api/v1/team-memberships/crud.tsx @@ -2,7 +2,7 @@ import { isTeamSystemPermission, teamSystemPermissionStringToDBType } from "@/li import { ensureTeamExists, ensureTeamMembershipDoesNotExist, ensureTeamMembershipExists, ensureUserExists, ensureUserTeamPermissionExists } from "@/lib/request-checks"; import { PrismaTransaction } from "@/lib/types"; import { sendTeamMembershipCreatedWebhook, sendTeamMembershipDeletedWebhook } from "@/lib/webhooks"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { runAsynchronouslyAndWaitUntil } from "@/utils/vercel"; import { KnownErrors } from "@stackframe/stack-shared"; @@ -57,7 +57,7 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl user_id: userIdOrMeSchema.defined(), }), onCreate: async ({ auth, params }) => { - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { await ensureUserExists(tx, { projectId: auth.project.id, userId: params.user_id, @@ -108,7 +108,7 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl return data; }, onDelete: async ({ auth, params }) => { - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { // Users are always allowed to remove themselves from a team // Only users with the $remove_members permission can remove other users if (auth.type === 'client') { diff --git a/apps/backend/src/app/api/v1/team-permission-definitions/crud.tsx b/apps/backend/src/app/api/v1/team-permission-definitions/crud.tsx index 240d0d187..f9dacaa21 100644 --- a/apps/backend/src/app/api/v1/team-permission-definitions/crud.tsx +++ b/apps/backend/src/app/api/v1/team-permission-definitions/crud.tsx @@ -1,5 +1,5 @@ import { createTeamPermissionDefinition, deleteTeamPermissionDefinition, listTeamPermissionDefinitions, updateTeamPermissionDefinitions } from "@/lib/permissions"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { teamPermissionDefinitionsCrud } from '@stackframe/stack-shared/dist/interface/crud/team-permissions'; import { teamPermissionDefinitionIdSchema, yupObject } from "@stackframe/stack-shared/dist/schema-fields"; @@ -10,7 +10,7 @@ export const teamPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat permission_id: teamPermissionDefinitionIdSchema.defined(), }), async onCreate({ auth, data }) { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { return await createTeamPermissionDefinition(tx, { project: auth.project, data, @@ -18,7 +18,7 @@ export const teamPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat }); }, async onUpdate({ auth, data, params }) { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { return await updateTeamPermissionDefinitions(tx, { project: auth.project, permissionId: params.permission_id, @@ -27,7 +27,7 @@ export const teamPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat }); }, async onDelete({ auth, params }) { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { await deleteTeamPermissionDefinition(tx, { project: auth.project, permissionId: params.permission_id @@ -35,7 +35,7 @@ export const teamPermissionDefinitionsCrudHandlers = createLazyProxy(() => creat }); }, async onList({ auth }) { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { return { items: await listTeamPermissionDefinitions(tx, auth.project), is_paginated: false, diff --git a/apps/backend/src/app/api/v1/team-permissions/crud.tsx b/apps/backend/src/app/api/v1/team-permissions/crud.tsx index 380248ee3..59d6751fe 100644 --- a/apps/backend/src/app/api/v1/team-permissions/crud.tsx +++ b/apps/backend/src/app/api/v1/team-permissions/crud.tsx @@ -1,6 +1,6 @@ import { grantTeamPermission, listUserTeamPermissions, revokeTeamPermission } from "@/lib/permissions"; import { ensureTeamMembershipExists, ensureUserTeamPermissionExists } from "@/lib/request-checks"; -import { maybeTransactionWithRetry } from "@/prisma-client"; +import { retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { KnownErrors } from "@stackframe/stack-shared"; import { teamPermissionsCrud } from '@stackframe/stack-shared/dist/interface/crud/team-permissions'; @@ -21,7 +21,7 @@ export const teamPermissionsCrudHandlers = createLazyProxy(() => createCrudHandl permission_id: teamPermissionDefinitionIdSchema.defined(), }), async onCreate({ auth, params }) { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { await ensureTeamMembershipExists(tx, { projectId: auth.project.id, teamId: params.team_id, userId: params.user_id }); return await grantTeamPermission(tx, { @@ -33,7 +33,7 @@ export const teamPermissionsCrudHandlers = createLazyProxy(() => createCrudHandl }); }, async onDelete({ auth, params }) { - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { await ensureUserTeamPermissionExists(tx, { project: auth.project, teamId: params.team_id, @@ -60,7 +60,7 @@ export const teamPermissionsCrudHandlers = createLazyProxy(() => createCrudHandl } } - return await maybeTransactionWithRetry(async (tx) => { + return await retryTransaction(async (tx) => { return { items: await listUserTeamPermissions(tx, { project: auth.project, diff --git a/apps/backend/src/app/api/v1/teams/crud.tsx b/apps/backend/src/app/api/v1/teams/crud.tsx index 26e1a760c..ed0a3b227 100644 --- a/apps/backend/src/app/api/v1/teams/crud.tsx +++ b/apps/backend/src/app/api/v1/teams/crud.tsx @@ -1,6 +1,6 @@ import { ensureTeamExists, ensureTeamMembershipExists, ensureUserTeamPermissionExists } from "@/lib/request-checks"; import { sendTeamCreatedWebhook, sendTeamDeletedWebhook, sendTeamUpdatedWebhook } from "@/lib/webhooks"; -import { maybeTransactionWithRetry, prismaClient } from "@/prisma-client"; +import { prismaClient, retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { runAsynchronouslyAndWaitUntil } from "@/utils/vercel"; import { Prisma } from "@prisma/client"; @@ -51,7 +51,7 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC throw new StatusError(400, "Invalid profile image URL"); } - const db = await maybeTransactionWithRetry(async (tx) => { + const db = await retryTransaction(async (tx) => { const db = await tx.team.create({ data: { displayName: data.display_name, @@ -101,7 +101,7 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC return result; }, onRead: async ({ params, auth }) => { - const db = await maybeTransactionWithRetry(async (tx) => { + const db = await retryTransaction(async (tx) => { if (auth.type === 'client') { await ensureTeamMembershipExists(tx, { projectId: auth.project.id, @@ -129,7 +129,7 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC return teamPrismaToCrud(db); }, onUpdate: async ({ params, auth, data }) => { - const db = await maybeTransactionWithRetry(async (tx) => { + const db = await retryTransaction(async (tx) => { if (auth.type === 'client' && data.profile_image_url && !validateBase64Image(data.profile_image_url)) { throw new StatusError(400, "Invalid profile image URL"); } @@ -174,7 +174,7 @@ export const teamsCrudHandlers = createLazyProxy(() => createCrudHandlers(teamsC return result; }, onDelete: async ({ params, auth }) => { - await maybeTransactionWithRetry(async (tx) => { + await retryTransaction(async (tx) => { if (auth.type === 'client') { await ensureUserTeamPermissionExists(tx, { project: auth.project, diff --git a/apps/backend/src/app/api/v1/users/crud.tsx b/apps/backend/src/app/api/v1/users/crud.tsx index acfdfdf83..db79f2786 100644 --- a/apps/backend/src/app/api/v1/users/crud.tsx +++ b/apps/backend/src/app/api/v1/users/crud.tsx @@ -1,7 +1,7 @@ import { ensureTeamMembershipExists, ensureUserExists } from "@/lib/request-checks"; import { PrismaTransaction } from "@/lib/types"; import { sendTeamMembershipDeletedWebhook, sendUserCreatedWebhook, sendUserDeletedWebhook, sendUserUpdatedWebhook } from "@/lib/webhooks"; -import { maybeTransactionWithRetry, prismaClient } from "@/prisma-client"; +import { prismaClient, retryTransaction } from "@/prisma-client"; import { createCrudHandlers } from "@/route-handlers/crud-handler"; import { runAsynchronouslyAndWaitUntil } from "@/utils/vercel"; import { BooleanTrue, Prisma } from "@prisma/client"; @@ -347,7 +347,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC }; }, onCreate: async ({ auth, data }) => { - const result = await maybeTransactionWithRetry(async (tx) => { + const result = await retryTransaction(async (tx) => { const passwordHash = await getPasswordHashFromData(data); await checkAuthData(tx, { projectId: auth.project.id, @@ -543,7 +543,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC }, onUpdate: async ({ auth, data, params }) => { const passwordHash = await getPasswordHashFromData(data); - const result = await maybeTransactionWithRetry(async (tx) => { + const result = await retryTransaction(async (tx) => { await ensureUserExists(tx, { projectId: auth.project.id, userId: params.user_id }); if (data.selected_team_id !== undefined) { @@ -840,7 +840,7 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC return result; }, onDelete: async ({ auth, params }) => { - const { teams } = await maybeTransactionWithRetry(async (tx) => { + const { teams } = await retryTransaction(async (tx) => { await ensureUserExists(tx, { projectId: auth.project.id, userId: params.user_id }); const teams = await tx.team.findMany({ diff --git a/apps/backend/src/lib/projects.tsx b/apps/backend/src/lib/projects.tsx index 7267b0dcc..05ef4f274 100644 --- a/apps/backend/src/lib/projects.tsx +++ b/apps/backend/src/lib/projects.tsx @@ -1,4 +1,4 @@ -import { maybeTransactionWithRetry, prismaClient } from "@/prisma-client"; +import { prismaClient, retryTransaction } from "@/prisma-client"; import { Prisma } from "@prisma/client"; import { InternalProjectsCrud, ProjectsCrud } from "@stackframe/stack-shared/dist/interface/crud/projects"; import { UsersCrud } from "@stackframe/stack-shared/dist/interface/crud/users"; @@ -207,7 +207,7 @@ export async function getProject(projectId: string): Promise { + const result = await retryTransaction(async (tx) => { const project = await tx.project.create({ data: { id: generateUuid(), diff --git a/apps/backend/src/prisma-client.tsx b/apps/backend/src/prisma-client.tsx index 0365044fa..b843963d9 100644 --- a/apps/backend/src/prisma-client.tsx +++ b/apps/backend/src/prisma-client.tsx @@ -17,7 +17,7 @@ if (getNodeEnvironment() !== 'production') { } -export async function maybeTransactionWithRetry(fn: (...args: Parameters[0]>) => Promise): Promise { +export async function retryTransaction(fn: (...args: Parameters[0]>) => Promise): Promise { const isDev = getNodeEnvironment() === 'development'; const res = await Result.retry(async () => {