From 13cb99b7fe5183a799bbaaaffb735f601983122a Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 11 Jul 2025 17:37:24 +0300 Subject: [PATCH] feat: inject required repositories into AvailableSlotsService using dependency injection (#22413) * feat: inject all repositories into AvailableSlotsService using dependency injection - Create DI modules for SelectedSlotsRepository, TeamRepository, UserRepository, BookingRepository, EventTypeRepository, RoutingFormResponseRepository - Update available-slots DI module to bind all 6 repositories - Update DI container to load all new repository modules - Replace all 10 direct repository instantiations with injected dependencies - Add missing DI tokens for repository modules - Expand IAvailableSlotsService interface to include all repository dependencies This follows the same dependency injection pattern established in previous repository refactoring PRs and enables better testability and modularity by making all dependencies explicit and configurable. Co-Authored-By: morgan@cal.com * chore: DI available slots repo on api v2 * chore: bump platform libs --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: morgan@cal.com --- apps/api/v2/package.json | 2 +- .../src/lib/modules/available-slots.module.ts | 28 +++++++++++++ .../repositories/prisma-booking.repository.ts | 12 ++++++ .../prisma-event-type.repository.ts | 12 ++++++ ...Repository.ts => prisma-ooo.repository.ts} | 4 +- ...prisma-routing-form-response.repository.ts | 12 ++++++ .../prisma-schedule.repository.ts | 12 ++++++ .../prisma-selected-slots.repository.ts | 12 ++++++ ...epository.ts => prisma-team.repository.ts} | 4 +- .../repositories/prisma-user.repository.ts | 12 ++++++ .../api/v2/src/lib/services/AvailableSlots.ts | 15 ------- .../lib/services/available-slots.service.ts | 36 +++++++++++++++++ .../controllers/slots.controller.ts | 2 +- .../slots/slots-2024-04-15/slots.module.ts | 9 +---- .../workers/slots.worker.module.ts | 7 ++-- .../slots-2024-04-15/workers/slots.worker.ts | 2 +- .../services/slots.service.ts | 2 +- .../slots/slots-2024-09-04/slots.module.ts | 8 +--- packages/lib/di/containers/available-slots.ts | 12 ++++++ packages/lib/di/modules/available-slots.ts | 6 +++ packages/lib/di/modules/booking.ts | 9 +++++ packages/lib/di/modules/eventType.ts | 9 +++++ .../lib/di/modules/routingFormResponse.ts | 9 +++++ packages/lib/di/modules/selectedSlots.ts | 9 +++++ packages/lib/di/modules/team.ts | 7 ++++ packages/lib/di/modules/user.ts | 7 ++++ packages/lib/di/tokens.ts | 12 ++++++ packages/platform/libraries/repositories.ts | 6 +++ .../trpc/server/routers/viewer/slots/util.ts | 40 +++++++++++-------- yarn.lock | 10 ++--- 30 files changed, 265 insertions(+), 62 deletions(-) create mode 100644 apps/api/v2/src/lib/modules/available-slots.module.ts create mode 100644 apps/api/v2/src/lib/repositories/prisma-booking.repository.ts create mode 100644 apps/api/v2/src/lib/repositories/prisma-event-type.repository.ts rename apps/api/v2/src/lib/repositories/{PrismaOOORepository.ts => prisma-ooo.repository.ts} (64%) create mode 100644 apps/api/v2/src/lib/repositories/prisma-routing-form-response.repository.ts create mode 100644 apps/api/v2/src/lib/repositories/prisma-schedule.repository.ts create mode 100644 apps/api/v2/src/lib/repositories/prisma-selected-slots.repository.ts rename apps/api/v2/src/lib/repositories/{PrismaScheduleRepository.ts => prisma-team.repository.ts} (63%) create mode 100644 apps/api/v2/src/lib/repositories/prisma-user.repository.ts delete mode 100644 apps/api/v2/src/lib/services/AvailableSlots.ts create mode 100644 apps/api/v2/src/lib/services/available-slots.service.ts create mode 100644 packages/lib/di/modules/booking.ts create mode 100644 packages/lib/di/modules/eventType.ts create mode 100644 packages/lib/di/modules/routingFormResponse.ts create mode 100644 packages/lib/di/modules/selectedSlots.ts create mode 100644 packages/lib/di/modules/team.ts create mode 100644 packages/lib/di/modules/user.ts diff --git a/apps/api/v2/package.json b/apps/api/v2/package.json index 9fb2b6f375..45910d225b 100644 --- a/apps/api/v2/package.json +++ b/apps/api/v2/package.json @@ -38,7 +38,7 @@ "@axiomhq/winston": "^1.2.0", "@calcom/platform-constants": "*", "@calcom/platform-enums": "*", - "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.256", + "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.257", "@calcom/platform-types": "*", "@calcom/platform-utils": "*", "@calcom/prisma": "*", diff --git a/apps/api/v2/src/lib/modules/available-slots.module.ts b/apps/api/v2/src/lib/modules/available-slots.module.ts new file mode 100644 index 0000000000..5be48dcf44 --- /dev/null +++ b/apps/api/v2/src/lib/modules/available-slots.module.ts @@ -0,0 +1,28 @@ +import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository"; +import { PrismaEventTypeRepository } from "@/lib/repositories/prisma-event-type.repository"; +import { PrismaOOORepository } from "@/lib/repositories/prisma-ooo.repository"; +import { PrismaRoutingFormResponseRepository } from "@/lib/repositories/prisma-routing-form-response.repository"; +import { PrismaScheduleRepository } from "@/lib/repositories/prisma-schedule.repository"; +import { PrismaSelectedSlotsRepository } from "@/lib/repositories/prisma-selected-slots.repository"; +import { PrismaTeamRepository } from "@/lib/repositories/prisma-team.repository"; +import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository"; +import { AvailableSlotsService } from "@/lib/services/available-slots.service"; +import { PrismaModule } from "@/modules/prisma/prisma.module"; +import { Module } from "@nestjs/common"; + +@Module({ + imports: [PrismaModule], + providers: [ + PrismaOOORepository, + PrismaScheduleRepository, + PrismaBookingRepository, + PrismaSelectedSlotsRepository, + PrismaUserRepository, + PrismaEventTypeRepository, + PrismaRoutingFormResponseRepository, + PrismaTeamRepository, + AvailableSlotsService, + ], + exports: [AvailableSlotsService], +}) +export class AvailableSlotsModule {} diff --git a/apps/api/v2/src/lib/repositories/prisma-booking.repository.ts b/apps/api/v2/src/lib/repositories/prisma-booking.repository.ts new file mode 100644 index 0000000000..a8b861327c --- /dev/null +++ b/apps/api/v2/src/lib/repositories/prisma-booking.repository.ts @@ -0,0 +1,12 @@ +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Injectable } from "@nestjs/common"; + +import { PrismaBookingRepository as PrismaBookingRepositoryLib } from "@calcom/platform-libraries/repositories"; +import { PrismaClient } from "@calcom/prisma"; + +@Injectable() +export class PrismaBookingRepository extends PrismaBookingRepositoryLib { + constructor(private readonly dbWrite: PrismaWriteService) { + super(dbWrite.prisma as unknown as PrismaClient); + } +} diff --git a/apps/api/v2/src/lib/repositories/prisma-event-type.repository.ts b/apps/api/v2/src/lib/repositories/prisma-event-type.repository.ts new file mode 100644 index 0000000000..edb45cb56a --- /dev/null +++ b/apps/api/v2/src/lib/repositories/prisma-event-type.repository.ts @@ -0,0 +1,12 @@ +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Injectable } from "@nestjs/common"; + +import { PrismaEventTypeRepository as PrismaEventTypeRepositoryLib } from "@calcom/platform-libraries/repositories"; +import { PrismaClient } from "@calcom/prisma"; + +@Injectable() +export class PrismaEventTypeRepository extends PrismaEventTypeRepositoryLib { + constructor(private readonly dbWrite: PrismaWriteService) { + super(dbWrite.prisma as unknown as PrismaClient); + } +} diff --git a/apps/api/v2/src/lib/repositories/PrismaOOORepository.ts b/apps/api/v2/src/lib/repositories/prisma-ooo.repository.ts similarity index 64% rename from apps/api/v2/src/lib/repositories/PrismaOOORepository.ts rename to apps/api/v2/src/lib/repositories/prisma-ooo.repository.ts index ebc51e51b2..92028a8c12 100644 --- a/apps/api/v2/src/lib/repositories/PrismaOOORepository.ts +++ b/apps/api/v2/src/lib/repositories/prisma-ooo.repository.ts @@ -1,11 +1,11 @@ import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable } from "@nestjs/common"; -import { PrismaOOORepository } from "@calcom/platform-libraries/repositories"; +import { PrismaOOORepository as PrismaOOORepositoryLib } from "@calcom/platform-libraries/repositories"; import { PrismaClient } from "@calcom/prisma"; @Injectable() -export class OOORepository extends PrismaOOORepository { +export class PrismaOOORepository extends PrismaOOORepositoryLib { constructor(private readonly dbWrite: PrismaWriteService) { super(dbWrite.prisma as unknown as PrismaClient); } diff --git a/apps/api/v2/src/lib/repositories/prisma-routing-form-response.repository.ts b/apps/api/v2/src/lib/repositories/prisma-routing-form-response.repository.ts new file mode 100644 index 0000000000..ce4df19064 --- /dev/null +++ b/apps/api/v2/src/lib/repositories/prisma-routing-form-response.repository.ts @@ -0,0 +1,12 @@ +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Injectable } from "@nestjs/common"; + +import { PrismaRoutingFormResponseRepository as PrismaRoutingFormResponseRepositoryLib } from "@calcom/platform-libraries/repositories"; +import { PrismaClient } from "@calcom/prisma"; + +@Injectable() +export class PrismaRoutingFormResponseRepository extends PrismaRoutingFormResponseRepositoryLib { + constructor(private readonly dbWrite: PrismaWriteService) { + super(dbWrite.prisma as unknown as PrismaClient); + } +} diff --git a/apps/api/v2/src/lib/repositories/prisma-schedule.repository.ts b/apps/api/v2/src/lib/repositories/prisma-schedule.repository.ts new file mode 100644 index 0000000000..b9880340a5 --- /dev/null +++ b/apps/api/v2/src/lib/repositories/prisma-schedule.repository.ts @@ -0,0 +1,12 @@ +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Injectable } from "@nestjs/common"; + +import { PrismaScheduleRepository as PrismaScheduleRepositoryLib } from "@calcom/platform-libraries/repositories"; +import { PrismaClient } from "@calcom/prisma"; + +@Injectable() +export class PrismaScheduleRepository extends PrismaScheduleRepositoryLib { + constructor(private readonly dbWrite: PrismaWriteService) { + super(dbWrite.prisma as unknown as PrismaClient); + } +} diff --git a/apps/api/v2/src/lib/repositories/prisma-selected-slots.repository.ts b/apps/api/v2/src/lib/repositories/prisma-selected-slots.repository.ts new file mode 100644 index 0000000000..bbc92a3b2c --- /dev/null +++ b/apps/api/v2/src/lib/repositories/prisma-selected-slots.repository.ts @@ -0,0 +1,12 @@ +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Injectable } from "@nestjs/common"; + +import { PrismaSelectedSlotsRepository as PrismaSelectedSlotsRepositoryLib } from "@calcom/platform-libraries/repositories"; +import { PrismaClient } from "@calcom/prisma"; + +@Injectable() +export class PrismaSelectedSlotsRepository extends PrismaSelectedSlotsRepositoryLib { + constructor(private readonly dbWrite: PrismaWriteService) { + super(dbWrite.prisma as unknown as PrismaClient); + } +} diff --git a/apps/api/v2/src/lib/repositories/PrismaScheduleRepository.ts b/apps/api/v2/src/lib/repositories/prisma-team.repository.ts similarity index 63% rename from apps/api/v2/src/lib/repositories/PrismaScheduleRepository.ts rename to apps/api/v2/src/lib/repositories/prisma-team.repository.ts index 7fdb6ededa..8538ea36f7 100644 --- a/apps/api/v2/src/lib/repositories/PrismaScheduleRepository.ts +++ b/apps/api/v2/src/lib/repositories/prisma-team.repository.ts @@ -1,11 +1,11 @@ import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable } from "@nestjs/common"; -import { PrismaScheduleRepository } from "@calcom/platform-libraries/repositories"; +import { PrismaTeamRepository as PrismaTeamRepositoryLib } from "@calcom/platform-libraries/repositories"; import { PrismaClient } from "@calcom/prisma"; @Injectable() -export class ScheduleRepository extends PrismaScheduleRepository { +export class PrismaTeamRepository extends PrismaTeamRepositoryLib { constructor(private readonly dbWrite: PrismaWriteService) { super(dbWrite.prisma as unknown as PrismaClient); } diff --git a/apps/api/v2/src/lib/repositories/prisma-user.repository.ts b/apps/api/v2/src/lib/repositories/prisma-user.repository.ts new file mode 100644 index 0000000000..8b7375385a --- /dev/null +++ b/apps/api/v2/src/lib/repositories/prisma-user.repository.ts @@ -0,0 +1,12 @@ +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Injectable } from "@nestjs/common"; + +import { PrismaUserRepository as PrismaUserRepositoryLib } from "@calcom/platform-libraries/repositories"; +import { PrismaClient } from "@calcom/prisma"; + +@Injectable() +export class PrismaUserRepository extends PrismaUserRepositoryLib { + constructor(private readonly dbWrite: PrismaWriteService) { + super(dbWrite.prisma as unknown as PrismaClient); + } +} diff --git a/apps/api/v2/src/lib/services/AvailableSlots.ts b/apps/api/v2/src/lib/services/AvailableSlots.ts deleted file mode 100644 index 8788b9d1da..0000000000 --- a/apps/api/v2/src/lib/services/AvailableSlots.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { OOORepository } from "@/lib/repositories/PrismaOOORepository"; -import { ScheduleRepository } from "@/lib/repositories/PrismaScheduleRepository"; -import { Injectable } from "@nestjs/common"; - -import { AvailableSlotsService as BaseAvailableSlotsService } from "@calcom/platform-libraries/slots"; - -@Injectable() -export class AvailableSlotsService extends BaseAvailableSlotsService { - constructor( - private readonly oooRepoDependency: OOORepository, - private readonly scheduleRepoDependency: ScheduleRepository - ) { - super({ oooRepo: oooRepoDependency, scheduleRepo: scheduleRepoDependency }); - } -} diff --git a/apps/api/v2/src/lib/services/available-slots.service.ts b/apps/api/v2/src/lib/services/available-slots.service.ts new file mode 100644 index 0000000000..e091301001 --- /dev/null +++ b/apps/api/v2/src/lib/services/available-slots.service.ts @@ -0,0 +1,36 @@ +import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository"; +import { PrismaEventTypeRepository } from "@/lib/repositories/prisma-event-type.repository"; +import { PrismaOOORepository } from "@/lib/repositories/prisma-ooo.repository"; +import { PrismaRoutingFormResponseRepository } from "@/lib/repositories/prisma-routing-form-response.repository"; +import { PrismaScheduleRepository } from "@/lib/repositories/prisma-schedule.repository"; +import { PrismaSelectedSlotsRepository } from "@/lib/repositories/prisma-selected-slots.repository"; +import { PrismaTeamRepository } from "@/lib/repositories/prisma-team.repository"; +import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository"; +import { Injectable } from "@nestjs/common"; + +import { AvailableSlotsService as BaseAvailableSlotsService } from "@calcom/platform-libraries/slots"; + +@Injectable() +export class AvailableSlotsService extends BaseAvailableSlotsService { + constructor( + private readonly oooRepoDependency: PrismaOOORepository, + private readonly scheduleRepoDependency: PrismaScheduleRepository, + private readonly teamRepository: PrismaTeamRepository, + private readonly routingFormResponseRepository: PrismaRoutingFormResponseRepository, + private readonly bookingRepository: PrismaBookingRepository, + private readonly selectedSlotsRepository: PrismaSelectedSlotsRepository, + private readonly eventTypeRepository: PrismaEventTypeRepository, + private readonly userRepository: PrismaUserRepository + ) { + super({ + oooRepo: oooRepoDependency, + scheduleRepo: scheduleRepoDependency, + teamRepo: teamRepository, + routingFormResponseRepo: routingFormResponseRepository, + bookingRepo: bookingRepository, + selectedSlotsRepo: selectedSlotsRepository, + eventTypeRepo: eventTypeRepository, + userRepo: userRepository, + }); + } +} diff --git a/apps/api/v2/src/modules/slots/slots-2024-04-15/controllers/slots.controller.ts b/apps/api/v2/src/modules/slots/slots-2024-04-15/controllers/slots.controller.ts index ae21b457bb..2c83a8dfe1 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-04-15/controllers/slots.controller.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-04-15/controllers/slots.controller.ts @@ -1,5 +1,5 @@ import { TRPC_ERROR_CODE, TRPC_ERROR_MAP, TRPCErrorCode } from "@/filters/trpc-exception.filter"; -import { AvailableSlotsService } from "@/lib/services/AvailableSlots"; +import { AvailableSlotsService } from "@/lib/services/available-slots.service"; import { SlotsOutputService_2024_04_15 } from "@/modules/slots/slots-2024-04-15/services/slots-output.service"; import type { RangeSlots, TimeSlots } from "@/modules/slots/slots-2024-04-15/services/slots-output.service"; import { SlotsWorkerService_2024_04_15 } from "@/modules/slots/slots-2024-04-15/services/slots-worker.service"; diff --git a/apps/api/v2/src/modules/slots/slots-2024-04-15/slots.module.ts b/apps/api/v2/src/modules/slots/slots-2024-04-15/slots.module.ts index 44cda28df2..5f62897314 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-04-15/slots.module.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-04-15/slots.module.ts @@ -1,7 +1,5 @@ import { EventTypesModule_2024_04_15 } from "@/ee/event-types/event-types_2024_04_15/event-types.module"; -import { OOORepository as PrismaOOORepository } from "@/lib/repositories/PrismaOOORepository"; -import { ScheduleRepository as PrismaScheduleRepository } from "@/lib/repositories/PrismaScheduleRepository"; -import { AvailableSlotsService } from "@/lib/services/AvailableSlots"; +import { AvailableSlotsModule } from "@/lib/modules/available-slots.module"; import { PrismaModule } from "@/modules/prisma/prisma.module"; import { SlotsController_2024_04_15 } from "@/modules/slots/slots-2024-04-15/controllers/slots.controller"; import { SlotsOutputService_2024_04_15 } from "@/modules/slots/slots-2024-04-15/services/slots-output.service"; @@ -11,15 +9,12 @@ import { SlotsRepository_2024_04_15 } from "@/modules/slots/slots-2024-04-15/slo import { Module } from "@nestjs/common"; @Module({ - imports: [PrismaModule, EventTypesModule_2024_04_15], + imports: [PrismaModule, EventTypesModule_2024_04_15, AvailableSlotsModule], providers: [ SlotsRepository_2024_04_15, SlotsService_2024_04_15, SlotsOutputService_2024_04_15, SlotsWorkerService_2024_04_15, - PrismaOOORepository, - PrismaScheduleRepository, - AvailableSlotsService, ], controllers: [SlotsController_2024_04_15], exports: [SlotsService_2024_04_15], diff --git a/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.module.ts b/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.module.ts index 4dc9af9571..c46a6b37e7 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.module.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.module.ts @@ -1,9 +1,7 @@ // apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots-worker.module.ts // Needed if ConfigService is used anywhere import appConfig from "@/config/app"; -import { OOORepository as PrismaOOORepository } from "@/lib/repositories/PrismaOOORepository"; -import { ScheduleRepository as PrismaScheduleRepository } from "@/lib/repositories/PrismaScheduleRepository"; -import { AvailableSlotsService } from "@/lib/services/AvailableSlots"; +import { AvailableSlotsModule } from "@/lib/modules/available-slots.module"; import { PrismaModule } from "@/modules/prisma/prisma.module"; import { Module, Logger } from "@nestjs/common"; import { ConfigModule } from "@nestjs/config"; @@ -18,7 +16,8 @@ import { SentryModule } from "@sentry/nestjs/setup"; load: [appConfig], }), PrismaModule, + AvailableSlotsModule, ], - providers: [Logger, PrismaOOORepository, PrismaScheduleRepository, AvailableSlotsService], + providers: [Logger], }) export class SlotsWorkerModule {} diff --git a/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.ts b/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.ts index c0416df4ec..79a7e22b75 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-04-15/workers/slots.worker.ts @@ -1,4 +1,4 @@ -import { AvailableSlotsService } from "@/lib/services/AvailableSlots"; +import { AvailableSlotsService } from "@/lib/services/available-slots.service"; import { Logger } from "@nestjs/common"; import { NestFactory } from "@nestjs/core"; import { IncomingMessage } from "http"; diff --git a/apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots.service.ts b/apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots.service.ts index 2d5eb87267..40ae4b3570 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots.service.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots.service.ts @@ -1,5 +1,5 @@ import { EventTypesRepository_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.repository"; -import { AvailableSlotsService } from "@/lib/services/AvailableSlots"; +import { AvailableSlotsService } from "@/lib/services/available-slots.service"; import { MembershipsRepository } from "@/modules/memberships/memberships.repository"; import { MembershipsService } from "@/modules/memberships/services/memberships.service"; import { TimeSlots } from "@/modules/slots/slots-2024-04-15/services/slots-output.service"; diff --git a/apps/api/v2/src/modules/slots/slots-2024-09-04/slots.module.ts b/apps/api/v2/src/modules/slots/slots-2024-09-04/slots.module.ts index dbee58ecb6..e57a563bc3 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-09-04/slots.module.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-09-04/slots.module.ts @@ -1,7 +1,5 @@ import { EventTypesModule_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.module"; -import { OOORepository as PrismaOOORepository } from "@/lib/repositories/PrismaOOORepository"; -import { ScheduleRepository as PrismaScheduleRepository } from "@/lib/repositories/PrismaScheduleRepository"; -import { AvailableSlotsService } from "@/lib/services/AvailableSlots"; +import { AvailableSlotsModule } from "@/lib/modules/available-slots.module"; import { MembershipsModule } from "@/modules/memberships/memberships.module"; import { OrganizationsRepository } from "@/modules/organizations/index/organizations.repository"; import { OrganizationsTeamsRepository } from "@/modules/organizations/teams/index/organizations-teams.repository"; @@ -26,6 +24,7 @@ import { Module } from "@nestjs/common"; TeamsModule, MembershipsModule, TeamsEventTypesModule, + AvailableSlotsModule, ], providers: [ SlotsRepository_2024_09_04, @@ -36,9 +35,6 @@ import { Module } from "@nestjs/common"; OrganizationsUsersRepository, OrganizationsRepository, OrganizationsTeamsRepository, - PrismaOOORepository, - PrismaScheduleRepository, - AvailableSlotsService, ], controllers: [SlotsController_2024_09_04], exports: [SlotsService_2024_09_04], diff --git a/packages/lib/di/containers/available-slots.ts b/packages/lib/di/containers/available-slots.ts index f5d81b0296..824467363a 100644 --- a/packages/lib/di/containers/available-slots.ts +++ b/packages/lib/di/containers/available-slots.ts @@ -5,13 +5,25 @@ import { prismaModule } from "@calcom/prisma/prisma.module"; import type { AvailableSlotsService } from "@calcom/trpc/server/routers/viewer/slots/util"; import { availableSlotsModule } from "../modules/available-slots"; +import { bookingRepositoryModule } from "../modules/booking"; +import { eventTypeRepositoryModule } from "../modules/eventType"; import { oooRepositoryModule } from "../modules/ooo"; +import { routingFormResponseRepositoryModule } from "../modules/routingFormResponse"; import { scheduleRepositoryModule } from "../modules/schedule"; +import { selectedSlotsRepositoryModule } from "../modules/selectedSlots"; +import { teamRepositoryModule } from "../modules/team"; +import { userRepositoryModule } from "../modules/user"; const container = createContainer(); container.load(DI_TOKENS.PRISMA_MODULE, prismaModule); container.load(DI_TOKENS.OOO_REPOSITORY_MODULE, oooRepositoryModule); container.load(DI_TOKENS.SCHEDULE_REPOSITORY_MODULE, scheduleRepositoryModule); +container.load(DI_TOKENS.SELECTED_SLOTS_REPOSITORY_MODULE, selectedSlotsRepositoryModule); +container.load(DI_TOKENS.TEAM_REPOSITORY_MODULE, teamRepositoryModule); +container.load(DI_TOKENS.USER_REPOSITORY_MODULE, userRepositoryModule); +container.load(DI_TOKENS.BOOKING_REPOSITORY_MODULE, bookingRepositoryModule); +container.load(DI_TOKENS.EVENT_TYPE_REPOSITORY_MODULE, eventTypeRepositoryModule); +container.load(DI_TOKENS.ROUTING_FORM_RESPONSE_REPOSITORY_MODULE, routingFormResponseRepositoryModule); container.load(DI_TOKENS.AVAILABLE_SLOTS_SERVICE_MODULE, availableSlotsModule); export function getAvailableSlotsService() { diff --git a/packages/lib/di/modules/available-slots.ts b/packages/lib/di/modules/available-slots.ts index 5e02adc73e..c3f663b865 100644 --- a/packages/lib/di/modules/available-slots.ts +++ b/packages/lib/di/modules/available-slots.ts @@ -9,4 +9,10 @@ export const availableSlotsModule = createModule(); availableSlotsModule.bind(DI_TOKENS.AVAILABLE_SLOTS_SERVICE).toClass(AvailableSlotsService, { oooRepo: DI_TOKENS.OOO_REPOSITORY, scheduleRepo: DI_TOKENS.SCHEDULE_REPOSITORY, + selectedSlotsRepo: DI_TOKENS.SELECTED_SLOTS_REPOSITORY, + teamRepo: DI_TOKENS.TEAM_REPOSITORY, + userRepo: DI_TOKENS.USER_REPOSITORY, + bookingRepo: DI_TOKENS.BOOKING_REPOSITORY, + eventTypeRepo: DI_TOKENS.EVENT_TYPE_REPOSITORY, + routingFormResponseRepo: DI_TOKENS.ROUTING_FORM_RESPONSE_REPOSITORY, } satisfies Record); diff --git a/packages/lib/di/modules/booking.ts b/packages/lib/di/modules/booking.ts new file mode 100644 index 0000000000..58d3f49eb1 --- /dev/null +++ b/packages/lib/di/modules/booking.ts @@ -0,0 +1,9 @@ +import { createModule } from "@evyweb/ioctopus"; + +import { DI_TOKENS } from "@calcom/lib/di/tokens"; +import { BookingRepository } from "@calcom/lib/server/repository/booking"; + +export const bookingRepositoryModule = createModule(); +bookingRepositoryModule + .bind(DI_TOKENS.BOOKING_REPOSITORY) + .toClass(BookingRepository, [DI_TOKENS.PRISMA_CLIENT]); diff --git a/packages/lib/di/modules/eventType.ts b/packages/lib/di/modules/eventType.ts new file mode 100644 index 0000000000..777799790d --- /dev/null +++ b/packages/lib/di/modules/eventType.ts @@ -0,0 +1,9 @@ +import { createModule } from "@evyweb/ioctopus"; + +import { DI_TOKENS } from "@calcom/lib/di/tokens"; +import { EventTypeRepository } from "@calcom/lib/server/repository/eventType"; + +export const eventTypeRepositoryModule = createModule(); +eventTypeRepositoryModule + .bind(DI_TOKENS.EVENT_TYPE_REPOSITORY) + .toClass(EventTypeRepository, [DI_TOKENS.PRISMA_CLIENT]); diff --git a/packages/lib/di/modules/routingFormResponse.ts b/packages/lib/di/modules/routingFormResponse.ts new file mode 100644 index 0000000000..2db9b72918 --- /dev/null +++ b/packages/lib/di/modules/routingFormResponse.ts @@ -0,0 +1,9 @@ +import { createModule } from "@evyweb/ioctopus"; + +import { DI_TOKENS } from "@calcom/lib/di/tokens"; +import { RoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse"; + +export const routingFormResponseRepositoryModule = createModule(); +routingFormResponseRepositoryModule + .bind(DI_TOKENS.ROUTING_FORM_RESPONSE_REPOSITORY) + .toClass(RoutingFormResponseRepository, [DI_TOKENS.PRISMA_CLIENT]); diff --git a/packages/lib/di/modules/selectedSlots.ts b/packages/lib/di/modules/selectedSlots.ts new file mode 100644 index 0000000000..ea88af1876 --- /dev/null +++ b/packages/lib/di/modules/selectedSlots.ts @@ -0,0 +1,9 @@ +import { createModule } from "@evyweb/ioctopus"; + +import { DI_TOKENS } from "@calcom/lib/di/tokens"; +import { SelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots"; + +export const selectedSlotsRepositoryModule = createModule(); +selectedSlotsRepositoryModule + .bind(DI_TOKENS.SELECTED_SLOTS_REPOSITORY) + .toClass(SelectedSlotsRepository, [DI_TOKENS.PRISMA_CLIENT]); diff --git a/packages/lib/di/modules/team.ts b/packages/lib/di/modules/team.ts new file mode 100644 index 0000000000..96d8555a2f --- /dev/null +++ b/packages/lib/di/modules/team.ts @@ -0,0 +1,7 @@ +import { createModule } from "@evyweb/ioctopus"; + +import { DI_TOKENS } from "@calcom/lib/di/tokens"; +import { TeamRepository } from "@calcom/lib/server/repository/team"; + +export const teamRepositoryModule = createModule(); +teamRepositoryModule.bind(DI_TOKENS.TEAM_REPOSITORY).toClass(TeamRepository, [DI_TOKENS.PRISMA_CLIENT]); diff --git a/packages/lib/di/modules/user.ts b/packages/lib/di/modules/user.ts new file mode 100644 index 0000000000..35cae3ac1f --- /dev/null +++ b/packages/lib/di/modules/user.ts @@ -0,0 +1,7 @@ +import { createModule } from "@evyweb/ioctopus"; + +import { DI_TOKENS } from "@calcom/lib/di/tokens"; +import { UserRepository } from "@calcom/lib/server/repository/user"; + +export const userRepositoryModule = createModule(); +userRepositoryModule.bind(DI_TOKENS.USER_REPOSITORY).toClass(UserRepository, [DI_TOKENS.PRISMA_CLIENT]); diff --git a/packages/lib/di/tokens.ts b/packages/lib/di/tokens.ts index 157a7c595f..b778389a89 100644 --- a/packages/lib/di/tokens.ts +++ b/packages/lib/di/tokens.ts @@ -6,6 +6,18 @@ export const DI_TOKENS = { OOO_REPOSITORY_MODULE: Symbol("OOORepositoryModule"), SCHEDULE_REPOSITORY: Symbol("ScheduleRepository"), SCHEDULE_REPOSITORY_MODULE: Symbol("ScheduleRepositoryModule"), + SELECTED_SLOTS_REPOSITORY: Symbol("SelectedSlotsRepository"), + SELECTED_SLOTS_REPOSITORY_MODULE: Symbol("SelectedSlotsRepositoryModule"), + TEAM_REPOSITORY: Symbol("TeamRepository"), + TEAM_REPOSITORY_MODULE: Symbol("TeamRepositoryModule"), + USER_REPOSITORY: Symbol("UserRepository"), + USER_REPOSITORY_MODULE: Symbol("UserRepositoryModule"), + BOOKING_REPOSITORY: Symbol("BookingRepository"), + BOOKING_REPOSITORY_MODULE: Symbol("BookingRepositoryModule"), + EVENT_TYPE_REPOSITORY: Symbol("EventTypeRepository"), + EVENT_TYPE_REPOSITORY_MODULE: Symbol("EventTypeRepositoryModule"), + ROUTING_FORM_RESPONSE_REPOSITORY: Symbol("RoutingFormResponseRepository"), + ROUTING_FORM_RESPONSE_REPOSITORY_MODULE: Symbol("RoutingFormResponseRepositoryModule"), AVAILABLE_SLOTS_SERVICE: Symbol("AvailableSlotsService"), AVAILABLE_SLOTS_SERVICE_MODULE: Symbol("AvailableSlotsModule"), }; diff --git a/packages/platform/libraries/repositories.ts b/packages/platform/libraries/repositories.ts index f49d993282..589d892d3e 100644 --- a/packages/platform/libraries/repositories.ts +++ b/packages/platform/libraries/repositories.ts @@ -1,2 +1,8 @@ export { PrismaOOORepository } from "@calcom/lib/server/repository/ooo"; export { ScheduleRepository as PrismaScheduleRepository } from "@calcom/lib/server/repository/schedule"; +export { BookingRepository as PrismaBookingRepository } from "@calcom/lib/server/repository/booking"; +export { EventTypeRepository as PrismaEventTypeRepository } from "@calcom/lib/server/repository/eventType"; +export { RoutingFormResponseRepository as PrismaRoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse"; +export { SelectedSlotsRepository as PrismaSelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots"; +export { TeamRepository as PrismaTeamRepository } from "@calcom/lib/server/repository/team"; +export { UserRepository as PrismaUserRepository } from "@calcom/lib/server/repository/user"; diff --git a/packages/trpc/server/routers/viewer/slots/util.ts b/packages/trpc/server/routers/viewer/slots/util.ts index e8df46d1d0..a7f83b2540 100644 --- a/packages/trpc/server/routers/viewer/slots/util.ts +++ b/packages/trpc/server/routers/viewer/slots/util.ts @@ -41,16 +41,16 @@ import { isRestrictionScheduleEnabled } from "@calcom/lib/restrictionSchedule"; import { safeStringify } from "@calcom/lib/safeStringify"; import { withReporting } from "@calcom/lib/sentryWrapper"; import { getTotalBookingDuration } from "@calcom/lib/server/queries/booking"; -import { BookingRepository } from "@calcom/lib/server/repository/booking"; -import { EventTypeRepository } from "@calcom/lib/server/repository/eventType"; -import { RoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse"; +import type { BookingRepository } from "@calcom/lib/server/repository/booking"; +import type { EventTypeRepository } from "@calcom/lib/server/repository/eventType"; +import type { RoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse"; import type { PrismaOOORepository } from "@calcom/lib/server/repository/ooo"; import type { ScheduleRepository } from "@calcom/lib/server/repository/schedule"; -import { SelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots"; -import { TeamRepository } from "@calcom/lib/server/repository/team"; -import { UserRepository, withSelectedCalendars } from "@calcom/lib/server/repository/user"; +import type { SelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots"; +import type { TeamRepository } from "@calcom/lib/server/repository/team"; +import type { UserRepository } from "@calcom/lib/server/repository/user"; +import { withSelectedCalendars } from "@calcom/lib/server/repository/user"; import getSlots from "@calcom/lib/slots"; -import prisma from "@calcom/prisma"; import { PeriodType } from "@calcom/prisma/client"; import { SchedulingType } from "@calcom/prisma/enums"; import type { EventBusyDate, EventBusyDetails } from "@calcom/types/Calendar"; @@ -92,6 +92,12 @@ export type GetAvailableSlotsResponse = Awaited< export interface IAvailableSlotsService { oooRepo: PrismaOOORepository; scheduleRepo: ScheduleRepository; + selectedSlotsRepo: SelectedSlotsRepository; + teamRepo: TeamRepository; + userRepo: UserRepository; + bookingRepo: BookingRepository; + eventTypeRepo: EventTypeRepository; + routingFormResponseRepo: RoutingFormResponseRepository; } export class AvailableSlotsService { @@ -107,7 +113,7 @@ export class AvailableSlotsService { eventTypeId: number; }) { const currentTimeInUtc = dayjs.utc().format(); - const slotsRepo = new SelectedSlotsRepository(prisma); + const slotsRepo = this.dependencies.selectedSlotsRepo; const unexpiredSelectedSlots = (await slotsRepo.findManyUnexpiredSlots({ @@ -142,7 +148,7 @@ export class AvailableSlotsService { } const dynamicEventType = getDefaultEvent(input.eventTypeSlug); - const userRepo = new UserRepository(prisma); + const userRepo = this.dependencies.userRepo; const usersForDynamicEventType = await userRepo.findManyUsersForDynamicEventType({ currentOrgDomain: isValidOrgDomain ? currentOrgDomain : null, usernameList: Array.isArray(input.usernameList) @@ -212,7 +218,7 @@ export class AvailableSlotsService { return null; } - const eventTypeRepo = new EventTypeRepository(prisma); + const eventTypeRepo = this.dependencies.eventTypeRepo; return await eventTypeRepo.findForSlots({ id: eventTypeId }); } @@ -250,7 +256,7 @@ export class AvailableSlotsService { ) { const { currentOrgDomain, isValidOrgDomain } = organizationDetails; log.info("getUserIdFromUsername", safeStringify({ organizationDetails, username })); - const userRepo = new UserRepository(prisma); + const userRepo = this.dependencies.userRepo; const [user] = await userRepo.findUsersByUsername({ usernameList: [username], orgSlug: isValidOrgDomain ? currentOrgDomain : null, @@ -284,7 +290,7 @@ export class AvailableSlotsService { organizationDetails ?? { currentOrgDomain: null, isValidOrgDomain: false } ); } - const eventTypeRepo = new EventTypeRepository(prisma); + const eventTypeRepo = this.dependencies.eventTypeRepo; const eventType = await eventTypeRepo.findFirstEventTypeId({ slug: eventTypeSlug, teamId, userId }); if (!eventType) { throw new TRPCError({ code: "NOT_FOUND" }); @@ -297,7 +303,7 @@ export class AvailableSlotsService { organizationDetails: { currentOrgDomain: string | null; isValidOrgDomain: boolean } ) { const { currentOrgDomain, isValidOrgDomain } = organizationDetails; - const teamRepo = new TeamRepository(prisma); + const teamRepo = this.dependencies.teamRepo; const team = await teamRepo.findFirstBySlugAndParentSlug({ slug, parentSlug: isValidOrgDomain && currentOrgDomain ? currentOrgDomain : null, @@ -510,7 +516,7 @@ export class AvailableSlotsService { bookingLimits ); - const bookingRepo = new BookingRepository(prisma); + const bookingRepo = this.dependencies.bookingRepo; const bookings = await bookingRepo.getAllAcceptedTeamBookingsOfUsers({ users, teamId, @@ -713,7 +719,7 @@ export class AvailableSlotsService { const userIdAndEmailMap = new Map(usersWithCredentials.map((user) => [user.id, user.email])); const allUserIds = Array.from(userIdAndEmailMap.keys()); - const bookingRepo = new BookingRepository(prisma); + const bookingRepo = this.dependencies.bookingRepo; const [currentBookingsAllUsers, outOfOfficeDaysAllUsers] = await Promise.all([ bookingRepo.findAllExistingBookingsForEventTypeBetween({ startDate: startTimeDate, @@ -940,12 +946,12 @@ export class AvailableSlotsService { let routingFormResponse = null; if (routingFormResponseId) { - const formResponseRepo = new RoutingFormResponseRepository(prisma); + const formResponseRepo = this.dependencies.routingFormResponseRepo; routingFormResponse = await formResponseRepo.findFormResponseIncludeForm({ routingFormResponseId, }); } else if (queuedFormResponseId) { - const formResponseRepo = new RoutingFormResponseRepository(prisma); + const formResponseRepo = this.dependencies.routingFormResponseRepo; routingFormResponse = await formResponseRepo.findQueuedFormResponseIncludeForm({ queuedFormResponseId, }); diff --git a/yarn.lock b/yarn.lock index b34d25667a..0d836c6068 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2519,7 +2519,7 @@ __metadata: "@axiomhq/winston": ^1.2.0 "@calcom/platform-constants": "*" "@calcom/platform-enums": "*" - "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.256" + "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.257" "@calcom/platform-types": "*" "@calcom/platform-utils": "*" "@calcom/prisma": "*" @@ -3565,13 +3565,13 @@ __metadata: languageName: unknown linkType: soft -"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.256": - version: 0.0.256 - resolution: "@calcom/platform-libraries@npm:0.0.256" +"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.257": + version: 0.0.257 + resolution: "@calcom/platform-libraries@npm:0.0.257" dependencies: "@calcom/features": "*" "@calcom/lib": "*" - checksum: 4c0b238ce803f7c660803bfcf4bc90435aef76a2efd1a476c10755a57e720354c739e88e3eaf44b176369750b211f81fc4a83f3eea452bac1d512bbf808a1085 + checksum: d45647591a26b6a73b6ae7602d8b8e59d87339de0e49468737437ffdd716fbd953898cd59a1eff8938326eba9ca895c28990bc91355aa55006980a2e716ddfd0 languageName: node linkType: hard