refactor: rename SelectedSlotsRepository to PrismaSelectedSlotRepository (#22705)
* refactor: rename SelectedSlotsRepository to PrismaSelectedSlotRepository - Rename class from SelectedSlotsRepository to PrismaSelectedSlotRepository for consistency - Update all imports and type references throughout the codebase - Update DI module bindings and variable names - Maintain type safety without breaking changes Co-Authored-By: alex@cal.com <me@alexvanandel.com> * refactor: complete PrismaSelectedSlotRepository rename - Update DI module binding property name from selectedSlotsRepo to selectedSlotRepo - Update test mock to use PrismaSelectedSlotRepository class name - Ensure all references are consistently updated Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: rename file to prismaSelectedSlotRepository.ts and fix plural variable references - Rename apps/api/v2/src/lib/repositories/prisma-selected-slots.repository.ts to prismaSelectedSlotRepository.ts - Update class name from PrismaSelectedSlotsRepository to PrismaSelectedSlotRepository - Fix plural variable reference selectedSlotsRepository to selectedSlotRepository in service - Update all import paths to reference the new file name - Maintain consistency with camelCase naming convention Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: rename SelectedSlotsRepositoryFixture to SelectedSlotRepositoryFixture for consistency - Rename test fixture class from SelectedSlotsRepositoryFixture to SelectedSlotRepositoryFixture (singular) - Update all import statements in test files to use the renamed class - Resolves naming mismatch between fixture class and variable declarations - Fixes TypeScript compilation errors in CI tests Co-Authored-By: alex@cal.com <me@alexvanandel.com> * feat: add SelectedSlotRepositoryInterface and update DI to use interface Co-Authored-By: alex@cal.com <me@alexvanandel.com> * refactor: rename selectedSlots.ts to selectedSlot.ts and update all imports Co-Authored-By: alex@cal.com <me@alexvanandel.com> * fix: update test mock import path after file rename Co-Authored-By: alex@cal.com <me@alexvanandel.com> * Update apps/api/v2/src/lib/modules/available-slots.module.ts * Update apps/api/v2/src/lib/modules/available-slots.module.ts * Implement DTO * dont declare dependencies locally, duplicating * Small DTO/token fix * chore: bump @calcom/platform-libraries from 0.0.266 to 0.0.267 * oops. * Update fixture names also * Omg these vscode actions preventing saves * Final fix, hopefully --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Somay Chauhan <somaychauhan98@gmail.com>
This commit is contained in:
co-authored by
Devin AI
Somay Chauhan
parent
9ccf5f3723
commit
fde1d671fb
@@ -38,7 +38,7 @@
|
||||
"@axiomhq/winston": "^1.2.0",
|
||||
"@calcom/platform-constants": "*",
|
||||
"@calcom/platform-enums": "*",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.266",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.267",
|
||||
"@calcom/platform-types": "*",
|
||||
"@calcom/platform-utils": "*",
|
||||
"@calcom/prisma": "*",
|
||||
|
||||
@@ -3,7 +3,7 @@ import { PrismaEventTypeRepository } from "@/lib/repositories/prisma-event-type.
|
||||
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 { PrismaSelectedSlotRepository } from "@/lib/repositories/prisma-selected-slot.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";
|
||||
@@ -16,7 +16,7 @@ import { Module } from "@nestjs/common";
|
||||
PrismaOOORepository,
|
||||
PrismaScheduleRepository,
|
||||
PrismaBookingRepository,
|
||||
PrismaSelectedSlotsRepository,
|
||||
PrismaSelectedSlotRepository,
|
||||
PrismaUserRepository,
|
||||
PrismaEventTypeRepository,
|
||||
PrismaRoutingFormResponseRepository,
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
import { PrismaSelectedSlotsRepository as PrismaSelectedSlotsRepositoryLib } from "@calcom/platform-libraries/repositories";
|
||||
import { PrismaSelectedSlotRepository as PrismaSelectedSlotRepositoryLib } from "@calcom/platform-libraries/repositories";
|
||||
import { PrismaClient } from "@calcom/prisma";
|
||||
|
||||
@Injectable()
|
||||
export class PrismaSelectedSlotsRepository extends PrismaSelectedSlotsRepositoryLib {
|
||||
export class PrismaSelectedSlotRepository extends PrismaSelectedSlotRepositoryLib {
|
||||
constructor(private readonly dbWrite: PrismaWriteService) {
|
||||
super(dbWrite.prisma as unknown as PrismaClient);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { PrismaEventTypeRepository } from "@/lib/repositories/prisma-event-type.
|
||||
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 { PrismaSelectedSlotRepository } from "@/lib/repositories/prisma-selected-slot.repository";
|
||||
import { PrismaTeamRepository } from "@/lib/repositories/prisma-team.repository";
|
||||
import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
@@ -13,14 +13,14 @@ import { AvailableSlotsService as BaseAvailableSlotsService } from "@calcom/plat
|
||||
@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
|
||||
oooRepoDependency: PrismaOOORepository,
|
||||
scheduleRepoDependency: PrismaScheduleRepository,
|
||||
teamRepository: PrismaTeamRepository,
|
||||
routingFormResponseRepository: PrismaRoutingFormResponseRepository,
|
||||
bookingRepository: PrismaBookingRepository,
|
||||
selectedSlotRepository: PrismaSelectedSlotRepository,
|
||||
eventTypeRepository: PrismaEventTypeRepository,
|
||||
userRepository: PrismaUserRepository
|
||||
) {
|
||||
super({
|
||||
oooRepo: oooRepoDependency,
|
||||
@@ -28,7 +28,7 @@ export class AvailableSlotsService extends BaseAvailableSlotsService {
|
||||
teamRepo: teamRepository,
|
||||
routingFormResponseRepo: routingFormResponseRepository,
|
||||
bookingRepo: bookingRepository,
|
||||
selectedSlotsRepo: selectedSlotsRepository,
|
||||
selectedSlotRepo: selectedSlotRepository,
|
||||
eventTypeRepo: eventTypeRepository,
|
||||
userRepo: userRepository,
|
||||
});
|
||||
|
||||
+4
-4
@@ -16,7 +16,7 @@ import { AttendeeRepositoryFixture } from "test/fixtures/repository/attendee.rep
|
||||
import { BookingSeatRepositoryFixture } from "test/fixtures/repository/booking-seat.repository.fixture";
|
||||
import { BookingsRepositoryFixture } from "test/fixtures/repository/bookings.repository.fixture";
|
||||
import { EventTypesRepositoryFixture } from "test/fixtures/repository/event-types.repository.fixture";
|
||||
import { SelectedSlotsRepositoryFixture } from "test/fixtures/repository/selected-slots.repository.fixture";
|
||||
import { SelectedSlotRepositoryFixture } from "test/fixtures/repository/selected-slot.repository.fixture";
|
||||
import { UserRepositoryFixture } from "test/fixtures/repository/users.repository.fixture";
|
||||
import { randomString } from "test/utils/randomString";
|
||||
import { withApiAuth } from "test/utils/withApiAuth";
|
||||
@@ -250,7 +250,7 @@ describe("Slots 2024-04-15 Endpoints", () => {
|
||||
let userRepositoryFixture: UserRepositoryFixture;
|
||||
let schedulesService: SchedulesService_2024_06_11;
|
||||
let eventTypesRepositoryFixture: EventTypesRepositoryFixture;
|
||||
let selectedSlotsRepositoryFixture: SelectedSlotsRepositoryFixture;
|
||||
let selectedSlotRepositoryFixture: SelectedSlotRepositoryFixture;
|
||||
let bookingsRepositoryFixture: BookingsRepositoryFixture;
|
||||
let bookingSeatsRepositoryFixture: BookingSeatRepositoryFixture;
|
||||
let attendeesRepositoryFixture: AttendeeRepositoryFixture;
|
||||
@@ -288,7 +288,7 @@ describe("Slots 2024-04-15 Endpoints", () => {
|
||||
userRepositoryFixture = new UserRepositoryFixture(moduleRef);
|
||||
schedulesService = moduleRef.get<SchedulesService_2024_06_11>(SchedulesService_2024_06_11);
|
||||
eventTypesRepositoryFixture = new EventTypesRepositoryFixture(moduleRef);
|
||||
selectedSlotsRepositoryFixture = new SelectedSlotsRepositoryFixture(moduleRef);
|
||||
selectedSlotRepositoryFixture = new SelectedSlotRepositoryFixture(moduleRef);
|
||||
bookingsRepositoryFixture = new BookingsRepositoryFixture(moduleRef);
|
||||
bookingSeatsRepositoryFixture = new BookingSeatRepositoryFixture(moduleRef);
|
||||
attendeesRepositoryFixture = new AttendeeRepositoryFixture(moduleRef);
|
||||
@@ -773,7 +773,7 @@ describe("Slots 2024-04-15 Endpoints", () => {
|
||||
|
||||
afterAll(async () => {
|
||||
await userRepositoryFixture.deleteByEmail(user.email);
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reservedSlotUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reservedSlotUid);
|
||||
await bookingsRepositoryFixture.deleteAllBookings(user.id, user.email);
|
||||
|
||||
await app.close();
|
||||
|
||||
+5
-5
@@ -21,7 +21,7 @@ import { ApiKeysRepositoryFixture } from "test/fixtures/repository/api-keys.repo
|
||||
import { BookingsRepositoryFixture } from "test/fixtures/repository/bookings.repository.fixture";
|
||||
import { EventTypesRepositoryFixture } from "test/fixtures/repository/event-types.repository.fixture";
|
||||
import { MembershipRepositoryFixture } from "test/fixtures/repository/membership.repository.fixture";
|
||||
import { SelectedSlotsRepositoryFixture } from "test/fixtures/repository/selected-slots.repository.fixture";
|
||||
import { SelectedSlotRepositoryFixture } from "test/fixtures/repository/selected-slot.repository.fixture";
|
||||
import { TeamRepositoryFixture } from "test/fixtures/repository/team.repository.fixture";
|
||||
import { UserRepositoryFixture } from "test/fixtures/repository/users.repository.fixture";
|
||||
import { randomString } from "test/utils/randomString";
|
||||
@@ -44,7 +44,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
let membershipsRepositoryFixture: MembershipRepositoryFixture;
|
||||
let bookingsRepositoryFixture: BookingsRepositoryFixture;
|
||||
let apiKeysRepositoryFixture: ApiKeysRepositoryFixture;
|
||||
let selectedSlotsRepositoryFixture: SelectedSlotsRepositoryFixture;
|
||||
let selectedSlotRepositoryFixture: SelectedSlotRepositoryFixture;
|
||||
|
||||
const teammateEmailOne = `slots-2024-09-04-user-1-team-slots-${randomString()}`;
|
||||
let teammateApiKeyString: string;
|
||||
@@ -93,7 +93,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
membershipsRepositoryFixture = new MembershipRepositoryFixture(moduleRef);
|
||||
bookingsRepositoryFixture = new BookingsRepositoryFixture(moduleRef);
|
||||
apiKeysRepositoryFixture = new ApiKeysRepositoryFixture(moduleRef);
|
||||
selectedSlotsRepositoryFixture = new SelectedSlotsRepositoryFixture(moduleRef);
|
||||
selectedSlotRepositoryFixture = new SelectedSlotRepositoryFixture(moduleRef);
|
||||
|
||||
teammateOne = await userRepositoryFixture.create({
|
||||
email: teammateEmailOne,
|
||||
@@ -368,14 +368,14 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(slots).toEqual({ ...expectedSlotsUTC, "2050-09-05": expectedSlotsUTC2050_09_05 });
|
||||
|
||||
const dbSlot = await selectedSlotsRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
const dbSlot = await selectedSlotRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
expect(dbSlot).toBeDefined();
|
||||
if (dbSlot) {
|
||||
const dbReleaseAt = DateTime.fromJSDate(dbSlot.releaseAt, { zone: "UTC" }).toISO();
|
||||
const expectedReleaseAt = DateTime.fromISO(now, { zone: "UTC" }).plus({ minutes: 10 }).toISO();
|
||||
expect(dbReleaseAt).toEqual(expectedReleaseAt);
|
||||
}
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
clear();
|
||||
});
|
||||
|
||||
|
||||
+16
-16
@@ -30,7 +30,7 @@ import { BookingsRepositoryFixture } from "test/fixtures/repository/bookings.rep
|
||||
import { EventTypesRepositoryFixture } from "test/fixtures/repository/event-types.repository.fixture";
|
||||
import { MembershipRepositoryFixture } from "test/fixtures/repository/membership.repository.fixture";
|
||||
import { OOORepositoryFixture } from "test/fixtures/repository/ooo.repository.fixture";
|
||||
import { SelectedSlotsRepositoryFixture } from "test/fixtures/repository/selected-slots.repository.fixture";
|
||||
import { SelectedSlotRepositoryFixture } from "test/fixtures/repository/selected-slot.repository.fixture";
|
||||
import { TeamRepositoryFixture } from "test/fixtures/repository/team.repository.fixture";
|
||||
import { UserRepositoryFixture } from "test/fixtures/repository/users.repository.fixture";
|
||||
import { randomString } from "test/utils/randomString";
|
||||
@@ -49,7 +49,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
let userRepositoryFixture: UserRepositoryFixture;
|
||||
let schedulesService: SchedulesService_2024_06_11;
|
||||
let eventTypesRepositoryFixture: EventTypesRepositoryFixture;
|
||||
let selectedSlotsRepositoryFixture: SelectedSlotsRepositoryFixture;
|
||||
let selectedSlotRepositoryFixture: SelectedSlotRepositoryFixture;
|
||||
let bookingsRepositoryFixture: BookingsRepositoryFixture;
|
||||
let bookingSeatsRepositoryFixture: BookingSeatRepositoryFixture;
|
||||
let attendeesRepositoryFixture: AttendeeRepositoryFixture;
|
||||
@@ -104,7 +104,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
userRepositoryFixture = new UserRepositoryFixture(moduleRef);
|
||||
schedulesService = moduleRef.get<SchedulesService_2024_06_11>(SchedulesService_2024_06_11);
|
||||
eventTypesRepositoryFixture = new EventTypesRepositoryFixture(moduleRef);
|
||||
selectedSlotsRepositoryFixture = new SelectedSlotsRepositoryFixture(moduleRef);
|
||||
selectedSlotRepositoryFixture = new SelectedSlotRepositoryFixture(moduleRef);
|
||||
bookingsRepositoryFixture = new BookingsRepositoryFixture(moduleRef);
|
||||
bookingSeatsRepositoryFixture = new BookingSeatRepositoryFixture(moduleRef);
|
||||
attendeesRepositoryFixture = new AttendeeRepositoryFixture(moduleRef);
|
||||
@@ -483,7 +483,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(slots).toEqual({ ...expectedSlotsUTC, "2050-09-05": expectedSlotsUTC2050_09_05 });
|
||||
|
||||
const dbSlot = await selectedSlotsRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
const dbSlot = await selectedSlotRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
expect(dbSlot).toBeDefined();
|
||||
if (dbSlot) {
|
||||
const dbReleaseAt = DateTime.fromJSDate(dbSlot.releaseAt, { zone: "UTC" }).toISO();
|
||||
@@ -617,7 +617,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(slots).toEqual({ ...expectedSlotsUTC, "2050-09-05": expectedSlotsUTC2050_09_05 });
|
||||
|
||||
const dbSlot = await selectedSlotsRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
const dbSlot = await selectedSlotRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
expect(dbSlot).toBeDefined();
|
||||
if (dbSlot) {
|
||||
const dbReleaseAt = DateTime.fromJSDate(dbSlot.releaseAt, { zone: "UTC" }).toISO();
|
||||
@@ -719,14 +719,14 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(slots).toEqual({ ...expectedSlotsUTC, "2050-09-05": expectedSlotsUTC2050_09_05 });
|
||||
|
||||
const dbSlot = await selectedSlotsRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
const dbSlot = await selectedSlotRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
expect(dbSlot).toBeDefined();
|
||||
if (dbSlot) {
|
||||
const dbReleaseAt = DateTime.fromJSDate(dbSlot.releaseAt, { zone: "UTC" }).toISO();
|
||||
const expectedReleaseAt = DateTime.fromISO(now, { zone: "UTC" }).plus({ minutes: 10 }).toISO();
|
||||
expect(dbReleaseAt).toEqual(expectedReleaseAt);
|
||||
}
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
clear();
|
||||
});
|
||||
|
||||
@@ -775,14 +775,14 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(slots).toEqual({ ...expectedSlotsUTC, "2050-09-05": expectedSlotsUTC2050_09_05 });
|
||||
|
||||
const dbSlot = await selectedSlotsRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
const dbSlot = await selectedSlotRepositoryFixture.getByUid(reservedSlot.reservationUid);
|
||||
expect(dbSlot).toBeDefined();
|
||||
if (dbSlot) {
|
||||
const dbReleaseAt = DateTime.fromJSDate(dbSlot.releaseAt, { zone: "UTC" }).toISO();
|
||||
const expectedReleaseAt = DateTime.fromISO(now, { zone: "UTC" }).plus({ minutes: 10 }).toISO();
|
||||
expect(dbReleaseAt).toEqual(expectedReleaseAt);
|
||||
}
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
clear();
|
||||
});
|
||||
|
||||
@@ -1397,7 +1397,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(slots).toEqual({ ...expectedSlotsUTC, "2050-09-05": expectedSlotsUTC2050_09_05 });
|
||||
|
||||
const dbSlot = await selectedSlotsRepositoryFixture.getByUid(
|
||||
const dbSlot = await selectedSlotRepositoryFixture.getByUid(
|
||||
responseReservedVariableSlot.reservationUid
|
||||
);
|
||||
expect(dbSlot).toBeDefined();
|
||||
@@ -1674,7 +1674,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
);
|
||||
expect(responseReservedSlot.reservationDuration).toEqual(5);
|
||||
await bookingsRepositoryFixture.deleteById(booking.id);
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(responseReservedSlot.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(responseReservedSlot.reservationUid);
|
||||
});
|
||||
|
||||
it("should be able to reserve a slot if booking is rejected during that time", async () => {
|
||||
@@ -1872,7 +1872,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
|
||||
expect(reserveResponse.body.data.reservationUid).toBeDefined();
|
||||
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await bookingsRepositoryFixture.deleteById(existingBooking.id);
|
||||
});
|
||||
|
||||
@@ -1888,7 +1888,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
|
||||
expect(reserveResponse.body.data.reservationUid).toBeDefined();
|
||||
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await bookingsRepositoryFixture.deleteById(existingBooking.id);
|
||||
});
|
||||
|
||||
@@ -1903,7 +1903,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
.expect(201);
|
||||
|
||||
expect(reserveResponse.body.data.reservationUid).toBeDefined();
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await bookingsRepositoryFixture.deleteById(existingBooking.id);
|
||||
});
|
||||
|
||||
@@ -1918,7 +1918,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
.expect(201);
|
||||
|
||||
expect(reserveResponse.body.data.reservationUid).toBeDefined();
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reserveResponse.body.data.reservationUid);
|
||||
await bookingsRepositoryFixture.deleteById(existingBooking.id);
|
||||
});
|
||||
});
|
||||
@@ -1928,7 +1928,7 @@ describe("Slots 2024-09-04 Endpoints", () => {
|
||||
await userRepositoryFixture.deleteByEmail(user.email);
|
||||
await userRepositoryFixture.deleteByEmail(oooTestUserEmail);
|
||||
await userRepositoryFixture.deleteByEmail(unrelatedUser.email);
|
||||
await selectedSlotsRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
await selectedSlotRepositoryFixture.deleteByUId(reservedSlot.reservationUid);
|
||||
await bookingsRepositoryFixture.deleteAllBookings(user.id, user.email);
|
||||
await teamRepositoryFixture.delete(team.id);
|
||||
clear();
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@ import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { TestingModule } from "@nestjs/testing";
|
||||
import { SelectedSlots } from "@prisma/client";
|
||||
|
||||
export class SelectedSlotsRepositoryFixture {
|
||||
export class SelectedSlotRepositoryFixture {
|
||||
private prismaReadClient: PrismaReadService["prisma"];
|
||||
private prismaWriteClient: PrismaWriteService["prisma"];
|
||||
|
||||
constructor(private readonly module: TestingModule) {
|
||||
constructor(module: TestingModule) {
|
||||
this.prismaReadClient = module.get(PrismaReadService).prisma;
|
||||
this.prismaWriteClient = module.get(PrismaWriteService).prisma;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ 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.SELECTED_SLOT_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);
|
||||
|
||||
@@ -9,7 +9,7 @@ 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,
|
||||
selectedSlotRepo: DI_TOKENS.SELECTED_SLOT_REPOSITORY,
|
||||
teamRepo: DI_TOKENS.TEAM_REPOSITORY,
|
||||
userRepo: DI_TOKENS.USER_REPOSITORY,
|
||||
bookingRepo: DI_TOKENS.BOOKING_REPOSITORY,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { createModule } from "@evyweb/ioctopus";
|
||||
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { SelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots";
|
||||
import { PrismaSelectedSlotRepository } from "@calcom/lib/server/repository/PrismaSelectedSlotRepository";
|
||||
|
||||
export const selectedSlotsRepositoryModule = createModule();
|
||||
selectedSlotsRepositoryModule
|
||||
.bind(DI_TOKENS.SELECTED_SLOTS_REPOSITORY)
|
||||
.toClass(SelectedSlotsRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
.bind(DI_TOKENS.SELECTED_SLOT_REPOSITORY)
|
||||
.toClass(PrismaSelectedSlotRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
|
||||
@@ -6,8 +6,8 @@ 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"),
|
||||
SELECTED_SLOT_REPOSITORY: Symbol("SelectedSlotRepository"),
|
||||
SELECTED_SLOT_REPOSITORY_MODULE: Symbol("SelectedSlotRepositoryModule"),
|
||||
TEAM_REPOSITORY: Symbol("TeamRepository"),
|
||||
TEAM_REPOSITORY_MODULE: Symbol("TeamRepositoryModule"),
|
||||
USER_REPOSITORY: Symbol("UserRepository"),
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { SelectedSlot } from "./dto/SelectedSlot";
|
||||
|
||||
export type TimeSlot = {
|
||||
utcStartIso: string;
|
||||
utcEndIso: string;
|
||||
};
|
||||
|
||||
export interface ISelectedSlotRepository {
|
||||
findReservedByOthers(args: {
|
||||
slot: TimeSlot;
|
||||
eventTypeId: number;
|
||||
uid: string;
|
||||
}): Promise<SelectedSlot | null>;
|
||||
findManyReservedByOthers(
|
||||
slots: TimeSlot[],
|
||||
eventTypeId: number,
|
||||
uid: string
|
||||
): Promise<Array<Pick<SelectedSlot, "slotUtcEndDate" | "slotUtcStartDate">>>;
|
||||
findManyUnexpiredSlots(args: {
|
||||
userIds: number[];
|
||||
currentTimeInUtc: string;
|
||||
}): Promise<Array<Omit<SelectedSlot, "releaseAt">>>;
|
||||
deleteManyExpiredSlots(args: { eventTypeId: number; currentTimeInUtc: string }): Promise<{ count: number }>;
|
||||
}
|
||||
+6
-28
@@ -1,35 +1,13 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
|
||||
type WhereCondition = {
|
||||
slotUtcStartDate?: Date | string;
|
||||
slotUtcEndDate?: Date | string;
|
||||
eventTypeId?: number;
|
||||
uid?: string | { not: string };
|
||||
releaseAt?: { gt: Date };
|
||||
};
|
||||
import type { ISelectedSlotRepository } from "./ISelectedSlotRepository";
|
||||
import type { TimeSlot } from "./ISelectedSlotRepository";
|
||||
|
||||
export type FindManyArgs = {
|
||||
where?: WhereCondition & {
|
||||
OR?: WhereCondition[];
|
||||
};
|
||||
select?: Prisma.SelectedSlotsSelect;
|
||||
};
|
||||
|
||||
export type TimeSlot = {
|
||||
utcStartIso: string;
|
||||
utcEndIso: string;
|
||||
};
|
||||
|
||||
export class SelectedSlotsRepository {
|
||||
export class PrismaSelectedSlotRepository implements ISelectedSlotRepository {
|
||||
constructor(private prismaClient: PrismaClient) {}
|
||||
|
||||
async findMany({ where, select }: FindManyArgs) {
|
||||
return await this.prismaClient.selectedSlots.findMany({ where, select });
|
||||
}
|
||||
|
||||
async findFirst({ where }: { where: Prisma.SelectedSlotsWhereInput }) {
|
||||
private async findFirst({ where }: { where: Prisma.SelectedSlotsWhereInput }) {
|
||||
return await this.prismaClient.selectedSlots.findFirst({
|
||||
where,
|
||||
});
|
||||
@@ -56,7 +34,7 @@ export class SelectedSlotsRepository {
|
||||
}
|
||||
|
||||
async findManyReservedByOthers(slots: TimeSlot[], eventTypeId: number, uid: string) {
|
||||
return await this.findMany({
|
||||
return await this.prismaClient.selectedSlots.findMany({
|
||||
where: {
|
||||
OR: slots.map((slot) => ({
|
||||
slotUtcStartDate: slot.utcStartIso,
|
||||
@@ -0,0 +1,6 @@
|
||||
import type { SelectedSlots } from "@prisma/client";
|
||||
|
||||
export type SelectedSlot = Pick<
|
||||
SelectedSlots,
|
||||
"id" | "uid" | "eventTypeId" | "slotUtcStartDate" | "slotUtcEndDate" | "releaseAt" | "isSeat"
|
||||
>;
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
|
||||
type EnforceTrueOrNested<T> = {
|
||||
[K in keyof T]: T[K] extends object ? EnforceTrueOrNested<T[K]> : true; // only allow `true` at leaves
|
||||
};
|
||||
|
||||
export type HashedLinkSelect = EnforceTrueOrNested<
|
||||
Pick<Prisma.HashedLinkSelect, "id"> & {
|
||||
eventType?: Pick<Prisma.EventTypeSelect, "userId" | "teamId"> & {
|
||||
hosts?: {
|
||||
user?: Prisma.UserSelect;
|
||||
};
|
||||
profile?: {
|
||||
user?: Prisma.UserSelect;
|
||||
};
|
||||
owner?: Prisma.UserSelect;
|
||||
};
|
||||
}
|
||||
>;
|
||||
@@ -3,6 +3,6 @@ export { ScheduleRepository as PrismaScheduleRepository } from "@calcom/lib/serv
|
||||
export { BookingRepository as PrismaBookingRepository } from "@calcom/lib/server/repository/booking";
|
||||
export { EventTypeRepository as PrismaEventTypeRepository } from "@calcom/lib/server/repository/eventTypeRepository";
|
||||
export { RoutingFormResponseRepository as PrismaRoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse";
|
||||
export { SelectedSlotsRepository as PrismaSelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots";
|
||||
export { PrismaSelectedSlotRepository } from "@calcom/lib/server/repository/PrismaSelectedSlotRepository";
|
||||
export { TeamRepository as PrismaTeamRepository } from "@calcom/lib/server/repository/team";
|
||||
export { UserRepository as PrismaUserRepository } from "@calcom/lib/server/repository/user";
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { NextApiRequest } from "next";
|
||||
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { getPastTimeAndMinimumBookingNoticeBoundsStatus } from "@calcom/lib/isOutOfBounds";
|
||||
import { PrismaSelectedSlotRepository } from "@calcom/lib/server/repository/PrismaSelectedSlotRepository";
|
||||
import { EventTypeRepository } from "@calcom/lib/server/repository/eventTypeRepository";
|
||||
import { SelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
|
||||
import type { TIsAvailableInputSchema, TIsAvailableOutputSchema } from "./isAvailable.schema";
|
||||
@@ -41,7 +41,7 @@ export const isAvailableHandler = async ({
|
||||
|
||||
// Check each slot's availability
|
||||
// Without uid, we must not check for reserved slots because if uuid isn't set in cookie yet, but it is going to be through reserveSlot request soon, we could consider the slot as reserved accidentally.
|
||||
const slotsRepo = new SelectedSlotsRepository(ctx.prisma);
|
||||
const slotsRepo = new PrismaSelectedSlotRepository(ctx.prisma);
|
||||
const reservedSlots = uid ? await slotsRepo.findManyReservedByOthers(slots, eventTypeId, uid) : [];
|
||||
|
||||
// Map all slots to their availability status
|
||||
|
||||
@@ -5,15 +5,15 @@ import { vi, describe, it, expect, afterEach } from "vitest";
|
||||
// reserveSlotHandler relies on WEBAPP_URL being evaluated at import time, so we need to reset modules
|
||||
// between tests after tweaking process.env to simulate different deployment environments.
|
||||
//
|
||||
// The handler also calls into Prisma and the SelectedSlotsRepository, so we stub those parts out.
|
||||
// The handler also calls into Prisma and the SelectedSlotRepository, so we stub those parts out.
|
||||
|
||||
// We alias the module path once we know WEBAPP_URL has been configured.
|
||||
const dynamicImportHandler = async () => await import("./reserveSlot.handler");
|
||||
|
||||
// The repository instance method is used to check for an existing reservation by someone else.
|
||||
// To keep this unit test isolated from the database layer, we stub this to always resolve falsey.
|
||||
vi.mock("@calcom/lib/server/repository/selectedSlots", () => ({
|
||||
SelectedSlotsRepository: vi.fn().mockImplementation(() => ({
|
||||
vi.mock("@calcom/lib/server/repository/PrismaSelectedSlotRepository", () => ({
|
||||
PrismaSelectedSlotRepository: vi.fn().mockImplementation(() => ({
|
||||
findReservedByOthers: vi.fn().mockResolvedValue(null),
|
||||
})),
|
||||
}));
|
||||
|
||||
@@ -5,7 +5,7 @@ import { v4 as uuid } from "uuid";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { MINUTES_TO_BOOK } from "@calcom/lib/constants";
|
||||
import { SelectedSlotsRepository } from "@calcom/lib/server/repository/selectedSlots";
|
||||
import { PrismaSelectedSlotRepository } from "@calcom/lib/server/repository/PrismaSelectedSlotRepository";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
|
||||
@@ -64,7 +64,7 @@ export const reserveSlotHandler = async ({ ctx, input }: ReserveSlotOptions) =>
|
||||
}
|
||||
|
||||
// Check for existing reservations for the same slot
|
||||
const slotsRepo = new SelectedSlotsRepository(prisma);
|
||||
const slotsRepo = new PrismaSelectedSlotRepository(prisma);
|
||||
const reservedBySomeoneElse = await slotsRepo.findReservedByOthers({
|
||||
slot: {
|
||||
utcStartIso: slotUtcStartDate,
|
||||
|
||||
@@ -42,12 +42,12 @@ 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 type { ISelectedSlotRepository } from "@calcom/lib/server/repository/ISelectedSlotRepository";
|
||||
import type { BookingRepository } from "@calcom/lib/server/repository/booking";
|
||||
import type { EventTypeRepository } from "@calcom/lib/server/repository/eventTypeRepository";
|
||||
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 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";
|
||||
@@ -93,7 +93,7 @@ export type GetAvailableSlotsResponse = Awaited<
|
||||
export interface IAvailableSlotsService {
|
||||
oooRepo: PrismaOOORepository;
|
||||
scheduleRepo: ScheduleRepository;
|
||||
selectedSlotsRepo: SelectedSlotsRepository;
|
||||
selectedSlotRepo: ISelectedSlotRepository;
|
||||
teamRepo: TeamRepository;
|
||||
userRepo: UserRepository;
|
||||
bookingRepo: BookingRepository;
|
||||
@@ -114,7 +114,7 @@ export class AvailableSlotsService {
|
||||
eventTypeId: number;
|
||||
}) {
|
||||
const currentTimeInUtc = dayjs.utc().format();
|
||||
const slotsRepo = this.dependencies.selectedSlotsRepo;
|
||||
const slotsRepo = this.dependencies.selectedSlotRepo;
|
||||
|
||||
const unexpiredSelectedSlots =
|
||||
(await slotsRepo.findManyUnexpiredSlots({
|
||||
|
||||
@@ -2722,7 +2722,7 @@ __metadata:
|
||||
"@axiomhq/winston": ^1.2.0
|
||||
"@calcom/platform-constants": "*"
|
||||
"@calcom/platform-enums": "*"
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.266"
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.267"
|
||||
"@calcom/platform-types": "*"
|
||||
"@calcom/platform-utils": "*"
|
||||
"@calcom/prisma": "*"
|
||||
@@ -3794,13 +3794,13 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.266":
|
||||
version: 0.0.266
|
||||
resolution: "@calcom/platform-libraries@npm:0.0.266"
|
||||
"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.267":
|
||||
version: 0.0.267
|
||||
resolution: "@calcom/platform-libraries@npm:0.0.267"
|
||||
dependencies:
|
||||
"@calcom/features": "*"
|
||||
"@calcom/lib": "*"
|
||||
checksum: 20f140bfb9fc1a08f4f302deb9cf247110ab385974dd0235a3c8ab73df4d2440d3e38cb494ca22d7f58445754e2bf6a6c981933a8e8106eaf55861a61945ce26
|
||||
checksum: 0c385514a04ddbd96ab3277774815233801a6eaf9a0d406b473eb7a446602f6f7d98de7f16747893b9fe1d50257db13b050a5726c8e7fe9500750d3ebf7be23a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user