Files
documenso/packages/trpc/server/admin-router/update-subscription-claim.ts
T
Lucas Smith 9f680c7a61 perf: set global prisma transaction timeouts and reduce transaction scope (#2607)
Configure default transaction options (5s maxWait, 10s timeout) on the
PrismaClient instead of per-transaction overrides. Move side effects
like email sending, webhook triggers, and job dispatches out of
$transaction blocks to avoid holding database connections open during
network I/O.

Also extracts the direct template email into a background job and fixes
a bug where prisma was used instead of tx inside a transaction.
2026-03-13 14:51:53 +11:00

68 lines
1.9 KiB
TypeScript

import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { jobsClient } from '@documenso/lib/jobs/client';
import type { TClaimFlags } from '@documenso/lib/types/subscription';
import { prisma } from '@documenso/prisma';
import { adminProcedure } from '../trpc';
import {
ZUpdateSubscriptionClaimRequestSchema,
ZUpdateSubscriptionClaimResponseSchema,
} from './update-subscription-claim.types';
export const updateSubscriptionClaimRoute = adminProcedure
.input(ZUpdateSubscriptionClaimRequestSchema)
.output(ZUpdateSubscriptionClaimResponseSchema)
.mutation(async ({ input, ctx }) => {
const { id, data } = input;
ctx.logger.info({
input,
});
const existingClaim = await prisma.subscriptionClaim.findUnique({
where: { id },
});
if (!existingClaim) {
throw new AppError(AppErrorCode.NOT_FOUND, { message: 'Subscription claim not found' });
}
const newlyEnabledFlags = getNewTruthyFlags(existingClaim.flags, data.flags);
await prisma.subscriptionClaim.update({
where: {
id,
},
data,
});
if (Object.keys(newlyEnabledFlags).length > 0) {
await jobsClient.triggerJob({
name: 'internal.backport-subscription-claims',
payload: {
subscriptionClaimId: id,
flags: newlyEnabledFlags,
},
});
}
});
function getNewTruthyFlags(
a: Partial<TClaimFlags>,
b: Partial<TClaimFlags>,
): Record<keyof TClaimFlags, true> {
const flags: { [key in keyof TClaimFlags]?: true } = {};
for (const key in b) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const typedKey = key as keyof TClaimFlags;
if (b[typedKey] === true && a[typedKey] !== true) {
flags[typedKey] = true;
}
}
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return flags as Record<keyof TClaimFlags, true>;
}