diff --git a/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/lib/contact.ts b/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/lib/contact.ts new file mode 100644 index 000000000000..70a9c4638406 --- /dev/null +++ b/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/lib/contact.ts @@ -0,0 +1,47 @@ +import { contactCache } from "@/lib/cache/contact"; +import { contactAttributeCache } from "@/lib/cache/contact-attribute"; +import { contactAttributeKeyCache } from "@/lib/cache/contact-attribute-key"; +import { cache as reactCache } from "react"; +import { prisma } from "@formbricks/database"; +import { cache } from "@formbricks/lib/cache"; + +export const getContactByUserIdWithAttributes = reactCache( + (environmentId: string, userId: string, updatedAttributes: Record) => + cache( + async () => { + const contact = await prisma.contact.findFirst({ + where: { + environmentId, + attributes: { some: { attributeKey: { key: "userId", environmentId }, value: userId } }, + }, + select: { + id: true, + attributes: { + where: { + attributeKey: { + key: { + in: Object.keys(updatedAttributes), + }, + }, + }, + select: { attributeKey: { select: { key: true } }, value: true }, + }, + }, + }); + + if (!contact) { + return null; + } + + return contact; + }, + [`getContactByUserId-${environmentId}-${userId}-${JSON.stringify(updatedAttributes)}`], + { + tags: [ + contactCache.tag.byEnvironmentIdAndUserId(environmentId, userId), + contactAttributeCache.tag.byEnvironmentIdAndUserId(environmentId, userId), + contactAttributeKeyCache.tag.byEnvironmentId(environmentId), + ], + } + )() +); diff --git a/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/route.ts b/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/route.ts index faeb88bbcbd9..b526dfd89b5d 100644 --- a/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/route.ts +++ b/apps/web/modules/ee/contacts/api/client/[environmentId]/contacts/[userId]/attributes/route.ts @@ -2,10 +2,10 @@ import { responses } from "@/app/lib/api/response"; import { transformErrorToDetails } from "@/app/lib/api/validator"; import { getIsContactsEnabled } from "@/modules/ee/license-check/lib/utils"; import { NextRequest } from "next/server"; -import { prisma } from "@formbricks/database"; import { ResourceNotFoundError } from "@formbricks/types/errors"; import { ZJsContactsUpdateAttributeInput } from "@formbricks/types/js"; import { updateAttributes } from "./lib/attributes"; +import { getContactByUserIdWithAttributes } from "./lib/contact"; export const OPTIONS = async () => { // cors headers @@ -48,25 +48,7 @@ export const PUT = async ( // ignore userId and id const { userId: userIdAttr, id: idAttr, ...updatedAttributes } = parsedInput.data.attributes; - const contact = await prisma.contact.findFirst({ - where: { - environmentId, - attributes: { some: { attributeKey: { key: "userId", environmentId }, value: userId } }, - }, - select: { - id: true, - attributes: { - where: { - attributeKey: { - key: { - in: Object.keys(updatedAttributes), - }, - }, - }, - select: { attributeKey: { select: { key: true } }, value: true }, - }, - }, - }); + const contact = await getContactByUserIdWithAttributes(environmentId, userId, updatedAttributes); if (!contact) { return responses.notFoundResponse("contact", userId, true);