From cd0a23639da715a8448ba8e4fac29b6c87e3e7c4 Mon Sep 17 00:00:00 2001 From: "cal.com" Date: Tue, 19 Aug 2025 10:22:21 +0300 Subject: [PATCH] refactor: replace static methods of HostRepository and PrismaAttributeRepository --- .../teams/[id]/members/page.tsx | 5 ++++- .../(org-user-only)/members/page.tsx | 5 ++++- .../repository/PrismaAttributeRepository.ts | 16 +++++++++------- packages/lib/server/repository/host.ts | 8 +++++--- .../attribute/server/assignValueToUser.ts | 3 ++- .../service/attribute/server/getAttributes.ts | 4 +++- .../routers/viewer/attributes/list.handler.ts | 4 +++- .../availability/schedule/delete.handler.ts | 7 ++++--- .../routers/viewer/availability/util.test.ts | 14 ++++++-------- .../server/routers/viewer/availability/util.ts | 9 --------- 10 files changed, 40 insertions(+), 35 deletions(-) diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/members/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/members/page.tsx index dc582367e0fd55..815d54f2bfbcdc 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/members/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/teams/[id]/members/page.tsx @@ -5,6 +5,7 @@ import { unstable_cache } from "next/cache"; import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory"; import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository"; +import prisma from "@calcom/prisma"; import { viewerTeamsRouter } from "@calcom/trpc/server/routers/viewer/teams/_router"; import { TeamMembersView } from "~/teams/team-members-view"; @@ -36,8 +37,10 @@ const getCachedTeamRoles = unstable_cache( const getCachedTeamAttributes = unstable_cache( async (organizationId?: number) => { if (!organizationId) return []; + const attributeRepo = new PrismaAttributeRepository(prisma); + try { - return await PrismaAttributeRepository.findAllByOrgIdWithOptions({ orgId: organizationId }); + return await attributeRepo.findAllByOrgIdWithOptions({ orgId: organizationId }); } catch (error) { return []; } diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/page.tsx index eeb9b26b1bce58..c54b412e952fb6 100644 --- a/apps/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/organizations/(org-user-only)/members/page.tsx @@ -4,6 +4,7 @@ import { unstable_cache } from "next/cache"; import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory"; import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository"; +import prisma from "@calcom/prisma"; import { viewerOrganizationsRouter } from "@calcom/trpc/server/routers/viewer/organizations/_router"; import { MembersView } from "~/members/members-view"; @@ -19,7 +20,9 @@ export const generateMetadata = async () => const getCachedAttributes = unstable_cache( async (orgId: number) => { - return await PrismaAttributeRepository.findAllByOrgIdWithOptions({ orgId }); + const attributeRepo = new PrismaAttributeRepository(prisma); + + return await attributeRepo.findAllByOrgIdWithOptions({ orgId }); }, undefined, { revalidate: 3600, tags: ["viewer.attributes.list"] } // Cache for 1 hour diff --git a/packages/lib/server/repository/PrismaAttributeRepository.ts b/packages/lib/server/repository/PrismaAttributeRepository.ts index e4f9d8746e6afa..b88e1043d99fdf 100644 --- a/packages/lib/server/repository/PrismaAttributeRepository.ts +++ b/packages/lib/server/repository/PrismaAttributeRepository.ts @@ -1,14 +1,16 @@ -import prisma from "@calcom/prisma"; +import type { PrismaClient } from "@calcom/prisma"; export class PrismaAttributeRepository { - static async findManyByNamesAndOrgIdIncludeOptions({ + constructor(private prismaClient: PrismaClient) {} + + async findManyByNamesAndOrgIdIncludeOptions({ attributeNames, orgId, }: { attributeNames: string[]; orgId: number; }) { - return prisma.attribute.findMany({ + return this.prismaClient.attribute.findMany({ where: { name: { in: attributeNames, mode: "insensitive" }, teamId: orgId, @@ -25,9 +27,9 @@ export class PrismaAttributeRepository { }); } - static async findManyByOrgId({ orgId }: { orgId: number }) { + async findManyByOrgId({ orgId }: { orgId: number }) { // It should be a faster query because of lesser number of attributes record and index on teamId - const result = await prisma.attribute.findMany({ + const result = await this.prismaClient.attribute.findMany({ where: { teamId: orgId, }, @@ -43,8 +45,8 @@ export class PrismaAttributeRepository { return result; } - static async findAllByOrgIdWithOptions({ orgId }: { orgId: number }) { - return await prisma.attribute.findMany({ + async findAllByOrgIdWithOptions({ orgId }: { orgId: number }) { + return await this.prismaClient.attribute.findMany({ where: { teamId: orgId, }, diff --git a/packages/lib/server/repository/host.ts b/packages/lib/server/repository/host.ts index 5a8967102d54a2..80ffef8397584f 100644 --- a/packages/lib/server/repository/host.ts +++ b/packages/lib/server/repository/host.ts @@ -1,8 +1,10 @@ -import prisma from "@calcom/prisma"; +import type { PrismaClient } from "@calcom/prisma"; export class HostRepository { - static async updateHostsSchedule(userId: number, oldScheduleId: number, newScheduleId: number) { - return await prisma.host.updateMany({ + constructor(private prismaClient: PrismaClient) {} + + async updateHostsSchedule(userId: number, oldScheduleId: number, newScheduleId: number) { + return await this.prismaClient.host.updateMany({ where: { userId, scheduleId: oldScheduleId, diff --git a/packages/lib/service/attribute/server/assignValueToUser.ts b/packages/lib/service/attribute/server/assignValueToUser.ts index fddd150ab8d27a..b26933bee1a6d8 100644 --- a/packages/lib/service/attribute/server/assignValueToUser.ts +++ b/packages/lib/service/attribute/server/assignValueToUser.ts @@ -37,7 +37,8 @@ const findAttributesByName = async ({ orgId: number; attributeNames: AttributeName[]; }) => { - const attributesFromDb = await PrismaAttributeRepository.findManyByNamesAndOrgIdIncludeOptions({ + const attributeRepo = new PrismaAttributeRepository(prisma); + const attributesFromDb = await attributeRepo.findManyByNamesAndOrgIdIncludeOptions({ attributeNames, orgId, }); diff --git a/packages/lib/service/attribute/server/getAttributes.ts b/packages/lib/service/attribute/server/getAttributes.ts index d5ed1f6c4ecdab..4a721bcc96decc 100644 --- a/packages/lib/service/attribute/server/getAttributes.ts +++ b/packages/lib/service/attribute/server/getAttributes.ts @@ -216,9 +216,11 @@ async function _getOrgMembershipToUserIdForTeam({ orgId, teamId }: { orgId: numb } async function _queryAllData({ orgId, teamId }: { orgId: number; teamId: number }) { + const attributeRepo = new PrismaAttributeRepository(prisma); + const [orgMembershipToUserIdForTeamMembers, attributesOfTheOrg] = await Promise.all([ _getOrgMembershipToUserIdForTeam({ orgId, teamId }), - PrismaAttributeRepository.findManyByOrgId({ orgId }), + attributeRepo.findManyByOrgId({ orgId }), ]); const orgMembershipIds = Array.from(orgMembershipToUserIdForTeamMembers.keys()); diff --git a/packages/trpc/server/routers/viewer/attributes/list.handler.ts b/packages/trpc/server/routers/viewer/attributes/list.handler.ts index de02016a1d1bba..377827af243b0b 100644 --- a/packages/trpc/server/routers/viewer/attributes/list.handler.ts +++ b/packages/trpc/server/routers/viewer/attributes/list.handler.ts @@ -1,4 +1,5 @@ import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository"; +import prisma from "@calcom/prisma"; import { TRPCError } from "@trpc/server"; @@ -19,8 +20,9 @@ const listHandler = async (opts: GetOptions) => { message: "You need to be apart of an organization to use this feature", }); } + const attributeRepo = new PrismaAttributeRepository(prisma); - return await PrismaAttributeRepository.findAllByOrgIdWithOptions({ orgId: org.id }); + return await attributeRepo.findAllByOrgIdWithOptions({ orgId: org.id }); }; export default listHandler; diff --git a/packages/trpc/server/routers/viewer/availability/schedule/delete.handler.ts b/packages/trpc/server/routers/viewer/availability/schedule/delete.handler.ts index 5cb8cc9a593e1e..564909c02db833 100644 --- a/packages/trpc/server/routers/viewer/availability/schedule/delete.handler.ts +++ b/packages/trpc/server/routers/viewer/availability/schedule/delete.handler.ts @@ -1,9 +1,9 @@ +import { HostRepository } from "@calcom/lib/server/repository/host"; import { prisma } from "@calcom/prisma"; import { TRPCError } from "@trpc/server"; import type { TrpcSessionUser } from "../../../../types"; -import { updateHostsWithNewDefaultSchedule } from "../util"; import type { TDeleteInputSchema } from "./delete.schema"; type DeleteOptions = { @@ -15,6 +15,7 @@ type DeleteOptions = { export const deleteHandler = async ({ input, ctx }: DeleteOptions) => { const { user } = ctx; + const hostRepo = new HostRepository(prisma); const scheduleToDelete = await prisma.schedule.findUnique({ where: { @@ -46,7 +47,7 @@ export const deleteHandler = async ({ input, ctx }: DeleteOptions) => { // to throw the error if there arent any other schedules if (!scheduleToSetAsDefault) throw new TRPCError({ code: "BAD_REQUEST" }); - await updateHostsWithNewDefaultSchedule(user.id, input.scheduleId, scheduleToSetAsDefault.id); + await hostRepo.updateHostsSchedule(user.id, input.scheduleId, scheduleToSetAsDefault.id); await prisma.user.update({ where: { @@ -57,7 +58,7 @@ export const deleteHandler = async ({ input, ctx }: DeleteOptions) => { }, }); } else if (user.defaultScheduleId) { - await updateHostsWithNewDefaultSchedule(user.id, input.scheduleId, user.defaultScheduleId); + await hostRepo.updateHostsSchedule(user.id, input.scheduleId, user.defaultScheduleId); } await prisma.schedule.delete({ diff --git a/packages/trpc/server/routers/viewer/availability/util.test.ts b/packages/trpc/server/routers/viewer/availability/util.test.ts index 34c1f29c2c999d..adcd39c2e62332 100644 --- a/packages/trpc/server/routers/viewer/availability/util.test.ts +++ b/packages/trpc/server/routers/viewer/availability/util.test.ts @@ -1,13 +1,9 @@ import { describe, expect, it, vi, beforeEach } from "vitest"; +import { HostRepository } from "@calcom/lib/server/repository/host"; import { PrismaClient } from "@calcom/prisma"; -import { - getDefaultScheduleId, - hasDefaultSchedule, - setupDefaultSchedule, - updateHostsWithNewDefaultSchedule, -} from "./util"; +import { getDefaultScheduleId, hasDefaultSchedule, setupDefaultSchedule } from "./util"; vi.mock("@calcom/prisma", () => { const mockPrisma = { @@ -31,9 +27,11 @@ vi.mock("@calcom/prisma", () => { describe("Availability Utils", () => { let prisma: PrismaClient; + let hostRepo: HostRepository; beforeEach(() => { prisma = new PrismaClient(); + hostRepo = new HostRepository(prisma); vi.clearAllMocks(); }); @@ -158,7 +156,7 @@ describe("Availability Utils", () => { (prisma.host.updateMany as any).mockResolvedValue(updateResult); - const result = await updateHostsWithNewDefaultSchedule(userId, oldScheduleId, newScheduleId, prisma); + const result = await hostRepo.updateHostsSchedule(userId, oldScheduleId, newScheduleId); expect(prisma.host.updateMany).toHaveBeenCalledWith({ where: { @@ -180,7 +178,7 @@ describe("Availability Utils", () => { (prisma.host.updateMany as any).mockResolvedValue(updateResult); - const result = await updateHostsWithNewDefaultSchedule(userId, oldScheduleId, newScheduleId, prisma); + const result = await hostRepo.updateHostsSchedule(userId, oldScheduleId, newScheduleId); expect(prisma.host.updateMany).toHaveBeenCalledWith({ where: { diff --git a/packages/trpc/server/routers/viewer/availability/util.ts b/packages/trpc/server/routers/viewer/availability/util.ts index e271da140de3d4..66b077538951b5 100644 --- a/packages/trpc/server/routers/viewer/availability/util.ts +++ b/packages/trpc/server/routers/viewer/availability/util.ts @@ -1,6 +1,5 @@ import type { User } from "@prisma/client"; -import { HostRepository } from "@calcom/lib/server/repository/host"; import type { PrismaClient } from "@calcom/prisma"; export const getDefaultScheduleId = async (userId: number, prisma: PrismaClient) => { @@ -54,11 +53,3 @@ export const setupDefaultSchedule = async (userId: number, scheduleId: number, p }, }); }; - -export const updateHostsWithNewDefaultSchedule = async ( - userId: number, - defaultScheduleId: number, - scheduleId: number -) => { - return await HostRepository.updateHostsSchedule(userId, defaultScheduleId, scheduleId); -};