diff --git a/.github/actions/cache-db/action.yml b/.github/actions/cache-db/action.yml index f1b519f23f..7906afed02 100644 --- a/.github/actions/cache-db/action.yml +++ b/.github/actions/cache-db/action.yml @@ -26,7 +26,7 @@ runs: with: path: ${{ inputs.path }} key: ${{ runner.os }}-${{ env.cache-name }}-${{ inputs.path }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }} - - run: echo ${{ env.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }} && yarn db-seed + - run: USE_POOL=true yarn db-seed if: steps.cache-db.outputs.cache-hit != 'true' shell: bash - name: Postgres Dump Backup diff --git a/.github/workflows/api-v2-production-build.yml b/.github/workflows/api-v2-production-build.yml index 4d95fd935d..8bdb3ec244 100644 --- a/.github/workflows/api-v2-production-build.yml +++ b/.github/workflows/api-v2-production-build.yml @@ -56,8 +56,8 @@ jobs: if: steps.cache-api-v2-build.outputs.cache-hit != 'true' run: | export NODE_OPTIONS="--max_old_space_size=8192" - yarn workspace @calcom/api-v2 run generate-schemas - rm -rf apps/api/v2/node_modules - yarn install + yarn workspace @calcom/api-v2 run generate-schemas && + rm -rf apps/api/v2/node_modules && + yarn install && yarn workspace @calcom/api-v2 run build shell: bash diff --git a/.gitignore b/.gitignore index 8574f3d252..7ddef52338 100644 --- a/.gitignore +++ b/.gitignore @@ -66,7 +66,8 @@ tsconfig.tsbuildinfo .turbo # Prisma generated files -packages/prisma/client/* +apps/api/v2/generated/prisma/* +packages/prisma/generated/prisma/* packages/prisma/zod/**/*.ts packages/prisma/enums diff --git a/apps/api/v1/pages/api/booking-references/[id]/_auth-middleware.ts b/apps/api/v1/pages/api/booking-references/[id]/_auth-middleware.ts index 542f16265b..5dd52285cb 100644 --- a/apps/api/v1/pages/api/booking-references/[id]/_auth-middleware.ts +++ b/apps/api/v1/pages/api/booking-references/[id]/_auth-middleware.ts @@ -12,7 +12,7 @@ async function authMiddleware(req: NextApiRequest) { if (isSystemWideAdmin) return; // Find all references where the user has bookings const bookingReference = await prisma.bookingReference.findFirst({ - where: { id, booking: { userId } }, + where: { id, booking: { userId }, deleted: null }, }); if (!bookingReference) throw new HttpError({ statusCode: 403, message: "Forbidden" }); } diff --git a/apps/api/v1/pages/api/booking-references/[id]/_delete.ts b/apps/api/v1/pages/api/booking-references/[id]/_delete.ts index 6f7328ed42..e3515d5ff5 100644 --- a/apps/api/v1/pages/api/booking-references/[id]/_delete.ts +++ b/apps/api/v1/pages/api/booking-references/[id]/_delete.ts @@ -37,7 +37,7 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform export async function deleteHandler(req: NextApiRequest) { const { query } = req; const { id } = schemaQueryIdParseInt.parse(query); - await prisma.bookingReference.delete({ where: { id } }); + await prisma.bookingReference.update({ where: { id }, data: { deleted: true } }); return { message: `BookingReference with id: ${id} deleted` }; } diff --git a/apps/api/v1/pages/api/booking-references/[id]/_get.ts b/apps/api/v1/pages/api/booking-references/[id]/_get.ts index d7d178bdba..1635dee7b0 100644 --- a/apps/api/v1/pages/api/booking-references/[id]/_get.ts +++ b/apps/api/v1/pages/api/booking-references/[id]/_get.ts @@ -38,7 +38,7 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform export async function getHandler(req: NextApiRequest) { const { query } = req; const { id } = schemaQueryIdParseInt.parse(query); - const booking_reference = await prisma.bookingReference.findUniqueOrThrow({ where: { id } }); + const booking_reference = await prisma.bookingReference.findUniqueOrThrow({ where: { id, deleted: null } }); return { booking_reference: schemaBookingReferenceReadPublic.parse(booking_reference) }; } diff --git a/apps/api/v1/pages/api/booking-references/_get.ts b/apps/api/v1/pages/api/booking-references/_get.ts index 8c4b350ea4..e328929c52 100644 --- a/apps/api/v1/pages/api/booking-references/_get.ts +++ b/apps/api/v1/pages/api/booking-references/_get.ts @@ -29,13 +29,13 @@ import { schemaBookingReferenceReadPublic } from "~/lib/validations/booking-refe * 404: * description: No booking references were found */ -async function getHandler(req: NextApiRequest) { +export async function handler(req: NextApiRequest) { const { userId, isSystemWideAdmin } = req; const args: Prisma.BookingReferenceFindManyArgs = isSystemWideAdmin - ? {} - : { where: { booking: { userId } } }; + ? { where: { deleted: null } } + : { where: { booking: { userId }, deleted: null } }; const data = await prisma.bookingReference.findMany(args); return { booking_references: data.map((br) => schemaBookingReferenceReadPublic.parse(br)) }; } -export default defaultResponder(getHandler); +export default defaultResponder(handler); diff --git a/apps/api/v1/pages/api/slots/_get.ts b/apps/api/v1/pages/api/slots/_get.ts index a344755f3e..c6dd674f1e 100644 --- a/apps/api/v1/pages/api/slots/_get.ts +++ b/apps/api/v1/pages/api/slots/_get.ts @@ -3,8 +3,8 @@ import utc from "dayjs/plugin/utc"; import type { NextApiRequest, NextApiResponse } from "next"; import dayjs from "@calcom/dayjs"; -import { isSupportedTimeZone } from "@calcom/lib/dayjs"; import { getAvailableSlotsService } from "@calcom/features/di/containers/AvailableSlots"; +import { isSupportedTimeZone } from "@calcom/lib/dayjs"; import { HttpError } from "@calcom/lib/http-error"; import { defaultResponder } from "@calcom/lib/server/defaultResponder"; import { createContext } from "@calcom/trpc/server/createContext"; @@ -48,7 +48,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { : availableSlots.slots; return { slots: slotsInProvidedTimeZone }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (cause) { if (cause instanceof TRPCError) { const statusCode = getHTTPStatusCodeFromError(cause); diff --git a/apps/api/v1/test/lib/booking-references.integration-test.ts b/apps/api/v1/test/lib/booking-references.integration-test.ts new file mode 100644 index 0000000000..845b16ad6b --- /dev/null +++ b/apps/api/v1/test/lib/booking-references.integration-test.ts @@ -0,0 +1,486 @@ +import type { Request, Response } from "express"; +import type { NextApiRequest, NextApiResponse } from "next"; +import { createMocks } from "node-mocks-http"; +import { describe, it, expect, beforeAll, afterAll } from "vitest"; + +import prisma from "@calcom/prisma"; +import type { Booking, Credential, EventType, User } from "@calcom/prisma/client"; +import { BookingStatus } from "@calcom/prisma/enums"; + +import { patchHandler } from "../../pages/api/booking-references/[id]/_patch"; +import { handler } from "../../pages/api/booking-references/_get"; + +type CustomNextApiRequest = NextApiRequest & Request; +type CustomNextApiResponse = NextApiResponse & Response; + +describe("GET /api/booking-references - Soft-delete filtering", () => { + let testUser: User; + let testCredential: Credential; + let testEventType: EventType; + let testBooking: Booking; + const createdBookingReferenceIds: number[] = []; + + beforeAll(async () => { + testUser = await prisma.user.create({ + data: { + email: "api-bookingreference-test@example.com", + username: "api-bookingreference-test", + }, + }); + + testCredential = await prisma.credential.create({ + data: { + type: "google_calendar", + key: {}, + userId: testUser.id, + }, + }); + + testEventType = await prisma.eventType.create({ + data: { + title: "Test Event Type", + slug: "api-test-event-type", + length: 30, + userId: testUser.id, + }, + }); + + testBooking = await prisma.booking.create({ + data: { + uid: "api-test-booking-uid", + title: "API Test Booking", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.ACCEPTED, + }, + }); + }); + + afterAll(async () => { + if (createdBookingReferenceIds.length > 0) { + await prisma.bookingReference.deleteMany({ + where: { + id: { + in: createdBookingReferenceIds, + }, + }, + }); + } + + await prisma.booking.delete({ + where: { + id: testBooking.id, + }, + }); + + await prisma.eventType.delete({ + where: { + id: testEventType.id, + }, + }); + + await prisma.credential.delete({ + where: { + id: testCredential.id, + }, + }); + + await prisma.user.delete({ + where: { + id: testUser.id, + }, + }); + }); + + it("should only return active booking references, excluding soft-deleted ones", async () => { + const timestamp = Date.now(); + const activeRef = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: `api-active-ref-${timestamp}`, + meetingId: `api-active-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(activeRef.id); + + const deletedRef = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: `api-deleted-ref-${timestamp}`, + meetingId: `api-deleted-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + deleted: true, + }, + }); + createdBookingReferenceIds.push(deletedRef.id); + + const { req } = createMocks({ + method: "GET", + }); + + req.userId = testUser.id; + + const responseData = await handler(req); + + expect(responseData.booking_references).toBeDefined(); + expect(Array.isArray(responseData.booking_references)).toBe(true); + + const returnedActiveRef = responseData.booking_references.find( + (ref: { id: number }) => ref.id === activeRef.id + ); + const returnedDeletedRef = responseData.booking_references.find( + (ref: { id: number }) => ref.id === deletedRef.id + ); + + expect(returnedActiveRef).toBeDefined(); + expect(returnedDeletedRef).toBeUndefined(); + }); + + it("should filter booking references by user when not system admin", async () => { + const timestamp = Date.now(); + const otherUser = await prisma.user.create({ + data: { + email: `other-user-bookingreference-${timestamp}@example.com`, + username: `other-user-bookingreference-${timestamp}`, + }, + }); + + const otherBooking = await prisma.booking.create({ + data: { + uid: `other-user-booking-uid-${timestamp}`, + title: "Other User Booking", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: otherUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.ACCEPTED, + }, + }); + + const otherUserRef = await prisma.bookingReference.create({ + data: { + type: "zoom_video", + uid: `other-user-ref-${timestamp}`, + meetingId: `other-user-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: otherBooking.id, + }, + }); + createdBookingReferenceIds.push(otherUserRef.id); + + const { req } = createMocks({ + method: "GET", + }); + + req.userId = testUser.id; + + const responseData = await handler(req); + + const userRefs = responseData.booking_references.filter( + (ref: { id: number }) => ref.id === otherUserRef.id + ); + + expect(userRefs).toHaveLength(0); + + await prisma.booking.delete({ where: { id: otherBooking.id } }); + await prisma.user.delete({ where: { id: otherUser.id } }); + }); + + it("should return only active booking references for user, not soft-deleted ones for system admin", async () => { + const timestamp = Date.now(); + const activeRef1 = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: `admin-active-ref-1-${timestamp}`, + meetingId: `admin-active-meeting-1-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(activeRef1.id); + + const activeRef2 = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: `admin-active-ref-2-${timestamp}`, + meetingId: `admin-active-meeting-2-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(activeRef2.id); + + const deletedRef = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: `admin-deleted-ref-${timestamp}`, + meetingId: `admin-deleted-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + deleted: true, + }, + }); + createdBookingReferenceIds.push(deletedRef.id); + + const { req } = createMocks({ + method: "GET", + }); + + req.userId = testUser.id; + + const responseData = await handler(req); + + const activeRefs = responseData.booking_references.filter( + (ref: { id: number }) => ref.id === activeRef1.id || ref.id === activeRef2.id + ); + const returnedDeletedRef = responseData.booking_references.find( + (ref: { id: number }) => ref.id === deletedRef.id + ); + + expect(activeRefs.length).toBe(2); + expect(returnedDeletedRef).toBeUndefined(); + }); + + it("should verify soft-deleted references are never returned through the API", async () => { + const timestamp = Date.now(); + const activeRef = await prisma.bookingReference.create({ + data: { + type: "office365_calendar", + uid: `never-return-active-${timestamp}`, + meetingId: `never-return-active-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(activeRef.id); + + await prisma.bookingReference.update({ + where: { id: activeRef.id }, + data: { deleted: true }, + }); + + const { req } = createMocks({ + method: "GET", + }); + + req.userId = testUser.id; + + const responseData = await handler(req); + + const softDeletedRef = responseData.booking_references.find( + (ref: { id: number }) => ref.id === activeRef.id + ); + + expect(softDeletedRef).toBeUndefined(); + + const refInDb = await prisma.bookingReference.findUnique({ + where: { id: activeRef.id }, + }); + expect(refInDb).toBeDefined(); + expect(refInDb?.deleted).toBe(true); + }); +}); + +describe("PATCH /api/booking-references/[id] - Existing functionality", () => { + let testUser: User; + let testCredential: Credential; + let testEventType: EventType; + let testBooking: Booking; + const createdBookingReferenceIds: number[] = []; + + beforeAll(async () => { + testUser = await prisma.user.create({ + data: { + email: "api-bookingreference-patch-test@example.com", + username: "api-bookingreference-patch-test", + }, + }); + + testCredential = await prisma.credential.create({ + data: { + type: "google_calendar", + key: {}, + userId: testUser.id, + }, + }); + + testEventType = await prisma.eventType.create({ + data: { + title: "Test Event Type", + slug: "api-patch-test-event-type", + length: 30, + userId: testUser.id, + }, + }); + + testBooking = await prisma.booking.create({ + data: { + uid: "api-patch-test-booking-uid", + title: "API Patch Test Booking", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.ACCEPTED, + }, + }); + }); + + afterAll(async () => { + if (createdBookingReferenceIds.length > 0) { + await prisma.bookingReference.deleteMany({ + where: { + id: { + in: createdBookingReferenceIds, + }, + }, + }); + } + + await prisma.booking.delete({ + where: { + id: testBooking.id, + }, + }); + + await prisma.eventType.delete({ + where: { + id: testEventType.id, + }, + }); + + await prisma.credential.delete({ + where: { + id: testCredential.id, + }, + }); + + await prisma.user.delete({ + where: { + id: testUser.id, + }, + }); + }); + + it("should successfully update an active booking reference", async () => { + const timestamp = Date.now(); + const activeRef = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: `patch-active-ref-${timestamp}`, + meetingId: `patch-active-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(activeRef.id); + + const { req } = createMocks({ + method: "PATCH", + query: { id: activeRef.id.toString() }, + body: { + meetingPassword: "new-password-123", + }, + }); + + req.userId = testUser.id; + req.isSystemWideAdmin = false; + + const responseData = await patchHandler(req); + + expect(responseData.booking_reference).toBeDefined(); + expect(responseData.booking_reference.id).toBe(activeRef.id); + expect(responseData.booking_reference.meetingPassword).toBe("new-password-123"); + + const updatedRef = await prisma.bookingReference.findUnique({ + where: { id: activeRef.id }, + }); + expect(updatedRef?.meetingPassword).toBe("new-password-123"); + }); + + it("should allow updating a soft-deleted booking reference (existing functionality)", async () => { + const timestamp = Date.now(); + const deletedRef = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: `patch-deleted-ref-${timestamp}`, + meetingId: `patch-deleted-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + deleted: true, + meetingPassword: "original-password", + }, + }); + createdBookingReferenceIds.push(deletedRef.id); + + const { req } = createMocks({ + method: "PATCH", + query: { id: deletedRef.id.toString() }, + body: { + meetingPassword: "updated-password", + }, + }); + + req.userId = testUser.id; + req.isSystemWideAdmin = false; + + const responseData = await patchHandler(req); + + expect(responseData.booking_reference).toBeDefined(); + expect(responseData.booking_reference.id).toBe(deletedRef.id); + expect(responseData.booking_reference.meetingPassword).toBe("updated-password"); + + const updatedRef = await prisma.bookingReference.findUnique({ + where: { id: deletedRef.id }, + }); + expect(updatedRef?.meetingPassword).toBe("updated-password"); + expect(updatedRef?.deleted).toBe(true); + }); + + it("should verify that booking references can be updated regardless of deleted status", async () => { + const timestamp = Date.now(); + const activeRef = await prisma.bookingReference.create({ + data: { + type: "zoom_video", + uid: `patch-verify-active-${timestamp}`, + meetingId: `patch-verify-active-meeting-${timestamp}`, + credentialId: testCredential.id, + bookingId: testBooking.id, + meetingPassword: "original-password", + }, + }); + createdBookingReferenceIds.push(activeRef.id); + + await prisma.bookingReference.update({ + where: { id: activeRef.id }, + data: { deleted: true }, + }); + + const { req } = createMocks({ + method: "PATCH", + query: { id: activeRef.id.toString() }, + body: { + meetingPassword: "updated-password", + }, + }); + + req.userId = testUser.id; + req.isSystemWideAdmin = false; + + const responseData = await patchHandler(req); + + expect(responseData.booking_reference).toBeDefined(); + expect(responseData.booking_reference.meetingPassword).toBe("updated-password"); + + const refInDb = await prisma.bookingReference.findUnique({ + where: { id: activeRef.id }, + }); + expect(refInDb?.meetingPassword).toBe("updated-password"); + expect(refInDb?.deleted).toBe(true); + }); +}); diff --git a/apps/api/v1/test/lib/bookings/[id]/recordings/_get.test.ts b/apps/api/v1/test/lib/bookings/[id]/recordings/_get.test.ts index 8cf1fe62f7..05a2a18070 100644 --- a/apps/api/v1/test/lib/bookings/[id]/recordings/_get.test.ts +++ b/apps/api/v1/test/lib/bookings/[id]/recordings/_get.test.ts @@ -5,11 +5,11 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { createMocks } from "node-mocks-http"; import { describe, expect, test, vi, afterEach } from "vitest"; -import { buildBooking } from "@calcom/lib/test/builder"; import { getRecordingsOfCalVideoByRoomName, getDownloadLinkOfCalVideoByRecordingId, } from "@calcom/features/conferencing/lib/videoClient"; +import { buildBooking } from "@calcom/lib/test/builder"; import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers"; diff --git a/apps/api/v1/test/lib/bookings/[id]/transcripts/_get.test.ts b/apps/api/v1/test/lib/bookings/[id]/transcripts/_get.test.ts index 053f5861de..b4b8bbc901 100644 --- a/apps/api/v1/test/lib/bookings/[id]/transcripts/_get.test.ts +++ b/apps/api/v1/test/lib/bookings/[id]/transcripts/_get.test.ts @@ -5,8 +5,8 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { createMocks } from "node-mocks-http"; import { describe, expect, test, vi, afterEach } from "vitest"; -import { buildBooking } from "@calcom/lib/test/builder"; import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/features/conferencing/lib/videoClient"; +import { buildBooking } from "@calcom/lib/test/builder"; import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers"; diff --git a/apps/api/v2/.gitignore b/apps/api/v2/.gitignore index d325e3b2eb..d60b8f7f21 100644 --- a/apps/api/v2/.gitignore +++ b/apps/api/v2/.gitignore @@ -42,4 +42,5 @@ lerna-debug.log* .env.* !.env.example !.env.appStore.example -/client/* \ No newline at end of file +/client/* +/generated/prisma/* diff --git a/apps/api/v2/src/config/app.ts b/apps/api/v2/src/config/app.ts index bbb2813cfb..a19f3b94a1 100644 --- a/apps/api/v2/src/config/app.ts +++ b/apps/api/v2/src/config/app.ts @@ -22,6 +22,10 @@ const loadConfig = (): AppConfig => { db: { readUrl: getEnv("DATABASE_READ_URL"), writeUrl: getEnv("DATABASE_WRITE_URL"), + readPoolMax: getEnv("DATABASE_READ_POOL_MAX", 9), + writePoolMax: getEnv("DATABASE_WRITE_POOL_MAX", 7), + workerReadPoolMax: getEnv("DATABASE_READ_WORKER_POOL_MAX", 4), + workerWritePoolMax: getEnv("DATABASE_WRITE_WORKER_POOL_MAX", 6), redisUrl: getEnv("REDIS_URL"), }, next: { diff --git a/apps/api/v2/src/config/type.ts b/apps/api/v2/src/config/type.ts index cd2fe252bf..102ad23739 100644 --- a/apps/api/v2/src/config/type.ts +++ b/apps/api/v2/src/config/type.ts @@ -13,6 +13,10 @@ export type AppConfig = { db: { readUrl: string; writeUrl: string; + readPoolMax: number; + writePoolMax: number; + workerReadPoolMax: number; + workerWritePoolMax: number; redisUrl: string; }; next: { diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/booking-references.repository.ts b/apps/api/v2/src/ee/bookings/2024-08-13/booking-references.repository.ts index c48a316f5c..76a75130b3 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/booking-references.repository.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/booking-references.repository.ts @@ -9,7 +9,7 @@ export class BookingReferencesRepository_2024_08_13 { constructor(private readonly dbRead: PrismaReadService) {} async getBookingReferences(bookingId: number, filter?: BookingReferencesFilterInput_2024_08_13) { - const whereClause: Prisma.BookingReferenceWhereInput = { bookingId }; + const whereClause: Prisma.BookingReferenceWhereInput = { bookingId, deleted: null }; if (filter?.type) { whereClause.type = filter.type; @@ -30,6 +30,7 @@ export class BookingReferencesRepository_2024_08_13 { return this.dbRead.prisma.bookingReference.findFirst({ where: { uid: eventUid, + deleted: null, }, include: { credential: true, diff --git a/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/event-types.service.ts b/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/event-types.service.ts index 11c060feb8..a932e5c54a 100644 --- a/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/event-types.service.ts +++ b/apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/event-types.service.ts @@ -39,9 +39,11 @@ export class EventTypesService_2024_06_14 { } await this.checkCanCreateEventType(user.id, body); const eventTypeUser = await this.getUserToCreateEvent(user); - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { destinationCalendar: _destinationCalendar, ...rest } = body; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore const { eventType: eventTypeCreated } = await createEventType({ input: rest, ctx: { diff --git a/apps/api/v2/src/env.ts b/apps/api/v2/src/env.ts index b3f359b853..be3cc6b143 100644 --- a/apps/api/v2/src/env.ts +++ b/apps/api/v2/src/env.ts @@ -34,6 +34,10 @@ export type Environment = { IS_TEAM_BILLING_ENABLED: boolean; // Used to enable/disable the rewrite of /api/v2 to /v2, active by default. REWRITE_API_V2_PREFIX: string; + DATABASE_READ_POOL_MAX: number; + DATABASE_WRITE_POOL_MAX: number; + DATABASE_READ_WORKER_POOL_MAX: number; + DATABASE_WRITE_WORKER_POOL_MAX: number; }; export const getEnv = (key: K, fallback?: Environment[K]): Environment[K] => { diff --git a/apps/api/v2/src/lib/modules/available-slots.module.ts b/apps/api/v2/src/lib/modules/available-slots.module.ts index 8a30a8b140..894eb01469 100644 --- a/apps/api/v2/src/lib/modules/available-slots.module.ts +++ b/apps/api/v2/src/lib/modules/available-slots.module.ts @@ -16,12 +16,12 @@ import { FilterHostsService } from "@/lib/services/filter-hosts.service"; import { NoSlotsNotificationService } from "@/lib/services/no-slots-notification.service"; import { QualifiedHostsService } from "@/lib/services/qualified-hosts.service"; import { UserAvailabilityService } from "@/lib/services/user-availability.service"; -import { PrismaModule } from "@/modules/prisma/prisma.module"; +import { PrismaWorkerModule } from "@/modules/prisma/prisma-worker.module"; import { RedisService } from "@/modules/redis/redis.service"; import { Module } from "@nestjs/common"; @Module({ - imports: [PrismaModule], + imports: [PrismaWorkerModule], providers: [ PrismaOOORepository, PrismaScheduleRepository, diff --git a/apps/api/v2/src/lib/services/booking-cancel.service.ts b/apps/api/v2/src/lib/services/booking-cancel.service.ts index 1457ad2468..6433db3c67 100644 --- a/apps/api/v2/src/lib/services/booking-cancel.service.ts +++ b/apps/api/v2/src/lib/services/booking-cancel.service.ts @@ -5,9 +5,7 @@ import { BookingCancelService as BaseBookingCancelService } from "@calcom/featur @Injectable() export class BookingCancelService extends BaseBookingCancelService { - constructor( - prismaWriteService: PrismaWriteService, - ) { + constructor(prismaWriteService: PrismaWriteService) { super({ prismaClient: prismaWriteService.prisma, }); diff --git a/apps/api/v2/src/modules/billing/interfaces/billing-service.interface.ts b/apps/api/v2/src/modules/billing/interfaces/billing-service.interface.ts index 776e191476..9c2e1f2115 100644 --- a/apps/api/v2/src/modules/billing/interfaces/billing-service.interface.ts +++ b/apps/api/v2/src/modules/billing/interfaces/billing-service.interface.ts @@ -1,6 +1,7 @@ import { PlatformPlan } from "@/modules/billing/types"; import type { StripeService } from "@/modules/stripe/stripe.service"; import Stripe from "stripe"; + import { PlatformBilling, Team } from "@calcom/prisma/client"; export type BillingData = { diff --git a/apps/api/v2/src/modules/memberships/memberships.repository.ts b/apps/api/v2/src/modules/memberships/memberships.repository.ts index 15b1b5b76c..d7fdf149c7 100644 --- a/apps/api/v2/src/modules/memberships/memberships.repository.ts +++ b/apps/api/v2/src/modules/memberships/memberships.repository.ts @@ -107,7 +107,7 @@ export class MembershipsRepository { }, }); - return userOrgAdminMemberships.map((m) => m.teamId); + return userOrgAdminMemberships.map((m: { teamId: number }) => m.teamId); } async createMembership(teamId: number, userId: number, role: MembershipRole, accepted: boolean) { diff --git a/apps/api/v2/src/modules/memberships/services/memberships.service.ts b/apps/api/v2/src/modules/memberships/services/memberships.service.ts index 4e20533d12..11ae41dbcd 100644 --- a/apps/api/v2/src/modules/memberships/services/memberships.service.ts +++ b/apps/api/v2/src/modules/memberships/services/memberships.service.ts @@ -2,6 +2,8 @@ import { MembershipsRepository } from "@/modules/memberships/memberships.reposit import { Injectable } from "@nestjs/common"; import { intersectionBy } from "lodash"; +import type { Membership } from "@calcom/prisma/client"; + @Injectable() export class MembershipsService { constructor(private readonly membershipsRepository: MembershipsRepository) {} @@ -16,8 +18,8 @@ export class MembershipsService { const secondUserMemberships = await this.membershipsRepository.findUserMemberships(secondUserId); return intersectionBy( - firstUserMemberships.filter((m) => m.accepted), - secondUserMemberships.filter((m) => m.accepted), + firstUserMemberships.filter((m: Membership) => m.accepted), + secondUserMemberships.filter((m: Membership) => m.accepted), "teamId" ); } diff --git a/apps/api/v2/src/modules/organizations/event-types/organizations-admin-not-team-member-event-types.e2e-spec.ts b/apps/api/v2/src/modules/organizations/event-types/organizations-admin-not-team-member-event-types.e2e-spec.ts index 792618a6fe..441adab5c8 100644 --- a/apps/api/v2/src/modules/organizations/event-types/organizations-admin-not-team-member-event-types.e2e-spec.ts +++ b/apps/api/v2/src/modules/organizations/event-types/organizations-admin-not-team-member-event-types.e2e-spec.ts @@ -434,20 +434,19 @@ describe("Organizations Event Types Endpoints", () => { const responseTeamEvent = responseBody.data.find((event) => event.teamId === team.id); expect(responseTeamEvent).toBeDefined(); - expect(responseTeamEvent?.hosts).toEqual([ - { - userId: teammate1.id, - name: teammate1.name, - username: teammate1.username, - avatarUrl: teammate1.avatarUrl, - }, - { - userId: teammate2.id, - name: teammate2.name, - username: teammate2.username, - avatarUrl: teammate2.avatarUrl, - }, - ]); + expect(responseTeamEvent?.hosts?.find((host) => host.userId === teammate1.id)).toEqual({ + userId: teammate1.id, + name: teammate1.name, + username: teammate1.username, + avatarUrl: teammate1.avatarUrl, + }); + + expect(responseTeamEvent?.hosts?.find((host) => host.userId === teammate2.id)).toEqual({ + userId: teammate2.id, + name: teammate2.name, + username: teammate2.username, + avatarUrl: teammate2.avatarUrl, + }); if (!responseTeamEvent) { throw new Error("Team event not found"); diff --git a/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.e2e-spec.ts b/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.e2e-spec.ts index ead68061fc..0506a3f94a 100644 --- a/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.e2e-spec.ts +++ b/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.e2e-spec.ts @@ -122,7 +122,6 @@ describe("Organizations Teams Invite Endpoints", () => { .expect(404); }); - afterAll(async () => { await userRepositoryFixture.deleteByEmail(user.email); await organizationsRepositoryFixture.delete(org.id); @@ -131,5 +130,3 @@ describe("Organizations Teams Invite Endpoints", () => { }); }); }); - - diff --git a/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.ts b/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.ts index 1b6457be5c..271ba8066c 100644 --- a/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.ts +++ b/apps/api/v2/src/modules/organizations/teams/invite/organizations-teams-invite.controller.ts @@ -1,5 +1,9 @@ import { API_VERSIONS_VALUES } from "@/lib/api-versions"; -import { OPTIONAL_API_KEY_HEADER, OPTIONAL_X_CAL_CLIENT_ID_HEADER, OPTIONAL_X_CAL_SECRET_KEY_HEADER } from "@/lib/docs/headers"; +import { + OPTIONAL_API_KEY_HEADER, + OPTIONAL_X_CAL_CLIENT_ID_HEADER, + OPTIONAL_X_CAL_SECRET_KEY_HEADER, +} from "@/lib/docs/headers"; import { Roles } from "@/modules/auth/decorators/roles/roles.decorator"; import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard"; import { PlatformPlanGuard } from "@/modules/auth/guards/billing/platform-plan.guard"; @@ -11,10 +15,8 @@ import { Controller, UseGuards, Post, Param, ParseIntPipe, HttpCode, HttpStatus import { ApiHeader, ApiOperation, ApiTags as DocsTags } from "@nestjs/swagger"; import { SUCCESS_STATUS } from "@calcom/platform-constants"; - import { TeamService } from "@calcom/platform-libraries"; - import { CreateInviteOutputDto } from "./outputs/invite.output"; @Controller({ @@ -39,5 +41,3 @@ export class OrganizationsTeamsInviteController { return { status: SUCCESS_STATUS, data: result }; } } - - diff --git a/apps/api/v2/src/modules/organizations/teams/invite/outputs/invite.output.ts b/apps/api/v2/src/modules/organizations/teams/invite/outputs/invite.output.ts index af0dabb58c..059ca461e1 100644 --- a/apps/api/v2/src/modules/organizations/teams/invite/outputs/invite.output.ts +++ b/apps/api/v2/src/modules/organizations/teams/invite/outputs/invite.output.ts @@ -11,7 +11,8 @@ export class InviteDataDto { @ApiProperty({ description: "Complete invitation URL that can be shared with prospective members. Opens the signup page with the token and redirects to getting started after signup.", - example: "http://app.cal.com/signup?token=f6a5c8b1d2e34c7f90a1b2c3d4e5f6a5b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2&callbackUrl=/getting-started", + example: + "http://app.cal.com/signup?token=f6a5c8b1d2e34c7f90a1b2c3d4e5f6a5b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2&callbackUrl=/getting-started", }) inviteLink!: string; } @@ -23,5 +24,3 @@ export class CreateInviteOutputDto { @ApiProperty({ type: InviteDataDto }) data!: InviteDataDto; } - - diff --git a/apps/api/v2/src/modules/organizations/users/index/organizations-users.repository.ts b/apps/api/v2/src/modules/organizations/users/index/organizations-users.repository.ts index 4401d166e2..388da56e58 100644 --- a/apps/api/v2/src/modules/organizations/users/index/organizations-users.repository.ts +++ b/apps/api/v2/src/modules/organizations/users/index/organizations-users.repository.ts @@ -1,7 +1,8 @@ import { PrismaReadService } from "@/modules/prisma/prisma-read.service"; import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable } from "@nestjs/common"; -import type { Prisma } from "@calcom/prisma/client"; + +import type { Prisma, AttributeToUser, Membership, User, Profile } from "@calcom/prisma/client"; @Injectable() export class OrganizationsUsersRepository { @@ -60,7 +61,11 @@ export class OrganizationsUsersRepository { skip, take, }); - return attributeToUsersWithProfile.map((attributeToUser) => attributeToUser.member.user); + return attributeToUsersWithProfile.map( + ( + attributeToUser: AttributeToUser & { member: Membership & { user: User & { profiles: Profile[] } } } + ) => attributeToUser.member.user + ); } async getOrganizationUsersByEmails( diff --git a/apps/api/v2/src/modules/prisma/prisma-read.service.ts b/apps/api/v2/src/modules/prisma/prisma-read.service.ts index e61b15149c..07722c5c89 100644 --- a/apps/api/v2/src/modules/prisma/prisma-read.service.ts +++ b/apps/api/v2/src/modules/prisma/prisma-read.service.ts @@ -1,36 +1,79 @@ import type { OnModuleDestroy, OnModuleInit } from "@nestjs/common"; import { Injectable, Logger } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { Pool } from "pg"; import { PrismaClient } from "@calcom/prisma/client"; +const DB_MAX_POOL_CONNECTION = 10; + +export interface PrismaServiceOptions { + readUrl?: string; + maxReadConnections?: number; + e2e?: boolean; + type: "main" | "worker"; +} + @Injectable() export class PrismaReadService implements OnModuleInit, OnModuleDestroy { private logger = new Logger("PrismaReadService"); - public prisma: PrismaClient; + public prisma!: PrismaClient; + private pool!: Pool; + private options!: PrismaServiceOptions; - constructor(readonly configService: ConfigService) { - const dbUrl = configService.get("db.readUrl", { infer: true }); + constructor(private configService?: ConfigService) { + if (configService) { + // Use ConfigService defaults + const readUrl = configService.get("db.readUrl", { infer: true }); + const poolMax = parseInt( + configService.get("db.readPoolMax", { infer: true }) ?? DB_MAX_POOL_CONNECTION + ); + const e2e = configService.get("e2e", { infer: true }) ?? false; - this.prisma = new PrismaClient({ - datasources: { - db: { - url: dbUrl, - }, - }, + this.setOptions({ + readUrl, + maxReadConnections: poolMax, + e2e, + type: "main", + }); + } + } + + setOptions(options: PrismaServiceOptions) { + this.options = options; + + const dbUrl = options.readUrl; + const isE2E = options.e2e ?? false; + + this.pool = new Pool({ + connectionString: dbUrl, + max: isE2E ? 1 : options.maxReadConnections ?? DB_MAX_POOL_CONNECTION, + idleTimeoutMillis: 300000, }); + + const adapter = new PrismaPg(this.pool); + this.prisma = new PrismaClient({ adapter }); } async onModuleInit() { - this.prisma.$connect(); + if (!this.prisma) return; + + try { + await this.prisma.$connect(); + this.logger.log("Connected to read database"); + } catch (error) { + this.logger.error("Database connection failed", error); + } } async onModuleDestroy() { try { - await this.prisma.$disconnect(); + if (this.prisma) await this.prisma.$disconnect(); + if (this.pool) await this.pool.end(); } catch (error) { - this.logger.error(error); + this.logger.error("Error disconnecting from read database", error); } } } diff --git a/apps/api/v2/src/modules/prisma/prisma-worker.module.ts b/apps/api/v2/src/modules/prisma/prisma-worker.module.ts new file mode 100644 index 0000000000..4a84620e60 --- /dev/null +++ b/apps/api/v2/src/modules/prisma/prisma-worker.module.ts @@ -0,0 +1,40 @@ +import { PrismaReadService } from "@/modules/prisma/prisma-read.service"; +import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; +import { Module } from "@nestjs/common"; +import { ConfigModule, ConfigService } from "@nestjs/config"; + +@Module({ + imports: [ConfigModule], + providers: [ + { + provide: PrismaReadService, + useFactory: (config: ConfigService) => { + const service = new PrismaReadService(); + service.setOptions({ + readUrl: config.get("db.readUrl", { infer: true }), + maxReadConnections: parseInt(config.get("db.workerReadPoolMax", { infer: true })), + e2e: config.get("e2e", { infer: true }) ?? false, + type: "worker", + }); + return service; + }, + inject: [ConfigService], + }, + { + provide: PrismaWriteService, + useFactory: (config: ConfigService) => { + const service = new PrismaWriteService(); + service.setOptions({ + writeUrl: config.get("db.writeUrl", { infer: true }), + maxWriteConnections: parseInt(config.get("db.workerWritePoolMax", { infer: true })), + e2e: config.get("e2e", { infer: true }) ?? false, + type: "worker", + }); + return service; + }, + inject: [ConfigService], + }, + ], + exports: [PrismaReadService, PrismaWriteService], +}) +export class PrismaWorkerModule {} diff --git a/apps/api/v2/src/modules/prisma/prisma-write.service.ts b/apps/api/v2/src/modules/prisma/prisma-write.service.ts index 986db859f8..cb60985f1e 100644 --- a/apps/api/v2/src/modules/prisma/prisma-write.service.ts +++ b/apps/api/v2/src/modules/prisma/prisma-write.service.ts @@ -1,36 +1,75 @@ -import { OnModuleDestroy, OnModuleInit } from "@nestjs/common"; -import { Injectable, Logger } from "@nestjs/common"; +import { OnModuleDestroy, OnModuleInit, Injectable, Logger } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { Pool } from "pg"; import { PrismaClient } from "@calcom/prisma/client"; +const DB_MAX_POOL_CONNECTION = 5; + +export interface PrismaServiceOptions { + writeUrl?: string; + maxWriteConnections?: number; + e2e?: boolean; + type: "main" | "worker"; +} + @Injectable() export class PrismaWriteService implements OnModuleInit, OnModuleDestroy { private logger = new Logger("PrismaWriteService"); + public prisma!: PrismaClient; + private pool!: Pool; + private options!: PrismaServiceOptions; - public prisma: PrismaClient; + constructor(private configService?: ConfigService) { + if (configService) { + const writeUrl = configService.get("db.writeUrl", { infer: true }); + const poolMax = parseInt( + configService.get("db.writePoolMax", { infer: true }) ?? DB_MAX_POOL_CONNECTION + ); + const e2e = configService.get("e2e", { infer: true }) ?? false; - constructor(readonly configService: ConfigService) { - const dbUrl = configService.get("db.writeUrl", { infer: true }); + this.setOptions({ + writeUrl, + maxWriteConnections: poolMax, + e2e, + type: "main", + }); + } + } - this.prisma = new PrismaClient({ - datasources: { - db: { - url: dbUrl, - }, - }, + setOptions(options: PrismaServiceOptions) { + this.options = options; + + const dbUrl = options.writeUrl; + const isE2E = options.e2e ?? false; + this.pool = new Pool({ + connectionString: dbUrl, + max: isE2E ? 1 : options.maxWriteConnections ?? DB_MAX_POOL_CONNECTION, + idleTimeoutMillis: 300000, }); + + const adapter = new PrismaPg(this.pool); + this.prisma = new PrismaClient({ adapter }); } async onModuleInit() { - this.prisma.$connect(); + if (!this.prisma) return; + + try { + await this.prisma.$connect(); + this.logger.log("Connected to write database"); + } catch (error) { + this.logger.error("Database connection failed", error); + } } async onModuleDestroy() { try { - await this.prisma.$disconnect(); + if (this.prisma) await this.prisma.$disconnect(); + if (this.pool) await this.pool.end(); } catch (error) { - this.logger.error(error); + this.logger.error("Error disconnecting from write database", error); } } } diff --git a/apps/api/v2/src/modules/prisma/prisma.module.ts b/apps/api/v2/src/modules/prisma/prisma.module.ts index e9a66a5fc4..3c5d0d7565 100644 --- a/apps/api/v2/src/modules/prisma/prisma.module.ts +++ b/apps/api/v2/src/modules/prisma/prisma.module.ts @@ -1,9 +1,40 @@ import { PrismaReadService } from "@/modules/prisma/prisma-read.service"; import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Module } from "@nestjs/common"; +import { ConfigModule, ConfigService } from "@nestjs/config"; @Module({ - providers: [PrismaReadService, PrismaWriteService], + imports: [ConfigModule], + providers: [ + { + provide: PrismaReadService, + useFactory: (config: ConfigService) => { + const service = new PrismaReadService(); + service.setOptions({ + readUrl: config.get("db.readUrl", { infer: true }), + maxReadConnections: parseInt(config.get("db.readPoolMax", { infer: true })), + e2e: config.get("e2e", { infer: true }) ?? false, + type: "main", + }); + return service; + }, + inject: [ConfigService], + }, + { + provide: PrismaWriteService, + useFactory: (config: ConfigService) => { + const service = new PrismaWriteService(); + service.setOptions({ + writeUrl: config.get("db.writeUrl", { infer: true }), + maxWriteConnections: parseInt(config.get("db.writePoolMax", { infer: true })), + e2e: config.get("e2e", { infer: true }) ?? false, + type: "main", + }); + return service; + }, + inject: [ConfigService], + }, + ], exports: [PrismaReadService, PrismaWriteService], }) export class PrismaModule {} 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 c46a6b37e7..360da1726f 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 @@ -2,7 +2,7 @@ // Needed if ConfigService is used anywhere import appConfig from "@/config/app"; import { AvailableSlotsModule } from "@/lib/modules/available-slots.module"; -import { PrismaModule } from "@/modules/prisma/prisma.module"; +import { PrismaWorkerModule } from "@/modules/prisma/prisma-worker.module"; import { Module, Logger } from "@nestjs/common"; import { ConfigModule } from "@nestjs/config"; import { SentryModule } from "@sentry/nestjs/setup"; @@ -15,7 +15,7 @@ import { SentryModule } from "@sentry/nestjs/setup"; isGlobal: true, load: [appConfig], }), - PrismaModule, + PrismaWorkerModule, AvailableSlotsModule, ], providers: [Logger], diff --git a/apps/api/v2/src/modules/stripe/stripe.service.ts b/apps/api/v2/src/modules/stripe/stripe.service.ts index a562665def..9302c716c1 100644 --- a/apps/api/v2/src/modules/stripe/stripe.service.ts +++ b/apps/api/v2/src/modules/stripe/stripe.service.ts @@ -118,7 +118,7 @@ export class StripeService { userId ); - const credentialIdsToDelete = existingCredentials.map((item) => item.id); + const credentialIdsToDelete = existingCredentials.map((item: Credential) => item.id); if (credentialIdsToDelete.length > 0) { await this.appsRepository.deleteAppCredentials(credentialIdsToDelete, userId); } diff --git a/apps/api/v2/src/modules/teams/memberships/teams-memberships.repository.ts b/apps/api/v2/src/modules/teams/memberships/teams-memberships.repository.ts index d298ebd767..3c1c3c7271 100644 --- a/apps/api/v2/src/modules/teams/memberships/teams-memberships.repository.ts +++ b/apps/api/v2/src/modules/teams/memberships/teams-memberships.repository.ts @@ -17,7 +17,7 @@ export const MembershipUserSelect: Prisma.UserSelect = { name: true, metadata: true, bio: true, -}; +} satisfies Prisma.UserSelect; @Injectable() export class TeamsMembershipsRepository { diff --git a/apps/api/v2/src/modules/teams/teams/teams.repository.ts b/apps/api/v2/src/modules/teams/teams/teams.repository.ts index 8d25133132..2cd9ab58d6 100644 --- a/apps/api/v2/src/modules/teams/teams/teams.repository.ts +++ b/apps/api/v2/src/modules/teams/teams/teams.repository.ts @@ -3,7 +3,7 @@ import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable, NotFoundException } from "@nestjs/common"; import { teamMetadataSchema } from "@calcom/platform-libraries"; -import { Prisma } from "@calcom/prisma/client"; +import type { Membership, Prisma } from "@calcom/prisma/client"; @Injectable() export class TeamsRepository { @@ -41,7 +41,7 @@ export class TeamsRepository { return []; } - return teamMembers.map((member) => member.userId); + return teamMembers.map((member: Membership) => member.userId); } async getTeamManagedUsersIds(teamId: number) { @@ -57,7 +57,7 @@ export class TeamsRepository { return []; } - return teamMembers.map((member) => member.userId); + return teamMembers.map((member: Membership) => member.userId); } async getTeamsUserIsMemberOf(userId: number) { diff --git a/apps/api/v2/src/modules/users/users.repository.ts b/apps/api/v2/src/modules/users/users.repository.ts index 0453475220..1604fd38de 100644 --- a/apps/api/v2/src/modules/users/users.repository.ts +++ b/apps/api/v2/src/modules/users/users.repository.ts @@ -289,7 +289,7 @@ export class UsersRepository { user: true, }, }); - return profiles.map((profile) => profile.user); + return profiles.map((profile: Profile & { user: User }) => profile.user); } async setDefaultConferencingApp(userId: number, appSlug?: string, appLink?: string) { diff --git a/apps/api/v2/tsconfig.json b/apps/api/v2/tsconfig.json index 0709c3bef9..03473dcc05 100644 --- a/apps/api/v2/tsconfig.json +++ b/apps/api/v2/tsconfig.json @@ -14,7 +14,7 @@ "jsx": "react-jsx", "paths": { "@/*": ["./src/*"], - "@prisma/client/*": ["./client/*"], + "@calcom/prisma/client": ["../../../packages/prisma/generated/prisma/client"], "@calcom/prisma/enums": ["../../../packages/prisma/enums"], "@calcom/platform-constants": ["../../../packages/platform/constants/index.ts"], "@calcom/platform-types": ["../../../packages/platform/types/index.ts"], diff --git a/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts b/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts index fb608f3867..0e0894befb 100644 --- a/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts +++ b/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/queries.ts @@ -3,6 +3,7 @@ import { unstable_cache } from "next/cache"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; import { getTeamData } from "@calcom/features/ee/teams/lib/getTeamData"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { getEventTypeHosts, getProfileFromEvent, @@ -11,10 +12,9 @@ import { } from "@calcom/features/eventtypes/lib/getPublicEvent"; import { getTeamEventType } from "@calcom/features/eventtypes/lib/getTeamEventType"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { NEXTJS_CACHE_TTL } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { SchedulingType } from "@calcom/prisma/enums"; diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx index 114b4f1489..287a278b42 100644 --- a/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx +++ b/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx @@ -23,8 +23,14 @@ const ServerPage = async ({ searchParams: _searchParams }: ServerPageProps) => { const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) }); const searchParams = await _searchParams; const token = Array.isArray(searchParams?.token) ? searchParams.token[0] : searchParams?.token; - const autoAccept = Array.isArray(searchParams?.autoAccept) ? searchParams.autoAccept[0] : searchParams?.autoAccept; - const callbackUrl = token ? `/teams?token=${encodeURIComponent(token)}${autoAccept ? `&autoAccept=${encodeURIComponent(autoAccept)}` : ''}` : null; + const autoAccept = Array.isArray(searchParams?.autoAccept) + ? searchParams.autoAccept[0] + : searchParams?.autoAccept; + const callbackUrl = token + ? `/teams?token=${encodeURIComponent(token)}${ + autoAccept ? `&autoAccept=${encodeURIComponent(autoAccept)}` : "" + }` + : null; if (!session) { redirect(callbackUrl ? `/auth/login?callbackUrl=${callbackUrl}` : "/auth/login"); diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx index bca38f4981..5698aa509c 100644 --- a/apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx +++ b/apps/web/app/(use-page-wrapper)/(main-nav)/teams/server-page.tsx @@ -3,9 +3,9 @@ import type { Session } from "next-auth"; import { unstable_cache } from "next/cache"; import { TeamsListing } from "@calcom/features/ee/teams/components/TeamsListing"; -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { TeamService } from "@calcom/features/ee/teams/services/teamService"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import prisma from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; @@ -33,7 +33,9 @@ export const ServerTeamsListing = async ({ session: Session; }) => { const token = Array.isArray(searchParams?.token) ? searchParams.token[0] : searchParams?.token; - const autoAccept = Array.isArray(searchParams?.autoAccept) ? searchParams.autoAccept[0] : searchParams?.autoAccept; + const autoAccept = Array.isArray(searchParams?.autoAccept) + ? searchParams.autoAccept[0] + : searchParams?.autoAccept; const userId = session.user.id; let invitationAccepted = false; @@ -42,7 +44,7 @@ export const ServerTeamsListing = async ({ if (token) { try { - if (autoAccept === "true") { + if (autoAccept === "true") { await TeamService.acceptInvitationByToken(token, userId); invitationAccepted = true; } else { diff --git a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/RouteBuilder.tsx b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/RouteBuilder.tsx index 21142e225d..d1cbfdc813 100644 --- a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/RouteBuilder.tsx +++ b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/RouteBuilder.tsx @@ -308,7 +308,7 @@ const WeightedAttributesSelector = ({ />
- {!!attributeIdForWeights ? ( + {attributeIdForWeights ? ( { hookForm.reset({}); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const filters = getTeamsFiltersFromQuery(routerQuery); diff --git a/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx b/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx index 24667ec843..8de884532e 100644 --- a/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx +++ b/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx @@ -5,8 +5,8 @@ import { cookies, headers } from "next/headers"; import { redirect } from "next/navigation"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; -import { APP_NAME } from "@calcom/lib/constants"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { APP_NAME } from "@calcom/lib/constants"; import prisma from "@calcom/prisma"; import { meRouter } from "@calcom/trpc/server/routers/viewer/me/_router"; diff --git a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx index fb9f4cd6c9..5e35f5db78 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx @@ -4,8 +4,8 @@ import { z } from "zod"; import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired"; import { OrgForm } from "@calcom/features/ee/organizations/pages/settings/admin/AdminOrgEditPage"; -import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; const orgIdSchema = z.object({ id: z.coerce.number() }); diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx index 4319041729..8a1dd35930 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/SettingsLayoutAppDirClient.tsx @@ -369,7 +369,6 @@ const TeamListCollapsible = ({ teamFeatures }: { teamFeatures?: Record bottom.dataset.testid === "vertical-tab-Members" )[1]; - // eslint-disable-next-line @calcom/eslint/no-scroll-into-view-embed -- Settings layout isn't embedded tabMembers?.scrollIntoView({ behavior: "smooth" }); }, 100); } @@ -568,7 +567,6 @@ const SettingsSidebarContainer = ({ const tabMembers = Array.from(document.getElementsByTagName("a")).filter( (bottom) => bottom.dataset.testid === "vertical-tab-Members" )[1]; - // eslint-disable-next-line @calcom/eslint/no-scroll-into-view-embed -- Settings layout isn't embedded tabMembers?.scrollIntoView({ behavior: "smooth" }); }, 100); } diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx index c161793e88..1dd209cb0b 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx @@ -2,9 +2,9 @@ import type { PageProps } from "app/_types"; import { getTranslate, _generateMetadata } from "app/_utils"; import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; +import { WebhookRepository } from "@calcom/features/webhooks/lib/repository/WebhookRepository"; import { EditWebhookView } from "@calcom/features/webhooks/pages/webhook-edit-view"; import { APP_NAME } from "@calcom/lib/constants"; -import { WebhookRepository } from "@calcom/features/webhooks/lib/repository/WebhookRepository"; export const generateMetadata = async ({ params }: { params: Promise<{ id: string }> }) => await _generateMetadata( diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/roles/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/roles/page.tsx index dcd08c327e..5b86ef0248 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/roles/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/roles/page.tsx @@ -1,7 +1,7 @@ import { _generateMetadata, getTranslate } from "app/_utils"; import { unstable_cache } from "next/cache"; -import { notFound } from "next/navigation"; import { revalidatePath } from "next/cache"; +import { notFound } from "next/navigation"; import type { AppFlags } from "@calcom/features/flags/config"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/teams/other/(main-page)/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/teams/other/(main-page)/page.tsx index 9160d5d47b..028a767e7e 100644 --- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/teams/other/(main-page)/page.tsx +++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/organizations/teams/other/(main-page)/page.tsx @@ -2,8 +2,8 @@ import { _generateMetadata, getTranslate } from "app/_utils"; import { redirect } from "next/navigation"; import { OtherTeamsListing } from "@calcom/features/ee/organizations/pages/components/OtherTeamsListing"; -import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader"; import { validateUserHasOrg } from "../../../actions/validateUserHasOrg"; diff --git a/apps/web/app/api/availability/calendar/route.ts b/apps/web/app/api/availability/calendar/route.ts index 2ac9b534e0..620cb1b0a3 100644 --- a/apps/web/app/api/availability/calendar/route.ts +++ b/apps/web/app/api/availability/calendar/route.ts @@ -6,11 +6,14 @@ import { z } from "zod"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { CalendarCache } from "@calcom/features/calendar-cache/calendar-cache"; -import { getCalendarCredentials, getConnectedCalendars } from "@calcom/features/calendars/lib/CalendarManager"; +import { + getCalendarCredentials, + getConnectedCalendars, +} from "@calcom/features/calendars/lib/CalendarManager"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { HttpError } from "@calcom/lib/http-error"; import notEmpty from "@calcom/lib/notEmpty"; import { SelectedCalendarRepository } from "@calcom/lib/server/repository/selectedCalendar"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import { buildLegacyRequest } from "@lib/buildLegacyCtx"; diff --git a/apps/web/app/api/cancel/route.ts b/apps/web/app/api/cancel/route.ts index c2eaabc8e5..a99ee46b73 100644 --- a/apps/web/app/api/cancel/route.ts +++ b/apps/web/app/api/cancel/route.ts @@ -13,7 +13,7 @@ async function handler(req: NextRequest) { let appDirRequestBody; try { appDirRequestBody = await req.json(); - } catch (error) { + } catch { return NextResponse.json({ success: false, message: "Invalid JSON" }, { status: 400 }); } const bookingData = bookingCancelWithCsrfSchema.parse(appDirRequestBody); diff --git a/apps/web/app/api/cron/calendar-subscriptions/route.ts b/apps/web/app/api/cron/calendar-subscriptions/route.ts index bd3e07fda6..61036eb7b4 100644 --- a/apps/web/app/api/cron/calendar-subscriptions/route.ts +++ b/apps/web/app/api/cron/calendar-subscriptions/route.ts @@ -1,6 +1,7 @@ import type { NextRequest } from "next/server"; import { NextResponse } from "next/server"; +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { DefaultAdapterFactory } from "@calcom/features/calendar-subscription/adapters/AdaptersFactory"; import { CalendarSubscriptionService } from "@calcom/features/calendar-subscription/lib/CalendarSubscriptionService"; import { CalendarCacheEventRepository } from "@calcom/features/calendar-subscription/lib/cache/CalendarCacheEventRepository"; @@ -8,7 +9,6 @@ import { CalendarCacheEventService } from "@calcom/features/calendar-subscriptio import { CalendarSyncService } from "@calcom/features/calendar-subscription/lib/sync/CalendarSyncService"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { SelectedCalendarRepository } from "@calcom/lib/server/repository/SelectedCalendarRepository"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { prisma } from "@calcom/prisma"; import { defaultResponderForAppDir } from "@calcom/web/app/api/defaultResponderForAppDir"; diff --git a/apps/web/app/api/cron/selected-calendars/route.ts b/apps/web/app/api/cron/selected-calendars/route.ts index 22a91932c4..77980294de 100644 --- a/apps/web/app/api/cron/selected-calendars/route.ts +++ b/apps/web/app/api/cron/selected-calendars/route.ts @@ -6,13 +6,13 @@ import type { NextRequest } from "next/server"; import { NextResponse } from "next/server"; -import GoogleCalendarService from "@calcom/app-store/googlecalendar/lib/CalendarService"; -import { CalendarAppDelegationCredentialInvalidGrantError } from "@calcom/lib/CalendarAppError"; import { findUniqueDelegationCalendarCredential } from "@calcom/app-store/delegationCredential"; +import GoogleCalendarService from "@calcom/app-store/googlecalendar/lib/CalendarService"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import { CalendarAppDelegationCredentialInvalidGrantError } from "@calcom/lib/CalendarAppError"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import { SelectedCalendarRepository } from "@calcom/lib/server/repository/selectedCalendar"; import type { CredentialForCalendarServiceWithEmail } from "@calcom/types/Credential"; import type { Ensure } from "@calcom/types/utils"; diff --git a/apps/web/app/api/recorded-daily-video/route.ts b/apps/web/app/api/recorded-daily-video/route.ts index c968a8eadb..8253835784 100644 --- a/apps/web/app/api/recorded-daily-video/route.ts +++ b/apps/web/app/api/recorded-daily-video/route.ts @@ -9,15 +9,15 @@ import { sendDailyVideoRecordingEmails, sendDailyVideoTranscriptEmails, } from "@calcom/emails/daily-video-emails"; +import { + getAllTranscriptsAccessLinkFromMeetingId, + submitBatchProcessorTranscriptionJob, +} from "@calcom/features/conferencing/lib/videoClient"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { - getAllTranscriptsAccessLinkFromMeetingId, - submitBatchProcessorTranscriptionJob, -} from "@calcom/features/conferencing/lib/videoClient"; import { generateVideoToken } from "@calcom/lib/videoTokens"; import prisma from "@calcom/prisma"; import { getBooking } from "@calcom/web/lib/daily-webhook/getBooking"; diff --git a/apps/web/app/api/support/conversation/route.ts b/apps/web/app/api/support/conversation/route.ts index 5df9f5fe3d..3718f5cc14 100644 --- a/apps/web/app/api/support/conversation/route.ts +++ b/apps/web/app/api/support/conversation/route.ts @@ -6,11 +6,11 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { BillingPlanService } from "@calcom/features/ee/billing/domain/billing-plans"; import type { Contact } from "@calcom/features/ee/support/lib/intercom/intercom"; import { intercom } from "@calcom/features/ee/support/lib/intercom/intercom"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import { buildLegacyRequest } from "@lib/buildLegacyCtx"; diff --git a/apps/web/app/api/webhooks/calendar-subscription/[provider]/route.ts b/apps/web/app/api/webhooks/calendar-subscription/[provider]/route.ts index 60abe54140..bc703c9ce1 100644 --- a/apps/web/app/api/webhooks/calendar-subscription/[provider]/route.ts +++ b/apps/web/app/api/webhooks/calendar-subscription/[provider]/route.ts @@ -2,6 +2,7 @@ import type { Params } from "app/_types"; import type { NextRequest } from "next/server"; import { NextResponse } from "next/server"; +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import type { CalendarSubscriptionProvider } from "@calcom/features/calendar-subscription/adapters/AdaptersFactory"; import { DefaultAdapterFactory } from "@calcom/features/calendar-subscription/adapters/AdaptersFactory"; import { CalendarSubscriptionService } from "@calcom/features/calendar-subscription/lib/CalendarSubscriptionService"; @@ -11,7 +12,6 @@ import { CalendarSyncService } from "@calcom/features/calendar-subscription/lib/ import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import logger from "@calcom/lib/logger"; import { SelectedCalendarRepository } from "@calcom/lib/server/repository/SelectedCalendarRepository"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { prisma } from "@calcom/prisma"; import { defaultResponderForAppDir } from "@calcom/web/app/api/defaultResponderForAppDir"; diff --git a/apps/web/app/api/webhooks/retell-ai/__tests__/route.test.ts b/apps/web/app/api/webhooks/retell-ai/__tests__/route.test.ts index 7d3d6d922a..a6dedcdf75 100644 --- a/apps/web/app/api/webhooks/retell-ai/__tests__/route.test.ts +++ b/apps/web/app/api/webhooks/retell-ai/__tests__/route.test.ts @@ -696,7 +696,15 @@ describe("Retell AI Webhook Handler", () => { describe("Web Call Tests", () => { const mockAgent: Pick< Agent, - "id" | "name" | "providerAgentId" | "enabled" | "userId" | "teamId" | "createdAt" | "updatedAt" | "inboundEventTypeId" + | "id" + | "name" + | "providerAgentId" + | "enabled" + | "userId" + | "teamId" + | "createdAt" + | "updatedAt" + | "inboundEventTypeId" > = { id: "agent-123", name: "Test Agent", diff --git a/apps/web/app/cache/membership.ts b/apps/web/app/cache/membership.ts index 9af484adde..112adfca32 100644 --- a/apps/web/app/cache/membership.ts +++ b/apps/web/app/cache/membership.ts @@ -2,8 +2,8 @@ import { revalidateTag, unstable_cache } from "next/cache"; -import { NEXTJS_CACHE_TTL } from "@calcom/lib/constants"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { NEXTJS_CACHE_TTL } from "@calcom/lib/constants"; const CACHE_TAGS = { HAS_TEAM_PLAN: "MembershipRepository.findFirstAcceptedMembershipByUserId", diff --git a/apps/web/components/apps/btcpayserver/BtcpayPaymentComponent.tsx b/apps/web/components/apps/btcpayserver/BtcpayPaymentComponent.tsx index 870c5e8c0b..e89db5fab3 100644 --- a/apps/web/components/apps/btcpayserver/BtcpayPaymentComponent.tsx +++ b/apps/web/components/apps/btcpayserver/BtcpayPaymentComponent.tsx @@ -3,8 +3,8 @@ import { useEffect, useState } from "react"; import z from "zod"; -import type { PaymentPageProps } from "@calcom/features/ee/payments/pages/payment"; import { useBookingSuccessRedirect } from "@calcom/features/bookings/lib/bookingSuccessRedirect"; +import type { PaymentPageProps } from "@calcom/features/ee/payments/pages/payment"; import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams"; import { useCopy } from "@calcom/lib/hooks/useCopy"; import { useLocale } from "@calcom/lib/hooks/useLocale"; diff --git a/apps/web/components/booking/bookingActions.ts b/apps/web/components/booking/bookingActions.ts index 96457a65da..ed482b8711 100644 --- a/apps/web/components/booking/bookingActions.ts +++ b/apps/web/components/booking/bookingActions.ts @@ -115,7 +115,9 @@ export function getEditEventActions(context: BookingActionContext): ActionType[] icon: "clock", label: t("reschedule_booking"), href: `/reschedule/${booking.uid}${ - booking.seatsReferences.length && isAttendee && seatReferenceUid ? `?seatReferenceUid=${seatReferenceUid}` : "" + booking.seatsReferences.length && isAttendee && seatReferenceUid + ? `?seatReferenceUid=${seatReferenceUid}` + : "" }`, disabled: (isBookingInPast && !booking.eventType.allowReschedulingPastBookings) || isDisabledRescheduling, diff --git a/apps/web/components/dialog/RerouteDialog.tsx b/apps/web/components/dialog/RerouteDialog.tsx index 6b0d39dd07..96d4e03b94 100644 --- a/apps/web/components/dialog/RerouteDialog.tsx +++ b/apps/web/components/dialog/RerouteDialog.tsx @@ -187,7 +187,7 @@ const useReroutingState = ({ isOpenDialog }: Pick { if (!value) return ReroutingStatusEnum.REROUTING_NOT_INITIATED; if (value.error) return ReroutingStatusEnum.REROUTING_FAILED; - if (!!value.newBooking) return ReroutingStatusEnum.REROUTING_COMPLETE; + if (value.newBooking) return ReroutingStatusEnum.REROUTING_COMPLETE; return ReroutingStatusEnum.REROUTING_IN_PROGRESS; })(); diff --git a/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts b/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts index 18630b9af8..aff5221966 100644 --- a/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts +++ b/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts @@ -6,10 +6,10 @@ import type { LocationObject } from "@calcom/app-store/locations"; import { isConferencing as isConferencingApp } from "@calcom/app-store/utils"; import { getLocale } from "@calcom/features/auth/lib/getLocale"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { AppOnboardingSteps } from "@calcom/lib/apps/appOnboardingSteps"; import { CAL_URL } from "@calcom/lib/constants"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import { eventTypeBookingFields } from "@calcom/prisma/zod-utils"; @@ -281,7 +281,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => id: user.id, name: user.name, avatarUrl: user.avatarUrl, - alreadyInstalled: appInstalls.some((install) => !Boolean(install.teamId) && install.userId === user.id), + alreadyInstalled: appInstalls.some((install) => !install.teamId && install.userId === user.id), }; const teamsWithIsAppInstalled = hasTeams diff --git a/apps/web/lib/apps/routing-forms/[...pages]/getServerSidePropsSingleForm.ts b/apps/web/lib/apps/routing-forms/[...pages]/getServerSidePropsSingleForm.ts index 49a5c60fdb..75b19fe15d 100644 --- a/apps/web/lib/apps/routing-forms/[...pages]/getServerSidePropsSingleForm.ts +++ b/apps/web/lib/apps/routing-forms/[...pages]/getServerSidePropsSingleForm.ts @@ -1,8 +1,8 @@ import { enrichFormWithMigrationData } from "@calcom/app-store/routing-forms/enrichFormWithMigrationData"; import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { Resource } from "@calcom/features/pbac/domain/types/permission-registry"; import { getResourcePermissions } from "@calcom/features/pbac/lib/resource-permissions"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { MembershipRole } from "@calcom/prisma/enums"; import type { AppGetServerSidePropsContext, AppPrisma, AppUser } from "@calcom/types/AppGetServerSideProps"; diff --git a/apps/web/lib/org/[orgSlug]/instant-meeting/team/[slug]/[type]/getServerSideProps.ts b/apps/web/lib/org/[orgSlug]/instant-meeting/team/[slug]/[type]/getServerSideProps.ts index 52836d898d..23a5164a2c 100644 --- a/apps/web/lib/org/[orgSlug]/instant-meeting/team/[slug]/[type]/getServerSideProps.ts +++ b/apps/web/lib/org/[orgSlug]/instant-meeting/team/[slug]/[type]/getServerSideProps.ts @@ -5,8 +5,8 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { getMultipleDurationValue } from "@calcom/features/bookings/lib/get-booking"; import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; -import { shouldHideBrandingForTeamEvent } from "@calcom/features/profile/lib/hideBranding"; import { EventRepository } from "@calcom/features/eventtypes/repositories/EventRepository"; +import { shouldHideBrandingForTeamEvent } from "@calcom/features/profile/lib/hideBranding"; import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; diff --git a/apps/web/lib/pages/auth/verify-email.ts b/apps/web/lib/pages/auth/verify-email.ts index f2685246bf..f204688889 100644 --- a/apps/web/lib/pages/auth/verify-email.ts +++ b/apps/web/lib/pages/auth/verify-email.ts @@ -2,10 +2,10 @@ import type { NextApiRequest, NextApiResponse } from "next"; import { z } from "zod"; import dayjs from "@calcom/dayjs"; +import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { IS_STRIPE_ENABLED } from "@calcom/lib/constants"; -import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; import { CreationSource } from "@calcom/prisma/enums"; diff --git a/apps/web/lib/team/[slug]/getServerSideProps.tsx b/apps/web/lib/team/[slug]/getServerSideProps.tsx index 96ca6d30f0..e2c7d71c95 100644 --- a/apps/web/lib/team/[slug]/getServerSideProps.tsx +++ b/apps/web/lib/team/[slug]/getServerSideProps.tsx @@ -1,5 +1,6 @@ import type { GetServerSidePropsContext } from "next"; +import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; import { getOrganizationSettings, @@ -9,7 +10,6 @@ import { getTeamWithMembers } from "@calcom/features/ee/teams/lib/queries"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { IS_CALCOM } from "@calcom/lib/constants"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; -import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import logger from "@calcom/lib/logger"; import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; import slugify from "@calcom/lib/slugify"; diff --git a/apps/web/lib/video/[uid]/getServerSideProps.ts b/apps/web/lib/video/[uid]/getServerSideProps.ts index 4fdcc2caf3..a7f5b6b09e 100644 --- a/apps/web/lib/video/[uid]/getServerSideProps.ts +++ b/apps/web/lib/video/[uid]/getServerSideProps.ts @@ -7,14 +7,14 @@ import { updateMeetingTokenIfExpired, } from "@calcom/app-store/dailyvideo/lib/VideoApiAdapter"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { getCalVideoReference } from "@calcom/features/get-cal-video-reference"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { CAL_VIDEO_MEETING_LINK_FOR_TESTING } from "@calcom/lib/constants"; import { isENVDev } from "@calcom/lib/env"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; -import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; import prisma from "@calcom/prisma"; const md = new MarkdownIt("default", { html: true, breaks: true, linkify: true }); @@ -210,7 +210,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { exp: epochTimeFourteenDaysAfter, }); - const sessionUserId = !!session?.user?.impersonatedBy ? session.user.impersonatedBy.id : session?.user.id; + const sessionUserId = session?.user?.impersonatedBy ? session.user.impersonatedBy.id : session?.user.id; const isOrganizer = await checkIfUserIsHost({ booking: { eventTypeId: bookingObj.eventType?.id, @@ -238,7 +238,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { videoReferencePassword, sessionUserId ); - if (!!meetingPassword) { + if (meetingPassword) { bookingObj.references.forEach((bookRef) => { bookRef.meetingPassword = meetingPassword; }); diff --git a/apps/web/modules/apps/installation/[[...step]]/step-view.tsx b/apps/web/modules/apps/installation/[[...step]]/step-view.tsx index dfd8121369..76acc80eea 100644 --- a/apps/web/modules/apps/installation/[[...step]]/step-view.tsx +++ b/apps/web/modules/apps/installation/[[...step]]/step-view.tsx @@ -8,6 +8,7 @@ import type { z } from "zod"; import checkForMultiplePaymentApps from "@calcom/app-store/_utils/payments/checkForMultiplePaymentApps"; import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation"; +import type { LocationObject } from "@calcom/app-store/locations"; import type { EventTypeAppSettingsComponentProps, EventTypeModel } from "@calcom/app-store/types"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; import type { LocationFormValues } from "@calcom/features/eventtypes/lib/types"; @@ -15,7 +16,6 @@ import { AppOnboardingSteps } from "@calcom/lib/apps/appOnboardingSteps"; import { getAppOnboardingUrl } from "@calcom/lib/apps/getAppOnboardingUrl"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; -import type { LocationObject } from "@calcom/app-store/locations"; import type { Team } from "@calcom/prisma/client"; import type { eventTypeBookingFields } from "@calcom/prisma/zod-utils"; import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; @@ -309,21 +309,20 @@ const OnboardingPage = ({ handleSetUpLater={handleSetUpLater} /> )} - {currentStep === AppOnboardingSteps.CONFIGURE_STEP && - eventTypeGroups && ( - - )} + {currentStep === AppOnboardingSteps.CONFIGURE_STEP && eventTypeGroups && ( + + )}
diff --git a/apps/web/modules/bookings/views/bookings-single-view.tsx b/apps/web/modules/bookings/views/bookings-single-view.tsx index 6eb21c2e23..12444cc4ba 100644 --- a/apps/web/modules/bookings/views/bookings-single-view.tsx +++ b/apps/web/modules/bookings/views/bookings-single-view.tsx @@ -24,13 +24,9 @@ import { import { Price } from "@calcom/features/bookings/components/event-meta/Price"; import { getCalendarLinks, CalendarLinkType } from "@calcom/features/bookings/lib/getCalendarLinks"; import { RATING_OPTIONS, validateRating } from "@calcom/features/bookings/lib/rating"; -import { - SMS_REMINDER_NUMBER_FIELD, - SystemField, - TITLE_FIELD, -} from "@calcom/lib/bookings/SystemField"; import type { nameObjectSchema } from "@calcom/features/eventtypes/lib/eventNaming"; import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming"; +import { SMS_REMINDER_NUMBER_FIELD, SystemField, TITLE_FIELD } from "@calcom/lib/bookings/SystemField"; import { APP_NAME } from "@calcom/lib/constants"; import { formatToLocalizedDate, formatToLocalizedTime, formatToLocalizedTimezone } from "@calcom/lib/dayjs"; import useGetBrandingColours from "@calcom/lib/getBrandColours"; @@ -771,7 +767,6 @@ export default function Success(props: PageProps) {
+ href="https://cal.com/blog/google-s-new-spam-policy-may-be-affecting-your-invitations" + rel="noreferrer"> {t("resolve")} diff --git a/apps/web/modules/signup-view.tsx b/apps/web/modules/signup-view.tsx index 712bbfec84..487f1581cb 100644 --- a/apps/web/modules/signup-view.tsx +++ b/apps/web/modules/signup-view.tsx @@ -274,7 +274,7 @@ export default function Signup({ }; const constructCallBackIfUrlNotPresent = () => { - if (!!isPlatformUser) { + if (isPlatformUser) { return `${WEBAPP_URL}/${gettingStartedWithPlatform}?from=signup`; } @@ -284,7 +284,7 @@ export default function Signup({ const constructCallBackUrl = () => { const callbackUrlSearchParams = searchParams?.get("callbackUrl"); - return !!callbackUrlSearchParams + return callbackUrlSearchParams ? constructCallBackIfUrlPresent() : constructCallBackIfUrlNotPresent(); }; diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 5e4eb4283f..ab1238288b 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -405,7 +405,7 @@ const nextConfig = (phase) => { }, */ ]; - if (Boolean(process.env.NEXT_PUBLIC_API_V2_URL)) { + if (process.env.NEXT_PUBLIC_API_V2_URL) { afterFiles.push({ source: "/api/v2/:path*", destination: `${process.env.NEXT_PUBLIC_API_V2_URL}/:path*`, diff --git a/apps/web/pages/api/book/event.ts b/apps/web/pages/api/book/event.ts index 85a7480771..7f5aa63d87 100644 --- a/apps/web/pages/api/book/event.ts +++ b/apps/web/pages/api/book/event.ts @@ -3,13 +3,13 @@ import type { NextApiRequest } from "next"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { getRegularBookingService } from "@calcom/features/bookings/di/RegularBookingService.container"; import { BotDetectionService } from "@calcom/features/bot-detection"; +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import getIP from "@calcom/lib/getIP"; import { piiHasher } from "@calcom/lib/server/PiiHasher"; import { checkCfTurnstileToken } from "@calcom/lib/server/checkCfTurnstileToken"; import { defaultResponder } from "@calcom/lib/server/defaultResponder"; -import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import prisma from "@calcom/prisma"; import { CreationSource } from "@calcom/prisma/enums"; diff --git a/apps/web/playwright/cancellation-fee-warning.e2e.ts b/apps/web/playwright/cancellation-fee-warning.e2e.ts index 17fc152d1c..239944f8ea 100644 --- a/apps/web/playwright/cancellation-fee-warning.e2e.ts +++ b/apps/web/playwright/cancellation-fee-warning.e2e.ts @@ -1,6 +1,6 @@ import { expect } from "@playwright/test"; -import type Prisma from "@calcom/prisma/client"; +import type { EventType } from "@calcom/prisma/client"; import { test } from "./lib/fixtures"; import { IS_STRIPE_ENABLED, selectFirstAvailableTimeSlotNextMonth } from "./lib/testUtils"; @@ -13,7 +13,7 @@ test.describe("Cancellation Fee Warning E2E", () => { // eslint-disable-next-line playwright/no-skipped-test test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed"); const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -41,7 +41,7 @@ test.describe("Cancellation Fee Warning E2E", () => { // eslint-disable-next-line playwright/no-skipped-test test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed"); const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -69,7 +69,7 @@ test.describe("Cancellation Fee Warning E2E", () => { // eslint-disable-next-line playwright/no-skipped-test test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed"); const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); diff --git a/apps/web/playwright/fixtures/users.ts b/apps/web/playwright/fixtures/users.ts index 67584a7cb5..c173994c49 100644 --- a/apps/web/playwright/fixtures/users.ts +++ b/apps/web/playwright/fixtures/users.ts @@ -6,13 +6,12 @@ import { v4 } from "uuid"; import updateChildrenEventTypes from "@calcom/features/ee/managed-event-types/lib/handleChildrenEventTypes"; import stripe from "@calcom/features/ee/payments/server/stripe"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/availability"; import { WEBAPP_URL } from "@calcom/lib/constants"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { prisma } from "@calcom/prisma"; -import type Prisma from "@calcom/prisma/client"; import type { Team } from "@calcom/prisma/client"; -import type { Prisma as PrismaType } from "@calcom/prisma/client"; +import type { Prisma, User, EventType } from "@calcom/prisma/client"; import { MembershipRole, SchedulingType, TimeUnit, WorkflowTriggerEvents } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; import type { Schedule } from "@calcom/types/schedule"; @@ -37,7 +36,7 @@ const userIncludes = { workflows: true, credentials: true, routingForms: true, -} satisfies PrismaType.UserInclude; +} satisfies Prisma.UserInclude; type InstallStripeParamsSkipTrue = { eventTypeIds?: number[]; @@ -63,16 +62,11 @@ type InstallStripeParams = InstallStripeParamsUnion & { page: Page; }; -const userWithEventTypes = { +const _userWithEventTypes = { include: userIncludes, -} satisfies PrismaType.UserDefaultArgs; +} satisfies Prisma.UserDefaultArgs; -const seededForm = { - id: "948ae412-d995-4865-875a-48302588de03", - name: "Seeded Form - Pro", -}; - -type UserWithIncludes = PrismaType.UserGetPayload; +type UserWithIncludes = Prisma.UserGetPayload; const createTeamWorkflow = async (user: { id: number }, team: { id: number }) => { return await prisma.workflow.create({ @@ -182,7 +176,7 @@ const createTeamAndAddUser = async ( teamSlug ?? orgRequestedSlug ?? `${isOrg ? "org" : "team"}-${workerInfo.workerIndex}-${Date.now()}${slugIndex}`; - const data: PrismaType.TeamCreateInput = { + const data: Prisma.TeamCreateInput = { name: `user-id-${user.id}'s ${isOrg ? "Org" : "Team"}`, isOrganization: isOrg, }; @@ -471,7 +465,7 @@ export const createUsersFixture = ( }, data: { orgProfiles: _user.profiles.length - ? { + ? { connect: _user.profiles.map((profile) => ({ id: profile.id })), } : { @@ -654,7 +648,6 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => { // self is a reflective method that return the Prisma object that references this fixture. const self = async () => - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (await prisma.user.findUnique({ where: { id: store.user.id }, include: { eventTypes: true }, @@ -791,9 +784,9 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => { }, }); }, - setupEventWithPrice: async (eventType: Pick, slug: string) => + setupEventWithPrice: async (eventType: Pick, slug: string) => setupEventWithPrice(eventType, slug, store.page), - bookAndPayEvent: async (eventType: Pick) => + bookAndPayEvent: async (eventType: Pick) => bookAndPayEvent(user, eventType, store.page), makePaymentUsingStripe: async () => makePaymentUsingStripe(store.page), installStripePersonal: async (params: InstallStripeParamsUnion) => @@ -819,11 +812,11 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => { }; }; -type SupportedTestEventTypes = PrismaType.EventTypeCreateInput & { - _bookings?: PrismaType.BookingCreateInput[]; +type SupportedTestEventTypes = Prisma.EventTypeCreateInput & { + _bookings?: Prisma.BookingCreateInput[]; }; -type SupportedTestWorkflows = PrismaType.WorkflowCreateInput; +type SupportedTestWorkflows = Prisma.WorkflowCreateInput; type CustomUserOptsKeys = | "username" @@ -836,7 +829,7 @@ type CustomUserOptsKeys = | "disableImpersonation" | "role" | "identityProvider"; -type CustomUserOpts = Partial> & { +type CustomUserOpts = Partial> & { timeZone?: TimeZoneEnum; eventTypes?: SupportedTestEventTypes[]; workflows?: SupportedTestWorkflows[]; @@ -857,7 +850,7 @@ const createUser = ( organizationId?: number | null; }) | null -): PrismaType.UserUncheckedCreateInput => { +): Prisma.UserUncheckedCreateInput => { const suffixToMakeUsernameUnique = `-${workerInfo.workerIndex}-${Date.now()}`; // build a unique name for our user const uname = @@ -983,7 +976,7 @@ async function confirmPendingPayment(page: Page) { // login using a replay of an E2E routine. export async function login( - user: Pick & Partial> & { password?: string | null }, + user: Pick & Partial> & { password?: string | null }, page: Page ) { // get locators @@ -997,7 +990,7 @@ export async function login( await page.waitForSelector("text=Welcome back"); await emailLocator.fill(user.email ?? `${user.username}@example.com`); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await passwordLocator.fill(user.password ?? user.username!); // waiting for specific login request to resolve @@ -1007,7 +1000,7 @@ export async function login( } export async function apiLogin( - user: Pick & Partial> & { password: string | null }, + user: Pick & Partial> & { password: string | null }, page: Page, navigateToUrl?: string ) { @@ -1047,14 +1040,14 @@ export async function apiLogin( // Only wait if we're on a protected page that would trigger the session API call try { await page.waitForResponse("/api/auth/session", { timeout: 2000 }); - } catch (error) { + } catch { // Session API call not made (likely on a public page), continue anyway } return response; } -export async function setupEventWithPrice(eventType: Pick, slug: string, page: Page) { +export async function setupEventWithPrice(eventType: Pick, slug: string, page: Page) { await page.goto(`/event-types/${eventType?.id}?tabName=apps`); await page.locator(`[data-testid='${slug}-app-switch']`).first().click(); await page.getByPlaceholder("Price").fill("100"); @@ -1062,8 +1055,8 @@ export async function setupEventWithPrice(eventType: Pick, - eventType: Pick, + user: Pick, + eventType: Pick, page: Page ) { // booking process with stripe integration diff --git a/apps/web/playwright/integrations-stripe.e2e.ts b/apps/web/playwright/integrations-stripe.e2e.ts index df6fa114b5..578ba3dd90 100644 --- a/apps/web/playwright/integrations-stripe.e2e.ts +++ b/apps/web/playwright/integrations-stripe.e2e.ts @@ -2,7 +2,7 @@ import { expect } from "@playwright/test"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; import prisma from "@calcom/prisma"; -import type Prisma from "@calcom/prisma/client"; +import type { EventType } from "@calcom/prisma/client"; import { SchedulingType } from "@calcom/prisma/enums"; import { test, todo } from "./lib/fixtures"; @@ -35,7 +35,7 @@ test.describe("Stripe integration skip true", () => { await user.installStripePersonal({ skip: true }); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.setupEventWithPrice(eventType, "stripe"); // Need to wait for the DB to be updated with the metadata @@ -102,7 +102,7 @@ test.describe("Stripe integration skip true", () => { }); test("Can book a paid booking", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -115,7 +115,7 @@ test.describe("Stripe integration skip true", () => { test("Pending payment booking should not be confirmed by default", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -139,7 +139,7 @@ test.describe("Stripe integration skip true", () => { test("Paid booking should be able to be rescheduled", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -162,7 +162,7 @@ test.describe("Stripe integration skip true", () => { test("Paid booking should be able to be cancelled", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -178,11 +178,11 @@ test.describe("Stripe integration skip true", () => { test.describe("When event is paid and confirmed", () => { let user: Awaited>; - let eventType: Prisma.EventType; + let eventType: EventType; test.beforeEach(async ({ page, users }) => { user = await users.create(); - eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -217,7 +217,7 @@ test.describe("Stripe integration skip true", () => { test.describe("Change stripe presented currency", () => { test("Should be able to change currency", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await user.installStripePersonal({ skip: true }); @@ -337,7 +337,7 @@ test.describe("Stripe integration with the new app install flow skip false", () }); test("Can book a paid booking skip false", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -348,7 +348,7 @@ test.describe("Stripe integration with the new app install flow skip false", () }); test("Pending payment booking should not be confirmed by default skip false", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -371,7 +371,7 @@ test.describe("Stripe integration with the new app install flow skip false", () test("Paid booking should be able to be rescheduled skip false", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -393,7 +393,7 @@ test.describe("Stripe integration with the new app install flow skip false", () test("Paid booking should be able to be cancelled skip false", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -408,11 +408,11 @@ test.describe("Stripe integration with the new app install flow skip false", () test.describe("When event is paid and confirmed skip false", () => { let user: Awaited>; - let eventType: Prisma.EventType; + let eventType: EventType; test.beforeEach(async ({ page, users }) => { user = await users.create(); - eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/installed"); @@ -449,7 +449,7 @@ test.describe("Stripe integration with the new app install flow skip false", () test.describe("Change stripe presented currency skip false", () => { test("Should be able to change currency skip false", async ({ page, users }) => { const user = await users.create(); - const eventType = user.eventTypes.find((e) => e.slug === "paid") as Prisma.EventType; + const eventType = user.eventTypes.find((e) => e.slug === "paid") as EventType; await user.apiLogin(); await page.goto("/apps/stripe"); diff --git a/apps/web/server/lib/[user]/[type]/getServerSideProps.ts b/apps/web/server/lib/[user]/[type]/getServerSideProps.ts index ac3a14eeb6..2923b8674a 100644 --- a/apps/web/server/lib/[user]/[type]/getServerSideProps.ts +++ b/apps/web/server/lib/[user]/[type]/getServerSideProps.ts @@ -6,10 +6,10 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking"; import { getBookingForReschedule, getBookingForSeatedEvent } from "@calcom/features/bookings/lib/get-booking"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; -import type { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEvent"; import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; -import { shouldHideBrandingForUserEvent } from "@calcom/features/profile/lib/hideBranding"; +import type { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEvent"; import { EventRepository } from "@calcom/features/eventtypes/repositories/EventRepository"; +import { shouldHideBrandingForUserEvent } from "@calcom/features/profile/lib/hideBranding"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import slugify from "@calcom/lib/slugify"; import { prisma } from "@calcom/prisma"; diff --git a/apps/web/server/lib/auth/sso/[provider]/getServerSideProps.tsx b/apps/web/server/lib/auth/sso/[provider]/getServerSideProps.tsx index 857bbd69f1..2f84a5df34 100644 --- a/apps/web/server/lib/auth/sso/[provider]/getServerSideProps.tsx +++ b/apps/web/server/lib/auth/sso/[provider]/getServerSideProps.tsx @@ -6,8 +6,8 @@ import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomain import stripe from "@calcom/features/ee/payments/server/stripe"; import { hostedCal, isSAMLLoginEnabled, samlProductID, samlTenantID } from "@calcom/features/ee/sso/lib/saml"; import { ssoTenantProduct } from "@calcom/features/ee/sso/lib/sso"; -import { IS_PREMIUM_USERNAME_ENABLED } from "@calcom/lib/constants"; import { checkUsername } from "@calcom/features/profile/lib/checkUsername"; +import { IS_PREMIUM_USERNAME_ENABLED } from "@calcom/lib/constants"; import prisma from "@calcom/prisma"; import { asStringOrNull } from "@lib/asStringOrNull"; diff --git a/apps/web/test/lib/checkDurationLimits.test.ts b/apps/web/test/lib/checkDurationLimits.test.ts index f55f32bec1..2d2c435558 100644 --- a/apps/web/test/lib/checkDurationLimits.test.ts +++ b/apps/web/test/lib/checkDurationLimits.test.ts @@ -1,10 +1,7 @@ import { describe, expect, it, vi } from "vitest"; import dayjs from "@calcom/dayjs"; -import { - checkDurationLimit, - checkDurationLimits, -} from "@calcom/features/bookings/lib/checkDurationLimits"; +import { checkDurationLimit, checkDurationLimits } from "@calcom/features/bookings/lib/checkDurationLimits"; import { validateIntervalLimitOrder } from "@calcom/lib/intervalLimits/validateIntervalLimitOrder"; const mockGetTotalBookingDuration = vi.fn(); diff --git a/apps/web/test/lib/handleChildrenEventTypes.test.ts b/apps/web/test/lib/handleChildrenEventTypes.test.ts index f53459e734..a48a42c678 100644 --- a/apps/web/test/lib/handleChildrenEventTypes.test.ts +++ b/apps/web/test/lib/handleChildrenEventTypes.test.ts @@ -423,7 +423,7 @@ describe("handleChildrenEventTypes", () => { timeZone: _timeZone, parentId: _parentId, userId: _userId, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + requiresBookerEmailVerification, lockTimeZoneToggleOnBookingPage, useEventTypeDestinationCalendarEmail, diff --git a/apps/web/test/utils/bookingScenario/bookingScenario.ts b/apps/web/test/utils/bookingScenario/bookingScenario.ts index ea8927f62f..ad5428a659 100644 --- a/apps/web/test/utils/bookingScenario/bookingScenario.ts +++ b/apps/web/test/utils/bookingScenario/bookingScenario.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import i18nMock from "../../../../../tests/libs/__mocks__/libServerI18n"; import prismock from "../../../../../tests/libs/__mocks__/prisma"; @@ -118,17 +119,6 @@ type InputWorkflow = { verifiedAt?: Date; }; -type PaymentData = { - // Common payment data fields based on Stripe and other payment providers - paymentIntent?: string; - paymentMethodId?: string; - clientSecret?: string; - customerId?: string; - subscriptionId?: string; - metadata?: Record; - [key: string]: unknown; // Allow additional provider-specific fields -}; - type InputPayment = { id?: number; uid: string; @@ -139,7 +129,7 @@ type InputPayment = { currency: string; success: boolean; refunded: boolean; - data: PaymentData; + data: Prisma.InputJsonValue; externalId: string; paymentOption?: PaymentOption; }; @@ -580,7 +570,7 @@ export async function addEventTypes(eventTypes: InputEventType[], usersStore: In }; }); log.silly("TestData: Creating EventType", JSON.stringify(eventTypesWithUsers)); - // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Pretty complex type here + return await addEventTypesToDb(eventTypesWithUsers as unknown as any); } @@ -592,7 +582,6 @@ function addBookingReferencesToDB(bookingReferences: Prisma.BookingReferenceCrea async function addBookingsToDb( bookings: (Prisma.BookingCreateInput & { - // eslint-disable-next-line @typescript-eslint/no-explicit-any references: any[]; user?: { id: number }; })[] @@ -700,7 +689,6 @@ export async function addBookings(bookings: InputBooking[]) { ); } -// eslint-disable-next-line @typescript-eslint/no-explicit-any async function addWebhooksToDb(webhooks: any[]) { await prismock.webhook.createMany({ data: webhooks, @@ -993,7 +981,6 @@ export async function addUsers(users: InputUser[]) { return await addUsersToDb(prismaUsersCreate); } -// eslint-disable-next-line @typescript-eslint/no-explicit-any async function addAppsToDb(apps: any[]) { log.silly("TestData: Creating Apps", JSON.stringify({ apps })); await prismock.app.createMany({ @@ -1060,7 +1047,6 @@ export async function createOrganization(orgData: { slug: string; metadata?: z.infer; withTeam?: boolean; - // eslint-disable-next-line @typescript-eslint/no-explicit-any }): Promise; children: any }> { const org = await prismock.team.create({ data: { @@ -1099,7 +1085,7 @@ export async function createOrganization(orgData: { export async function createCredentials( credentialData: { type: string; - key: Prisma.JsonValue; + key: Prisma.InputJsonValue; id?: number; userId?: number | null; teamId?: number | null; @@ -2061,11 +2047,11 @@ export function mockVideoApp({ url: `http://mock-${metadataLookupKey}.example.com`, }; log.silly("mockVideoApp", JSON.stringify({ metadataLookupKey, appStoreLookupKey })); - // eslint-disable-next-line @typescript-eslint/no-explicit-any + const createMeetingCalls: any[] = []; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + const updateMeetingCalls: any[] = []; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + const deleteMeetingCalls: any[] = []; const mockVideoAdapter = (credential: unknown) => { @@ -2314,7 +2300,7 @@ export function getExpectedCalEventForBookingRequest({ eventType, }: { bookingRequest: ReturnType; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + eventType: any; }) { return { @@ -2541,7 +2527,7 @@ export const createDelegationCredential = async (orgId: number, type: "google" | id: orgId, }, }, - serviceAccountKey: workspace.defaultServiceAccountKey, + serviceAccountKey: workspace.defaultServiceAccountKey as unknown as Prisma.InputJsonValue, }, }); @@ -2583,7 +2569,7 @@ export const createDelegationCredential = async (orgId: number, type: "google" | id: orgId, }, }, - serviceAccountKey: workspace.defaultServiceAccountKey, + serviceAccountKey: workspace.defaultServiceAccountKey as unknown as Prisma.InputJsonValue, }, }); @@ -2592,7 +2578,6 @@ export const createDelegationCredential = async (orgId: number, type: "google" | throw new Error(`Unsupported type: ${type}`); }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any export const buildDelegationCredential = ({ serviceAccountKey }: { serviceAccountKey: any }) => { return { id: -1, diff --git a/package.json b/package.json index 28c07378cb..8b5f9f12a9 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "@faker-js/faker": "9.2.0", "@jetstreamapp/soql-parser-js": "^6.1.0", "@playwright/test": "^1.45.3", + "@prisma/internals": "^6.16.2", "@snaplet/copycat": "^4.1.0", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^16.0.1", diff --git a/packages/app-store/_appRegistry.ts b/packages/app-store/_appRegistry.ts index 314f80f448..109d4cd78d 100644 --- a/packages/app-store/_appRegistry.ts +++ b/packages/app-store/_appRegistry.ts @@ -1,8 +1,8 @@ import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData"; -import { getAppFromSlug } from "@calcom/app-store/utils"; import { getAllDelegationCredentialsForUser } from "@calcom/app-store/delegationCredential"; -import getInstallCountPerApp from "@calcom/lib/apps/getInstallCountPerApp"; +import { getAppFromSlug } from "@calcom/app-store/utils"; import type { UserAdminTeams } from "@calcom/features/users/repositories/UserRepository"; +import getInstallCountPerApp from "@calcom/lib/apps/getInstallCountPerApp"; import prisma, { safeAppSelect, safeCredentialSelect } from "@calcom/prisma"; import { userMetadata } from "@calcom/prisma/zod-utils"; import type { AppFrontendPayload as App } from "@calcom/types/App"; diff --git a/packages/app-store/_utils/installation.ts b/packages/app-store/_utils/installation.ts index 611155c637..96c4157d1c 100644 --- a/packages/app-store/_utils/installation.ts +++ b/packages/app-store/_utils/installation.ts @@ -1,5 +1,5 @@ -import { HttpError } from "@calcom/lib/http-error"; import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import { HttpError } from "@calcom/lib/http-error"; import prisma from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { UserProfile } from "@calcom/types/UserProfile"; diff --git a/packages/app-store/_utils/oauth/getCurrentTokenObject.ts b/packages/app-store/_utils/oauth/getCurrentTokenObject.ts index a19095f64d..419b622099 100644 --- a/packages/app-store/_utils/oauth/getCurrentTokenObject.ts +++ b/packages/app-store/_utils/oauth/getCurrentTokenObject.ts @@ -1,6 +1,6 @@ +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import { isInMemoryDelegationCredential } from "@calcom/lib/delegationCredential"; import logger from "@calcom/lib/logger"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import type { CredentialForCalendarService } from "@calcom/types/Credential"; import { getTokenObjectFromCredential } from "./getTokenObjectFromCredential"; diff --git a/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts b/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts index 7a70232c82..f21265e884 100644 --- a/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts +++ b/packages/app-store/_utils/oauth/updateProfilePhotoGoogle.ts @@ -1,9 +1,9 @@ import { oauth2_v2 } from "@googleapis/oauth2"; import type { OAuth2Client } from "googleapis-common"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; import { uploadAvatar } from "@calcom/lib/server/avatar"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { resizeBase64Image } from "@calcom/lib/server/resizeBase64Image"; import prisma from "@calcom/prisma"; diff --git a/packages/app-store/_utils/oauth/updateTokenObject.ts b/packages/app-store/_utils/oauth/updateTokenObject.ts index 2ca29cd597..906fc84ddb 100644 --- a/packages/app-store/_utils/oauth/updateTokenObject.ts +++ b/packages/app-store/_utils/oauth/updateTokenObject.ts @@ -1,7 +1,7 @@ import type z from "zod"; -import logger from "@calcom/lib/logger"; import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import logger from "@calcom/lib/logger"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; diff --git a/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.test.ts b/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.test.ts index 6310626a02..8d04bd7faa 100644 --- a/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.test.ts +++ b/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.test.ts @@ -1,12 +1,12 @@ import type { BaseWidget } from "react-awesome-query-builder"; import { describe, it, expect, vi, beforeEach } from "vitest"; -import { RouteActionType } from "@calcom/app-store/routing-forms/zod"; -import { RaqbLogicResult } from "@calcom/lib/raqb/evaluateRaqbLogic"; import { findTeamMembersMatchingAttributeLogic, TroubleshooterCase, } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; +import { RouteActionType } from "@calcom/app-store/routing-forms/zod"; +import { RaqbLogicResult } from "@calcom/lib/raqb/evaluateRaqbLogic"; import * as getAttributesModule from "@calcom/lib/service/attribute/server/getAttributes"; import type { AttributeType } from "@calcom/prisma/enums"; import { RoutingFormFieldType } from "@calcom/routing-forms/lib/FieldTypes"; @@ -64,13 +64,13 @@ function mockAttributesScenario({ Object.entries(member.attributes).map(([attributeId, value]) => { return [ attributeId, - + { attributeOption: value instanceof Array ? value.map((value) => ({ value, isGroup: false, contains: [] })) : { value, isGroup: false, contains: [] }, - + type: attributes.find((attribute) => attribute.id === attributeId)!.type, }, ]; diff --git a/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.ts b/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.ts index 15de66d9ff..c306b30580 100644 --- a/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.ts +++ b/packages/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic.ts @@ -159,7 +159,7 @@ async function getLogicResultForAllMembers( attributesQueryValue, }); attributesDataPerUser.set(member.userId, attributesData); - const result = !!jsonLogic.apply(attributeJsonLogic as any, attributesData) + const result = jsonLogic.apply(attributeJsonLogic as any, attributesData) ? RaqbLogicResult.MATCH : RaqbLogicResult.NO_MATCH; diff --git a/packages/app-store/_utils/raqb/raqbUtils.test.ts b/packages/app-store/_utils/raqb/raqbUtils.test.ts index 98d4c5005d..e56f60d609 100644 --- a/packages/app-store/_utils/raqb/raqbUtils.test.ts +++ b/packages/app-store/_utils/raqb/raqbUtils.test.ts @@ -93,7 +93,7 @@ const createComplexQueryValue = ({ }>; }): AttributesQueryValue => { const children1: Record = {}; - + rules.forEach((rule) => { children1[rule.ruleId] = createQueryValueRule({ type: "rule", diff --git a/packages/app-store/_utils/throwIfNotHaveAdminAccessToTeam.ts b/packages/app-store/_utils/throwIfNotHaveAdminAccessToTeam.ts index 3313029e17..f02193023b 100644 --- a/packages/app-store/_utils/throwIfNotHaveAdminAccessToTeam.ts +++ b/packages/app-store/_utils/throwIfNotHaveAdminAccessToTeam.ts @@ -1,5 +1,5 @@ -import { HttpError } from "@calcom/lib/http-error"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { HttpError } from "@calcom/lib/http-error"; import prisma from "@calcom/prisma"; export const throwIfNotHaveAdminAccessToTeam = async ({ diff --git a/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts b/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts index 79c7b187c2..a82104a996 100644 --- a/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts +++ b/packages/app-store/dailyvideo/lib/VideoApiAdapter.ts @@ -172,7 +172,7 @@ export const updateMeetingTokenIfExpired = async ({ try { await fetcher(`/meeting-tokens/${meetingToken}`).then(ZGetMeetingTokenResponseSchema.parse); - } catch (err) { + } catch { const organizerMeetingToken = await postToDailyAPI("/meeting-tokens", { properties: { room_name: roomName, @@ -426,7 +426,7 @@ const DailyVideoApiAdapter = (): VideoApiAdapter => { getRecordingsResponseSchema.parse ); return Promise.resolve(res); - } catch (err) { + } catch { throw new Error("Something went wrong! Unable to get recording"); } }, diff --git a/packages/app-store/delegationCredential.ts b/packages/app-store/delegationCredential.ts index b0bdefb1bf..4b984641db 100644 --- a/packages/app-store/delegationCredential.ts +++ b/packages/app-store/delegationCredential.ts @@ -3,6 +3,10 @@ import { metadata as googleCalendarMetadata } from "@calcom/app-store/googlecale import { metadata as googleMeetMetadata } from "@calcom/app-store/googlevideo/_metadata"; import { metadata as office365CalendarMetaData } from "@calcom/app-store/office365calendar/_metadata"; import { metadata as office365VideoMetaData } from "@calcom/app-store/office365video/_metadata"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import type { ServiceAccountKey } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; +import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { buildNonDelegationCredential, buildNonDelegationCredentials, @@ -10,10 +14,6 @@ import { } from "@calcom/lib/delegationCredential"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; -import type { ServiceAccountKey } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; -import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import type { SelectedCalendar } from "@calcom/prisma/client"; import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential"; diff --git a/packages/app-store/dub/lib/AnalyticsService.ts b/packages/app-store/dub/lib/AnalyticsService.ts index 71fd037a8b..1c8846cf92 100644 --- a/packages/app-store/dub/lib/AnalyticsService.ts +++ b/packages/app-store/dub/lib/AnalyticsService.ts @@ -1,7 +1,7 @@ import { Dub } from "dub-package"; -import logger from "@calcom/lib/logger"; import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import logger from "@calcom/lib/logger"; import type { AnalyticsService, SendEventProps } from "@calcom/types/AnalyticsService"; import type { CredentialPayload } from "@calcom/types/Credential"; diff --git a/packages/app-store/googlecalendar/api/callback.ts b/packages/app-store/googlecalendar/api/callback.ts index 283841c6b5..80ecd5ff00 100644 --- a/packages/app-store/googlecalendar/api/callback.ts +++ b/packages/app-store/googlecalendar/api/callback.ts @@ -3,6 +3,7 @@ import { OAuth2Client } from "googleapis-common"; import type { NextApiRequest, NextApiResponse } from "next"; import GoogleCalendarService from "@calcom/app-store/googlecalendar/lib/CalendarService"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import { renewSelectedCalendarCredentialId } from "@calcom/lib/connectedCalendar"; import { GOOGLE_CALENDAR_SCOPES, @@ -14,7 +15,6 @@ import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import { HttpError } from "@calcom/lib/http-error"; import { defaultHandler } from "@calcom/lib/server/defaultHandler"; import { defaultResponder } from "@calcom/lib/server/defaultResponder"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import { Prisma } from "@calcom/prisma/client"; import getInstalledAppPath from "../../_utils/getInstalledAppPath"; diff --git a/packages/app-store/googlecalendar/tests/testUtils.ts b/packages/app-store/googlecalendar/tests/testUtils.ts index c7960fd3bd..b51d61640f 100644 --- a/packages/app-store/googlecalendar/tests/testUtils.ts +++ b/packages/app-store/googlecalendar/tests/testUtils.ts @@ -1,3 +1,4 @@ +import { calendar_v3 } from "@googleapis/calendar"; import type { Page } from "@playwright/test"; import { expect } from "@playwright/test"; @@ -29,7 +30,7 @@ export const createBookingAndFetchGCalEvent = async ( await page.locator("[data-testid=success-page]"); const bookingUrl = await page.url(); - const bookingUid = bookingUrl.match(/booking\/([^\/?]+)/); + const bookingUid = bookingUrl.match(/booking\/([^/?]+)/); assertValueExists(bookingUid, "bookingUid"); const [gCalReference, booking] = await Promise.all([ @@ -40,6 +41,7 @@ export const createBookingAndFetchGCalEvent = async ( }, type: metadata.type, credentialId: qaGCalCredential?.id, + deleted: null, }, select: { uid: true, @@ -107,7 +109,7 @@ export const createBookingAndFetchGCalEvent = async ( }; export const deleteBookingAndEvent = async ( - authedCalendar: any, + authedCalendar: calendar_v3.Calendar, bookingUid: string, gCalReferenceUid?: string ) => { diff --git a/packages/app-store/routing-forms/lib/formSubmissionUtils.ts b/packages/app-store/routing-forms/lib/formSubmissionUtils.ts index b05b86816c..0c2e8172b0 100644 --- a/packages/app-store/routing-forms/lib/formSubmissionUtils.ts +++ b/packages/app-store/routing-forms/lib/formSubmissionUtils.ts @@ -1,4 +1,5 @@ import dayjs from "@calcom/dayjs"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { Tasker } from "@calcom/features/tasker/tasker"; import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import { sendGenericWebhookPayload } from "@calcom/features/webhooks/lib/sendPayload"; @@ -6,7 +7,6 @@ import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { withReporting } from "@calcom/lib/sentryWrapper"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { App_RoutingForms_Form, User } from "@calcom/prisma/client"; diff --git a/packages/app-store/routing-forms/lib/handleResponse.ts b/packages/app-store/routing-forms/lib/handleResponse.ts index c331f024bf..b8731e3fb3 100644 --- a/packages/app-store/routing-forms/lib/handleResponse.ts +++ b/packages/app-store/routing-forms/lib/handleResponse.ts @@ -1,9 +1,9 @@ import { z } from "zod"; +import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; import { emailSchema } from "@calcom/lib/emailSchema"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; -import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; import { safeStringify } from "@calcom/lib/safeStringify"; import { withReporting } from "@calcom/lib/sentryWrapper"; import { RoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse"; diff --git a/packages/app-store/salesforce/lib/CrmService.ts b/packages/app-store/salesforce/lib/CrmService.ts index 8efb084fac..447b6603e4 100644 --- a/packages/app-store/salesforce/lib/CrmService.ts +++ b/packages/app-store/salesforce/lib/CrmService.ts @@ -741,6 +741,7 @@ export default class SalesforceCRMService implements CRM { booking: { uid: bookingUid, }, + deleted: null, }, }); diff --git a/packages/app-store/stripepayment/api/__tests__/portal.test.ts b/packages/app-store/stripepayment/api/__tests__/portal.test.ts index 5d9880ce12..4a3a29253e 100644 --- a/packages/app-store/stripepayment/api/__tests__/portal.test.ts +++ b/packages/app-store/stripepayment/api/__tests__/portal.test.ts @@ -2,9 +2,9 @@ import type { NextApiRequest } from "next"; import type { Session } from "next-auth"; import { describe, it, expect, vi, beforeEach } from "vitest"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { WEBAPP_URL } from "@calcom/lib/constants"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { MembershipRole } from "@calcom/prisma/enums"; import { @@ -54,7 +54,7 @@ describe("Portal API - Service-Based Architecture", () => { user: { id: 123 }, hasValidLicense: true, upId: "test-upid", - expires: "2024-12-31T23:59:59.999Z" + expires: "2024-12-31T23:59:59.999Z", } as Session, } as RequestWithSession; @@ -77,7 +77,7 @@ describe("Portal API - Service-Based Architecture", () => { user: {} as any, hasValidLicense: true, upId: "test-upid", - expires: "2024-12-31T23:59:59.999Z" + expires: "2024-12-31T23:59:59.999Z", } as Session, } as RequestWithSession; diff --git a/packages/app-store/stripepayment/lib/PaymentService.ts b/packages/app-store/stripepayment/lib/PaymentService.ts index 676dc0195f..0e48dc560a 100644 --- a/packages/app-store/stripepayment/lib/PaymentService.ts +++ b/packages/app-store/stripepayment/lib/PaymentService.ts @@ -3,12 +3,12 @@ import { v4 as uuidv4 } from "uuid"; import z from "zod"; import { sendAwaitingPaymentEmailAndSMS } from "@calcom/emails"; +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { getErrorFromUnknown } from "@calcom/lib/errors"; import { ErrorWithCode } from "@calcom/lib/errors"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import prisma from "@calcom/prisma"; import type { Booking, Payment, PaymentOption, Prisma } from "@calcom/prisma/client"; import type { EventTypeMetadata } from "@calcom/prisma/zod-utils"; diff --git a/packages/app-store/stripepayment/lib/services/base/BillingPortalService.ts b/packages/app-store/stripepayment/lib/services/base/BillingPortalService.ts index 4b92f57697..9f3ade6b73 100644 --- a/packages/app-store/stripepayment/lib/services/base/BillingPortalService.ts +++ b/packages/app-store/stripepayment/lib/services/base/BillingPortalService.ts @@ -1,10 +1,10 @@ import type { NextApiResponse } from "next"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl"; import logger from "@calcom/lib/logger"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import prisma from "@calcom/prisma"; import stripe from "../../server"; diff --git a/packages/app-store/utils.ts b/packages/app-store/utils.ts index 57f86594f9..f0675f4995 100644 --- a/packages/app-store/utils.ts +++ b/packages/app-store/utils.ts @@ -57,7 +57,7 @@ function getApps(credentials: CredentialDataWithTeamName[], filterOnCredentials? const credential = { id: 0, type: appMeta.type, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + key: appMeta.key!, userId: 0, user: { email: "" }, diff --git a/packages/app-store/vital/lib/reschedule.ts b/packages/app-store/vital/lib/reschedule.ts index 99df75be2d..f29ceab2cf 100644 --- a/packages/app-store/vital/lib/reschedule.ts +++ b/packages/app-store/vital/lib/reschedule.ts @@ -2,11 +2,11 @@ import type { TFunction } from "i18next"; import dayjs from "@calcom/dayjs"; import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails"; +import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient"; import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder"; import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director"; import logger from "@calcom/lib/logger"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient"; import prisma from "@calcom/prisma"; import type { Booking, BookingReference, User } from "@calcom/prisma/client"; import { BookingStatus } from "@calcom/prisma/enums"; @@ -119,7 +119,7 @@ const Reschedule = async (bookingUid: string, cancellationReason: string) => { ), organizer: userOwnerAsPeopleType, hideOrganizerEmail: bookingToReschedule.eventType?.hideOrganizerEmail, - team: !!bookingToReschedule.eventType?.team + team: bookingToReschedule.eventType?.team ? { name: bookingToReschedule.eventType.team.name, id: bookingToReschedule.eventType.team.id, diff --git a/packages/app-store/wipemycalother/lib/reschedule.ts b/packages/app-store/wipemycalother/lib/reschedule.ts index fe05984d65..95303b8925 100644 --- a/packages/app-store/wipemycalother/lib/reschedule.ts +++ b/packages/app-store/wipemycalother/lib/reschedule.ts @@ -2,11 +2,11 @@ import type { TFunction } from "i18next"; import dayjs from "@calcom/dayjs"; import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails"; +import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient"; import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder"; import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director"; import logger from "@calcom/lib/logger"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient"; import prisma from "@calcom/prisma"; import type { Booking, BookingReference, User } from "@calcom/prisma/client"; import { BookingStatus } from "@calcom/prisma/enums"; @@ -122,7 +122,7 @@ const Reschedule = async (bookingUid: string, cancellationReason: string) => { ), organizer: userOwnerAsPeopleType, hideOrganizerEmail: bookingToReschedule.eventType?.hideOrganizerEmail, - team: !!bookingToReschedule.eventType?.team + team: bookingToReschedule.eventType?.team ? { name: bookingToReschedule.eventType.team.name, id: bookingToReschedule.eventType.team.id, diff --git a/packages/features/Segment.tsx b/packages/features/Segment.tsx index 4e822000c3..65491ba444 100644 --- a/packages/features/Segment.tsx +++ b/packages/features/Segment.tsx @@ -5,6 +5,7 @@ import { Query, Builder, Utils as QbUtils } from "react-awesome-query-builder"; import type { ImmutableTree, BuilderProps } from "react-awesome-query-builder"; import type { JsonTree } from "react-awesome-query-builder"; +import { buildStateFromQueryValue } from "@calcom/app-store/_utils/raqb/raqbUtils"; import { withRaqbSettingsAndWidgets, ConfigFor, @@ -12,7 +13,6 @@ import { import { getQueryBuilderConfigForAttributes } from "@calcom/app-store/routing-forms/lib/getQueryBuilderConfig"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { isEqual } from "@calcom/lib/isEqual"; -import { buildStateFromQueryValue } from "@calcom/app-store/_utils/raqb/raqbUtils"; import type { AttributesQueryValue } from "@calcom/lib/raqb/types"; import { trpc, type RouterOutputs } from "@calcom/trpc"; import cn from "@calcom/ui/classNames"; diff --git a/packages/features/apps/components/AllApps.tsx b/packages/features/apps/components/AllApps.tsx index ff3c579d4e..5f1af6ebd5 100644 --- a/packages/features/apps/components/AllApps.tsx +++ b/packages/features/apps/components/AllApps.tsx @@ -4,8 +4,8 @@ import { useAutoAnimate } from "@formkit/auto-animate/react"; import type { UIEvent } from "react"; import { useEffect, useRef, useState } from "react"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { UserAdminTeams } from "@calcom/features/users/repositories/UserRepository"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { AppCategories } from "@calcom/prisma/client"; import type { AppFrontendPayload as App } from "@calcom/types/App"; import type { CredentialFrontendPayload as Credential } from "@calcom/types/Credential"; diff --git a/packages/features/apps/components/AppCard.tsx b/packages/features/apps/components/AppCard.tsx index 7c0351626c..d908739bc6 100644 --- a/packages/features/apps/components/AppCard.tsx +++ b/packages/features/apps/components/AppCard.tsx @@ -7,11 +7,12 @@ import { InstallAppButton } from "@calcom/app-store/InstallAppButton"; import { isRedirectApp } from "@calcom/app-store/_utils/redirectApps"; import useAddAppMutation from "@calcom/app-store/_utils/useAddAppMutation"; import { doesAppSupportTeamInstall, isConferencing } from "@calcom/app-store/utils"; +import type { UserAdminTeams } from "@calcom/features/users/repositories/UserRepository"; import { AppOnboardingSteps } from "@calcom/lib/apps/appOnboardingSteps"; import { getAppOnboardingUrl } from "@calcom/lib/apps/getAppOnboardingUrl"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; -import type { UserAdminTeams } from "@calcom/features/users/repositories/UserRepository"; +import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; import type { AppFrontendPayload as App } from "@calcom/types/App"; import type { CredentialFrontendPayload as Credential } from "@calcom/types/Credential"; import classNames from "@calcom/ui/classNames"; @@ -19,7 +20,6 @@ import { Badge } from "@calcom/ui/components/badge"; import { Button } from "@calcom/ui/components/button"; import type { ButtonProps } from "@calcom/ui/components/button"; import { showToast } from "@calcom/ui/components/toast"; -import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; interface AppCardProps { app: App; @@ -120,14 +120,14 @@ export function AppCard({ app, credentials, searchText, userAdminTeams }: AppCar
*/}

+ }} + />

{t("dont_want_to_wait")}
-
+
{disabled ? ( diff --git a/packages/features/bookings/Booker/components/OutOfOfficeInSlots.tsx b/packages/features/bookings/Booker/components/OutOfOfficeInSlots.tsx index a0fa7d76a1..6a7d90dd12 100644 --- a/packages/features/bookings/Booker/components/OutOfOfficeInSlots.tsx +++ b/packages/features/bookings/Booker/components/OutOfOfficeInSlots.tsx @@ -1,7 +1,7 @@ import { useRouter } from "next/navigation"; -import ServerTrans from "@calcom/lib/components/ServerTrans"; import type { IOutOfOfficeData } from "@calcom/features/availability/lib/getUserAvailability"; +import ServerTrans from "@calcom/lib/components/ServerTrans"; import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import classNames from "@calcom/ui/classNames"; diff --git a/packages/features/bookings/Booker/components/hooks/useBookings.ts b/packages/features/bookings/Booker/components/hooks/useBookings.ts index 87915e4b62..37095979b7 100644 --- a/packages/features/bookings/Booker/components/hooks/useBookings.ts +++ b/packages/features/bookings/Booker/components/hooks/useBookings.ts @@ -18,7 +18,6 @@ import { createRecurringBooking } from "@calcom/features/bookings/lib/create-rec import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking"; import type { BookerEvent } from "@calcom/features/bookings/types"; import { getFullName } from "@calcom/features/form-builder/utils"; -import { useBookingSuccessRedirect } from "../../../lib/bookingSuccessRedirect"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { localStorage } from "@calcom/lib/webstorage"; @@ -27,6 +26,7 @@ import { bookingMetadataSchema } from "@calcom/prisma/zod-utils"; import { trpc } from "@calcom/trpc"; import { showToast } from "@calcom/ui/components/toast"; +import { useBookingSuccessRedirect } from "../../../lib/bookingSuccessRedirect"; import type { UseBookingFormReturnType } from "./useBookingForm"; export interface IUseBookings { diff --git a/packages/features/bookings/Booker/components/hooks/useDecoyBooking.ts b/packages/features/bookings/Booker/components/hooks/useDecoyBooking.ts index 39356f04ba..483a52d007 100644 --- a/packages/features/bookings/Booker/components/hooks/useDecoyBooking.ts +++ b/packages/features/bookings/Booker/components/hooks/useDecoyBooking.ts @@ -28,4 +28,3 @@ export function useDecoyBooking(uid: string) { return bookingData; } - diff --git a/packages/features/bookings/components/AvailableTimes.tsx b/packages/features/bookings/components/AvailableTimes.tsx index bb58f211c7..3d2094da45 100644 --- a/packages/features/bookings/components/AvailableTimes.tsx +++ b/packages/features/bookings/components/AvailableTimes.tsx @@ -6,12 +6,12 @@ import { useMemo } from "react"; import { getPaymentAppData } from "@calcom/app-store/_utils/payments/getPaymentAppData"; import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform"; import dayjs from "@calcom/dayjs"; +import type { IOutOfOfficeData } from "@calcom/features/availability/lib/getUserAvailability"; import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; import { OutOfOfficeInSlots } from "@calcom/features/bookings/Booker/components/OutOfOfficeInSlots"; import type { IUseBookingLoadingStates } from "@calcom/features/bookings/Booker/components/hooks/useBookings"; import type { BookerEvent } from "@calcom/features/bookings/types"; import type { Slot } from "@calcom/features/schedules/lib/use-schedule/types"; -import type { IOutOfOfficeData } from "@calcom/features/availability/lib/getUserAvailability"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { localStorage } from "@calcom/lib/webstorage"; import classNames from "@calcom/ui/classNames"; diff --git a/packages/features/bookings/di/RecurringBookingService.module.ts b/packages/features/bookings/di/RecurringBookingService.module.ts index 4217d73306..c6846da3f3 100644 --- a/packages/features/bookings/di/RecurringBookingService.module.ts +++ b/packages/features/bookings/di/RecurringBookingService.module.ts @@ -1,5 +1,4 @@ import { RecurringBookingService } from "@calcom/features/bookings/lib/service/RecurringBookingService"; - import { createModule, bindModuleToClassOnToken } from "@calcom/features/di/di"; import { DI_TOKENS } from "@calcom/features/di/tokens"; diff --git a/packages/features/bookings/di/RegularBookingService.module.ts b/packages/features/bookings/di/RegularBookingService.module.ts index db8b56c5e5..e338f753c6 100644 --- a/packages/features/bookings/di/RegularBookingService.module.ts +++ b/packages/features/bookings/di/RegularBookingService.module.ts @@ -1,10 +1,8 @@ - import { RegularBookingService } from "@calcom/features/bookings/lib/service/RegularBookingService"; import { bindModuleToClassOnToken, createModule } from "@calcom/features/di/di"; import { moduleLoader as bookingRepositoryModuleLoader } from "@calcom/features/di/modules/Booking"; import { moduleLoader as cacheModuleLoader } from "@calcom/features/di/modules/Cache"; import { moduleLoader as checkBookingAndDurationLimitsModuleLoader } from "@calcom/features/di/modules/CheckBookingAndDurationLimits"; - import { moduleLoader as luckyUserServiceModuleLoader } from "@calcom/features/di/modules/LuckyUser"; import { moduleLoader as userRepositoryModuleLoader } from "@calcom/features/di/modules/User"; import { DI_TOKENS } from "@calcom/features/di/tokens"; diff --git a/packages/features/bookings/lib/EventManager.ts b/packages/features/bookings/lib/EventManager.ts index fe254500a2..eda5cf027e 100644 --- a/packages/features/bookings/lib/EventManager.ts +++ b/packages/features/bookings/lib/EventManager.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-restricted-imports import { cloneDeep, merge } from "lodash"; import { v5 as uuidv5 } from "uuid"; import type { z } from "zod"; @@ -10,6 +9,7 @@ import { getLocationFromApp, MeetLocationType, MSTeamsLocationType } from "@calc import getApps from "@calcom/app-store/utils"; import { createEvent, updateEvent, deleteEvent } from "@calcom/features/calendars/lib/CalendarManager"; import { createMeeting, updateMeeting, deleteMeeting } from "@calcom/features/conferencing/lib/videoClient"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import CrmManager from "@calcom/features/crmManager/crmManager"; import CRMScheduler from "@calcom/features/crmManager/crmScheduler"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; @@ -24,7 +24,6 @@ import { getPiiFreeCalendarEvent, } from "@calcom/lib/piiFreeData"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; import { prisma } from "@calcom/prisma"; import type { DestinationCalendar, BookingReference } from "@calcom/prisma/client"; import { createdEventSchema } from "@calcom/prisma/zod-utils"; diff --git a/packages/features/bookings/lib/bookingSuccessRedirect.test.ts b/packages/features/bookings/lib/bookingSuccessRedirect.test.ts index 9ab1da7932..9efdef3351 100644 --- a/packages/features/bookings/lib/bookingSuccessRedirect.test.ts +++ b/packages/features/bookings/lib/bookingSuccessRedirect.test.ts @@ -33,15 +33,7 @@ const WEBAPP_PARAMS = ["overlayCalendar"]; // Helper function to create a mock booking with sensible defaults type MockBooking = Pick< BookingResponse, - | "uid" - | "title" - | "description" - | "startTime" - | "endTime" - | "location" - | "attendees" - | "user" - | "responses" + "uid" | "title" | "description" | "startTime" | "endTime" | "location" | "attendees" | "user" | "responses" >; const createMockBooking = (overrides: Partial = {}): MockBooking => ({ diff --git a/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts b/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts index 90cc769326..6ed2b690c2 100644 --- a/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts +++ b/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/getAllCredentials.ts @@ -1,7 +1,7 @@ import type { z } from "zod"; -import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils"; import { enrichUserWithDelegationCredentialsIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential"; +import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential"; diff --git a/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/refreshCredentials.ts b/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/refreshCredentials.ts index e132c26c67..87f5a2e4e7 100644 --- a/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/refreshCredentials.ts +++ b/packages/features/bookings/lib/getAllCredentialsForUsersOnEvent/refreshCredentials.ts @@ -1,7 +1,7 @@ import async from "async"; -import { isDelegationCredential } from "@calcom/lib/delegationCredential"; import { buildAllCredentials } from "@calcom/app-store/delegationCredential"; +import { isDelegationCredential } from "@calcom/lib/delegationCredential"; import { withReporting } from "@calcom/lib/sentryWrapper"; import type { CredentialForCalendarService } from "@calcom/types/Credential"; diff --git a/packages/features/bookings/lib/getBookingFields.ts b/packages/features/bookings/lib/getBookingFields.ts index d3639ecda0..b572cb797c 100644 --- a/packages/features/bookings/lib/getBookingFields.ts +++ b/packages/features/bookings/lib/getBookingFields.ts @@ -1,12 +1,9 @@ import type { z } from "zod"; -import { - SMS_REMINDER_NUMBER_FIELD, - CAL_AI_AGENT_PHONE_NUMBER_FIELD, -} from "@calcom/lib/bookings/SystemField"; import type { Workflow } from "@calcom/features/ee/workflows/lib/types"; import { fieldsThatSupportLabelAsSafeHtml } from "@calcom/features/form-builder/fieldsThatSupportLabelAsSafeHtml"; import { getFieldIdentifier } from "@calcom/features/form-builder/utils/getFieldIdentifier"; +import { SMS_REMINDER_NUMBER_FIELD, CAL_AI_AGENT_PHONE_NUMBER_FIELD } from "@calcom/lib/bookings/SystemField"; import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; import slugify from "@calcom/lib/slugify"; import type { EventTypeCustomInput, EventType } from "@calcom/prisma/client"; diff --git a/packages/features/bookings/lib/getCalEventResponses.ts b/packages/features/bookings/lib/getCalEventResponses.ts index 14fe2a7665..a34e9dc91b 100644 --- a/packages/features/bookings/lib/getCalEventResponses.ts +++ b/packages/features/bookings/lib/getCalEventResponses.ts @@ -1,7 +1,7 @@ import type z from "zod"; -import { SystemField } from "@calcom/lib/bookings/SystemField"; import type { bookingResponsesDbSchema } from "@calcom/features/bookings/lib/getBookingResponsesSchema"; +import { SystemField } from "@calcom/lib/bookings/SystemField"; import { contructEmailFromPhoneNumber } from "@calcom/lib/contructEmailFromPhoneNumber"; import { getBookingWithResponses } from "@calcom/lib/getBooking"; import { HttpError } from "@calcom/lib/http-error"; @@ -47,7 +47,7 @@ export const getCalEventResponses = ({ if (!backwardCompatibleResponses) throw new Error("Couldn't get responses"); // To set placeholder email for the booking - if (!!!backwardCompatibleResponses.email) { + if (!backwardCompatibleResponses.email) { if (typeof backwardCompatibleResponses["attendeePhoneNumber"] !== "string") { log.error(`backwardCompatibleResponses: ${JSON.stringify(backwardCompatibleResponses)}`, { responses, diff --git a/packages/features/bookings/lib/getLuckyUser.ts b/packages/features/bookings/lib/getLuckyUser.ts index ceb7a27540..8d6c75d8bc 100644 --- a/packages/features/bookings/lib/getLuckyUser.ts +++ b/packages/features/bookings/lib/getLuckyUser.ts @@ -2,16 +2,16 @@ import { acrossQueryValueCompatiblity } from "@calcom/app-store/_utils/raqb/raqb import type { FormResponse, Fields } from "@calcom/app-store/routing-forms/types/types"; import { zodRoutes } from "@calcom/app-store/routing-forms/zod"; import dayjs from "@calcom/dayjs"; +import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { getBusyCalendarTimes } from "@calcom/features/calendars/lib/CalendarManager"; import { mergeOverlappingRanges } from "@calcom/features/schedules/lib/date-ranges"; +import type { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; import { raqbQueryValueSchema } from "@calcom/lib/raqb/zod"; import { safeStringify } from "@calcom/lib/safeStringify"; import type { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository"; -import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import type { HostRepository } from "@calcom/lib/server/repository/host"; import type { PrismaOOORepository } from "@calcom/lib/server/repository/ooo"; -import type { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import type { Prisma } from "@calcom/prisma/client"; import type { User, Booking, SelectedCalendar } from "@calcom/prisma/client"; import type { AttributeType } from "@calcom/prisma/enums"; diff --git a/packages/features/bookings/lib/handleBookingRequested.ts b/packages/features/bookings/lib/handleBookingRequested.ts index d9813ce6f9..c1f66a3ab1 100644 --- a/packages/features/bookings/lib/handleBookingRequested.ts +++ b/packages/features/bookings/lib/handleBookingRequested.ts @@ -1,12 +1,12 @@ import { sendAttendeeRequestEmailAndSMS, sendOrganizerRequestEmail } from "@calcom/emails"; import { getWebhookPayloadForBooking } from "@calcom/features/bookings/lib/getWebhookPayloadForBooking"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { Workflow } from "@calcom/features/ee/workflows/lib/types"; import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { Prisma } from "@calcom/prisma/client"; import { WebhookTriggerEvents, WorkflowTriggerEvents } from "@calcom/prisma/enums"; import type { EventTypeMetadata } from "@calcom/prisma/zod-utils"; diff --git a/packages/features/bookings/lib/handleCancelBooking.ts b/packages/features/bookings/lib/handleCancelBooking.ts index 71cfd3a9f7..6b24bb913c 100644 --- a/packages/features/bookings/lib/handleCancelBooking.ts +++ b/packages/features/bookings/lib/handleCancelBooking.ts @@ -524,10 +524,11 @@ async function handler(input: CancelBookingInput) { await eventManager.cancelEvent(evt, bookingToDelete.references, isBookingInRecurringSeries); - await prisma.bookingReference.deleteMany({ + await prisma.bookingReference.updateMany({ where: { bookingId: bookingToDelete.id, }, + data: { deleted: true }, }); } catch (error) { log.error(`Error deleting integrations`, safeStringify({ error })); diff --git a/packages/features/bookings/lib/handleConfirmation.ts b/packages/features/bookings/lib/handleConfirmation.ts index 91a59dd71f..839f773511 100644 --- a/packages/features/bookings/lib/handleConfirmation.ts +++ b/packages/features/bookings/lib/handleConfirmation.ts @@ -1,24 +1,24 @@ import { eventTypeAppMetadataOptionalSchema } from "@calcom/app-store/zod-utils"; import { scheduleMandatoryReminder } from "@calcom/ee/workflows/lib/reminders/scheduleMandatoryReminder"; import { sendScheduledEmailsAndSMS } from "@calcom/emails"; +import type { EventManagerUser } from "@calcom/features/bookings/lib/EventManager"; +import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { allowDisablingAttendeeConfirmationEmails, allowDisablingHostConfirmationEmails, } from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { Workflow } from "@calcom/features/ee/workflows/lib/types"; import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import { scheduleTrigger } from "@calcom/features/webhooks/lib/scheduleTrigger"; import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload"; import type { EventPayloadType, EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload"; import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser"; -import type { EventManagerUser } from "@calcom/features/bookings/lib/EventManager"; -import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { PrismaClient } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { SchedulingType } from "@calcom/prisma/enums"; diff --git a/packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts b/packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts index 504d962466..a9a2fc39da 100644 --- a/packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts +++ b/packages/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits.ts @@ -1,7 +1,7 @@ import dayjs from "@calcom/dayjs"; -import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema"; import type { CheckBookingLimitsService } from "@calcom/features/bookings/lib/checkBookingLimits"; import { checkDurationLimits } from "@calcom/features/bookings/lib/checkDurationLimits"; +import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema"; import { withReporting } from "@calcom/lib/sentryWrapper"; import type { NewBookingEventType } from "./getEventTypesFromDB"; diff --git a/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts b/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts index 57f6fe6090..a667994f4a 100644 --- a/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts +++ b/packages/features/bookings/lib/handleNewBooking/ensureAvailableUsers.ts @@ -3,9 +3,9 @@ import type { Logger } from "tslog"; import dayjs from "@calcom/dayjs"; import type { Dayjs } from "@calcom/dayjs"; import { checkForConflicts } from "@calcom/features/bookings/lib/conflictChecker/checkForConflicts"; -import { buildDateRanges } from "@calcom/features/schedules/lib/date-ranges"; import { getBusyTimesService } from "@calcom/features/di/containers/BusyTimes"; import { getUserAvailabilityService } from "@calcom/features/di/containers/GetUserAvailability"; +import { buildDateRanges } from "@calcom/features/schedules/lib/date-ranges"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { parseBookingLimit } from "@calcom/lib/intervalLimits/isBookingLimits"; import { parseDurationLimit } from "@calcom/lib/intervalLimits/isDurationLimits"; diff --git a/packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts b/packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts index 26394861bf..b7646ce77f 100644 --- a/packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts +++ b/packages/features/bookings/lib/handleNewBooking/getEventTypesFromDB.ts @@ -2,9 +2,9 @@ import type { LocationObject } from "@calcom/app-store/locations"; import { workflowSelect } from "@calcom/ee/workflows/lib/getAllWorkflows"; import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/getBookingFields"; import type { DefaultEvent } from "@calcom/features/eventtypes/lib/defaultEvents"; +import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent"; -import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential"; diff --git a/packages/features/bookings/lib/handleNewBooking/loadAndValidateUsers.ts b/packages/features/bookings/lib/handleNewBooking/loadAndValidateUsers.ts index bb9f1d4767..ff28f88ee0 100644 --- a/packages/features/bookings/lib/handleNewBooking/loadAndValidateUsers.ts +++ b/packages/features/bookings/lib/handleNewBooking/loadAndValidateUsers.ts @@ -3,6 +3,7 @@ import type { Logger } from "tslog"; import { enrichUsersWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; import type { RoutingFormResponse } from "@calcom/features/bookings/lib/getLuckyUser"; import { getQualifiedHostsService } from "@calcom/features/di/containers/QualifiedHosts"; +import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import { sentrySpan } from "@calcom/features/watchlist/lib/telemetry"; import { checkIfUsersAreBlocked } from "@calcom/features/watchlist/operations/check-if-users-are-blocked.controller"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; @@ -10,7 +11,6 @@ import { HttpError } from "@calcom/lib/http-error"; import { getPiiFreeUser } from "@calcom/lib/piiFreeData"; import { safeStringify } from "@calcom/lib/safeStringify"; import { withReporting } from "@calcom/lib/sentryWrapper"; -import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import { userSelect } from "@calcom/prisma"; import prisma from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; diff --git a/packages/features/bookings/lib/handleNewBooking/loadUsers.ts b/packages/features/bookings/lib/handleNewBooking/loadUsers.ts index d52794c67f..004d3ac21d 100644 --- a/packages/features/bookings/lib/handleNewBooking/loadUsers.ts +++ b/packages/features/bookings/lib/handleNewBooking/loadUsers.ts @@ -4,10 +4,10 @@ import { findMatchingHostsWithEventSegment, getNormalizedHosts, } from "@calcom/features/users/lib/getRoutedUsers"; +import { withSelectedCalendars, UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { withSelectedCalendars, UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma, { userSelect } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential"; @@ -100,7 +100,7 @@ const loadDynamicUsers = async (dynamicUserList: string[], currentOrgDomain: str } return findUsersByUsername({ usernameList: dynamicUserList, - orgSlug: !!currentOrgDomain ? currentOrgDomain : null, + orgSlug: currentOrgDomain ? currentOrgDomain : null, }); }; diff --git a/packages/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils.ts b/packages/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils.ts index 96efeebe6a..abebfe9c7a 100644 --- a/packages/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils.ts +++ b/packages/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils.ts @@ -1,9 +1,8 @@ +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { HttpError } from "@calcom/lib/http-error"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; -import type { Prisma } from "@calcom/prisma/client"; -import { BookingStatus } from "@calcom/prisma/enums"; import prisma from "@calcom/prisma"; +import { BookingStatus } from "@calcom/prisma/enums"; // TODO: Inject. export async function getOriginalRescheduledBooking(uid: string, seatsEventType?: boolean) { @@ -21,6 +20,5 @@ export async function getOriginalRescheduledBooking(uid: string, seatsEventType? return originalBooking; } -export type BookingType = Prisma.PromiseReturnType | null; - +export type BookingType = Awaited> | null; export type OriginalRescheduledBooking = Awaited> | null; diff --git a/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts b/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts index 26a9e577ca..2f0b2877a5 100644 --- a/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts +++ b/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts @@ -149,16 +149,18 @@ describe("handleNewBooking", () => { organizer, apps: [TestData.apps["google-calendar"], TestData.apps["daily-video"]], }, - org?.organization ? { - ...org.organization, - profileUsername: "username-in-org" - } : null + org?.organization + ? { + ...org.organization, + profileUsername: "username-in-org", + } + : null ) ); const orgProfiles = await prismaMock.profile.findMany({ where: { - organizationId: org?.organization.id, + organizationId: org?.organization.id ?? undefined, }, }); const orgProfile = orgProfiles[0]; @@ -257,8 +259,7 @@ describe("handleNewBooking", () => { booker, organizer: { ...organizer, - ...(orgProfile?.username ? - { usernameInOrg: orgProfile?.username } : null), + ...(orgProfile?.username ? { usernameInOrg: orgProfile?.username } : null), }, location: BookingLocations.CalVideo, subscriberUrl: "http://my-webhook.example.com", diff --git a/packages/features/bookings/lib/handleSeats/handleSeats.ts b/packages/features/bookings/lib/handleSeats/handleSeats.ts index 3473da579c..f424fb560a 100644 --- a/packages/features/bookings/lib/handleSeats/handleSeats.ts +++ b/packages/features/bookings/lib/handleSeats/handleSeats.ts @@ -1,10 +1,10 @@ -// eslint-disable-next-line no-restricted-imports + import dayjs from "@calcom/dayjs"; import { handleWebhookTrigger } from "@calcom/features/bookings/lib/handleWebhookTrigger"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { EventPayloadType } from "@calcom/features/webhooks/lib/sendPayload"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { HttpError } from "@calcom/lib/http-error"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import prisma from "@calcom/prisma"; import { BookingStatus } from "@calcom/prisma/enums"; diff --git a/packages/features/bookings/lib/handleSeats/lib/lastAttendeeDeleteBooking.ts b/packages/features/bookings/lib/handleSeats/lib/lastAttendeeDeleteBooking.ts index 1d50c02c8d..b7e68415b0 100644 --- a/packages/features/bookings/lib/handleSeats/lib/lastAttendeeDeleteBooking.ts +++ b/packages/features/bookings/lib/handleSeats/lib/lastAttendeeDeleteBooking.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line no-restricted-imports + import { getCalendar } from "@calcom/app-store/_utils/getCalendar"; import { getAllDelegationCredentialsForUserIncludeServiceAccountKey } from "@calcom/app-store/delegationCredential"; import { getDelegationCredentialOrFindRegularCredential } from "@calcom/app-store/delegationCredential"; diff --git a/packages/features/bookings/lib/host-filtering/filterHostsByLeadThreshold.ts b/packages/features/bookings/lib/host-filtering/filterHostsByLeadThreshold.ts index be3be96f6d..5d10129e9f 100644 --- a/packages/features/bookings/lib/host-filtering/filterHostsByLeadThreshold.ts +++ b/packages/features/bookings/lib/host-filtering/filterHostsByLeadThreshold.ts @@ -1,6 +1,6 @@ +import type { LuckyUserService, RoutingFormResponse } from "@calcom/features/bookings/lib/getLuckyUser"; import { getLuckyUserService } from "@calcom/features/di/containers/LuckyUser"; import logger from "@calcom/lib/logger"; -import type { LuckyUserService, RoutingFormResponse } from "@calcom/features/bookings/lib/getLuckyUser"; import type { RRResetInterval, SelectedCalendar } from "@calcom/prisma/client"; import { RRTimestampBasis } from "@calcom/prisma/enums"; import type { CredentialForCalendarService } from "@calcom/types/Credential"; diff --git a/packages/features/bookings/lib/host-filtering/filterHostsBySameRoundRobinHost.ts b/packages/features/bookings/lib/host-filtering/filterHostsBySameRoundRobinHost.ts index 587c37836d..398f5b9a4a 100644 --- a/packages/features/bookings/lib/host-filtering/filterHostsBySameRoundRobinHost.ts +++ b/packages/features/bookings/lib/host-filtering/filterHostsBySameRoundRobinHost.ts @@ -1,5 +1,5 @@ -import { isRerouting } from "@calcom/lib/bookings/routing/utils"; import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { isRerouting } from "@calcom/lib/bookings/routing/utils"; export interface IFilterHostsService { bookingRepo: BookingRepository; diff --git a/packages/features/bookings/lib/host-filtering/findQualifiedHostsWithDelegationCredentials.ts b/packages/features/bookings/lib/host-filtering/findQualifiedHostsWithDelegationCredentials.ts index 27483c327c..7bffec2a18 100644 --- a/packages/features/bookings/lib/host-filtering/findQualifiedHostsWithDelegationCredentials.ts +++ b/packages/features/bookings/lib/host-filtering/findQualifiedHostsWithDelegationCredentials.ts @@ -1,11 +1,11 @@ +import type { RoutingFormResponse } from "@calcom/features/bookings/lib/getLuckyUser"; +import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { findMatchingHostsWithEventSegment, getNormalizedHostsWithDelegationCredentials, } from "@calcom/features/users/lib/getRoutedUsers"; import type { EventType } from "@calcom/features/users/lib/getRoutedUsers"; import { withReporting } from "@calcom/lib/sentryWrapper"; -import type { RoutingFormResponse } from "@calcom/features/bookings/lib/getLuckyUser"; -import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import type { SelectedCalendar } from "@calcom/prisma/client"; import type { SchedulingType } from "@calcom/prisma/enums"; import type { CredentialForCalendarService, CredentialPayload } from "@calcom/types/Credential"; diff --git a/packages/features/bookings/lib/payment/getBooking.ts b/packages/features/bookings/lib/payment/getBooking.ts index 004f57d484..b1917a3469 100644 --- a/packages/features/bookings/lib/payment/getBooking.ts +++ b/packages/features/bookings/lib/payment/getBooking.ts @@ -1,6 +1,6 @@ +import { enrichUserWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; import { workflowSelect } from "@calcom/ee/workflows/lib/getAllWorkflows"; import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; -import { enrichUserWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { HttpError as HttpCode } from "@calcom/lib/http-error"; import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj"; diff --git a/packages/features/bookings/lib/payment/handleNoShowFee.test.ts b/packages/features/bookings/lib/payment/handleNoShowFee.test.ts index e2a9537a3c..abd9901e96 100644 --- a/packages/features/bookings/lib/payment/handleNoShowFee.test.ts +++ b/packages/features/bookings/lib/payment/handleNoShowFee.test.ts @@ -1,14 +1,13 @@ import { describe, expect, it, vi, beforeEach } from "vitest"; - import { PaymentServiceMap } from "@calcom/app-store/payment.services.generated"; import { sendNoShowFeeChargedEmail } from "@calcom/emails"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { ErrorWithCode } from "@calcom/lib/errors"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { handleNoShowFee } from "./handleNoShowFee"; diff --git a/packages/features/bookings/lib/payment/handleNoShowFee.ts b/packages/features/bookings/lib/payment/handleNoShowFee.ts index 3725ba224b..bae0636869 100644 --- a/packages/features/bookings/lib/payment/handleNoShowFee.ts +++ b/packages/features/bookings/lib/payment/handleNoShowFee.ts @@ -1,15 +1,14 @@ -// eslint-disable-next-line import { PaymentServiceMap } from "@calcom/app-store/payment.services.generated"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; import dayjs from "@calcom/dayjs"; import { sendNoShowFeeChargedEmail } from "@calcom/emails"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { ErrorWithCode } from "@calcom/lib/errors"; import logger from "@calcom/lib/logger"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import prisma from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { CalendarEvent } from "@calcom/types/Calendar"; diff --git a/packages/features/bookings/lib/payment/processNoShowFeeOnCancellation.ts b/packages/features/bookings/lib/payment/processNoShowFeeOnCancellation.ts index 9015d72af5..151aa7256a 100644 --- a/packages/features/bookings/lib/payment/processNoShowFeeOnCancellation.ts +++ b/packages/features/bookings/lib/payment/processNoShowFeeOnCancellation.ts @@ -1,6 +1,6 @@ import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; -import logger from "@calcom/lib/logger"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import logger from "@calcom/lib/logger"; import type { Payment } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/bookings/lib/service/InstantBookingCreateService.test.ts b/packages/features/bookings/lib/service/InstantBookingCreateService.test.ts index 34080a43a8..45827697d8 100644 --- a/packages/features/bookings/lib/service/InstantBookingCreateService.test.ts +++ b/packages/features/bookings/lib/service/InstantBookingCreateService.test.ts @@ -13,10 +13,11 @@ import { import { describe, it, expect, vi, beforeEach } from "vitest"; -import type { CreateInstantBookingData } from "../dto/types"; -import { getInstantBookingCreateService } from "../../di/InstantBookingCreateService.container"; import { BookingStatus } from "@calcom/prisma/enums"; +import { getInstantBookingCreateService } from "../../di/InstantBookingCreateService.container"; +import type { CreateInstantBookingData } from "../dto/types"; + vi.mock("@calcom/features/notifications/sendNotification", () => ({ sendNotification: vi.fn(), })); diff --git a/packages/features/bookings/lib/service/RegularBookingService.ts b/packages/features/bookings/lib/service/RegularBookingService.ts index b2465a1999..ac071a6563 100644 --- a/packages/features/bookings/lib/service/RegularBookingService.ts +++ b/packages/features/bookings/lib/service/RegularBookingService.ts @@ -1,6 +1,6 @@ import short, { uuid } from "short-uuid"; import { v5 as uuidv5 } from "uuid"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; + import processExternalId from "@calcom/app-store/_utils/calendars/processExternalId"; import { getPaymentAppData } from "@calcom/app-store/_utils/payments/getPaymentAppData"; import { @@ -23,7 +23,6 @@ import { scheduleMandatoryReminder } from "@calcom/ee/workflows/lib/reminders/sc import getICalUID from "@calcom/emails/lib/getICalUID"; import { CalendarEventBuilder } from "@calcom/features/CalendarEventBuilder"; import EventManager, { placeholderCreatedEvent } from "@calcom/features/bookings/lib/EventManager"; -import type { CheckBookingLimitsService } from "@calcom/features/bookings/lib/checkBookingLimits"; import type { BookingDataSchemaGetter } from "@calcom/features/bookings/lib/dto/types"; import type { CreateRegularBookingData, @@ -38,10 +37,13 @@ import type { CacheService } from "@calcom/features/calendar-cache/lib/getShould import { getSpamCheckService } from "@calcom/features/di/watchlist/containers/SpamCheckService.container"; import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import AssignmentReasonRecorder from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; import { getEventName, updateHostInEventName } from "@calcom/features/eventtypes/lib/eventNaming"; import { getFullName } from "@calcom/features/form-builder/utils"; +import { HashedLinkService } from "@calcom/features/hashedLink/services/hashedLinkService"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { handleAnalyticsEvents } from "@calcom/features/tasker/tasks/analytics/handleAnalyticsEvents"; import type { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { UsersRepository } from "@calcom/features/users/users.repository"; @@ -57,8 +59,6 @@ import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser"; import { groupHostsByGroupId } from "@calcom/lib/bookings/hostGroupUtils"; import { shouldIgnoreContactOwner } from "@calcom/lib/bookings/routing/utils"; import { DEFAULT_GROUP_ID } from "@calcom/lib/constants"; -import type { BookingRepository } from "../../repositories/BookingRepository"; - import { ErrorCode } from "@calcom/lib/errorCodes"; import { getErrorFromUnknown, ErrorWithCode } from "@calcom/lib/errors"; import { extractBaseEmail } from "@calcom/lib/extract-base-email"; @@ -69,8 +69,6 @@ import logger from "@calcom/lib/logger"; import { getPiiFreeCalendarEvent, getPiiFreeEventType } from "@calcom/lib/piiFreeData"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { HashedLinkService } from "@calcom/features/hashedLink/services/hashedLinkService"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import type { PrismaClient } from "@calcom/prisma"; import type { DestinationCalendar, Prisma, User, AssignmentReasonEnum } from "@calcom/prisma/client"; @@ -93,6 +91,7 @@ import type { import type { CredentialForCalendarService } from "@calcom/types/Credential"; import type { EventResult, PartialReference } from "@calcom/types/EventManager"; +import type { BookingRepository } from "../../repositories/BookingRepository"; import { BookingActionMap, BookingEmailSmsHandler } from "../BookingEmailSmsHandler"; import { getAllCredentialsIncludeServiceAccountKey } from "../getAllCredentialsForUsersOnEvent/getAllCredentials"; import { refreshCredentials } from "../getAllCredentialsForUsersOnEvent/refreshCredentials"; @@ -1255,9 +1254,9 @@ async function handler( // This ensures that createMeeting isn't called for static video apps as bookingLocation becomes just a regular value for them. const { bookingLocation, conferenceCredentialId } = organizerOrFirstDynamicGroupMemberDefaultLocationUrl ? { - bookingLocation: organizerOrFirstDynamicGroupMemberDefaultLocationUrl, - conferenceCredentialId: undefined, - } + bookingLocation: organizerOrFirstDynamicGroupMemberDefaultLocationUrl, + conferenceCredentialId: undefined, + } : getLocationValueForDB(locationBodyString, eventType.locations); log.info("locationBodyString", locationBodyString); @@ -1303,8 +1302,8 @@ async function handler( const destinationCalendar = eventType.destinationCalendar ? [eventType.destinationCalendar] : organizerUser.destinationCalendar - ? [organizerUser.destinationCalendar] - : null; + ? [organizerUser.destinationCalendar] + : null; let organizerEmail = organizerUser.email || "Email-less"; if (eventType.useEventTypeDestinationCalendarEmail && destinationCalendar?.[0]?.primaryEmail) { @@ -1646,7 +1645,8 @@ async function handler( const changedOrganizer = !!originalRescheduledBooking && - (eventType.schedulingType === SchedulingType.ROUND_ROBIN || eventType.schedulingType === SchedulingType.COLLECTIVE) && + (eventType.schedulingType === SchedulingType.ROUND_ROBIN || + eventType.schedulingType === SchedulingType.COLLECTIVE) && originalRescheduledBooking.userId !== evt.organizer.id; const skipDeleteEventsAndMeetings = changedOrganizer; @@ -1922,14 +1922,14 @@ async function handler( } const updateManager = !skipCalendarSyncTaskCreation ? await eventManager.reschedule( - evt, - originalRescheduledBooking.uid, - undefined, - changedOrganizer, - previousHostDestinationCalendar, - isBookingRequestedReschedule, - skipDeleteEventsAndMeetings - ) + evt, + originalRescheduledBooking.uid, + undefined, + changedOrganizer, + previousHostDestinationCalendar, + isBookingRequestedReschedule, + skipDeleteEventsAndMeetings + ) : placeholderCreatedEvent; // This gets overridden when updating the event - to check if notes have been hidden or not. We just reset this back // to the default description when we are sending the emails. @@ -2227,8 +2227,8 @@ async function handler( const metadata = videoCallUrl ? { - videoCallUrl: getVideoCallUrlFromCalEvent(evt) || videoCallUrl, - } + videoCallUrl: getVideoCallUrlFromCalEvent(evt) || videoCallUrl, + } : undefined; const webhookData: EventPayloadType = { @@ -2290,9 +2290,9 @@ async function handler( ...eventType, metadata: eventType.metadata ? { - ...eventType.metadata, - apps: eventType.metadata?.apps as Prisma.JsonValue, - } + ...eventType.metadata, + apps: eventType.metadata?.apps as Prisma.JsonValue, + } : {}, }, paymentAppCredentials: eventTypePaymentAppCredential as IEventTypePaymentCredentialType, @@ -2606,7 +2606,7 @@ async function handler( * We are open to renaming it to something more descriptive. */ export class RegularBookingService implements IBookingService { - constructor(private readonly deps: IBookingServiceDependencies) { } + constructor(private readonly deps: IBookingServiceDependencies) {} async createBooking(input: { bookingData: CreateRegularBookingData; bookingMeta?: CreateBookingMeta }) { return handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps); diff --git a/packages/features/bot-detection/BotDetectionService.test.ts b/packages/features/bot-detection/BotDetectionService.test.ts index fc164d8bdb..09c396c91e 100644 --- a/packages/features/bot-detection/BotDetectionService.test.ts +++ b/packages/features/bot-detection/BotDetectionService.test.ts @@ -1,9 +1,9 @@ import type { IncomingHttpHeaders } from "http"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import type { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import type { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { HttpError } from "@calcom/lib/http-error"; -import type { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { BotDetectionService } from "./BotDetectionService"; diff --git a/packages/features/bot-detection/BotDetectionService.ts b/packages/features/bot-detection/BotDetectionService.ts index 33e4716859..2f8a871219 100644 --- a/packages/features/bot-detection/BotDetectionService.ts +++ b/packages/features/bot-detection/BotDetectionService.ts @@ -1,10 +1,10 @@ import { checkBotId } from "botid/server"; import type { IncomingHttpHeaders } from "http"; +import type { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import type { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; -import type { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; interface BotDetectionConfig { eventTypeId?: number; diff --git a/packages/features/busyTimes/services/getBusyTimes.ts b/packages/features/busyTimes/services/getBusyTimes.ts index 27fc99985f..04e83de9f5 100644 --- a/packages/features/busyTimes/services/getBusyTimes.ts +++ b/packages/features/busyTimes/services/getBusyTimes.ts @@ -1,4 +1,5 @@ import dayjs from "@calcom/dayjs"; +import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import { getBusyCalendarTimes } from "@calcom/features/calendars/lib/CalendarManager"; import { getDefinedBufferTimes } from "@calcom/features/eventtypes/lib/getDefinedBufferTimes"; import { subtract } from "@calcom/features/schedules/lib/date-ranges"; @@ -9,7 +10,6 @@ import logger from "@calcom/lib/logger"; import { getPiiFreeBooking } from "@calcom/lib/piiFreeData"; import { withReporting } from "@calcom/lib/sentryWrapper"; import { performance } from "@calcom/lib/server/perfObserver"; -import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import prisma from "@calcom/prisma"; import type { Booking, EventType } from "@calcom/prisma/client"; import type { Prisma } from "@calcom/prisma/client"; diff --git a/packages/features/calAIPhone/providers/adapters/PrismaAgentRepositoryAdapter.ts b/packages/features/calAIPhone/providers/adapters/PrismaAgentRepositoryAdapter.ts index ec3f958e64..101cdf397e 100644 --- a/packages/features/calAIPhone/providers/adapters/PrismaAgentRepositoryAdapter.ts +++ b/packages/features/calAIPhone/providers/adapters/PrismaAgentRepositoryAdapter.ts @@ -1,5 +1,6 @@ import { PrismaAgentRepository } from "@calcom/lib/server/repository/PrismaAgentRepository"; import prisma from "@calcom/prisma"; + import type { AgentRepositoryInterface, AgentData, diff --git a/packages/features/calAIPhone/providers/interfaces/PhoneNumberRepositoryInterface.ts b/packages/features/calAIPhone/providers/interfaces/PhoneNumberRepositoryInterface.ts index 0aef238b49..a6108ae05d 100644 --- a/packages/features/calAIPhone/providers/interfaces/PhoneNumberRepositoryInterface.ts +++ b/packages/features/calAIPhone/providers/interfaces/PhoneNumberRepositoryInterface.ts @@ -83,7 +83,9 @@ export interface PhoneNumberRepositoryInterface { /** * Find inbound agent by phone number ID */ - findInboundAgentIdByPhoneNumberId(params: { phoneNumberId: number }): Promise<{ inboundAgentId: string | null } | null>; + findInboundAgentIdByPhoneNumberId(params: { + phoneNumberId: number; + }): Promise<{ inboundAgentId: string | null } | null>; } /** diff --git a/packages/features/calAIPhone/providers/retellAI/RetellAIService.test.ts b/packages/features/calAIPhone/providers/retellAI/RetellAIService.test.ts index 87c77bf719..3a52833e8e 100644 --- a/packages/features/calAIPhone/providers/retellAI/RetellAIService.test.ts +++ b/packages/features/calAIPhone/providers/retellAI/RetellAIService.test.ts @@ -11,7 +11,6 @@ import { RetellAIError } from "./errors"; import { createMockDatabaseAgent } from "./services/__tests__/test-utils"; import type { RetellAIRepository } from "./types"; - vi.mock("@calcom/app-store/stripepayment/lib/customer", () => ({ getStripeCustomerIdFromUserId: vi.fn(), })); diff --git a/packages/features/calAIPhone/providers/retellAI/RetellSDKClient.ts b/packages/features/calAIPhone/providers/retellAI/RetellSDKClient.ts index eed22b5b61..415c209f3b 100644 --- a/packages/features/calAIPhone/providers/retellAI/RetellSDKClient.ts +++ b/packages/features/calAIPhone/providers/retellAI/RetellSDKClient.ts @@ -273,7 +273,6 @@ export class RetellSDKClient implements RetellAIRepository { } async listVoices(): Promise { - try { const response = await this.client.voice.list(); diff --git a/packages/features/calendar-cache/calendar-cache.ts b/packages/features/calendar-cache/calendar-cache.ts index 2ca45693a7..2ae881f5e6 100644 --- a/packages/features/calendar-cache/calendar-cache.ts +++ b/packages/features/calendar-cache/calendar-cache.ts @@ -1,6 +1,6 @@ import { getCalendar } from "@calcom/app-store/_utils/getCalendar"; -import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { getCredentialForCalendarCache } from "@calcom/app-store/delegationCredential"; +import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import prisma from "@calcom/prisma"; diff --git a/packages/features/calendar-subscription/lib/sync/CalendarSyncService.ts b/packages/features/calendar-subscription/lib/sync/CalendarSyncService.ts index e283cc403f..2a2aff77f3 100644 --- a/packages/features/calendar-subscription/lib/sync/CalendarSyncService.ts +++ b/packages/features/calendar-subscription/lib/sync/CalendarSyncService.ts @@ -1,6 +1,6 @@ +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import type { CalendarSubscriptionEventItem } from "@calcom/features/calendar-subscription/lib/CalendarSubscriptionPort.interface"; import logger from "@calcom/lib/logger"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; import type { SelectedCalendar } from "@calcom/prisma/client"; const log = logger.getSubLogger({ prefix: ["CalendarSyncService"] }); diff --git a/packages/features/calendars/DatePicker.tsx b/packages/features/calendars/DatePicker.tsx index d5c2b8bccf..f68fa64d31 100644 --- a/packages/features/calendars/DatePicker.tsx +++ b/packages/features/calendars/DatePicker.tsx @@ -4,10 +4,10 @@ import { shallow } from "zustand/shallow"; import type { Dayjs } from "@calcom/dayjs"; import dayjs from "@calcom/dayjs"; import { useEmbedStyles } from "@calcom/embed-core/embed-iframe"; +import type { IFromUser, IToUser } from "@calcom/features/availability/lib/getUserAvailability"; import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; import { getAvailableDatesInMonth } from "@calcom/features/calendars/lib/getAvailableDatesInMonth"; import { daysInMonth, yyyymmdd } from "@calcom/lib/dayjs"; -import type { IFromUser, IToUser } from "@calcom/features/availability/lib/getUserAvailability"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { weekdayNames } from "@calcom/lib/weekday"; import type { PeriodData } from "@calcom/types/Event"; diff --git a/packages/features/calendars/lib/CalendarManager.ts b/packages/features/calendars/lib/CalendarManager.ts index d677806a00..7fdeb2dde0 100644 --- a/packages/features/calendars/lib/CalendarManager.ts +++ b/packages/features/calendars/lib/CalendarManager.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line no-restricted-imports + import { sortBy } from "lodash"; import { getCalendar } from "@calcom/app-store/_utils/getCalendar"; diff --git a/packages/features/calendars/lib/getConnectedDestinationCalendars.ts b/packages/features/calendars/lib/getConnectedDestinationCalendars.ts index 518e8e6a7a..5a2f339672 100644 --- a/packages/features/calendars/lib/getConnectedDestinationCalendars.ts +++ b/packages/features/calendars/lib/getConnectedDestinationCalendars.ts @@ -3,10 +3,10 @@ import { getCalendarCredentials, getConnectedCalendars, } from "@calcom/features/calendars/lib/CalendarManager"; +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { isDelegationCredential } from "@calcom/lib/delegationCredential"; import logger from "@calcom/lib/logger"; import { DestinationCalendarRepository } from "@calcom/lib/server/repository/destinationCalendar"; -import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { SelectedCalendarRepository } from "@calcom/lib/server/repository/selectedCalendar"; import type { PrismaClient } from "@calcom/prisma"; import prisma from "@calcom/prisma"; diff --git a/packages/features/credentials/deleteCredential.test.ts b/packages/features/credentials/deleteCredential.test.ts index d2618056ef..f57fd9f917 100644 --- a/packages/features/credentials/deleteCredential.test.ts +++ b/packages/features/credentials/deleteCredential.test.ts @@ -7,9 +7,9 @@ import { describe, test, expect, beforeEach } from "vitest"; import { PrismaAppRepository } from "@calcom/features/apps/repository/PrismaAppRepository"; import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; -import { DestinationCalendarRepository } from "@calcom/lib/server/repository/destinationCalendar"; import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { DestinationCalendarRepository } from "@calcom/lib/server/repository/destinationCalendar"; import prisma from "@calcom/prisma"; const testUser = { diff --git a/packages/features/credentials/handleDeleteCredential.integration-test.ts b/packages/features/credentials/handleDeleteCredential.integration-test.ts new file mode 100644 index 0000000000..5290da5f9f --- /dev/null +++ b/packages/features/credentials/handleDeleteCredential.integration-test.ts @@ -0,0 +1,462 @@ +import { describe, it, expect, beforeAll, afterAll, afterEach } from "vitest"; + +import handleDeleteCredential from "@calcom/features/credentials/handleDeleteCredential"; +import prisma from "@calcom/prisma"; +import type { Credential, EventType, User } from "@calcom/prisma/client"; +import { BookingStatus } from "@calcom/prisma/enums"; + +describe("handleDeleteCredential Integration Tests - BookingReference Soft Delete", () => { + let testUser: User; + let testCredential: Credential; + let testEventType: EventType; + const createdBookingReferenceIds: number[] = []; + const createdBookingIds: number[] = []; + + async function deleteCredentialWithMetadata(credentialId: number, userId: number) { + const user = await prisma.user.findUnique({ + where: { id: userId }, + select: { metadata: true }, + }); + + return handleDeleteCredential({ + userId, + userMetadata: user?.metadata ?? {}, + credentialId, + }); + } + + beforeAll(async () => { + testUser = await prisma.user.create({ + data: { + email: "delete-credential-test@example.com", + username: "delete-credential-test", + }, + }); + + testCredential = await prisma.credential.create({ + data: { + type: "stripe_payment", + key: { test_key: "test_value" }, + userId: testUser.id, + appId: "stripe", + }, + }); + + testEventType = await prisma.eventType.create({ + data: { + title: "Paid Event", + slug: "paid-event-test", + length: 30, + userId: testUser.id, + price: 1000, // $10 + currency: "usd", + }, + }); + }); + + afterEach(async () => { + if (createdBookingReferenceIds.length > 0) { + await prisma.bookingReference.deleteMany({ + where: { + id: { + in: createdBookingReferenceIds, + }, + }, + }); + createdBookingReferenceIds.splice(0, createdBookingReferenceIds.length); + } + + if (createdBookingIds.length > 0) { + await prisma.attendee.deleteMany({ + where: { + bookingId: { + in: createdBookingIds, + }, + }, + }); + + await prisma.booking.deleteMany({ + where: { + id: { + in: createdBookingIds, + }, + }, + }); + createdBookingIds.splice(0, createdBookingIds.length); + } + }); + + afterAll(async () => { + await prisma.eventType.delete({ + where: { + id: testEventType.id, + }, + }); + + try { + await prisma.credential.delete({ + where: { + id: testCredential.id, + }, + }); + } catch (error) { + // Credential already deleted by test + console.log("Credential deletion error:", error); + } + + await prisma.user.delete({ + where: { + id: testUser.id, + }, + }); + }); + + describe("Soft-delete bookingReferences when deleting payment credential", () => { + it("should soft-delete booking references for unpaid bookings when credential is deleted", async () => { + const unpaidBooking = await prisma.booking.create({ + data: { + uid: "unpaid-booking-uid-123", + title: "Unpaid Booking", + startTime: new Date(Date.now() + 86400000), // Tomorrow + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.PENDING, + paid: false, + attendees: { + create: [ + { + email: "attendee@test.com", + name: "Test Attendee", + timeZone: "America/New_York", + }, + ], + }, + }, + }); + createdBookingIds.push(unpaidBooking.id); + + const bookingRef1 = await prisma.bookingReference.create({ + data: { + type: "stripe_payment", + uid: "stripe-ref-123", + meetingId: "stripe-meeting-123", + credentialId: testCredential.id, + bookingId: unpaidBooking.id, + }, + }); + createdBookingReferenceIds.push(bookingRef1.id); + + const bookingRef2 = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: "gcal-ref-123", + meetingId: "gcal-meeting-123", + credentialId: testCredential.id, + bookingId: unpaidBooking.id, + }, + }); + createdBookingReferenceIds.push(bookingRef2.id); + + const refsBeforeDeletion = await prisma.bookingReference.findMany({ + where: { + bookingId: unpaidBooking.id, + }, + }); + expect(refsBeforeDeletion).toHaveLength(2); + expect(refsBeforeDeletion.every((ref) => ref.deleted === null)).toBe(true); + + await deleteCredentialWithMetadata(testCredential.id, testUser.id); + + const refsAfterDeletion = await prisma.bookingReference.findMany({ + where: { + bookingId: unpaidBooking.id, + }, + }); + + expect(refsAfterDeletion).toHaveLength(2); + expect(refsAfterDeletion.every((ref) => ref.deleted === true)).toBe(true); + + const cancelledBooking = await prisma.booking.findUnique({ + where: { id: unpaidBooking.id }, + }); + expect(cancelledBooking?.status).toBe(BookingStatus.CANCELLED); + }); + + it("should persist soft-deleted references in database", async () => { + const newCredential = await prisma.credential.create({ + data: { + type: "stripe_payment", + key: { test_key: "test_value" }, + userId: testUser.id, + appId: "stripe", + }, + }); + + const unpaidBooking = await prisma.booking.create({ + data: { + uid: "unpaid-booking-uid-456", + title: "Another Unpaid Booking", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.PENDING, + paid: false, + attendees: { + create: [ + { + email: "attendee2@test.com", + name: "Test Attendee 2", + timeZone: "America/New_York", + }, + ], + }, + }, + }); + createdBookingIds.push(unpaidBooking.id); + + const bookingRef = await prisma.bookingReference.create({ + data: { + type: "stripe_payment", + uid: "stripe-ref-456", + meetingId: "stripe-meeting-456", + meetingUrl: "https://example.com/meeting", + credentialId: newCredential.id, + bookingId: unpaidBooking.id, + }, + }); + createdBookingReferenceIds.push(bookingRef.id); + + await deleteCredentialWithMetadata(newCredential.id, testUser.id); + + const deletedRef = await prisma.bookingReference.findUnique({ + where: { id: bookingRef.id }, + }); + + expect(deletedRef).toBeDefined(); + expect(deletedRef?.deleted).toBe(true); + expect(deletedRef?.uid).toBe("stripe-ref-456"); + expect(deletedRef?.meetingUrl).toBe("https://example.com/meeting"); + expect(deletedRef?.type).toBe("stripe_payment"); + }); + + it("should soft-delete references for multiple unpaid bookings when credential is deleted", async () => { + const newCredential = await prisma.credential.create({ + data: { + type: "stripe_payment", + key: { test_key: "test_value" }, + userId: testUser.id, + appId: "stripe", + }, + }); + + const booking1 = await prisma.booking.create({ + data: { + uid: "booking-1-uid", + title: "Booking 1", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.PENDING, + paid: false, + attendees: { + create: [ + { + email: "attendee-b1@test.com", + name: "Attendee B1", + timeZone: "America/New_York", + }, + ], + }, + }, + }); + createdBookingIds.push(booking1.id); + + const booking2 = await prisma.booking.create({ + data: { + uid: "booking-2-uid", + title: "Booking 2", + startTime: new Date(Date.now() + 172800000), // 2 days from now + endTime: new Date(Date.now() + 176400000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.PENDING, + paid: false, + attendees: { + create: [ + { + email: "attendee-b2@test.com", + name: "Attendee B2", + timeZone: "America/New_York", + }, + ], + }, + }, + }); + createdBookingIds.push(booking2.id); + + const ref1 = await prisma.bookingReference.create({ + data: { + type: "stripe_payment", + uid: "stripe-ref-b1", + meetingId: "meeting-b1", + credentialId: newCredential.id, + bookingId: booking1.id, + }, + }); + createdBookingReferenceIds.push(ref1.id); + + const ref2 = await prisma.bookingReference.create({ + data: { + type: "stripe_payment", + uid: "stripe-ref-b2", + meetingId: "meeting-b2", + credentialId: newCredential.id, + bookingId: booking2.id, + }, + }); + createdBookingReferenceIds.push(ref2.id); + + await deleteCredentialWithMetadata(newCredential.id, testUser.id); + + const allRefsAfter = await prisma.bookingReference.findMany({ + where: { + id: { + in: [ref1.id, ref2.id], + }, + }, + }); + + expect(allRefsAfter).toHaveLength(2); + expect(allRefsAfter.every((ref) => ref.deleted === true)).toBe(true); + }); + + it("should not affect references of paid bookings when credential is deleted", async () => { + const newCredential = await prisma.credential.create({ + data: { + type: "stripe_payment", + key: { test_key: "test_value" }, + userId: testUser.id, + appId: "stripe", + }, + }); + + const paidBooking = await prisma.booking.create({ + data: { + uid: "paid-booking-uid", + title: "Paid Booking", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.ACCEPTED, + paid: true, + attendees: { + create: [ + { + email: "paid-attendee@test.com", + name: "Paid Attendee", + timeZone: "America/New_York", + }, + ], + }, + }, + }); + createdBookingIds.push(paidBooking.id); + + const paidBookingRef = await prisma.bookingReference.create({ + data: { + type: "stripe_payment", + uid: "stripe-paid-ref", + meetingId: "stripe-paid-meeting", + credentialId: newCredential.id, + bookingId: paidBooking.id, + }, + }); + createdBookingReferenceIds.push(paidBookingRef.id); + + await deleteCredentialWithMetadata(newCredential.id, testUser.id); + + const refAfter = await prisma.bookingReference.findUnique({ + where: { id: paidBookingRef.id }, + }); + + expect(refAfter).toBeDefined(); + expect(refAfter?.deleted).toBe(null); + + const bookingAfter = await prisma.booking.findUnique({ + where: { id: paidBooking.id }, + }); + expect(bookingAfter?.status).toBe(BookingStatus.ACCEPTED); + }); + }); + + describe("Soft-delete behavior with queries after credential deletion", () => { + it("should exclude soft-deleted references from regular queries", async () => { + const newCredential = await prisma.credential.create({ + data: { + type: "stripe_payment", + key: { test_key: "test_value" }, + userId: testUser.id, + appId: "stripe", + }, + }); + + const unpaidBooking = await prisma.booking.create({ + data: { + uid: "query-test-booking-uid", + title: "Query Test Booking", + startTime: new Date(Date.now() + 86400000), + endTime: new Date(Date.now() + 90000000), + userId: testUser.id, + eventTypeId: testEventType.id, + status: BookingStatus.PENDING, + paid: false, + attendees: { + create: [ + { + email: "query-test@test.com", + name: "Query Test", + timeZone: "America/New_York", + }, + ], + }, + }, + }); + createdBookingIds.push(unpaidBooking.id); + + const ref = await prisma.bookingReference.create({ + data: { + type: "stripe_payment", + uid: "query-test-ref", + meetingId: "query-test-meeting", + credentialId: newCredential.id, + bookingId: unpaidBooking.id, + }, + }); + createdBookingReferenceIds.push(ref.id); + + await deleteCredentialWithMetadata(newCredential.id, testUser.id); + + const activeRefs = await prisma.bookingReference.findMany({ + where: { + bookingId: unpaidBooking.id, + deleted: null, + }, + }); + + expect(activeRefs).toHaveLength(0); + + const allRefs = await prisma.bookingReference.findMany({ + where: { + bookingId: unpaidBooking.id, + }, + }); + + expect(allRefs).toHaveLength(1); + expect(allRefs[0].deleted).toBe(true); + }); + }); +}); diff --git a/packages/features/credentials/handleDeleteCredential.ts b/packages/features/credentials/handleDeleteCredential.ts index dd58639ac8..b8787fd758 100644 --- a/packages/features/credentials/handleDeleteCredential.ts +++ b/packages/features/credentials/handleDeleteCredential.ts @@ -298,10 +298,11 @@ const handleDeleteCredential = async ({ }, }); - await prisma.bookingReference.deleteMany({ + await prisma.bookingReference.updateMany({ where: { bookingId: booking.id, }, + data: { deleted: true }, }); const attendeesListPromises = booking.attendees.map(async (attendee) => { diff --git a/packages/features/data-table/components/filters/ColumnVisibilityButton.tsx b/packages/features/data-table/components/filters/ColumnVisibilityButton.tsx index 1ccff683b9..c25894b97f 100644 --- a/packages/features/data-table/components/filters/ColumnVisibilityButton.tsx +++ b/packages/features/data-table/components/filters/ColumnVisibilityButton.tsx @@ -1,7 +1,7 @@ "use client"; import { type Table } from "@tanstack/react-table"; -// eslint-disable-next-line no-restricted-imports + import { forwardRef, useState } from "react"; import { useLocale } from "@calcom/lib/hooks/useLocale"; @@ -82,7 +82,7 @@ function ColumnVisibilityButtonComponent( }} className={classNames( buttonClasses({ color: "secondary" }), - "w-full justify-center text-center cursor-pointer mt-0" + "mt-0 w-full cursor-pointer justify-center text-center" )}> {t("show_all_columns")} diff --git a/packages/features/di/containers/AvailableSlots.ts b/packages/features/di/containers/AvailableSlots.ts index 4ddfd5b240..7ce09436e2 100644 --- a/packages/features/di/containers/AvailableSlots.ts +++ b/packages/features/di/containers/AvailableSlots.ts @@ -1,5 +1,5 @@ -import { redisModule } from "@calcom/features/redis/di/redisModule"; import { DI_TOKENS } from "@calcom/features/di/tokens"; +import { redisModule } from "@calcom/features/redis/di/redisModule"; import { prismaModule } from "@calcom/prisma/prisma.module"; import type { AvailableSlotsService } from "@calcom/trpc/server/routers/viewer/slots/util"; diff --git a/packages/features/di/containers/BookingLimits.ts b/packages/features/di/containers/BookingLimits.ts index 9aafc5e4df..e2d1f39d7e 100644 --- a/packages/features/di/containers/BookingLimits.ts +++ b/packages/features/di/containers/BookingLimits.ts @@ -1,5 +1,5 @@ -import { DI_TOKENS } from "@calcom/features/di/tokens"; import type { CheckBookingLimitsService } from "@calcom/features/bookings/lib/checkBookingLimits"; +import { DI_TOKENS } from "@calcom/features/di/tokens"; import { prismaModule } from "@calcom/prisma/prisma.module"; import type { CheckBookingAndDurationLimitsService } from "../../bookings/lib/handleNewBooking/checkBookingAndDurationLimits"; diff --git a/packages/features/di/containers/GetUserAvailability.ts b/packages/features/di/containers/GetUserAvailability.ts index a56890ea1e..6545f546cb 100644 --- a/packages/features/di/containers/GetUserAvailability.ts +++ b/packages/features/di/containers/GetUserAvailability.ts @@ -1,6 +1,6 @@ +import type { UserAvailabilityService } from "@calcom/features/availability/lib/getUserAvailability"; import { DI_TOKENS } from "@calcom/features/di/tokens"; import { redisModule } from "@calcom/features/redis/di/redisModule"; -import type { UserAvailabilityService } from "@calcom/features/availability/lib/getUserAvailability"; import { prismaModule } from "@calcom/prisma/prisma.module"; import { createContainer } from "../di"; diff --git a/packages/features/di/containers/NoSlotsNotification.ts b/packages/features/di/containers/NoSlotsNotification.ts index 6e909c42b9..8ffac5ace4 100644 --- a/packages/features/di/containers/NoSlotsNotification.ts +++ b/packages/features/di/containers/NoSlotsNotification.ts @@ -1,5 +1,5 @@ -import { redisModule } from "@calcom/features/redis/di/redisModule"; import { DI_TOKENS } from "@calcom/features/di/tokens"; +import { redisModule } from "@calcom/features/redis/di/redisModule"; import { prismaModule } from "@calcom/prisma/prisma.module"; import type { NoSlotsNotificationService } from "@calcom/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots"; diff --git a/packages/features/di/modules/Booking.ts b/packages/features/di/modules/Booking.ts index a1033f48a5..c2905fdbe6 100644 --- a/packages/features/di/modules/Booking.ts +++ b/packages/features/di/modules/Booking.ts @@ -1,5 +1,5 @@ -import { DI_TOKENS } from "@calcom/features/di/tokens"; import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { DI_TOKENS } from "@calcom/features/di/tokens"; import { type Container, createModule } from "../di"; diff --git a/packages/features/di/modules/Cache.ts b/packages/features/di/modules/Cache.ts index dcb213c035..422aa4d4f8 100644 --- a/packages/features/di/modules/Cache.ts +++ b/packages/features/di/modules/Cache.ts @@ -1,7 +1,9 @@ import { CacheService } from "@calcom/features/calendar-cache/lib/getShouldServeCache"; + import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di"; import { DI_TOKENS } from "../tokens"; import { moduleLoader as featuresRepositoryModuleLoader } from "./Features"; + export const cacheModule = createModule(); const token = DI_TOKENS.CACHE_SERVICE; const moduleToken = DI_TOKENS.CACHE_SERVICE_MODULE; diff --git a/packages/features/di/modules/CheckBookingAndDurationLimits.ts b/packages/features/di/modules/CheckBookingAndDurationLimits.ts index ced47d7df7..c2ea5d884b 100644 --- a/packages/features/di/modules/CheckBookingAndDurationLimits.ts +++ b/packages/features/di/modules/CheckBookingAndDurationLimits.ts @@ -1,4 +1,3 @@ - import { CheckBookingAndDurationLimitsService } from "@calcom/features/bookings/lib/handleNewBooking/checkBookingAndDurationLimits"; import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di"; diff --git a/packages/features/di/modules/CheckBookingLimits.ts b/packages/features/di/modules/CheckBookingLimits.ts index 1dc5ae2731..eb6ba29c22 100644 --- a/packages/features/di/modules/CheckBookingLimits.ts +++ b/packages/features/di/modules/CheckBookingLimits.ts @@ -1,5 +1,5 @@ -import { DI_TOKENS } from "@calcom/features/di/tokens"; import { CheckBookingLimitsService } from "@calcom/features/bookings/lib/checkBookingLimits"; +import { DI_TOKENS } from "@calcom/features/di/tokens"; import { type Container, createModule } from "../di"; diff --git a/packages/features/di/modules/Features.ts b/packages/features/di/modules/Features.ts index 5207d3e0e3..f902098e52 100644 --- a/packages/features/di/modules/Features.ts +++ b/packages/features/di/modules/Features.ts @@ -1,5 +1,5 @@ -import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { DI_TOKENS } from "@calcom/features/di/tokens"; +import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { type Container, createModule } from "../di"; diff --git a/packages/features/di/modules/LuckyUser.ts b/packages/features/di/modules/LuckyUser.ts index 359b928af4..7ef9f35060 100644 --- a/packages/features/di/modules/LuckyUser.ts +++ b/packages/features/di/modules/LuckyUser.ts @@ -1,5 +1,5 @@ -import { DI_TOKENS } from "@calcom/features/di/tokens"; import { LuckyUserService } from "@calcom/features/bookings/lib/getLuckyUser"; +import { DI_TOKENS } from "@calcom/features/di/tokens"; import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "../di"; import { moduleLoader as attributeRepositoryModuleLoader } from "./Attribute"; diff --git a/packages/features/di/watchlist/modules/Watchlist.module.ts b/packages/features/di/watchlist/modules/Watchlist.module.ts index 243c01eabb..5438e6e65c 100644 --- a/packages/features/di/watchlist/modules/Watchlist.module.ts +++ b/packages/features/di/watchlist/modules/Watchlist.module.ts @@ -4,18 +4,18 @@ import { DI_TOKENS } from "@calcom/features/di/tokens"; import { GlobalWatchlistRepository } from "@calcom/features/watchlist/lib/repository/GlobalWatchlistRepository"; import { OrganizationWatchlistRepository } from "@calcom/features/watchlist/lib/repository/OrganizationWatchlistRepository"; import { PrismaWatchlistAuditRepository } from "@calcom/features/watchlist/lib/repository/PrismaWatchlistAuditRepository"; - -import { WATCHLIST_DI_TOKENS } from "../Watchlist.tokens"; import { GlobalBlockingService } from "@calcom/features/watchlist/lib/service/GlobalBlockingService"; import { OrganizationBlockingService } from "@calcom/features/watchlist/lib/service/OrganizationBlockingService"; +import { WATCHLIST_DI_TOKENS } from "../Watchlist.tokens"; + export const watchlistModule = createModule(); watchlistModule.bind(WATCHLIST_DI_TOKENS.GLOBAL_BLOCKING_SERVICE).toClass(GlobalBlockingService, { globalRepo: DI_TOKENS.GLOBAL_WATCHLIST_REPOSITORY, }); -watchlistModule.bind(WATCHLIST_DI_TOKENS.ORGANIZATION_BLOCKING_SERVICE).toClass(OrganizationBlockingService,{ +watchlistModule.bind(WATCHLIST_DI_TOKENS.ORGANIZATION_BLOCKING_SERVICE).toClass(OrganizationBlockingService, { orgRepo: DI_TOKENS.ORGANIZATION_WATCHLIST_REPOSITORY, }); diff --git a/packages/features/ee/billing/credit-service.test.ts b/packages/features/ee/billing/credit-service.test.ts index b0bfa99cee..01c0f74d49 100644 --- a/packages/features/ee/billing/credit-service.test.ts +++ b/packages/features/ee/billing/credit-service.test.ts @@ -3,9 +3,9 @@ import { describe, it, expect, beforeEach, vi } from "vitest"; import dayjs from "@calcom/dayjs"; import * as EmailManager from "@calcom/emails/email-manager"; -import { CreditsRepository } from "@calcom/lib/server/repository/credits"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { CreditsRepository } from "@calcom/lib/server/repository/credits"; import { CreditType } from "@calcom/prisma/enums"; import { CreditService } from "./credit-service"; diff --git a/packages/features/ee/billing/credit-service.ts b/packages/features/ee/billing/credit-service.ts index 2ea4332acb..b0d536e1ff 100644 --- a/packages/features/ee/billing/credit-service.ts +++ b/packages/features/ee/billing/credit-service.ts @@ -7,13 +7,13 @@ import { } from "@calcom/emails/email-manager"; import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service"; import { InternalTeamBilling } from "@calcom/features/ee/billing/teams/internal-team-billing"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { cancelScheduledMessagesAndScheduleEmails } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { IS_SMS_CREDITS_ENABLED } from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; import { getTranslation } from "@calcom/lib/server/i18n"; import { CreditsRepository } from "@calcom/lib/server/repository/credits"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import prisma, { type PrismaTransaction } from "@calcom/prisma"; import type { CreditUsageType } from "@calcom/prisma/enums"; import { CreditType } from "@calcom/prisma/enums"; diff --git a/packages/features/ee/dsync/lib/handleGroupEvents.ts b/packages/features/ee/dsync/lib/handleGroupEvents.ts index 27cca705a1..26fb3226f2 100644 --- a/packages/features/ee/dsync/lib/handleGroupEvents.ts +++ b/packages/features/ee/dsync/lib/handleGroupEvents.ts @@ -1,10 +1,10 @@ import type { DirectorySyncEvent, Group } from "@boxyhq/saml-jackson"; +import { addNewMembersToEventTypes } from "@calcom/features/ee/teams/lib/queries"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { addNewMembersToEventTypes } from "@calcom/features/ee/teams/lib/queries"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import prisma from "@calcom/prisma"; import { IdentityProvider, MembershipRole } from "@calcom/prisma/enums"; import { diff --git a/packages/features/ee/organizations/lib/OrganizationPermissionService.ts b/packages/features/ee/organizations/lib/OrganizationPermissionService.ts index 6d6f8c3868..88f962e5a2 100644 --- a/packages/features/ee/organizations/lib/OrganizationPermissionService.ts +++ b/packages/features/ee/organizations/lib/OrganizationPermissionService.ts @@ -1,8 +1,8 @@ +import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; import { UserPermissionRole } from "@calcom/kysely/types"; import { ORGANIZATION_SELF_SERVE_MIN_SEATS, ORGANIZATION_SELF_SERVE_PRICE } from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/ee/organizations/lib/onboardingStore.test.ts b/packages/features/ee/organizations/lib/onboardingStore.test.ts index d16b0312a9..c850aafb20 100644 --- a/packages/features/ee/organizations/lib/onboardingStore.test.ts +++ b/packages/features/ee/organizations/lib/onboardingStore.test.ts @@ -1,13 +1,11 @@ /** * @vitest-environment jsdom */ - // @ts-nocheck - Test file with mock type compatibility issues that don't affect test functionality - -import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { renderHook, act, waitFor } from "@testing-library/react"; import { useSession } from "next-auth/react"; import { useSearchParams, useRouter, usePathname } from "next/navigation"; +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { WEBAPP_URL } from "@calcom/lib/constants"; import { UserPermissionRole } from "@calcom/prisma/enums"; @@ -19,135 +17,132 @@ import { useOnboardingStore, useOnboarding } from "./onboardingStore"; vi.mock("next-auth/react"); vi.mock("next/navigation"); vi.mock("@calcom/trpc/react", () => ({ - trpc: { - viewer: { - organizations: { - getOrganizationOnboarding: { - useQuery: vi.fn(), - }, - }, + trpc: { + viewer: { + organizations: { + getOrganizationOnboarding: { + useQuery: vi.fn(), }, + }, }, + }, })); // Mock constants vi.mock("@calcom/lib/constants", async () => { - const actual = await vi.importActual("@calcom/lib/constants"); - return { - ...actual, - IS_SELF_HOSTED: false, // Default to false, will be overridden in specific tests - }; + const actual = await vi.importActual("@calcom/lib/constants"); + return { + ...actual, + IS_SELF_HOSTED: false, // Default to false, will be overridden in specific tests + }; }); - function renderUseOnboardingStore() { - renderHook(() => useOnboarding(), { wrapper: createWrapper() }); - return renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); + renderHook(() => useOnboarding(), { wrapper: createWrapper() }); + return renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); } // Test Data Builders const createTestSession = (overrides?: { - email?: string; - role?: UserPermissionRole; - status?: "loading" | "authenticated" | "unauthenticated"; + email?: string; + role?: UserPermissionRole; + status?: "loading" | "authenticated" | "unauthenticated"; }) => { - const status = overrides?.status || "authenticated"; - - if (status === "loading") { - return { - data: null, - status: "loading" as const, - update: vi.fn(), - }; - } - - if (status === "unauthenticated") { - return { - data: null, - status: "unauthenticated" as const, - update: vi.fn(), - }; - } + const status = overrides?.status || "authenticated"; + if (status === "loading") { return { - data: { - user: { - email: overrides?.email || "test@example.com", - role: overrides?.role || UserPermissionRole.USER, - }, - }, - status: "authenticated" as const, - update: vi.fn(), + data: null, + status: "loading" as const, + update: vi.fn(), }; + } + + if (status === "unauthenticated") { + return { + data: null, + status: "unauthenticated" as const, + update: vi.fn(), + }; + } + + return { + data: { + user: { + email: overrides?.email || "test@example.com", + role: overrides?.role || UserPermissionRole.USER, + }, + }, + status: "authenticated" as const, + update: vi.fn(), + }; }; const createTestOrganizationOnboarding = (overrides?: { - isComplete?: boolean; - id?: string; - billingPeriod?: string; - pricePerSeat?: number; - seats?: number; - orgOwnerEmail?: string; - name?: string; - slug?: string; - bio?: string; - logo?: string; + isComplete?: boolean; + id?: string; + billingPeriod?: string; + pricePerSeat?: number; + seats?: number; + orgOwnerEmail?: string; + name?: string; + slug?: string; + bio?: string; + logo?: string; }) => ({ - id: overrides?.id || "test-onboarding-id", - isComplete: overrides?.isComplete ?? false, - billingPeriod: overrides?.billingPeriod || "MONTHLY", - pricePerSeat: overrides?.pricePerSeat ?? 20, - seats: overrides?.seats ?? 5, - orgOwnerEmail: overrides?.orgOwnerEmail || "test@example.com", - name: overrides?.name || "Test Organization", - slug: overrides?.slug || "test-org", - bio: overrides?.bio || "Test bio", - logo: overrides?.logo || "test-logo.png", + id: overrides?.id || "test-onboarding-id", + isComplete: overrides?.isComplete ?? false, + billingPeriod: overrides?.billingPeriod || "MONTHLY", + pricePerSeat: overrides?.pricePerSeat ?? 20, + seats: overrides?.seats ?? 5, + orgOwnerEmail: overrides?.orgOwnerEmail || "test@example.com", + name: overrides?.name || "Test Organization", + slug: overrides?.slug || "test-org", + bio: overrides?.bio || "Test bio", + logo: overrides?.logo || "test-logo.png", }); - - function mockOrganizationOnboardingFromDB(data: ReturnType | null) { - const organizationOnboarding = data ? createTestOrganizationOnboarding(data) : null; - (trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType).mockReturnValue({ - data: organizationOnboarding, - isPending: false, - isLoading: false, - error: null, - refetch: vi.fn(), - }); + const organizationOnboarding = data ? createTestOrganizationOnboarding(data) : null; + (trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType).mockReturnValue({ + data: organizationOnboarding, + isPending: false, + isLoading: false, + error: null, + refetch: vi.fn(), + }); } const createTestSearchParams = (params?: Record) => { - return new URLSearchParams(params); + return new URLSearchParams(params); }; // Mock localStorage const localStorageMock = { - getItem: vi.fn(), - setItem: vi.fn(), - removeItem: vi.fn(), - clear: vi.fn(), + getItem: vi.fn(), + setItem: vi.fn(), + removeItem: vi.fn(), + clear: vi.fn(), }; -Object.defineProperty(window, 'localStorage', { - value: localStorageMock, - writable: true, +Object.defineProperty(window, "localStorage", { + value: localStorageMock, + writable: true, }); // Mock implementations const mockRouterPush = vi.fn().mockImplementation((...args: string[]) => { - console.trace(); - console.log("mockRouterPush called", args[0]); + console.trace(); + console.log("mockRouterPush called", args[0]); }); const mockUseSession = vi.mocked(useSession); vi.mocked(useRouter).mockReturnValue({ - push: mockRouterPush, - replace: vi.fn(), - back: vi.fn(), - forward: vi.fn(), - refresh: vi.fn(), - prefetch: vi.fn(), + push: mockRouterPush, + replace: vi.fn(), + back: vi.fn(), + forward: vi.fn(), + refresh: vi.fn(), + prefetch: vi.fn(), }); const mockUsePathname = vi.mocked(usePathname); const mockUseSearchParams = vi.mocked(useSearchParams); @@ -156,234 +151,244 @@ const mockUseSearchParams = vi.mocked(useSearchParams); const createWrapper = () => undefined; describe("OnboardingStore", () => { - beforeEach(() => { - // Reset the store and let React do any side effects + beforeEach(() => { + // Reset the store and let React do any side effects + act(() => { + useOnboardingStore.getState().reset(); + }); + // Reset localStorage mock + localStorageMock.clear.mockClear(); + localStorageMock.getItem.mockClear(); + localStorageMock.setItem.mockClear(); + localStorageMock.removeItem.mockClear(); + + mockRouterPush.mockClear(); + + // Setup default mocks + mockUsePathname.mockReturnValue("/settings/organizations/new"); + mockUseSearchParams.mockReturnValue(createTestSearchParams()); + + ( + trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType + ).mockReturnValue({ + data: undefined, + isPending: false, + isLoading: false, + error: null, + refetch: vi.fn(), + }); + }); + + afterEach(() => { + act(() => { + useOnboardingStore.getState().reset(); + }); + vi.clearAllMocks(); + mockRouterPush.mockClear(); + localStorageMock.clear.mockClear(); + localStorageMock.getItem.mockClear(); + localStorageMock.setItem.mockClear(); + localStorageMock.removeItem.mockClear(); + }); + + describe("Zustand Store Actions - Complex Logic", () => { + describe("Reset Functionality", () => { + it("should reset to initial state when called without parameters", () => { + const { result } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); + + // Set some values act(() => { - useOnboardingStore.getState().reset(); + result.current.setName("Test Org"); + result.current.setSlug("test-org"); + result.current.setBillingPeriod("ANNUALLY" as const); + result.current.setSeats(15); + result.current.addInvitedMember({ email: "test@example.com", name: "Test User" }); }); - // Reset localStorage mock - localStorageMock.clear.mockClear(); - localStorageMock.getItem.mockClear(); - localStorageMock.setItem.mockClear(); - localStorageMock.removeItem.mockClear(); - mockRouterPush.mockClear(); + // Reset + act(() => { + result.current.reset(); + }); - // Setup default mocks + expect(result.current.name).toBe(""); + expect(result.current.slug).toBe(""); + expect(result.current.billingPeriod).toBeUndefined(); + expect(result.current.seats).toBeNull(); + expect(result.current.invitedMembers).toEqual([]); + }); + + it("should set specific state when called with parameters", () => { + const { result } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); + const newState = { + name: "Partial Reset Org", + slug: "partial-reset", + seats: 25, + }; + + act(() => { + result.current.reset(newState); + }); + + expect(result.current.name).toBe("Partial Reset Org"); + expect(result.current.slug).toBe("partial-reset"); + expect(result.current.seats).toBe(25); + }); + + it("should clear localStorage when resetting without parameters", () => { + const { result } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); + + // Set some values to trigger localStorage save + act(() => { + result.current.setName("Test Org"); + }); + + // Reset + act(() => { + result.current.reset(); + }); + + // Verify localStorage removeItem was called + expect(localStorageMock.removeItem).toHaveBeenCalledWith("org-creation-onboarding"); + }); + }); + }); + + describe("useOnboarding Hook", () => { + beforeEach(() => { + mockUseSession.mockReturnValue(createTestSession()); + }); + + describe("Authentication Handling", () => { + it("should redirect to login when session is unauthenticated", async () => { + mockUseSession.mockReturnValue(createTestSession({ status: "unauthenticated" })); mockUsePathname.mockReturnValue("/settings/organizations/new"); mockUseSearchParams.mockReturnValue(createTestSearchParams()); - (trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType).mockReturnValue({ - data: undefined, - isPending: false, - isLoading: false, - error: null, - refetch: vi.fn(), - }); - }); + renderHook(() => useOnboarding(), { wrapper: createWrapper() }); - afterEach(() => { - act(() => { - useOnboardingStore.getState().reset(); + await waitFor(() => { + expect(mockRouterPush).toHaveBeenCalledWith( + `/auth/login?callbackUrl=${WEBAPP_URL}/settings/organizations/new` + ); }); - vi.clearAllMocks(); mockRouterPush.mockClear(); - localStorageMock.clear.mockClear(); - localStorageMock.getItem.mockClear(); - localStorageMock.setItem.mockClear(); - localStorageMock.removeItem.mockClear(); + expect(mockRouterPush).not.toHaveBeenCalled(); + }); + + it("should not redirect when session is authenticated", () => { + expect(mockRouterPush).not.toHaveBeenCalled(); + mockUseSession.mockReturnValue(createTestSession({ status: "authenticated" })); + + renderHook(() => useOnboarding(), { wrapper: createWrapper() }); + + expect(mockRouterPush).not.toHaveBeenCalled(); + }); }); - describe("Zustand Store Actions - Complex Logic", () => { - describe("Reset Functionality", () => { - it("should reset to initial state when called without parameters", () => { - const { result } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); - - // Set some values - act(() => { - result.current.setName("Test Org"); - result.current.setSlug("test-org"); - result.current.setBillingPeriod("ANNUALLY" as const); - result.current.setSeats(15); - result.current.addInvitedMember({ email: "test@example.com", name: "Test User" }); - }); - - // Reset - act(() => { - result.current.reset(); - }); - - expect(result.current.name).toBe(""); - expect(result.current.slug).toBe(""); - expect(result.current.billingPeriod).toBeUndefined(); - expect(result.current.seats).toBeNull(); - expect(result.current.invitedMembers).toEqual([]); - }); - - it("should set specific state when called with parameters", () => { - const { result } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); - const newState = { - name: "Partial Reset Org", - slug: "partial-reset", - seats: 25, - }; - - act(() => { - result.current.reset(newState); - }); - - expect(result.current.name).toBe("Partial Reset Org"); - expect(result.current.slug).toBe("partial-reset"); - expect(result.current.seats).toBe(25); - }); - - it("should clear localStorage when resetting without parameters", () => { - const { result } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); - - // Set some values to trigger localStorage save - act(() => { - result.current.setName("Test Org"); - }); - - // Reset - act(() => { - result.current.reset(); - }); - - // Verify localStorage removeItem was called - expect(localStorageMock.removeItem).toHaveBeenCalledWith("org-creation-onboarding"); - }); - }); - }); - - describe("useOnboarding Hook", () => { - beforeEach(() => { - mockUseSession.mockReturnValue(createTestSession()); - }); - - describe("Authentication Handling", () => { - it("should redirect to login when session is unauthenticated", async () => { - mockUseSession.mockReturnValue(createTestSession({ status: "unauthenticated" })); - mockUsePathname.mockReturnValue("/settings/organizations/new"); - mockUseSearchParams.mockReturnValue(createTestSearchParams()); - - renderHook(() => useOnboarding(), { wrapper: createWrapper() }); - - await waitFor(() => { - expect(mockRouterPush).toHaveBeenCalledWith( - `/auth/login?callbackUrl=${WEBAPP_URL}/settings/organizations/new` - ); - }); - mockRouterPush.mockClear(); - expect(mockRouterPush).not.toHaveBeenCalled(); - }); - - it("should not redirect when session is authenticated", () => { - expect(mockRouterPush).not.toHaveBeenCalled(); - mockUseSession.mockReturnValue(createTestSession({ status: "authenticated" })); - - renderHook(() => useOnboarding(), { wrapper: createWrapper() }); - - expect(mockRouterPush).not.toHaveBeenCalled(); - }); - }); - - describe("Organization Onboarding State Sync", () => { - it("should return organization onboarding data when available", () => { - const organizationOnboarding = createTestOrganizationOnboarding({ - name: "Test Org", - slug: "test-org", - }); - - (trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType).mockReturnValue({ - data: organizationOnboarding, - isPending: false, - isLoading: false, - error: null, - refetch: vi.fn(), - }); - - const { result } = renderHook(() => useOnboarding(), { wrapper: createWrapper() }); - - expect(result.current.dbOnboarding).toEqual(organizationOnboarding); - expect(result.current.isLoadingOrgOnboarding).toBe(false); - }); - - it("should set onboardingData from DB to zustand if not set already", async () => { - const organizationOnboarding = createTestOrganizationOnboarding({ - id: "sync-test-id", - name: "Synced Organization", - slug: "synced-org", - bio: "Synced bio content", - logo: "synced-logo.png", - billingPeriod: "ANNUALLY", - pricePerSeat: 25, - seats: 10, - orgOwnerEmail: "owner@synced.com", - }); - - (trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType).mockReturnValue({ - data: organizationOnboarding, - isPending: false, - isLoading: false, - error: null, - refetch: vi.fn(), - }); - - renderHook(() => useOnboarding(), { wrapper: createWrapper() }); - const { result: storeResult } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); - - await waitFor(() => { - expect(storeResult.current.onboardingId).toBe("sync-test-id"); - }); - - expect(storeResult.current.name).toBe("Synced Organization"); - expect(storeResult.current.slug).toBe("synced-org"); - expect(storeResult.current.bio).toBe("Synced bio content"); - expect(storeResult.current.logo).toBe("synced-logo.png"); - expect(storeResult.current.billingPeriod).toBe("ANNUALLY"); - expect(storeResult.current.pricePerSeat).toBe(25); - expect(storeResult.current.seats).toBe(10); - expect(storeResult.current.orgOwnerEmail).toBe("owner@synced.com"); - }); - - it("should sync onboardingData from DB to zustand if set already", async () => { - mockOrganizationOnboardingFromDB(createTestOrganizationOnboarding({ - id: "onboarding1", - name: "Onboarding 1 Organization", - slug: "onboarding1-org", - bio: "Onboarding 1 bio content", - logo: "onboarding1-logo.png", - billingPeriod: "MONTHLY", - pricePerSeat: 15, - seats: 5, - orgOwnerEmail: "owner@onboarding1.com", - })) - - // Load the store to set the initial state - const { result: storeResultBefore } = renderUseOnboardingStore(); - - expect(storeResultBefore.current.name).toBe("Onboarding 1 Organization"); - expect(storeResultBefore.current.slug).toBe("onboarding1-org"); - - mockOrganizationOnboardingFromDB(createTestOrganizationOnboarding({ - id: "sync-test-id", - name: "Synced Organization", - slug: "synced-org", - bio: "Synced bio content", - logo: "synced-logo.png", - billingPeriod: "ANNUALLY", - pricePerSeat: 25, - seats: 10, - orgOwnerEmail: "owner@synced.com", - })); - - // Load the store to sync the new data - const { result: storeResultAfter } = renderUseOnboardingStore(); - // Verify the data is synced - expect(storeResultAfter.current.name).toBe("Synced Organization"); - expect(storeResultAfter.current.slug).toBe("synced-org"); - }); + describe("Organization Onboarding State Sync", () => { + it("should return organization onboarding data when available", () => { + const organizationOnboarding = createTestOrganizationOnboarding({ + name: "Test Org", + slug: "test-org", }); + + ( + trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType + ).mockReturnValue({ + data: organizationOnboarding, + isPending: false, + isLoading: false, + error: null, + refetch: vi.fn(), + }); + + const { result } = renderHook(() => useOnboarding(), { wrapper: createWrapper() }); + + expect(result.current.dbOnboarding).toEqual(organizationOnboarding); + expect(result.current.isLoadingOrgOnboarding).toBe(false); + }); + + it("should set onboardingData from DB to zustand if not set already", async () => { + const organizationOnboarding = createTestOrganizationOnboarding({ + id: "sync-test-id", + name: "Synced Organization", + slug: "synced-org", + bio: "Synced bio content", + logo: "synced-logo.png", + billingPeriod: "ANNUALLY", + pricePerSeat: 25, + seats: 10, + orgOwnerEmail: "owner@synced.com", + }); + + ( + trpc.viewer.organizations.getOrganizationOnboarding.useQuery as ReturnType + ).mockReturnValue({ + data: organizationOnboarding, + isPending: false, + isLoading: false, + error: null, + refetch: vi.fn(), + }); + + renderHook(() => useOnboarding(), { wrapper: createWrapper() }); + const { result: storeResult } = renderHook(() => useOnboardingStore(), { wrapper: createWrapper() }); + + await waitFor(() => { + expect(storeResult.current.onboardingId).toBe("sync-test-id"); + }); + + expect(storeResult.current.name).toBe("Synced Organization"); + expect(storeResult.current.slug).toBe("synced-org"); + expect(storeResult.current.bio).toBe("Synced bio content"); + expect(storeResult.current.logo).toBe("synced-logo.png"); + expect(storeResult.current.billingPeriod).toBe("ANNUALLY"); + expect(storeResult.current.pricePerSeat).toBe(25); + expect(storeResult.current.seats).toBe(10); + expect(storeResult.current.orgOwnerEmail).toBe("owner@synced.com"); + }); + + it("should sync onboardingData from DB to zustand if set already", async () => { + mockOrganizationOnboardingFromDB( + createTestOrganizationOnboarding({ + id: "onboarding1", + name: "Onboarding 1 Organization", + slug: "onboarding1-org", + bio: "Onboarding 1 bio content", + logo: "onboarding1-logo.png", + billingPeriod: "MONTHLY", + pricePerSeat: 15, + seats: 5, + orgOwnerEmail: "owner@onboarding1.com", + }) + ); + + // Load the store to set the initial state + const { result: storeResultBefore } = renderUseOnboardingStore(); + + expect(storeResultBefore.current.name).toBe("Onboarding 1 Organization"); + expect(storeResultBefore.current.slug).toBe("onboarding1-org"); + + mockOrganizationOnboardingFromDB( + createTestOrganizationOnboarding({ + id: "sync-test-id", + name: "Synced Organization", + slug: "synced-org", + bio: "Synced bio content", + logo: "synced-logo.png", + billingPeriod: "ANNUALLY", + pricePerSeat: 25, + seats: 10, + orgOwnerEmail: "owner@synced.com", + }) + ); + + // Load the store to sync the new data + const { result: storeResultAfter } = renderUseOnboardingStore(); + // Verify the data is synced + expect(storeResultAfter.current.name).toBe("Synced Organization"); + expect(storeResultAfter.current.slug).toBe("synced-org"); + }); }); + }); }); diff --git a/packages/features/ee/organizations/lib/server/orgCreationUtils.ts b/packages/features/ee/organizations/lib/server/orgCreationUtils.ts index 6bc078f440..9aead5b715 100644 --- a/packages/features/ee/organizations/lib/server/orgCreationUtils.ts +++ b/packages/features/ee/organizations/lib/server/orgCreationUtils.ts @@ -3,6 +3,7 @@ import { type TFunction } from "i18next"; import { sendAdminOrganizationNotification } from "@calcom/emails"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { RESERVED_SUBDOMAINS, ORG_MINIMUM_PUBLISHED_TEAMS_SELF_SERVE, @@ -12,7 +13,6 @@ import { import { createDomain } from "@calcom/lib/domainManager/organization"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import { UserPermissionRole } from "@calcom/prisma/enums"; diff --git a/packages/features/ee/organizations/pages/components/OtherTeamList.tsx b/packages/features/ee/organizations/pages/components/OtherTeamList.tsx index 8e501f1abf..aafcfac3bb 100644 --- a/packages/features/ee/organizations/pages/components/OtherTeamList.tsx +++ b/packages/features/ee/organizations/pages/components/OtherTeamList.tsx @@ -2,8 +2,8 @@ import { useState } from "react"; -import { trackFormbricksAction } from "@calcom/lib/formbricks-client"; import type { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import { trackFormbricksAction } from "@calcom/lib/formbricks-client"; import { trpc } from "@calcom/trpc/react"; import { showToast } from "@calcom/ui/components/toast"; diff --git a/packages/features/ee/organizations/pages/components/OtherTeamsListing.tsx b/packages/features/ee/organizations/pages/components/OtherTeamsListing.tsx index e76929207c..50c39cb32c 100644 --- a/packages/features/ee/organizations/pages/components/OtherTeamsListing.tsx +++ b/packages/features/ee/organizations/pages/components/OtherTeamsListing.tsx @@ -1,7 +1,7 @@ "use client"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; import type { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; import { EmptyScreen } from "@calcom/ui/components/empty-screen"; import OtherTeamList from "./OtherTeamList"; diff --git a/packages/features/ee/organizations/repositories/OrganizationRepository.ts b/packages/features/ee/organizations/repositories/OrganizationRepository.ts index a0990df4b7..ed038ba484 100644 --- a/packages/features/ee/organizations/repositories/OrganizationRepository.ts +++ b/packages/features/ee/organizations/repositories/OrganizationRepository.ts @@ -1,8 +1,8 @@ import type { z } from "zod"; import { getOrgUsernameFromEmail } from "@calcom/features/auth/signup/utils/getOrgUsernameFromEmail"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getParsedTeam } from "@calcom/lib/server/repository/teamUtils"; diff --git a/packages/features/ee/payments/pages/payment.tsx b/packages/features/ee/payments/pages/payment.tsx index c3ee0b906c..f3e086fdb3 100644 --- a/packages/features/ee/payments/pages/payment.tsx +++ b/packages/features/ee/payments/pages/payment.tsx @@ -47,7 +47,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => if (!eventType) return { notFound: true } as const; - if (eventType.users.length === 0 && !!!eventType.team) return { notFound: true } as const; + if (eventType.users.length === 0 && !eventType.team) return { notFound: true } as const; const [user] = eventType?.users.length ? eventType.users diff --git a/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts b/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts index cfc972762c..50c7c9ff22 100644 --- a/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts +++ b/packages/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder.ts @@ -1,6 +1,6 @@ +import { acrossQueryValueCompatiblity } from "@calcom/app-store/_utils/raqb/raqbUtils"; import type { FormResponse, Fields } from "@calcom/app-store/routing-forms/types/types"; import { zodRoutes } from "@calcom/app-store/routing-forms/zod"; -import { acrossQueryValueCompatiblity } from "@calcom/app-store/_utils/raqb/raqbUtils"; import { withReporting } from "@calcom/lib/sentryWrapper"; import { getUsersAttributes } from "@calcom/lib/service/attribute/server/getAttributes"; import prisma from "@calcom/prisma"; diff --git a/packages/features/ee/round-robin/roundRobinManualReassignment.ts b/packages/features/ee/round-robin/roundRobinManualReassignment.ts index ff07e155e1..ea0a3e8717 100644 --- a/packages/features/ee/round-robin/roundRobinManualReassignment.ts +++ b/packages/features/ee/round-robin/roundRobinManualReassignment.ts @@ -14,6 +14,7 @@ import { getAllCredentialsIncludeServiceAccountKey } from "@calcom/features/book import getBookingResponsesSchema from "@calcom/features/bookings/lib/getBookingResponsesSchema"; import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBooking/getEventTypesFromDB"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import AssignmentReasonRecorder, { RRReassignmentType, } from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder"; @@ -26,7 +27,6 @@ import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/rem import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming"; import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser"; import { SENDER_NAME } from "@calcom/lib/constants"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { IdempotencyKeyService } from "@calcom/lib/idempotencyKey/idempotencyKeyService"; import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj"; import logger from "@calcom/lib/logger"; diff --git a/packages/features/ee/sso/lib/sso.ts b/packages/features/ee/sso/lib/sso.ts index 4915ee5dbc..f8007c18ea 100644 --- a/packages/features/ee/sso/lib/sso.ts +++ b/packages/features/ee/sso/lib/sso.ts @@ -1,6 +1,6 @@ import createUsersAndConnectToOrg from "@calcom/features/ee/dsync/lib/users/createUsersAndConnectToOrg"; -import { HOSTED_CAL_FEATURES } from "@calcom/lib/constants"; import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import { HOSTED_CAL_FEATURES } from "@calcom/lib/constants"; import type { PrismaClient } from "@calcom/prisma"; import { IdentityProvider } from "@calcom/prisma/enums"; diff --git a/packages/features/ee/support/lib/intercom/useIntercom.ts b/packages/features/ee/support/lib/intercom/useIntercom.ts index 56714f34a7..a639483c25 100644 --- a/packages/features/ee/support/lib/intercom/useIntercom.ts +++ b/packages/features/ee/support/lib/intercom/useIntercom.ts @@ -1,4 +1,3 @@ - import { noop } from "lodash"; import { useEffect } from "react"; import type { IntercomBootProps, IntercomProps } from "react-use-intercom"; @@ -13,18 +12,17 @@ import useMediaQuery from "@calcom/lib/hooks/useMediaQuery"; import { localStorage } from "@calcom/lib/webstorage"; import { trpc } from "@calcom/trpc/react"; - export const isInterComEnabled = z.string().min(1).safeParse(process.env.NEXT_PUBLIC_INTERCOM_APP_ID).success; const useIntercomHook = isInterComEnabled ? useIntercomLib : () => { return { - // eslint-disable-next-line + boot: (_props: IntercomBootProps) => {}, show: noop, shutdown: noop, - // eslint-disable-next-line + update: (_props: Partial) => {}, }; }; diff --git a/packages/features/ee/teams/lib/queries.ts b/packages/features/ee/teams/lib/queries.ts index 5a5b660338..461b49764a 100644 --- a/packages/features/ee/teams/lib/queries.ts +++ b/packages/features/ee/teams/lib/queries.ts @@ -1,13 +1,13 @@ import { z } from "zod"; import { getAppFromSlug } from "@calcom/app-store/utils"; -import { DATABASE_CHUNK_SIZE } from "@calcom/lib/constants"; import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; +import { getTeam, getOrg } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { DATABASE_CHUNK_SIZE } from "@calcom/lib/constants"; import { parseBookingLimit } from "@calcom/lib/intervalLimits/isBookingLimits"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { getTeam, getOrg } from "@calcom/features/ee/teams/repositories/TeamRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { Team } from "@calcom/prisma/client"; diff --git a/packages/features/ee/teams/services/teamService.alternative.test.ts b/packages/features/ee/teams/services/teamService.alternative.test.ts index 2d15dbcfaa..a2628d78e0 100644 --- a/packages/features/ee/teams/services/teamService.alternative.test.ts +++ b/packages/features/ee/teams/services/teamService.alternative.test.ts @@ -3,9 +3,9 @@ import { prisma } from "@calcom/prisma/__mocks__/prisma"; import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { TeamBilling } from "@calcom/features/ee/billing/teams"; -import { deleteDomain } from "@calcom/lib/domainManager/organization"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; +import { deleteDomain } from "@calcom/lib/domainManager/organization"; import { TeamService } from "./teamService"; diff --git a/packages/features/ee/teams/services/teamService.test.ts b/packages/features/ee/teams/services/teamService.test.ts index 657bb5f4ca..0c1df1c3f6 100644 --- a/packages/features/ee/teams/services/teamService.test.ts +++ b/packages/features/ee/teams/services/teamService.test.ts @@ -4,10 +4,10 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; import { TeamBilling } from "@calcom/features/ee/billing/teams"; import { updateNewTeamMemberEventTypes } from "@calcom/features/ee/teams/lib/queries"; -import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; -import { deleteDomain } from "@calcom/lib/domainManager/organization"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; +import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; +import { deleteDomain } from "@calcom/lib/domainManager/organization"; import type { Membership, Team, User, VerificationToken, Profile } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/ee/teams/services/teamService.ts b/packages/features/ee/teams/services/teamService.ts index 66256e2e83..b7aa220aba 100644 --- a/packages/features/ee/teams/services/teamService.ts +++ b/packages/features/ee/teams/services/teamService.ts @@ -3,16 +3,16 @@ import { randomBytes } from "crypto"; import { TeamBilling } from "@calcom/features/ee/billing/teams"; import { deleteWorkfowRemindersOfRemovedMember } from "@calcom/features/ee/teams/lib/deleteWorkflowRemindersOfRemovedMember"; import { updateNewTeamMemberEventTypes } from "@calcom/features/ee/teams/lib/queries"; -import { WEBAPP_URL } from "@calcom/lib/constants"; -import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; -import { deleteDomain } from "@calcom/lib/domainManager/organization"; -import logger from "@calcom/lib/logger"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; +import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; +import { WEBAPP_URL } from "@calcom/lib/constants"; +import { deleteDomain } from "@calcom/lib/domainManager/organization"; +import logger from "@calcom/lib/logger"; import { prisma } from "@calcom/prisma"; -import { Prisma } from "@calcom/prisma/client"; import type { Membership } from "@calcom/prisma/client"; +import { Prisma } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; import { TRPCError } from "@trpc/server"; @@ -269,13 +269,7 @@ export class TeamService { await updateNewTeamMemberEventTypes(userId, teamId); } - static async leaveTeamMembership({ - userId, - teamId, - }: { - userId: number; - teamId: number; - }) { + static async leaveTeamMembership({ userId, teamId }: { userId: number; teamId: number }) { try { const membership = await prisma.membership.delete({ where: { diff --git a/packages/features/ee/workflows/api/scheduleSMSReminders.ts b/packages/features/ee/workflows/api/scheduleSMSReminders.ts index 6959bd5f37..f724516ebc 100644 --- a/packages/features/ee/workflows/api/scheduleSMSReminders.ts +++ b/packages/features/ee/workflows/api/scheduleSMSReminders.ts @@ -5,9 +5,9 @@ import { NextResponse } from "next/server"; import dayjs from "@calcom/dayjs"; import { bulkShortenLinks } from "@calcom/ee/workflows/lib/reminders/utils"; import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { isAttendeeAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions"; import { scheduleSmsOrFallbackEmail } from "@calcom/features/ee/workflows/lib/reminders/messageDispatcher"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { getTranslation } from "@calcom/lib/server/i18n"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import prisma from "@calcom/prisma"; diff --git a/packages/features/ee/workflows/components/WorkflowListPage.tsx b/packages/features/ee/workflows/components/WorkflowListPage.tsx index bab32ccaab..1b831db1a0 100644 --- a/packages/features/ee/workflows/components/WorkflowListPage.tsx +++ b/packages/features/ee/workflows/components/WorkflowListPage.tsx @@ -229,7 +229,7 @@ export default function WorkflowListPage({ workflows }: Props) {
{workflow.team?.name && ( - + { const CalAIAgentDataSkeleton = () => { return ( -
-
+
+
- -
- - - + +
+ + +
-
- - +
+ +
@@ -517,7 +517,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) { return ( <>
- +
{!!timeSectionText && ( -
- +
+
)} @@ -601,7 +601,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) { {selectedOptions && setSelectedOptions && allOptions && (
{isOrganization ? ( -
+
@@ -668,7 +668,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
)} {!!timeSectionText && ( -
+

{t("testing_sms_workflow_info_message")}

@@ -815,12 +815,12 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) { />
-
{t("sender_id_info")}
+
{t("sender_id_info")}
{form.formState.errors.steps && form.formState?.errors?.steps[step.stepNumber - 1]?.sender && ( -

{t("sender_id_error_message")}

+

{t("sender_id_error_message")}

)} ) : ( @@ -839,23 +839,23 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
)} {isCalAIAction(form.getValues(`steps.${step.stepNumber - 1}.action`)) && !stepAgentId && ( -
-
+
+
-

+

{t("cal_ai_agent")} - + {t("set_up_required")}

-

+

{t("no_phone_number_connected")}.

{form.formState.errors.steps && form.formState?.errors?.steps[step.stepNumber - 1]?.sendTo && ( -

+

{form.formState?.errors?.steps[step.stepNumber - 1]?.sendTo?.message || ""}

)} @@ -1176,9 +1176,9 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) { ) : ( !props.readOnly && ( <> -
+
-
+
{form.formState.errors.steps && form.formState?.errors?.steps[step.stepNumber - 1]?.sendTo && ( -

+

{form.formState?.errors?.steps[step.stepNumber - 1]?.sendTo?.message || ""}

)} @@ -1295,7 +1295,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
)} {!isCalAIAction(form.getValues(`steps.${step.stepNumber - 1}.action`)) && ( -
+
{isEmailSubjectNeeded && (
@@ -1328,14 +1328,14 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) { /> {form.formState.errors.steps && form.formState?.errors?.steps[step.stepNumber - 1]?.emailSubject && ( -

+

{form.formState?.errors?.steps[step.stepNumber - 1]?.emailSubject?.message || ""}

)}
)} -
-
)} {!props.readOnly && !isFormTrigger(trigger) && ( -
+
@@ -1503,23 +1503,23 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {

{t("how_booking_questions_as_variables")}

-
-

{t("format")}

-
    +
    +

    {t("format")}

    +
    • {t("uppercase_for_letters")}
    • {t("replace_whitespaces_underscores")}
    • {t("ignore_special_characters_booking_questions")}
    -

    {t("example_1")}

    -
    -
    +

    {t("example_1")}

    +
    +
    {t("booking_question_identifier")}
    -
    {t("company_size")}
    -
    {t("variable")}
    +
    {t("company_size")}
    +
    {t("variable")}
    -
    +
    {" "} {`{${t("company_size") .replace(/[^a-zA-Z0-9 ]/g, "") @@ -1530,14 +1530,14 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
    -

    {t("example_2")}

    -
    -
    +

    {t("example_2")}

    +
    +
    {t("booking_question_identifier")}
    -
    {t("what_help_needed")}
    -
    {t("variable")}
    -
    +
    {t("what_help_needed")}
    +
    {t("variable")}
    +
    {" "} {`{${t("what_help_needed") .replace(/[^a-zA-Z0-9 ]/g, "") @@ -1607,17 +1607,17 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
    -

    {t("do_you_still_want_to_unsubscribe")}

    +

    {t("do_you_still_want_to_unsubscribe")}

    {getActivePhoneNumbers( agentData?.outboundPhoneNumbers?.map((phone) => ({ ...phone, subscriptionStatus: phone.subscriptionStatus ?? undefined, })) ).length > 0 && ( -
    -
    - - +
    +
    + + {formatPhoneNumber( getActivePhoneNumbers( agentData?.outboundPhoneNumbers?.map((phone) => ({ @@ -1630,7 +1630,7 @@ export default function WorkflowStepContainer(props: WorkflowStepProps) {
    )} -

    {t("the_action_will_disconnect_phone_number")}

    +

    {t("the_action_will_disconnect_phone_number")}

    - { - const isChecked = e.target.checked; - formMethods.setValue( - "periodDays", - Math.min(periodDaysWatch, ROLLING_WINDOW_PERIOD_MAX_DAYS_TO_CHECK) - ); - formMethods.setValue( - "periodType", - getPeriodTypeFromUiValue({ - value: PeriodType.ROLLING, - rollingExcludeUnavailableDays: isChecked, - }), - { shouldDirty: true } - ); - }} - /> - - { + const isChecked = e.target.checked; + formMethods.setValue( + "periodDays", + Math.min(periodDaysWatch, ROLLING_WINDOW_PERIOD_MAX_DAYS_TO_CHECK) + ); + formMethods.setValue( + "periodType", + getPeriodTypeFromUiValue({ + value: PeriodType.ROLLING, + rollingExcludeUnavailableDays: isChecked, + }), + { shouldDirty: true } + ); + }} /> - + + +
    diff --git a/packages/features/eventtypes/lib/getEventTypeById.ts b/packages/features/eventtypes/lib/getEventTypeById.ts index d2e38f4fe3..ae0bfaa840 100644 --- a/packages/features/eventtypes/lib/getEventTypeById.ts +++ b/packages/features/eventtypes/lib/getEventTypeById.ts @@ -4,16 +4,16 @@ import { getLocationGroupedOptions } from "@calcom/app-store/server"; import { getEventTypeAppData } from "@calcom/app-store/utils"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/getBookingFields"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { WEBSITE_URL } from "@calcom/lib/constants"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { parseBookingLimit } from "@calcom/lib/intervalLimits/isBookingLimits"; import { parseDurationLimit } from "@calcom/lib/intervalLimits/isDurationLimits"; import { parseEventTypeColor } from "@calcom/lib/isEventTypeColor"; import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import type { PrismaClient } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import { SchedulingType, MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/eventtypes/lib/getEventTypesByViewer.ts b/packages/features/eventtypes/lib/getEventTypesByViewer.ts index e064e24d34..12fb8886f4 100644 --- a/packages/features/eventtypes/lib/getEventTypesByViewer.ts +++ b/packages/features/eventtypes/lib/getEventTypesByViewer.ts @@ -1,19 +1,18 @@ -// eslint-disable-next-line no-restricted-imports import { orderBy } from "lodash"; -import { hasFilter } from "@calcom/features/filters/lib/hasFilter"; -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; +import { hasFilter } from "@calcom/features/filters/lib/hasFilter"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; +import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import logger from "@calcom/lib/logger"; import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import { MembershipRole, SchedulingType } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; @@ -123,7 +122,7 @@ export const getEventTypesByViewer = async (user: User, filters?: Filters, forRo ...eventType, safeDescription: eventType?.description ? markdownToSafeHTML(eventType.description) : undefined, users: await Promise.all( - (!!eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users).map( + (eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users).map( async (u) => await userRepo.enrichUserWithItsProfile({ user: u, diff --git a/packages/features/eventtypes/lib/getPublicEvent.ts b/packages/features/eventtypes/lib/getPublicEvent.ts index 17c516dabe..75d3fc1fe3 100644 --- a/packages/features/eventtypes/lib/getPublicEvent.ts +++ b/packages/features/eventtypes/lib/getPublicEvent.ts @@ -4,15 +4,15 @@ import { getAppFromSlug } from "@calcom/app-store/utils"; import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; import dayjs from "@calcom/dayjs"; import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/getBookingFields"; +import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains"; +import { getDefaultEvent, getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { getOrgOrTeamAvatar } from "@calcom/lib/defaultAvatarImage"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { getDefaultEvent, getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; -import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import { isRecurringEvent, parseRecurringEvent } from "@calcom/lib/isRecurringEvent"; import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import type { PrismaClient } from "@calcom/prisma"; import type { User as UserType } from "@calcom/prisma/client"; import type { Prisma } from "@calcom/prisma/client"; @@ -635,7 +635,7 @@ export async function getUsersFromEvent( ) { const { team, hosts, subsetOfHosts, owner, id } = event; if (team) { - const eventHosts = !!hosts?.length ? hosts : subsetOfHosts; + const eventHosts = hosts?.length ? hosts : subsetOfHosts; // getOwnerFromUsersArray is used here for backward compatibility when team event type has users[] but not hosts[] return eventHosts.length ? eventHosts.filter((host) => host.user.username).map(mapHostsToUsers) diff --git a/packages/features/eventtypes/repositories/eventTypeRepository.ts b/packages/features/eventtypes/repositories/eventTypeRepository.ts index bb6cfebc84..b90d013b8d 100644 --- a/packages/features/eventtypes/repositories/eventTypeRepository.ts +++ b/packages/features/eventtypes/repositories/eventTypeRepository.ts @@ -1,10 +1,10 @@ +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { LookupTarget, ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import type { UserWithLegacySelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { eventTypeSelect } from "@calcom/lib/server/eventTypeSelect"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import type { PrismaClient } from "@calcom/prisma"; import { prisma, availabilityUserSelect } from "@calcom/prisma"; import type { EventType as PrismaEventType } from "@calcom/prisma/client"; diff --git a/packages/features/form-builder/FormBuilder.tsx b/packages/features/form-builder/FormBuilder.tsx index 0bf7f725e3..17f8fa9898 100644 --- a/packages/features/form-builder/FormBuilder.tsx +++ b/packages/features/form-builder/FormBuilder.tsx @@ -426,7 +426,7 @@ export const FormBuilder = function FormBuilder({ function Options({ label = "Options", value, - // eslint-disable-next-line @typescript-eslint/no-empty-function + onChange = () => {}, className = "", readOnly = false, @@ -700,7 +700,7 @@ function FieldEditDialog({ /> ) : null} - {!!fieldType?.supportsLengthCheck ? ( + {fieldType?.supportsLengthCheck ? ( ) : null} diff --git a/packages/features/handleMarkNoShow.ts b/packages/features/handleMarkNoShow.ts index b33cd78b68..177ffdceb8 100644 --- a/packages/features/handleMarkNoShow.ts +++ b/packages/features/handleMarkNoShow.ts @@ -4,12 +4,12 @@ import { BookingRepository } from "@calcom/features/bookings/repositories/Bookin import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { workflowSelect } from "@calcom/features/ee/workflows/lib/getAllWorkflows"; import type { ExtendedCalendarEvent } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import { WebhookService } from "@calcom/features/webhooks/lib/WebhookService"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import { prisma } from "@calcom/prisma"; import { WebhookTriggerEvents, WorkflowTriggerEvents } from "@calcom/prisma/enums"; @@ -249,7 +249,7 @@ const handleMarkNoShow = async ({ : booking.user?.destinationCalendar ? [booking.user?.destinationCalendar] : []; - const team = !!booking.eventType?.team + const team = booking.eventType?.team ? { name: booking.eventType.team.name, id: booking.eventType.team.id, diff --git a/packages/features/insights/server/routing-events.ts b/packages/features/insights/server/routing-events.ts index 35725af575..5c17974cab 100644 --- a/packages/features/insights/server/routing-events.ts +++ b/packages/features/insights/server/routing-events.ts @@ -1,6 +1,6 @@ -// eslint-disable-next-line no-restricted-imports + import mapKeys from "lodash/mapKeys"; -// eslint-disable-next-line no-restricted-imports + import startCase from "lodash/startCase"; import { diff --git a/packages/features/insights/server/trpc-router.ts b/packages/features/insights/server/trpc-router.ts index 65022aae2b..0367ecf671 100644 --- a/packages/features/insights/server/trpc-router.ts +++ b/packages/features/insights/server/trpc-router.ts @@ -1,6 +1,8 @@ import { z } from "zod"; import dayjs from "@calcom/dayjs"; +import { getInsightsBookingService } from "@calcom/features/di/containers/InsightsBooking"; +import { getInsightsRoutingService } from "@calcom/features/di/containers/InsightsRouting"; import { extractDateRangeFromColumnFilters, replaceDateRangeColumnFilter, @@ -13,8 +15,6 @@ import { routedToPerPeriodCsvInputSchema, bookingRepositoryBaseInputSchema, } from "@calcom/features/insights/server/raw-data.schema"; -import { getInsightsBookingService } from "@calcom/features/di/containers/InsightsBooking"; -import { getInsightsRoutingService } from "@calcom/features/di/containers/InsightsRouting"; import type { PrismaClient } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import authedProcedure from "@calcom/trpc/server/procedures/authedProcedure"; diff --git a/packages/features/insights/services/InsightsBookingBaseService.ts b/packages/features/insights/services/InsightsBookingBaseService.ts index 6272aa0c94..4f35a6d50b 100644 --- a/packages/features/insights/services/InsightsBookingBaseService.ts +++ b/packages/features/insights/services/InsightsBookingBaseService.ts @@ -12,11 +12,11 @@ import { isNumberFilterValue, isDateRangeFilterValue, } from "@calcom/features/data-table/lib/utils"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { extractDateRangeFromColumnFilters } from "@calcom/features/insights/lib/bookingUtils"; import type { DateRange } from "@calcom/features/insights/server/insightsDateUtils"; -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import type { PrismaClient } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/insights/services/InsightsRoutingBaseService.ts b/packages/features/insights/services/InsightsRoutingBaseService.ts index 7c19cfb788..a2680a71e0 100644 --- a/packages/features/insights/services/InsightsRoutingBaseService.ts +++ b/packages/features/insights/services/InsightsRoutingBaseService.ts @@ -10,9 +10,9 @@ import { isNumberFilterValue, isSingleSelectFilterValue, } from "@calcom/features/data-table/lib/utils"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import type { DateRange } from "@calcom/features/insights/server/insightsDateUtils"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import type { PrismaClient } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; import type { BookingStatus } from "@calcom/prisma/enums"; diff --git a/packages/features/pbac/domain/types/permission-registry.ts b/packages/features/pbac/domain/types/permission-registry.ts index b54b70e3f7..7511b7ae85 100644 --- a/packages/features/pbac/domain/types/permission-registry.ts +++ b/packages/features/pbac/domain/types/permission-registry.ts @@ -121,7 +121,6 @@ export const isValidPermissionString = (val: unknown): val is PermissionString = * @returns A new object without the _resource property */ export const filterResourceConfig = (config: ResourceConfig): Omit => { - const { _resource, ...rest } = config; return rest; }; diff --git a/packages/features/pbac/lib/__tests__/event-type-permissions.test.ts b/packages/features/pbac/lib/__tests__/event-type-permissions.test.ts index adf7904bec..8f9494a9c5 100644 --- a/packages/features/pbac/lib/__tests__/event-type-permissions.test.ts +++ b/packages/features/pbac/lib/__tests__/event-type-permissions.test.ts @@ -423,11 +423,9 @@ describe("getEventTypePermissions", () => { }); it("should use org MEMBER role when user has no team membership", async () => { - (prisma.membership.findFirst as Mock) - .mockResolvedValueOnce(null) - .mockResolvedValueOnce({ - role: MembershipRole.MEMBER, - }); + (prisma.membership.findFirst as Mock).mockResolvedValueOnce(null).mockResolvedValueOnce({ + role: MembershipRole.MEMBER, + }); const result = await getEventTypePermissions(1, 2); @@ -459,9 +457,7 @@ describe("getEventTypePermissions", () => { describe("error handling", () => { it("should propagate errors from FeaturesRepository", async () => { - mockFeaturesRepository.checkIfTeamHasFeature.mockRejectedValue( - new Error("Database connection failed") - ); + mockFeaturesRepository.checkIfTeamHasFeature.mockRejectedValue(new Error("Database connection failed")); await expect(getEventTypePermissions(1, 2)).rejects.toThrow("Database connection failed"); }); diff --git a/packages/features/pbac/services/legacy-role-manager.service.ts b/packages/features/pbac/services/legacy-role-manager.service.ts index b1a6cdab90..14e0c807ce 100644 --- a/packages/features/pbac/services/legacy-role-manager.service.ts +++ b/packages/features/pbac/services/legacy-role-manager.service.ts @@ -112,7 +112,7 @@ export class LegacyRoleManager implements IRoleManager { organizationId: number, role: MembershipRole | string, // Used in other implementation - // eslint-disable-next-line @typescript-eslint/no-unused-vars + _membershipId: number ): Promise { await prisma.membership.update({ @@ -129,7 +129,7 @@ export class LegacyRoleManager implements IRoleManager { } // Used in other implementation - // eslint-disable-next-line @typescript-eslint/no-unused-vars + async getAllRoles(_organizationId: number): Promise<{ id: string; name: string }[]> { return [ { id: MembershipRole.OWNER, name: "Owner" }, @@ -139,7 +139,7 @@ export class LegacyRoleManager implements IRoleManager { } // Used in other implementation - // eslint-disable-next-line @typescript-eslint/no-unused-vars + async getTeamRoles(_teamId: number): Promise<{ id: string; name: string }[]> { return [ { id: MembershipRole.OWNER, name: "Owner" }, @@ -147,4 +147,4 @@ export class LegacyRoleManager implements IRoleManager { { id: MembershipRole.MEMBER, name: "Member" }, ]; } -} \ No newline at end of file +} diff --git a/packages/features/pbac/services/permission-check.service.ts b/packages/features/pbac/services/permission-check.service.ts index 56398690bf..370449ed35 100644 --- a/packages/features/pbac/services/permission-check.service.ts +++ b/packages/features/pbac/services/permission-check.service.ts @@ -1,6 +1,6 @@ import { FeaturesRepository } from "@calcom/features/flags/features.repository"; -import logger from "@calcom/lib/logger"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import logger from "@calcom/lib/logger"; import prisma from "@calcom/prisma"; import type { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/profile/lib/createAProfileForAnExistingUser.ts b/packages/features/profile/lib/createAProfileForAnExistingUser.ts index 860e675fcc..6bd2f6f720 100644 --- a/packages/features/profile/lib/createAProfileForAnExistingUser.ts +++ b/packages/features/profile/lib/createAProfileForAnExistingUser.ts @@ -1,10 +1,10 @@ import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains"; import { getOrgUsernameFromEmail } from "@calcom/features/auth/signup/utils/getOrgUsernameFromEmail"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import prisma from "@calcom/prisma"; import { RedirectType } from "@calcom/prisma/enums"; diff --git a/packages/features/profile/lib/hideBranding.ts b/packages/features/profile/lib/hideBranding.ts index e82c2ecf4d..9603bae5ce 100644 --- a/packages/features/profile/lib/hideBranding.ts +++ b/packages/features/profile/lib/hideBranding.ts @@ -1,7 +1,7 @@ +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { prisma } from "@calcom/prisma"; const log = logger.getSubLogger({ name: "hideBranding" }); diff --git a/packages/features/routing-forms/lib/getRoutedUrl.test.ts b/packages/features/routing-forms/lib/getRoutedUrl.test.ts index 25b0bf4d5b..7b5e4a7255 100644 --- a/packages/features/routing-forms/lib/getRoutedUrl.test.ts +++ b/packages/features/routing-forms/lib/getRoutedUrl.test.ts @@ -12,9 +12,9 @@ import { findMatchingRoute } from "@calcom/app-store/routing-forms/lib/processRo import { substituteVariables } from "@calcom/app-store/routing-forms/lib/substituteVariables"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; import { isAuthorizedToViewFormOnOrgDomain } from "@calcom/features/routing-forms/lib/isAuthorizedToViewForm"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import { PrismaRoutingFormRepository } from "@calcom/lib/server/repository/PrismaRoutingFormRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { getRoutedUrl } from "./getRoutedUrl"; import { getUrlSearchParamsToForward } from "./getUrlSearchParamsToForward"; diff --git a/packages/features/routing-forms/lib/getRoutedUrl.ts b/packages/features/routing-forms/lib/getRoutedUrl.ts index cb58c40f84..d354740261 100644 --- a/packages/features/routing-forms/lib/getRoutedUrl.ts +++ b/packages/features/routing-forms/lib/getRoutedUrl.ts @@ -16,17 +16,18 @@ import { substituteVariables } from "@calcom/app-store/routing-forms/lib/substit import type { FormResponse } from "@calcom/app-store/routing-forms/types/types"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; import { isAuthorizedToViewFormOnOrgDomain } from "@calcom/features/routing-forms/lib/isAuthorizedToViewForm"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; +import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { withReporting } from "@calcom/lib/sentryWrapper"; import { PrismaRoutingFormRepository } from "@calcom/lib/server/repository/PrismaRoutingFormRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; + import { TRPCError } from "@trpc/server"; import { getUrlSearchParamsToForward } from "./getUrlSearchParamsToForward"; -import { HttpError } from "@calcom/lib/http-error"; const log = logger.getSubLogger({ prefix: ["[routing-forms]", "[router]"] }); const querySchema = z @@ -181,7 +182,7 @@ const _getRoutedUrl = async (context: Pick { const existingBookingReferences = await prisma.bookingReference.findMany({ where: { bookingId: booking.id, + deleted: null, }, }); diff --git a/packages/features/timezone-buddy/components/AvailabilitySliderTable.tsx b/packages/features/timezone-buddy/components/AvailabilitySliderTable.tsx index 75a12ce69e..23c6dbc5da 100644 --- a/packages/features/timezone-buddy/components/AvailabilitySliderTable.tsx +++ b/packages/features/timezone-buddy/components/AvailabilitySliderTable.tsx @@ -9,8 +9,8 @@ import dayjs from "@calcom/dayjs"; import { DataTableProvider } from "@calcom/features/data-table/DataTableProvider"; import { DataTable, DataTableToolbar } from "@calcom/features/data-table/components"; import { useDataTable } from "@calcom/features/data-table/hooks"; -import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants"; import type { DateRange } from "@calcom/features/schedules/lib/date-ranges"; +import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { CURRENT_TIMEZONE } from "@calcom/lib/timezoneConstants"; import type { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/features/users/lib/deleteUser.ts b/packages/features/users/lib/deleteUser.ts index 555ce45823..8dcbb3b3e1 100644 --- a/packages/features/users/lib/deleteUser.ts +++ b/packages/features/users/lib/deleteUser.ts @@ -1,7 +1,6 @@ -import type { User } from "@calcom/prisma/client"; - import { deleteStripeCustomer } from "@calcom/app-store/stripepayment/lib/customer"; import prisma from "@calcom/prisma"; +import type { User } from "@calcom/prisma/client"; export async function deleteUser(user: Pick) { // If 2FA is disabled or totpCode is valid then delete the user from stripe and database diff --git a/packages/features/users/lib/getRoutedUsers.ts b/packages/features/users/lib/getRoutedUsers.ts index b3c4ea2009..8e84b28279 100644 --- a/packages/features/users/lib/getRoutedUsers.ts +++ b/packages/features/users/lib/getRoutedUsers.ts @@ -1,7 +1,7 @@ +import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; import { enrichHostsWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import logger from "@calcom/lib/logger"; -import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; import type { AttributesQueryValue } from "@calcom/lib/raqb/types"; import { safeStringify } from "@calcom/lib/safeStringify"; import type { RRResetInterval } from "@calcom/prisma/client"; diff --git a/packages/features/users/repositories/UserRepository.test.ts b/packages/features/users/repositories/UserRepository.test.ts index fbe2b30fca..10c26ae85b 100644 --- a/packages/features/users/repositories/UserRepository.test.ts +++ b/packages/features/users/repositories/UserRepository.test.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars + import prismock from "../../../../tests/libs/__mocks__/prisma"; import { describe, test, vi, expect, beforeEach } from "vitest"; diff --git a/packages/features/users/services/userCreationService.ts b/packages/features/users/services/userCreationService.ts index 59ac593e19..5fb9f9f2ee 100644 --- a/packages/features/users/services/userCreationService.ts +++ b/packages/features/users/services/userCreationService.ts @@ -1,8 +1,8 @@ +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { sentrySpan } from "@calcom/features/watchlist/lib/telemetry"; import { checkIfEmailIsBlockedInWatchlistController } from "@calcom/features/watchlist/operations/check-if-email-in-watchlist.controller"; import { hashPassword } from "@calcom/lib/auth/hashPassword"; import logger from "@calcom/lib/logger"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; import type { CreationSource, UserPermissionRole, IdentityProvider } from "@calcom/prisma/enums"; diff --git a/packages/features/watchlist/lib/service/SpamCheckService.ts b/packages/features/watchlist/lib/service/SpamCheckService.ts index 7b2d6a0bf3..1965d11667 100644 --- a/packages/features/watchlist/lib/service/SpamCheckService.ts +++ b/packages/features/watchlist/lib/service/SpamCheckService.ts @@ -17,9 +17,9 @@ export class SpamCheckService { constructor( private readonly globalBlockingService: GlobalBlockingService, private readonly organizationBlockingService: OrganizationBlockingService - ) { } + ) {} - startCheck({ email, organizationId }: { email: string, organizationId: number | null }): void { + startCheck({ email, organizationId }: { email: string; organizationId: number | null }): void { this.spamCheckPromise = this.isBlocked(email, organizationId ?? undefined).catch((error) => { logger.error("Error starting spam check", safeStringify(error)); return { isBlocked: false }; diff --git a/packages/features/watchlist/lib/testUtils.ts b/packages/features/watchlist/lib/testUtils.ts index c0f93e3b5c..ed2d6b173a 100644 --- a/packages/features/watchlist/lib/testUtils.ts +++ b/packages/features/watchlist/lib/testUtils.ts @@ -11,7 +11,6 @@ export const createWatchlistEntry = async (input: WatchlistInput) => { await prismock.watchlist.create({ data: { ...input, - createdById: 0, }, }); }; diff --git a/packages/features/webhooks/lib/interface/repository.ts b/packages/features/webhooks/lib/interface/repository.ts index 3e89392210..6a4792147c 100644 --- a/packages/features/webhooks/lib/interface/repository.ts +++ b/packages/features/webhooks/lib/interface/repository.ts @@ -1,5 +1,5 @@ -import type { WebhookTriggerEvents, UserPermissionRole } from "@calcom/prisma/enums"; import type { Webhook } from "@calcom/prisma/client"; +import type { WebhookTriggerEvents, UserPermissionRole } from "@calcom/prisma/enums"; import type { WebhookSubscriber } from "../dto/types"; @@ -42,10 +42,7 @@ export interface IWebhookRepository { time: number | null; timeUnit: string | null; }>; - getFilteredWebhooksForUser(options: { - userId: number; - userRole?: UserPermissionRole; - }): Promise<{ + getFilteredWebhooksForUser(options: { userId: number; userRole?: UserPermissionRole }): Promise<{ webhookGroups: WebhookGroup[]; profiles: { teamId: number | null | undefined; diff --git a/packages/features/webhooks/pages/webhooks-view.tsx b/packages/features/webhooks/pages/webhooks-view.tsx index 5905d1e834..d6c3460e06 100644 --- a/packages/features/webhooks/pages/webhooks-view.tsx +++ b/packages/features/webhooks/pages/webhooks-view.tsx @@ -41,7 +41,7 @@ const WebhooksList = ({ webhooksByViewer }: { webhooksByViewer: WebhooksByViewer description={t("add_webhook_description", { appName: APP_NAME })} CTA={webhooksByViewer.webhookGroups.length > 0 ? : null} borderInShellHeader={false}> - {!!webhookGroups.length ? ( + {webhookGroups.length ? (
    {webhookGroups.map((group) => (
    diff --git a/packages/lib/CalendarService.ts b/packages/lib/CalendarService.ts index 47d692a4e9..ec090504df 100644 --- a/packages/lib/CalendarService.ts +++ b/packages/lib/CalendarService.ts @@ -17,7 +17,6 @@ import { v4 as uuidv4 } from "uuid"; import dayjs from "@calcom/dayjs"; import sanitizeCalendarObject from "@calcom/lib/sanitizeCalendarObject"; -import type { Prisma } from "@calcom/prisma/client"; import type { Person as AttendeeInCalendarEvent } from "@calcom/types/Calendar"; import type { Calendar, @@ -707,7 +706,8 @@ export default abstract class BaseCalendarService implements Calendar { } private async getEventsByUID(uid: string): Promise { - const events: Prisma.PromiseReturnType = []; + type EventsType = Awaited>; + const events: EventsType = []; const calendars = await this.listCalendars(); for (const cal of calendars) { diff --git a/packages/lib/server/repository/PrismaPhoneNumberRepository.ts b/packages/lib/server/repository/PrismaPhoneNumberRepository.ts index d56a424bb7..1739249697 100644 --- a/packages/lib/server/repository/PrismaPhoneNumberRepository.ts +++ b/packages/lib/server/repository/PrismaPhoneNumberRepository.ts @@ -86,7 +86,9 @@ export class PrismaPhoneNumberRepository { const phoneNumberIds = phoneNumbers.map((pn) => pn.id); const agents = phoneNumberIds.length > 0 - ? await this.prismaClient.$queryRaw<(AgentRawResult & { phoneNumberId: number; agentType: string })[]>` + ? await this.prismaClient.$queryRaw< + (AgentRawResult & { phoneNumberId: number; agentType: string })[] + >` SELECT a.id, a.name, @@ -236,15 +238,7 @@ export class PrismaPhoneNumberRepository { }); } - async findByIdWithTeamAccess({ - id, - teamId, - userId, - }: { - id: number; - teamId: number; - userId: number; - }) { + async findByIdWithTeamAccess({ id, teamId, userId }: { id: number; teamId: number; userId: number }) { const accessibleTeamIds = await this.getUserAccessibleTeamIds(userId); if (!accessibleTeamIds.includes(teamId)) { @@ -380,7 +374,9 @@ export class PrismaPhoneNumberRepository { const phoneNumberIds = phoneNumbers.map((pn) => pn.id); const agents = phoneNumberIds.length > 0 - ? await this.prismaClient.$queryRaw<(AgentRawResult & { phoneNumberId: number; agentType: string })[]>` + ? await this.prismaClient.$queryRaw< + (AgentRawResult & { phoneNumberId: number; agentType: string })[] + >` SELECT a.id, a.name, @@ -522,13 +518,7 @@ export class PrismaPhoneNumberRepository { }); } - async updateInboundAgentId({ - id, - agentId, - }: { - id: number; - agentId: string; - }) { + async updateInboundAgentId({ id, agentId }: { id: number; agentId: string }) { // Atomic update: only set if inboundAgentId is currently null return await this.prismaClient.calAiPhoneNumber.updateMany({ where: { diff --git a/packages/lib/server/repository/bookingReference.integration-test.ts b/packages/lib/server/repository/bookingReference.integration-test.ts new file mode 100644 index 0000000000..b1e01a49bd --- /dev/null +++ b/packages/lib/server/repository/bookingReference.integration-test.ts @@ -0,0 +1,382 @@ +import { describe, it, expect, beforeAll, afterAll, afterEach } from "vitest"; + +import { BookingReferenceRepository } from "@calcom/lib/server/repository/bookingReference"; +import prisma from "@calcom/prisma"; +import type { Booking, Credential, User } from "@calcom/prisma/client"; + +describe("BookingReferenceRepository Integration Tests", () => { + let testUser: User; + let testCredential: Credential; + let testBooking: Booking; + const createdBookingReferenceIds: number[] = []; + + beforeAll(async () => { + testUser = await prisma.user.create({ + data: { + email: "bookingreference-test@example.com", + username: "bookingreference-test", + }, + }); + + testCredential = await prisma.credential.create({ + data: { + type: "google_calendar", + key: {}, + userId: testUser.id, + }, + }); + + testBooking = await prisma.booking.create({ + data: { + uid: "test-booking-uid-123", + title: "Test Booking", + startTime: new Date(), + endTime: new Date(), + userId: testUser.id, + }, + }); + }); + + afterEach(async () => { + if (createdBookingReferenceIds.length > 0) { + await prisma.bookingReference.deleteMany({ + where: { + id: { + in: createdBookingReferenceIds, + }, + }, + }); + createdBookingReferenceIds.splice(0, createdBookingReferenceIds.length); + } + }); + + afterAll(async () => { + await prisma.booking.delete({ + where: { + id: testBooking.id, + }, + }); + + await prisma.credential.delete({ + where: { + id: testCredential.id, + }, + }); + + await prisma.user.delete({ + where: { + id: testUser.id, + }, + }); + }); + + describe("replaceBookingReferences", () => { + it("should soft-delete existing references and create new ones", async () => { + const existingReference1 = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: "old-ref-1", + meetingId: "old-meeting-1", + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(existingReference1.id); + + const existingReference2 = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: "old-ref-2", + meetingId: "old-meeting-2", + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(existingReference2.id); + + const newReferences = [ + { + type: "google_calendar", + uid: "new-ref-1", + meetingId: "new-meeting-1", + credentialId: testCredential.id, + }, + { + type: "google_calendar", + uid: "new-ref-2", + meetingId: "new-meeting-2", + credentialId: testCredential.id, + }, + ]; + + await BookingReferenceRepository.replaceBookingReferences({ + bookingId: testBooking.id, + newReferencesToCreate: newReferences, + }); + + const allReferences = await prisma.bookingReference.findMany({ + where: { + bookingId: testBooking.id, + }, + }); + + const oldReferences = allReferences.filter((ref) => ref.uid === "old-ref-1" || ref.uid === "old-ref-2"); + const newlyCreatedReferences = allReferences.filter( + (ref) => ref.uid === "new-ref-1" || ref.uid === "new-ref-2" + ); + + expect(oldReferences).toHaveLength(2); + expect(oldReferences.every((ref) => ref.deleted === true)).toBe(true); + + expect(newlyCreatedReferences).toHaveLength(2); + expect(newlyCreatedReferences.every((ref) => ref.deleted === null)).toBe(true); + + newlyCreatedReferences.forEach((ref) => { + createdBookingReferenceIds.push(ref.id); + }); + }); + + it("should only soft-delete references of the same type as new references being created", async () => { + const googleRef = await prisma.bookingReference.create({ + data: { + type: "google_calendar", + uid: "google-ref", + meetingId: "google-meeting", + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(googleRef.id); + + const zoomRef = await prisma.bookingReference.create({ + data: { + type: "zoom_video", + uid: "zoom-ref", + meetingId: "zoom-meeting", + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(zoomRef.id); + + const newGoogleReferences = [ + { + type: "google_calendar", + uid: "new-google-ref", + meetingId: "new-google-meeting", + credentialId: testCredential.id, + }, + ]; + + await BookingReferenceRepository.replaceBookingReferences({ + bookingId: testBooking.id, + newReferencesToCreate: newGoogleReferences, + }); + + const googleRefAfter = await prisma.bookingReference.findUnique({ + where: { id: googleRef.id }, + }); + expect(googleRefAfter?.deleted).toBe(true); + + const zoomRefAfter = await prisma.bookingReference.findUnique({ + where: { id: zoomRef.id }, + }); + expect(zoomRefAfter?.deleted).toBe(null); + + const newRef = await prisma.bookingReference.findFirst({ + where: { + uid: "new-google-ref", + bookingId: testBooking.id, + }, + }); + expect(newRef).toBeDefined(); + expect(newRef?.deleted).toBe(null); + if (newRef) { + createdBookingReferenceIds.push(newRef.id); + } + }); + + it("should persist soft-deleted records in database", async () => { + const reference = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: "daily-ref", + meetingId: "daily-meeting", + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(reference.id); + + const newReferences = [ + { + type: "daily_video", + uid: "new-daily-ref", + meetingId: "new-daily-meeting", + credentialId: testCredential.id, + }, + ]; + + await BookingReferenceRepository.replaceBookingReferences({ + bookingId: testBooking.id, + newReferencesToCreate: newReferences, + }); + + const deletedRefInDb = await prisma.bookingReference.findUnique({ + where: { id: reference.id }, + }); + expect(deletedRefInDb).toBeDefined(); + expect(deletedRefInDb?.deleted).toBe(true); + expect(deletedRefInDb?.uid).toBe("daily-ref"); + + const newRef = await prisma.bookingReference.findFirst({ + where: { + uid: "new-daily-ref", + bookingId: testBooking.id, + }, + }); + if (newRef) { + createdBookingReferenceIds.push(newRef.id); + } + }); + }); + + describe("findDailyVideoReferenceByRoomName", () => { + it("should find active daily video references", async () => { + const roomName = "test-daily-room-123"; + const dailyRef = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: roomName, + meetingId: roomName, + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(dailyRef.id); + + const result = await BookingReferenceRepository.findDailyVideoReferenceByRoomName({ + roomName, + }); + + expect(result).toBeDefined(); + expect(result?.id).toBe(dailyRef.id); + expect(result?.uid).toBe(roomName); + expect(result?.deleted).toBe(null); + }); + + it("should exclude soft-deleted daily video references", async () => { + const roomName = "test-daily-room-deleted-456"; + const dailyRef = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: roomName, + meetingId: roomName, + credentialId: testCredential.id, + bookingId: testBooking.id, + deleted: true, + }, + }); + createdBookingReferenceIds.push(dailyRef.id); + + const result = await BookingReferenceRepository.findDailyVideoReferenceByRoomName({ + roomName, + }); + + expect(result).toBeNull(); + }); + + it("should return null when room name does not exist", async () => { + const result = await BookingReferenceRepository.findDailyVideoReferenceByRoomName({ + roomName: "non-existent-room", + }); + + expect(result).toBeNull(); + }); + + it("should not return daily video references without a booking", async () => { + const roomName = "test-daily-room-no-booking"; + const dailyRef = await prisma.bookingReference.create({ + data: { + type: "daily_video", + uid: roomName, + meetingId: roomName, + credentialId: testCredential.id, + bookingId: null, + }, + }); + createdBookingReferenceIds.push(dailyRef.id); + + const result = await BookingReferenceRepository.findDailyVideoReferenceByRoomName({ + roomName, + }); + + expect(result).toBeNull(); + }); + }); + + describe("Soft-delete behavior verification", () => { + it("should not return soft-deleted references in regular queries", async () => { + const activeRef = await prisma.bookingReference.create({ + data: { + type: "zoom_video", + uid: "active-zoom", + meetingId: "active-zoom-meeting", + credentialId: testCredential.id, + bookingId: testBooking.id, + }, + }); + createdBookingReferenceIds.push(activeRef.id); + + const deletedRef = await prisma.bookingReference.create({ + data: { + type: "zoom_video", + uid: "deleted-zoom", + meetingId: "deleted-zoom-meeting", + credentialId: testCredential.id, + bookingId: testBooking.id, + deleted: true, + }, + }); + createdBookingReferenceIds.push(deletedRef.id); + + const foundReferences = await prisma.bookingReference.findMany({ + where: { + bookingId: testBooking.id, + type: "zoom_video", + deleted: null, + }, + }); + + expect(foundReferences).toHaveLength(1); + expect(foundReferences[0].id).toBe(activeRef.id); + expect(foundReferences[0].uid).toBe("active-zoom"); + }); + + it("should allow querying soft-deleted references explicitly", async () => { + const deletedRef = await prisma.bookingReference.create({ + data: { + type: "office365_calendar", + uid: "deleted-office365", + meetingId: "deleted-office365-meeting", + credentialId: testCredential.id, + bookingId: testBooking.id, + deleted: true, + }, + }); + createdBookingReferenceIds.push(deletedRef.id); + + const foundDeletedReferences = await prisma.bookingReference.findMany({ + where: { + bookingId: testBooking.id, + deleted: true, + }, + }); + + expect(foundDeletedReferences.length).toBeGreaterThan(0); + const ourDeletedRef = foundDeletedReferences.find((ref) => ref.id === deletedRef.id); + expect(ourDeletedRef).toBeDefined(); + expect(ourDeletedRef?.uid).toBe("deleted-office365"); + }); + }); +}); diff --git a/packages/lib/server/repository/bookingReference.ts b/packages/lib/server/repository/bookingReference.ts index 29fdd886fd..f5d49a9c3f 100644 --- a/packages/lib/server/repository/bookingReference.ts +++ b/packages/lib/server/repository/bookingReference.ts @@ -16,7 +16,13 @@ const bookingReferenceSelect = { export class BookingReferenceRepository { static async findDailyVideoReferenceByRoomName({ roomName }: { roomName: string }) { return prisma.bookingReference.findFirst({ - where: { type: "daily_video", uid: roomName, meetingId: roomName, bookingId: { not: null } }, + where: { + type: "daily_video", + uid: roomName, + meetingId: roomName, + bookingId: { not: null }, + deleted: null, + }, select: bookingReferenceSelect, }); } @@ -33,13 +39,16 @@ export class BookingReferenceRepository { }) { const newReferenceTypes = newReferencesToCreate.map((reference) => reference.type); - await prisma.bookingReference.deleteMany({ + await prisma.bookingReference.updateMany({ where: { bookingId, type: { in: newReferenceTypes, }, }, + data: { + deleted: true, + }, }); await prisma.bookingReference.createMany({ diff --git a/packages/platform/atoms/booker/BookerPlatformWrapper.tsx b/packages/platform/atoms/booker/BookerPlatformWrapper.tsx index 5e20dbf4e7..ae5fbffc4a 100644 --- a/packages/platform/atoms/booker/BookerPlatformWrapper.tsx +++ b/packages/platform/atoms/booker/BookerPlatformWrapper.tsx @@ -1,6 +1,6 @@ /* eslint-disable react-hooks/exhaustive-deps */ import { useQueryClient } from "@tanstack/react-query"; -// eslint-disable-next-line no-restricted-imports + import debounce from "lodash/debounce"; import { useMemo, useEffect, useCallback, useState, useRef, useContext } from "react"; import { shallow } from "zustand/shallow"; @@ -19,10 +19,10 @@ import { useLocalSet } from "@calcom/features/bookings/Booker/components/hooks/u import { usePrefetch } from "@calcom/features/bookings/Booker/components/hooks/usePrefetch"; import { useInitializeBookerStore } from "@calcom/features/bookings/Booker/store"; import { useTimePreferences } from "@calcom/features/bookings/lib"; +import type { ConnectedDestinationCalendars } from "@calcom/features/calendars/lib/getConnectedDestinationCalendars"; +import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; import { useTimesForSchedule } from "@calcom/features/schedules/lib/use-schedule/useTimesForSchedule"; import { getRoutedTeamMemberIdsFromSearchParams } from "@calcom/lib/bookings/getRoutedTeamMemberIdsFromSearchParams"; -import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; -import type { ConnectedDestinationCalendars } from "@calcom/features/calendars/lib/getConnectedDestinationCalendars"; import { localStorage } from "@calcom/lib/webstorage"; import { BookerLayouts } from "@calcom/prisma/zod-utils"; @@ -364,7 +364,7 @@ const BookerPlatformWrapperComponent = ( schedule.refetch(); props.onCreateRecurringBookingSuccess?.(data); - if (!!event?.data?.successRedirectUrl) { + if (event?.data?.successRedirectUrl) { window.location.href = event?.data?.successRedirectUrl; } }, diff --git a/packages/platform/atoms/event-types/wrappers/EventAdvancedWebWrapper.tsx b/packages/platform/atoms/event-types/wrappers/EventAdvancedWebWrapper.tsx index 5d67a53ea1..e262bcdf59 100644 --- a/packages/platform/atoms/event-types/wrappers/EventAdvancedWebWrapper.tsx +++ b/packages/platform/atoms/event-types/wrappers/EventAdvancedWebWrapper.tsx @@ -1,7 +1,7 @@ import type { EventAdvancedBaseProps } from "@calcom/features/eventtypes/components/tabs/advanced/EventAdvancedTab"; import { EventAdvancedTab } from "@calcom/features/eventtypes/components/tabs/advanced/EventAdvancedTab"; -import { trpc } from "@calcom/trpc/react"; import { localeOptions } from "@calcom/lib/i18n"; +import { trpc } from "@calcom/trpc/react"; const EventAdvancedWebWrapper = ({ ...props }: EventAdvancedBaseProps) => { const connectedCalendarsQuery = trpc.viewer.calendars.connectedCalendars.useQuery(); diff --git a/packages/platform/libraries/slots.ts b/packages/platform/libraries/slots.ts index e4679c1e53..d3925543f2 100644 --- a/packages/platform/libraries/slots.ts +++ b/packages/platform/libraries/slots.ts @@ -1,7 +1,7 @@ -import { validateRoundRobinSlotAvailability } from "@calcom/features/ee/round-robin/utils/validateRoundRobinSlotAvailability"; import { FilterHostsService } from "@calcom/features/bookings/lib/host-filtering/filterHostsBySameRoundRobinHost"; import { QualifiedHostsService } from "@calcom/features/bookings/lib/host-filtering/findQualifiedHostsWithDelegationCredentials"; import { BusyTimesService } from "@calcom/features/busyTimes/services/getBusyTimes"; +import { validateRoundRobinSlotAvailability } from "@calcom/features/ee/round-robin/utils/validateRoundRobinSlotAvailability"; import { NoSlotsNotificationService } from "@calcom/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots"; import { AvailableSlotsService } from "@calcom/trpc/server/routers/viewer/slots/util"; diff --git a/packages/platform/libraries/vite.config.js b/packages/platform/libraries/vite.config.js index 62cc96342d..da6a1981ef 100644 --- a/packages/platform/libraries/vite.config.js +++ b/packages/platform/libraries/vite.config.js @@ -1,3 +1,4 @@ +/* eslint-disable no-undef */ // vite.config.ts import react from "@vitejs/plugin-react"; import { resolve } from "path"; @@ -7,6 +8,9 @@ import dts from "vite-plugin-dts"; // https://vitejs.dev/guide/build.html#library-mode export default defineConfig({ + define: { + "process.env.USE_POOL": `"true"`, + }, esbuild: { target: "node18", platform: "node", @@ -50,6 +54,8 @@ export default defineConfig({ "fs/promises", "perf_hooks", "@prisma/client", + "@prisma/adapter-pg", + "pg", "async", "libphonenumber-js", "lodash", @@ -121,6 +127,8 @@ export default defineConfig({ "fs/promises": "fs/promises", perf_hooks: "perf_hooks", "@prisma/client": "@prisma/client", + "@prisma/adapter-pg": "@prisma/adapter-pg", + pg: "pg", async: "async", "libphonenumber-js": "libphonenumber-js", lodash: "lodash", @@ -187,6 +195,7 @@ export default defineConfig({ }, plugins: [react(), dts()], resolve: { + conditions: ["node", "import", "require", "default"], alias: { "@calcom/lib/server/i18n": path.resolve(__dirname, "./i18n.ts"), "./server/i18n": path.resolve(__dirname, "./i18n.ts"), @@ -195,13 +204,10 @@ export default defineConfig({ "@calcom/lib": path.resolve(__dirname, "../../lib"), "@calcom/trpc": resolve("../../trpc"), "lru-cache": resolve("../../../node_modules/lru-cache/dist/cjs/index.js"), - "@calcom/prisma/client/runtime/library": resolve( - "../../../node_modules/@calcom/prisma/client/runtime/library.js" - ), - "@calcom/prisma/client": resolve("../../../node_modules/@calcom/prisma/client/index.js"), + "@calcom/prisma/client/runtime/library": resolve("../../prisma/client/runtime/library"), + "@calcom/prisma/client": resolve("../../prisma/client"), "@calcom/platform-constants": path.resolve(__dirname, "../constants/index.ts"), "@calcom/platform-types": path.resolve(__dirname, "../types/index.ts"), - // eslint-disable-next-line prettier/prettier tslog: path.resolve(__dirname, "../../../apps/api/v2/src/lib/logger.bridge.ts"), }, }, diff --git a/packages/prisma/auto-migrations.ts b/packages/prisma/auto-migrations.ts index 2286f5d801..9af3fe3a38 100644 --- a/packages/prisma/auto-migrations.ts +++ b/packages/prisma/auto-migrations.ts @@ -26,6 +26,10 @@ async function main(): Promise { console.info("No DATABASE_DIRECT_URL found, skipping migrations"); return; } + if (process.env.CI) { + console.info("Running in CI mode, skipping migrations"); + return; + } if (!(await isPrismaAvailableCheck())) { console.info("Prisma can't be initialized, skipping migrations"); return; diff --git a/packages/prisma/client/index.ts b/packages/prisma/client/index.ts new file mode 100644 index 0000000000..bd6691c4bf --- /dev/null +++ b/packages/prisma/client/index.ts @@ -0,0 +1,2 @@ +// INFO: This is to keep backwards compatibility with hundreds of imports before v6.16 of Prisma +export * from "../generated/prisma/client"; diff --git a/packages/prisma/extensions/disallow-undefined-delete-update-many.ts b/packages/prisma/extensions/disallow-undefined-delete-update-many.ts index a25a1ce9fb..0c2b2b17a3 100644 --- a/packages/prisma/extensions/disallow-undefined-delete-update-many.ts +++ b/packages/prisma/extensions/disallow-undefined-delete-update-many.ts @@ -1,4 +1,4 @@ -import { Prisma } from "@calcom/prisma/client"; +import { Prisma } from "../client"; export const checkUndefinedInValue = (where: any) => { if (where) { @@ -28,10 +28,14 @@ export function disallowUndefinedDeleteUpdateManyExtension() { return Prisma.defineExtension({ query: { $allModels: { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore async deleteMany({ args, query }) { checkUndefinedInValue(args.where); return query(args); }, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore async updateMany({ args, query }) { checkUndefinedInValue(args.where); return query(args); diff --git a/packages/prisma/index.ts b/packages/prisma/index.ts index c014de6c7d..cebded00bf 100644 --- a/packages/prisma/index.ts +++ b/packages/prisma/index.ts @@ -1,18 +1,31 @@ -import { PrismaClient, type Prisma } from "@calcom/prisma/client"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { Pool } from "pg"; import { bookingIdempotencyKeyExtension } from "./extensions/booking-idempotency-key"; import { disallowUndefinedDeleteUpdateManyExtension } from "./extensions/disallow-undefined-delete-update-many"; import { excludeLockedUsersExtension } from "./extensions/exclude-locked-users"; import { excludePendingPaymentsExtension } from "./extensions/exclude-pending-payment-teams"; import { usageTrackingExtention } from "./extensions/usage-tracking"; -import { bookingReferenceMiddleware } from "./middleware"; +import { PrismaClient, type Prisma } from "./generated/prisma/client"; -const prismaOptions: Prisma.PrismaClientOptions = {}; +const connectionString = process.env.DATABASE_URL || ""; +const pool = + process.env.USE_POOL === "true" || process.env.USE_POOL === "1" + ? new Pool({ + connectionString: connectionString, + max: 5, + idleTimeoutMillis: 300000, + }) + : undefined; + +const adapter = pool ? new PrismaPg(pool) : new PrismaPg({ connectionString }); +const prismaOptions: Prisma.PrismaClientOptions = { + adapter, +}; const globalForPrisma = global as unknown as { baseClient: PrismaClient; }; - const loggerLevel = parseInt(process.env.NEXT_PUBLIC_LOGGER_LEVEL ?? "", 10); if (!isNaN(loggerLevel)) { @@ -33,20 +46,32 @@ if (!isNaN(loggerLevel)) { break; } } - const baseClient = globalForPrisma.baseClient || new PrismaClient(prismaOptions); -export const customPrisma = (options?: Prisma.PrismaClientOptions) => - new PrismaClient({ ...prismaOptions, ...options }) +export const customPrisma = (options?: Prisma.PrismaClientOptions) => { + let finalOptions = { ...prismaOptions }; + + if (options?.datasources?.db?.url) { + const customConnectionString = options.datasources.db.url; + const customAdapter = new PrismaPg({ connectionString: customConnectionString }); + + const { datasources: _datasources, ...restOptions } = options; + finalOptions = { + ...prismaOptions, + ...restOptions, + adapter: customAdapter, + }; + } else if (options) { + finalOptions = { ...prismaOptions, ...options }; + } + + return new PrismaClient(finalOptions) .$extends(usageTrackingExtention(baseClient)) .$extends(excludeLockedUsersExtension()) .$extends(excludePendingPaymentsExtension()) .$extends(bookingIdempotencyKeyExtension()) .$extends(disallowUndefinedDeleteUpdateManyExtension()) as unknown as PrismaClient; - -// If any changed on middleware server restart is required -// TODO: Migrate it to $extends -bookingReferenceMiddleware(baseClient); +}; // FIXME: Due to some reason, there are types failing in certain places due to the $extends. Fix it and then enable it // Specifically we get errors like `Type 'string | Date | null | undefined' is not assignable to type 'Exact'` diff --git a/packages/prisma/is-prisma-available-check.ts b/packages/prisma/is-prisma-available-check.ts index 9c94a867cc..98dcc2a039 100644 --- a/packages/prisma/is-prisma-available-check.ts +++ b/packages/prisma/is-prisma-available-check.ts @@ -1,11 +1,10 @@ -import { Prisma } from "./client"; +import { Prisma } from "@calcom/prisma/client"; export async function isPrismaAvailableCheck(): Promise { try { - const { PrismaClient } = await import("./client"); - const prisma = new PrismaClient(); + const { prisma } = await import("./index"); - await prisma.$queryRawUnsafe("SELECT 1"); + await prisma.$queryRaw(Prisma.sql`SELECT 1`); await prisma.$disconnect(); return true; } catch (e: unknown) { diff --git a/packages/prisma/middleware/bookingReference.ts b/packages/prisma/middleware/bookingReference.ts deleted file mode 100644 index 057933b7f0..0000000000 --- a/packages/prisma/middleware/bookingReference.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { PrismaClient } from "../client"; - -function middleware(prisma: PrismaClient) { - /***********************************/ - /* SOFT DELETE MIDDLEWARE */ - /***********************************/ - prisma.$use(async (params, next) => { - // Check incoming query type - - if (params.model === "BookingReference") { - if (params.action === "delete") { - // Delete queries - // Change action to an update - params.action = "update"; - params.args["data"] = { deleted: true }; - } - if (params.action === "deleteMany") { - // Delete many queries - params.action = "updateMany"; - if (params.args.data !== undefined) { - params.args.data["deleted"] = true; - } else { - params.args["data"] = { deleted: true }; - } - } - if (params.action === "findUnique") { - // Change to findFirst - you cannot filter - // by anything except ID / unique with findUnique - params.action = "findFirst"; - // Add 'deleted' filter - // ID filter maintained - params.args.where["deleted"] = null; - } - if (params.action === "findMany" || params.action === "findFirst") { - // Find many queries - if (params.args.where !== undefined) { - if (params.args.where.deleted === undefined) { - // Exclude deleted records if they have not been explicitly requested - params.args.where["deleted"] = null; - } - } else { - params.args["where"] = { deleted: null }; - } - } - } - return next(params); - }); -} - -export default middleware; diff --git a/packages/prisma/middleware/index.ts b/packages/prisma/middleware/index.ts deleted file mode 100644 index 90097ed181..0000000000 --- a/packages/prisma/middleware/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as bookingReferenceMiddleware } from "./bookingReference"; diff --git a/packages/prisma/package.json b/packages/prisma/package.json index 3f2b7178d1..c8254f5c4d 100644 --- a/packages/prisma/package.json +++ b/packages/prisma/package.json @@ -23,10 +23,11 @@ }, "dependencies": { "@calcom/lib": "workspace:*", - "@prisma/client": "^6.7.0", + "@prisma/adapter-pg": "^6.16.0", + "@prisma/client": "^6.16.0", "@prisma/extension-accelerate": "^1.3.0", - "@prisma/generator-helper": "^6.7.0", - "prisma": "^6.7.0", + "@prisma/generator-helper": "^6.16.0", + "prisma": "^6.16.0", "prisma-kysely": "2.2.0", "ts-node": "^10.9.1", "zod": "^3.22.4", @@ -39,6 +40,7 @@ "types": "index.d.ts", "files": [ "client", + "generated/prisma", "zod", "zod-utils.ts" ], diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 0b2d04e7e5..707c4466ec 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -8,17 +8,12 @@ datasource db { } generator client { - provider = "prisma-client-js" - previewFeatures = ["views"] - output = "./client" - binaryTargets = ["native", "debian-openssl-1.1.x"] -} - -generator client_for_api_v2 { - provider = "prisma-client-js" - previewFeatures = ["views"] - output = "../../apps/api/v2/client" - binaryTargets = ["native", "debian-openssl-1.1.x"] + provider = "prisma-client" + previewFeatures = ["views"] + output = "./generated/prisma" + engineType = "client" + moduleFormat = "cjs" + importFileExtension = "" } generator zod { @@ -29,6 +24,8 @@ generator zod { addIncludeType = false addSelectType = false validateWhereUniqueInput = false + prismaClientPath = "../../generated/prisma/client" + moduleFormat = "cjs" /// createRelationValuesTypes = true } diff --git a/packages/trpc/server/middlewares/sessionMiddleware.ts b/packages/trpc/server/middlewares/sessionMiddleware.ts index d7b9a19f85..ffddaa0198 100644 --- a/packages/trpc/server/middlewares/sessionMiddleware.ts +++ b/packages/trpc/server/middlewares/sessionMiddleware.ts @@ -1,11 +1,11 @@ import { setUser as SentrySetUser } from "@sentry/nextjs"; import type { Session } from "next-auth"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { WEBAPP_URL } from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import { teamMetadataSchema, userMetadata } from "@calcom/prisma/zod-utils"; diff --git a/packages/trpc/server/routers/apps/routing-forms/formMutation.handler.ts b/packages/trpc/server/routers/apps/routing-forms/formMutation.handler.ts index 36d66ce286..c114336ad0 100644 --- a/packages/trpc/server/routers/apps/routing-forms/formMutation.handler.ts +++ b/packages/trpc/server/routers/apps/routing-forms/formMutation.handler.ts @@ -1,6 +1,3 @@ -import type { App_RoutingForms_Form } from "@calcom/prisma/client"; -import { Prisma } from "@calcom/prisma/client"; - import { createFallbackRoute } from "@calcom/app-store/routing-forms/lib/createFallbackRoute"; import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm"; import { isFallbackRoute } from "@calcom/app-store/routing-forms/lib/isFallbackRoute"; @@ -8,9 +5,14 @@ import isRouter from "@calcom/app-store/routing-forms/lib/isRouter"; import isRouterLinkedField from "@calcom/app-store/routing-forms/lib/isRouterLinkedField"; import type { SerializableForm } from "@calcom/app-store/routing-forms/types/types"; import { zodFields, zodRouterRoute, zodRoutes } from "@calcom/app-store/routing-forms/zod"; +import { + entityPrismaWhereClause, + canEditEntity, +} from "@calcom/features/pbac/lib/entityPermissionUtils.server"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { entityPrismaWhereClause, canEditEntity } from "@calcom/features/pbac/lib/entityPermissionUtils.server"; import type { PrismaClient } from "@calcom/prisma"; +import type { App_RoutingForms_Form } from "@calcom/prisma/client"; +import { Prisma } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/apps/routing-forms/forms.handler.ts b/packages/trpc/server/routers/apps/routing-forms/forms.handler.ts index 8501f83a63..17d6d2675f 100644 --- a/packages/trpc/server/routers/apps/routing-forms/forms.handler.ts +++ b/packages/trpc/server/routers/apps/routing-forms/forms.handler.ts @@ -3,7 +3,10 @@ import type { z } from "zod"; import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm"; import type { zodFields, zodRoutes } from "@calcom/app-store/routing-forms/zod"; import { hasFilter } from "@calcom/features/filters/lib/hasFilter"; -import { entityPrismaWhereClause, canEditEntity } from "@calcom/features/pbac/lib/entityPermissionUtils.server"; +import { + entityPrismaWhereClause, + canEditEntity, +} from "@calcom/features/pbac/lib/entityPermissionUtils.server"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import type { PrismaClient } from "@calcom/prisma"; diff --git a/packages/trpc/server/routers/viewer/aiVoiceAgent/listCalls.handler.ts b/packages/trpc/server/routers/viewer/aiVoiceAgent/listCalls.handler.ts index e66ce00aea..96170be00e 100644 --- a/packages/trpc/server/routers/viewer/aiVoiceAgent/listCalls.handler.ts +++ b/packages/trpc/server/routers/viewer/aiVoiceAgent/listCalls.handler.ts @@ -1,7 +1,7 @@ import { createDefaultAIPhoneServiceProvider } from "@calcom/features/calAIPhone"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import logger from "@calcom/lib/logger"; import { CalAiPhoneNumberRepository } from "@calcom/lib/server/repository/calAiPhoneNumber"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { MembershipRole } from "@calcom/prisma/enums"; import { TRPCError } from "@trpc/server"; diff --git a/packages/trpc/server/routers/viewer/aiVoiceAgent/setupInboundAgent.schema.ts b/packages/trpc/server/routers/viewer/aiVoiceAgent/setupInboundAgent.schema.ts index 6babe71a18..b689859d0d 100644 --- a/packages/trpc/server/routers/viewer/aiVoiceAgent/setupInboundAgent.schema.ts +++ b/packages/trpc/server/routers/viewer/aiVoiceAgent/setupInboundAgent.schema.ts @@ -6,4 +6,4 @@ export const ZSetupInboundAgentInputSchema = z.object({ workflowStepId: z.number(), }); -export type TSetupInboundAgentInputSchema = z.infer; \ No newline at end of file +export type TSetupInboundAgentInputSchema = z.infer; diff --git a/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.handler.ts b/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.handler.ts index c24805fa52..f20048cbce 100644 --- a/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.handler.ts +++ b/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.handler.ts @@ -3,6 +3,7 @@ import { replaceEventTypePlaceholders } from "@calcom/features/ee/workflows/comp import logger from "@calcom/lib/logger"; import { PrismaAgentRepository } from "@calcom/lib/server/repository/PrismaAgentRepository"; import prisma from "@calcom/prisma"; + import type { TrpcSessionUser } from "../../../types"; import type { TUpdateInboundAgentEventTypeInputSchema } from "./updateInboundAgentEventType.schema"; diff --git a/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.schema.ts b/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.schema.ts index a6960d46e8..caca28c2b9 100644 --- a/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.schema.ts +++ b/packages/trpc/server/routers/viewer/aiVoiceAgent/updateInboundAgentEventType.schema.ts @@ -6,4 +6,4 @@ export const ZUpdateInboundAgentEventTypeInputSchema = z.object({ teamId: z.number().optional(), }); -export type TUpdateInboundAgentEventTypeInputSchema = z.infer; \ No newline at end of file +export type TUpdateInboundAgentEventTypeInputSchema = z.infer; diff --git a/packages/trpc/server/routers/viewer/apps/appById.handler.ts b/packages/trpc/server/routers/viewer/apps/appById.handler.ts index 9b45a322d6..3737db59cf 100644 --- a/packages/trpc/server/routers/viewer/apps/appById.handler.ts +++ b/packages/trpc/server/routers/viewer/apps/appById.handler.ts @@ -24,7 +24,7 @@ export const appByIdHandler = async ({ ctx, input }: AppByIdOptions) => { throw new TRPCError({ code: "BAD_REQUEST", message: `Could not find app ${appId}` }); } - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { credential: _, credentials: _1, ...app } = appFromDb; return { isInstalled: appFromDb.credentials.length, diff --git a/packages/trpc/server/routers/viewer/apps/queryForDependencies.handler.ts b/packages/trpc/server/routers/viewer/apps/queryForDependencies.handler.ts index 19c441953f..48b9849716 100644 --- a/packages/trpc/server/routers/viewer/apps/queryForDependencies.handler.ts +++ b/packages/trpc/server/routers/viewer/apps/queryForDependencies.handler.ts @@ -1,5 +1,5 @@ -import { getAppFromSlug } from "@calcom/app-store/utils"; import { getAllDelegationCredentialsForUserByAppSlug } from "@calcom/app-store/delegationCredential"; +import { getAppFromSlug } from "@calcom/app-store/utils"; import { prisma } from "@calcom/prisma"; import type { TrpcSessionUser } from "../../../types"; diff --git a/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts b/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts index f975a7f8d3..b1545acdd2 100644 --- a/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts +++ b/packages/trpc/server/routers/viewer/bookings/confirm.handler.ts @@ -7,16 +7,16 @@ import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventR import { handleConfirmation } from "@calcom/features/bookings/lib/handleConfirmation"; import { handleWebhookTrigger } from "@calcom/features/bookings/lib/handleWebhookTrigger"; import { processPaymentRefund } from "@calcom/features/bookings/lib/payment/processPaymentRefund"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { workflowSelect } from "@calcom/features/ee/workflows/lib/getAllWorkflows"; +import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import type { GetSubscriberOptions } from "@calcom/features/webhooks/lib/getWebhooks"; import type { EventPayloadType, EventTypeInfo } from "@calcom/features/webhooks/lib/sendPayload"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType"; import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj"; import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/WorkflowService"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import { prisma } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; @@ -239,7 +239,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => { hideCalendarEventDetails: booking.eventType?.hideCalendarEventDetails, eventTypeId: booking.eventType?.id, customReplyToEmail: booking.eventType?.customReplyToEmail, - team: !!booking.eventType?.team + team: booking.eventType?.team ? { name: booking.eventType.team.name, id: booking.eventType.team.id, @@ -326,7 +326,7 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => { }); } else { // handle refunds - if (!!booking.payment.length) { + if (booking.payment.length) { await processPaymentRefund({ booking: booking, teamId: booking.eventType?.teamId, diff --git a/packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts b/packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts index 48ab05b92a..94a61f29d3 100644 --- a/packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts +++ b/packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts @@ -5,14 +5,14 @@ import { getEventLocationType, OrganizerDefaultConferencingAppType } from "@calc import { getAppFromSlug } from "@calcom/app-store/utils"; import { sendLocationChangeEmailsAndSMS } from "@calcom/emails"; import EventManager from "@calcom/features/bookings/lib/EventManager"; +import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser"; import { buildCalEventFromBooking } from "@calcom/lib/buildCalEventFromBooking"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; -import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import type { Booking, BookingReference } from "@calcom/prisma/client"; import type { userMetadata } from "@calcom/prisma/zod-utils"; diff --git a/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts b/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts index a41f304843..0168c20931 100644 --- a/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts +++ b/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts @@ -7,6 +7,8 @@ import dayjs from "@calcom/dayjs"; import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails"; import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; import { deleteMeeting } from "@calcom/features/conferencing/lib/videoClient"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; +import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; import getWebhooks from "@calcom/features/webhooks/lib/getWebhooks"; import { deleteWebhookScheduledTriggers, @@ -15,13 +17,11 @@ import { import sendPayload from "@calcom/features/webhooks/lib/sendOrSchedulePayload"; import { CalendarEventBuilder } from "@calcom/lib/builders/CalendarEvent/builder"; import { CalendarEventDirector } from "@calcom/lib/builders/CalendarEvent/director"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; import { BookingWebhookFactory } from "@calcom/lib/server/service/BookingWebhookFactory"; import { prisma } from "@calcom/prisma"; import type { BookingReference, EventType } from "@calcom/prisma/client"; @@ -208,7 +208,7 @@ export const requestRescheduleHandler = async ({ ctx, input }: RequestReschedule organizer, iCalUID: bookingToReschedule.iCalUID, customReplyToEmail: bookingToReschedule.eventType?.customReplyToEmail, - team: !!bookingToReschedule.eventType?.team + team: bookingToReschedule.eventType?.team ? { name: bookingToReschedule.eventType.team.name, id: bookingToReschedule.eventType.team.id, diff --git a/packages/trpc/server/routers/viewer/calVideo/getDownloadLinkOfCalVideoRecordings.handler.ts b/packages/trpc/server/routers/viewer/calVideo/getDownloadLinkOfCalVideoRecordings.handler.ts index 6be2f16969..e6f3d14db0 100644 --- a/packages/trpc/server/routers/viewer/calVideo/getDownloadLinkOfCalVideoRecordings.handler.ts +++ b/packages/trpc/server/routers/viewer/calVideo/getDownloadLinkOfCalVideoRecordings.handler.ts @@ -1,6 +1,6 @@ /// -import { IS_SELF_HOSTED } from "@calcom/lib/constants"; import { getDownloadLinkOfCalVideoByRecordingId } from "@calcom/features/conferencing/lib/videoClient"; +import { IS_SELF_HOSTED } from "@calcom/lib/constants"; import { TRPCError } from "@trpc/server"; diff --git a/packages/trpc/server/routers/viewer/credits/buyCredits.handler.ts b/packages/trpc/server/routers/viewer/credits/buyCredits.handler.ts index e3a61baff2..bbce6372b8 100644 --- a/packages/trpc/server/routers/viewer/credits/buyCredits.handler.ts +++ b/packages/trpc/server/routers/viewer/credits/buyCredits.handler.ts @@ -1,9 +1,9 @@ import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service"; -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { WEBAPP_URL } from "@calcom/lib/constants"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { TeamService } from "@calcom/features/ee/teams/services/teamService"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; +import { WEBAPP_URL } from "@calcom/lib/constants"; import prisma from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/credits/downloadExpenseLog.handler.ts b/packages/trpc/server/routers/viewer/credits/downloadExpenseLog.handler.ts index 2a50b81f10..640143a6f2 100644 --- a/packages/trpc/server/routers/viewer/credits/downloadExpenseLog.handler.ts +++ b/packages/trpc/server/routers/viewer/credits/downloadExpenseLog.handler.ts @@ -1,6 +1,6 @@ +import { TeamService } from "@calcom/features/ee/teams/services/teamService"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { CreditsRepository } from "@calcom/lib/server/repository/credits"; -import { TeamService } from "@calcom/features/ee/teams/services/teamService"; import { MembershipRole } from "@calcom/prisma/enums"; import { TRPCError } from "@trpc/server"; diff --git a/packages/trpc/server/routers/viewer/credits/getAllCredits.handler.ts b/packages/trpc/server/routers/viewer/credits/getAllCredits.handler.ts index a65d56bf3b..a13fa34323 100644 --- a/packages/trpc/server/routers/viewer/credits/getAllCredits.handler.ts +++ b/packages/trpc/server/routers/viewer/credits/getAllCredits.handler.ts @@ -1,6 +1,6 @@ -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { TeamService } from "@calcom/features/ee/teams/services/teamService"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { MembershipRole } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/delegationCredential/getAffectedMembersForDisable.handler.ts b/packages/trpc/server/routers/viewer/delegationCredential/getAffectedMembersForDisable.handler.ts index e821fc8f03..46d5e9e1e1 100644 --- a/packages/trpc/server/routers/viewer/delegationCredential/getAffectedMembersForDisable.handler.ts +++ b/packages/trpc/server/routers/viewer/delegationCredential/getAffectedMembersForDisable.handler.ts @@ -1,6 +1,6 @@ -import logger from "@calcom/lib/logger"; import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import logger from "@calcom/lib/logger"; import type { TDelegationCredentialGetAffectedMembersForDisableSchema } from "./schema"; diff --git a/packages/trpc/server/routers/viewer/delegationCredential/toggleEnabled.handler.ts b/packages/trpc/server/routers/viewer/delegationCredential/toggleEnabled.handler.ts index 44f68fa2c1..9dd32a3c03 100644 --- a/packages/trpc/server/routers/viewer/delegationCredential/toggleEnabled.handler.ts +++ b/packages/trpc/server/routers/viewer/delegationCredential/toggleEnabled.handler.ts @@ -1,11 +1,11 @@ import type { z } from "zod"; -import { sendDelegationCredentialDisabledEmail } from "@calcom/emails/email-manager"; import { checkIfSuccessfullyConfiguredInWorkspace } from "@calcom/app-store/delegationCredential"; -import logger from "@calcom/lib/logger"; -import { getTranslation } from "@calcom/lib/server/i18n"; +import { sendDelegationCredentialDisabledEmail } from "@calcom/emails/email-manager"; import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; import type { ServiceAccountKey } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; +import logger from "@calcom/lib/logger"; +import { getTranslation } from "@calcom/lib/server/i18n"; import { getAffectedMembersForDisable } from "./getAffectedMembersForDisable.handler"; import type { DelegationCredentialToggleEnabledSchema } from "./schema"; diff --git a/packages/trpc/server/routers/viewer/delegationCredential/utils.ts b/packages/trpc/server/routers/viewer/delegationCredential/utils.ts index a237225cb0..9d05fd3870 100644 --- a/packages/trpc/server/routers/viewer/delegationCredential/utils.ts +++ b/packages/trpc/server/routers/viewer/delegationCredential/utils.ts @@ -1,8 +1,8 @@ import { z } from "zod"; +import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { DelegationCredentialRepository } from "@calcom/features/delegation-credentials/repositories/DelegationCredentialRepository"; import type { Prisma } from "@calcom/prisma/client"; import { TRPCError } from "@trpc/server"; diff --git a/packages/trpc/server/routers/viewer/eventTypes/getEventTypesFromGroup.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/getEventTypesFromGroup.handler.ts index 9c92be1b29..d5a55ac4db 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/getEventTypesFromGroup.handler.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/getEventTypesFromGroup.handler.ts @@ -1,7 +1,7 @@ +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { hasFilter } from "@calcom/features/filters/lib/hasFilter"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import logger from "@calcom/lib/logger"; -import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { prisma } from "@calcom/prisma"; import type { PrismaClient } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; diff --git a/packages/trpc/server/routers/viewer/eventTypes/getUserEventGroups.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/getUserEventGroups.handler.ts index 1d2a82c7b1..0fd58452af 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/getUserEventGroups.handler.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/getUserEventGroups.handler.ts @@ -1,7 +1,7 @@ -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; +import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import type { PrismaClient } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/eventTypes/heavy/create.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/heavy/create.handler.ts index 509e7dfa2d..f9f34feecd 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/heavy/create.handler.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/heavy/create.handler.ts @@ -2,8 +2,8 @@ import type { z } from "zod"; import { getDefaultLocations } from "@calcom/app-store/_utils/getDefaultLocations"; import { DailyLocationType } from "@calcom/app-store/constants"; -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import type { PrismaClient } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; import { MembershipRole, SchedulingType } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/eventTypes/heavy/duplicate.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/heavy/duplicate.handler.ts index bf26c9c6c2..67a136bad8 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/heavy/duplicate.handler.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/heavy/duplicate.handler.ts @@ -1,6 +1,6 @@ +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { generateHashedLink } from "@calcom/lib/generateHashedLink"; import { CalVideoSettingsRepository } from "@calcom/lib/server/repository/calVideoSettings"; -import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { prisma } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; @@ -94,13 +94,13 @@ export const duplicateHandler = async ({ ctx, input }: DuplicateOptions) => { workflows, hashedLink, destinationCalendar, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + id: _id, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + webhooks: _webhooks, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + schedule: _schedule, - // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/ban-ts-comment + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - descriptionAsSafeHTML is added on the fly using a prisma middleware it shouldn't be used to create event type. Such a property doesn't exist on schema descriptionAsSafeHTML: _descriptionAsSafeHTML, secondaryEmailId, @@ -146,7 +146,7 @@ export const duplicateHandler = async ({ ctx, input }: DuplicateOptions) => { }; // Validate the secondary email - if (!!secondaryEmailId) { + if (secondaryEmailId) { const secondaryEmail = await prisma.secondaryEmail.findUnique({ where: { id: secondaryEmailId, diff --git a/packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts index ec23c4e1d0..bca595b4ea 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/heavy/update.handler.ts @@ -599,13 +599,13 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => { }, update: { ...aiPhoneCallConfig, - guestEmail: !!aiPhoneCallConfig?.guestEmail ? aiPhoneCallConfig.guestEmail : null, - guestCompany: !!aiPhoneCallConfig?.guestCompany ? aiPhoneCallConfig.guestCompany : null, + guestEmail: aiPhoneCallConfig?.guestEmail ? aiPhoneCallConfig.guestEmail : null, + guestCompany: aiPhoneCallConfig?.guestCompany ? aiPhoneCallConfig.guestCompany : null, }, create: { ...aiPhoneCallConfig, - guestEmail: !!aiPhoneCallConfig?.guestEmail ? aiPhoneCallConfig.guestEmail : null, - guestCompany: !!aiPhoneCallConfig?.guestCompany ? aiPhoneCallConfig.guestCompany : null, + guestEmail: aiPhoneCallConfig?.guestEmail ? aiPhoneCallConfig.guestEmail : null, + guestCompany: aiPhoneCallConfig?.guestCompany ? aiPhoneCallConfig.guestCompany : null, eventTypeId: id, }, }); diff --git a/packages/trpc/server/routers/viewer/eventTypes/util.ts b/packages/trpc/server/routers/viewer/eventTypes/util.ts index aba7dab84b..13f5d6308c 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/util.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/util.ts @@ -1,10 +1,10 @@ import { z } from "zod"; +import type { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import type { PermissionString } from "@calcom/features/pbac/domain/types/permission-registry"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; -import type { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML"; import prisma from "@calcom/prisma"; import type { MembershipRole } from "@calcom/prisma/enums"; import { PeriodType } from "@calcom/prisma/enums"; @@ -315,7 +315,7 @@ export const mapEventType = async (eventType: EventType) => ({ ...eventType, safeDescription: eventType?.description ? markdownToSafeHTML(eventType.description) : undefined, users: await Promise.all( - (!!eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users).map( + (eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users).map( async (u) => await new UserRepository(prisma).enrichUserWithItsProfile({ user: u, diff --git a/packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts b/packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts index fc7b32415f..3d1de82e8f 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/utils/transformUtils.ts @@ -1,7 +1,7 @@ -import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; -import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; +import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; +import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import type { MembershipRole } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; diff --git a/packages/trpc/server/routers/viewer/me/get.handler.ts b/packages/trpc/server/routers/viewer/me/get.handler.ts index e860c01a10..dfca7e93b8 100644 --- a/packages/trpc/server/routers/viewer/me/get.handler.ts +++ b/packages/trpc/server/routers/viewer/me/get.handler.ts @@ -1,8 +1,8 @@ import type { Session } from "next-auth"; -import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import prisma from "@calcom/prisma"; import { IdentityProvider, MembershipRole } from "@calcom/prisma/enums"; import { userMetadata } from "@calcom/prisma/zod-utils"; diff --git a/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts b/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts index 2056a038dc..70c5212308 100644 --- a/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts +++ b/packages/trpc/server/routers/viewer/me/updateProfile.handler.ts @@ -1,4 +1,4 @@ -// eslint-disable-next-line no-restricted-imports + import { keyBy } from "lodash"; import type { GetServerSidePropsContext, NextApiResponse } from "next"; @@ -7,11 +7,11 @@ import { sendChangeOfEmailVerification } from "@calcom/features/auth/lib/verifyE import { StripeBillingService } from "@calcom/features/ee/billing/stripe-billing-service"; import { updateNewTeamMemberEventTypes } from "@calcom/features/ee/teams/lib/queries"; import { FeaturesRepository } from "@calcom/features/flags/features.repository"; +import { checkUsername } from "@calcom/features/profile/lib/checkUsername"; import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata"; import { HttpError } from "@calcom/lib/http-error"; import logger from "@calcom/lib/logger"; import { uploadAvatar } from "@calcom/lib/server/avatar"; -import { checkUsername } from "@calcom/features/profile/lib/checkUsername"; import { getTranslation } from "@calcom/lib/server/i18n"; import { resizeBase64Image } from "@calcom/lib/server/resizeBase64Image"; import slugify from "@calcom/lib/slugify"; @@ -312,7 +312,7 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) username: updatedUser.username ?? "Nameless User", emailFrom: user.email, // We know email has been changed here so we can use input - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + emailTo: input.email!, }, }); diff --git a/packages/trpc/server/routers/viewer/organizations/create.handler.ts b/packages/trpc/server/routers/viewer/organizations/create.handler.ts index 5b0f09d929..6d848e27e8 100644 --- a/packages/trpc/server/routers/viewer/organizations/create.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/create.handler.ts @@ -4,6 +4,8 @@ import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains"; import { isNotACompanyEmail } from "@calcom/ee/organizations/lib/server/orgCreationUtils"; import { sendAdminOrganizationNotification, sendOrganizationCreationEmail } from "@calcom/emails"; import { sendEmailVerification } from "@calcom/features/auth/lib/verifyEmail"; +import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/availability"; import { RESERVED_SUBDOMAINS, @@ -13,8 +15,6 @@ import { } from "@calcom/lib/constants"; import { createDomain } from "@calcom/lib/domainManager/organization"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import { UserPermissionRole } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/organizations/createTeams.handler.ts b/packages/trpc/server/routers/viewer/organizations/createTeams.handler.ts index b008162c38..ba83378688 100644 --- a/packages/trpc/server/routers/viewer/organizations/createTeams.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/createTeams.handler.ts @@ -2,9 +2,9 @@ import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains"; import { CreditService } from "@calcom/features/ee/billing/credit-service"; import stripe from "@calcom/features/ee/payments/server/stripe"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import slugify from "@calcom/lib/slugify"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; diff --git a/packages/trpc/server/routers/viewer/organizations/createWithPaymentIntent.schema.ts b/packages/trpc/server/routers/viewer/organizations/createWithPaymentIntent.schema.ts index 7ee2074d52..3e569866fb 100644 --- a/packages/trpc/server/routers/viewer/organizations/createWithPaymentIntent.schema.ts +++ b/packages/trpc/server/routers/viewer/organizations/createWithPaymentIntent.schema.ts @@ -2,7 +2,6 @@ * @deprecated This schema is deprecated. Use ZIntentToCreateOrgInputSchema instead. * See createWithPaymentIntent.handler.ts for migration guide. */ - import type { z } from "zod"; import { createOrganizationSchema } from "@calcom/features/ee/organizations/types/schemas"; diff --git a/packages/trpc/server/routers/viewer/organizations/getTeams.handler.ts b/packages/trpc/server/routers/viewer/organizations/getTeams.handler.ts index 1027bdd7fa..cfe21d91bc 100644 --- a/packages/trpc/server/routers/viewer/organizations/getTeams.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/getTeams.handler.ts @@ -1,6 +1,6 @@ import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { MembershipRole } from "@calcom/prisma/enums"; import { prisma } from "@calcom/prisma"; +import { MembershipRole } from "@calcom/prisma/enums"; import { TRPCError } from "@trpc/server"; diff --git a/packages/trpc/server/routers/viewer/organizations/list.handler.ts b/packages/trpc/server/routers/viewer/organizations/list.handler.ts index 924adc517b..216c2a47b7 100644 --- a/packages/trpc/server/routers/viewer/organizations/list.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/list.handler.ts @@ -1,5 +1,5 @@ -import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { OrganizationRepository } from "@calcom/features/ee/organizations/repositories/OrganizationRepository"; +import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import prisma from "@calcom/prisma"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts b/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts index e158a017d5..a172b86774 100644 --- a/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/listMembers.handler.ts @@ -25,7 +25,7 @@ const isAllString = (array: (string | number)[]): array is string[] => { return array.every((value) => typeof value === "string"); }; function getUserConditions(oAuthClientId?: string) { - if (!!oAuthClientId) { + if (oAuthClientId) { return { platformOAuthClients: { some: { id: oAuthClientId }, diff --git a/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts b/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts index 3cc26caac7..049781a3c6 100644 --- a/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts +++ b/packages/trpc/server/routers/viewer/organizations/updateUser.handler.ts @@ -6,7 +6,7 @@ import { checkRegularUsername } from "@calcom/features/profile/lib/checkRegularU import { uploadAvatar } from "@calcom/lib/server/avatar"; import { resizeBase64Image } from "@calcom/lib/server/resizeBase64Image"; import { prisma } from "@calcom/prisma"; -import type { Prisma, PrismaPromise, User, Membership, Profile } from "@calcom/prisma/client"; +import type { Prisma } from "@calcom/prisma/client"; import type { MembershipRole } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; @@ -132,7 +132,9 @@ export const updateUserHandler = async ({ ctx, input }: UpdateUserOptions) => { } // Update user - const transactions: PrismaPromise[] = [ + type TransactionPromise = ReturnType | ReturnType; + + const transactions: TransactionPromise[] = [ prisma.user.update({ where: { id: input.userId, diff --git a/packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts b/packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts index e71d5950eb..357b89fa38 100644 --- a/packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts +++ b/packages/trpc/server/routers/viewer/routing-forms/findTeamMembersMatchingAttributeLogicOfRoute.handler.ts @@ -6,15 +6,15 @@ import type { ServerResponse } from "http"; import type { NextApiResponse } from "next"; +import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; import { enrichHostsWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; import { enrichFormWithMigrationData } from "@calcom/app-store/routing-forms/enrichFormWithMigrationData"; import { getLuckyUserService } from "@calcom/features/di/containers/LuckyUser"; -import { getUrlSearchParamsToForwardForTestPreview } from "@calcom/features/routing-forms/lib/getUrlSearchParamsToForward"; -import { entityPrismaWhereClause } from "@calcom/features/pbac/lib/entityPermissionUtils.server"; -import { fromEntriesWithDuplicateKeys } from "@calcom/lib/fromEntriesWithDuplicateKeys"; -import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic"; import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; +import { entityPrismaWhereClause } from "@calcom/features/pbac/lib/entityPermissionUtils.server"; +import { getUrlSearchParamsToForwardForTestPreview } from "@calcom/features/routing-forms/lib/getUrlSearchParamsToForward"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; +import { fromEntriesWithDuplicateKeys } from "@calcom/lib/fromEntriesWithDuplicateKeys"; import type { PrismaClient } from "@calcom/prisma"; import type { App_RoutingForms_Form } from "@calcom/prisma/client"; import { getAbsoluteEventTypeRedirectUrl } from "@calcom/routing-forms/getEventTypeRedirectUrl"; diff --git a/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.test.ts b/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.test.ts index e962ba6676..3531c2a38c 100644 --- a/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.test.ts +++ b/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.test.ts @@ -5,8 +5,8 @@ import { vi, describe, it, beforeAll, afterAll, expect, beforeEach, afterEach } import dayjs from "@calcom/dayjs"; import * as CalcomEmails from "@calcom/emails"; -import { RedisService } from "@calcom/features/redis/RedisService"; import { getNoSlotsNotificationService } from "@calcom/features/di/containers/NoSlotsNotification"; +import { RedisService } from "@calcom/features/redis/RedisService"; vi.mock("@calcom/features/redis/RedisService", () => { const mockedRedis = vi.fn(); diff --git a/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.ts b/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.ts index e0027751b1..c94c6324f5 100644 --- a/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.ts +++ b/packages/trpc/server/routers/viewer/slots/handleNotificationWhenNoSlots.ts @@ -1,10 +1,10 @@ import type { Dayjs } from "@calcom/dayjs"; import { sendOrganizationAdminNoSlotsNotification } from "@calcom/emails"; +import type { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import type { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import type { IRedisService } from "@calcom/features/redis/IRedisService"; import { IS_PRODUCTION, WEBAPP_URL } from "@calcom/lib/constants"; import { getTranslation } from "@calcom/lib/server/i18n"; -import type { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; -import type { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; type EventDetails = { username: string; diff --git a/packages/trpc/server/routers/viewer/slots/isAvailable.handler.ts b/packages/trpc/server/routers/viewer/slots/isAvailable.handler.ts index 1be3c06711..0727af5498 100644 --- a/packages/trpc/server/routers/viewer/slots/isAvailable.handler.ts +++ b/packages/trpc/server/routers/viewer/slots/isAvailable.handler.ts @@ -1,9 +1,9 @@ import type { NextApiRequest } from "next"; +import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository"; 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/features/eventtypes/repositories/eventTypeRepository"; import type { PrismaClient } from "@calcom/prisma"; import type { TIsAvailableInputSchema, TIsAvailableOutputSchema } from "./isAvailable.schema"; diff --git a/packages/trpc/server/routers/viewer/slots/util.ts b/packages/trpc/server/routers/viewer/slots/util.ts index 5f5e369ece..68f12eadc5 100644 --- a/packages/trpc/server/routers/viewer/slots/util.ts +++ b/packages/trpc/server/routers/viewer/slots/util.ts @@ -1,4 +1,3 @@ -// eslint-disable-next-line no-restricted-imports import type { Logger } from "tslog"; import { v4 as uuid } from "uuid"; @@ -253,7 +252,6 @@ export class AvailableSlotsService { ); const eventTypeId = input.eventTypeId || - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (await this.getEventTypeId({ slug: usernameList?.[0], eventTypeSlug: eventTypeSlug, diff --git a/packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts b/packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts index 850b652993..aadfe8135a 100644 --- a/packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/changeMemberRole.handler.ts @@ -1,5 +1,5 @@ -import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory"; import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; +import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory"; import { prisma } from "@calcom/prisma"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/teams/create.handler.ts b/packages/trpc/server/routers/viewer/teams/create.handler.ts index e5cc55ce13..8dcbb87dfa 100644 --- a/packages/trpc/server/routers/viewer/teams/create.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/create.handler.ts @@ -1,7 +1,7 @@ import { generateTeamCheckoutSession } from "@calcom/features/ee/teams/lib/payments"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants"; import { uploadLogo } from "@calcom/lib/server/avatar"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { resizeBase64Image } from "@calcom/lib/server/resizeBase64Image"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/teams/createInvite.handler.ts b/packages/trpc/server/routers/viewer/teams/createInvite.handler.ts index 03a68a8c56..a4bad516b5 100644 --- a/packages/trpc/server/routers/viewer/teams/createInvite.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/createInvite.handler.ts @@ -1,5 +1,5 @@ -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { TeamService } from "@calcom/features/ee/teams/services/teamService"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/teams/delete.handler.ts b/packages/trpc/server/routers/viewer/teams/delete.handler.ts index 9d460b4beb..f382a18013 100644 --- a/packages/trpc/server/routers/viewer/teams/delete.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/delete.handler.ts @@ -1,5 +1,5 @@ -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { TeamService } from "@calcom/features/ee/teams/services/teamService"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/teams/hasActiveTeamPlan.handler.ts b/packages/trpc/server/routers/viewer/teams/hasActiveTeamPlan.handler.ts index 69db80c7c8..90d5c8fa9e 100644 --- a/packages/trpc/server/routers/viewer/teams/hasActiveTeamPlan.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/hasActiveTeamPlan.handler.ts @@ -1,6 +1,6 @@ import { InternalTeamBilling } from "@calcom/ee/billing/teams/internal-team-billing"; -import { IS_SELF_HOSTED } from "@calcom/lib/constants"; import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; +import { IS_SELF_HOSTED } from "@calcom/lib/constants"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts index 554aa56d58..dcb6e105a7 100644 --- a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts @@ -1,12 +1,12 @@ import { type TFunction } from "i18next"; import { TeamBilling } from "@calcom/ee/billing/teams"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; import { isOrganisationOwner } from "@calcom/lib/server/queries/organisations"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import prisma from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; import type { CreationSource } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts index f9b78a438b..3ff0895bc6 100644 --- a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts +++ b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts @@ -6,15 +6,15 @@ import { sendTeamInviteEmail } from "@calcom/emails"; import { checkAdminOrOwner } from "@calcom/features/auth/lib/checkAdminOrOwner"; import { updateNewTeamMemberEventTypes } from "@calcom/features/ee/teams/lib/queries"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; +import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; +import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; +import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/availability"; import { ENABLE_PROFILE_SWITCHER, WEBAPP_URL } from "@calcom/lib/constants"; -import { createAProfileForAnExistingUser } from "@calcom/features/profile/lib/createAProfileForAnExistingUser"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; import { getParsedTeam } from "@calcom/lib/server/repository/teamUtils"; -import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import slugify from "@calcom/lib/slugify"; import { prisma } from "@calcom/prisma"; import type { Membership, OrganizationSettings, Team } from "@calcom/prisma/client"; diff --git a/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts b/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts index 5ae0aef261..1e0bb521d5 100644 --- a/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/listMembers.handler.ts @@ -1,3 +1,5 @@ +import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { Resource, CustomAction, @@ -6,8 +8,6 @@ import { import { getSpecificPermissions } from "@calcom/features/pbac/lib/resource-permissions"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory"; -import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; diff --git a/packages/trpc/server/routers/viewer/teams/publish.handler.ts b/packages/trpc/server/routers/viewer/teams/publish.handler.ts index 5d7a12daa5..979e576d23 100644 --- a/packages/trpc/server/routers/viewer/teams/publish.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/publish.handler.ts @@ -1,8 +1,8 @@ import { purchaseTeamOrOrgSubscription } from "@calcom/features/ee/teams/lib/payments"; +import { TeamService } from "@calcom/features/ee/teams/services/teamService"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants"; import { Redirect } from "@calcom/lib/redirect"; -import { TeamService } from "@calcom/features/ee/teams/services/teamService"; import type { Prisma } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; diff --git a/packages/trpc/server/routers/viewer/teams/removeMember/__tests__/PBACRemoveMemberService.test.ts b/packages/trpc/server/routers/viewer/teams/removeMember/__tests__/PBACRemoveMemberService.test.ts index b0b2302340..309623db5e 100644 --- a/packages/trpc/server/routers/viewer/teams/removeMember/__tests__/PBACRemoveMemberService.test.ts +++ b/packages/trpc/server/routers/viewer/teams/removeMember/__tests__/PBACRemoveMemberService.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it, vi, beforeEach, type Mock } from "vitest"; import * as teamQueries from "@calcom/features/ee/teams/lib/queries"; +import { TeamService } from "@calcom/features/ee/teams/services/teamService"; import { PermissionMapper } from "@calcom/features/pbac/domain/mappers/PermissionMapper"; import { Resource, CustomAction } from "@calcom/features/pbac/domain/types/permission-registry"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { TeamService } from "@calcom/features/ee/teams/services/teamService"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/teams/roundRobin/getRoundRobinHostsToReasign.handler.ts b/packages/trpc/server/routers/viewer/teams/roundRobin/getRoundRobinHostsToReasign.handler.ts index 3e51fa5e9b..72ee49149f 100644 --- a/packages/trpc/server/routers/viewer/teams/roundRobin/getRoundRobinHostsToReasign.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/roundRobin/getRoundRobinHostsToReasign.handler.ts @@ -1,10 +1,10 @@ +import { enrichUsersWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; import dayjs from "@calcom/dayjs"; import { ensureAvailableUsers } from "@calcom/features/bookings/lib/handleNewBooking/ensureAvailableUsers"; import type { IsFixedAwareUser } from "@calcom/features/bookings/lib/handleNewBooking/types"; -import { enrichUsersWithDelegationCredentials } from "@calcom/app-store/delegationCredential"; +import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import { ErrorCode } from "@calcom/lib/errorCodes"; import logger from "@calcom/lib/logger"; -import { withSelectedCalendars } from "@calcom/features/users/repositories/UserRepository"; import type { PrismaClient } from "@calcom/prisma"; import { userSelect } from "@calcom/prisma"; import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential"; diff --git a/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinManualReassign.handler.ts b/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinManualReassign.handler.ts index 587c45a0ed..b05c87718d 100644 --- a/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinManualReassign.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinManualReassign.handler.ts @@ -1,5 +1,5 @@ -import { roundRobinManualReassignment } from "@calcom/features/ee/round-robin/roundRobinManualReassignment"; import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { roundRobinManualReassignment } from "@calcom/features/ee/round-robin/roundRobinManualReassignment"; import { prisma } from "@calcom/prisma"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinReassign.handler.ts b/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinReassign.handler.ts index f0d8c2fed3..c407c00909 100644 --- a/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinReassign.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/roundRobin/roundRobinReassign.handler.ts @@ -1,5 +1,5 @@ -import { roundRobinReassignment } from "@calcom/features/ee/round-robin/roundRobinReassignment"; import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { roundRobinReassignment } from "@calcom/features/ee/round-robin/roundRobinReassignment"; import { prisma } from "@calcom/prisma"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/teams/skipTeamTrials.handler.ts b/packages/trpc/server/routers/viewer/teams/skipTeamTrials.handler.ts index fae063d4c4..433eaee3a7 100644 --- a/packages/trpc/server/routers/viewer/teams/skipTeamTrials.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/skipTeamTrials.handler.ts @@ -1,7 +1,7 @@ import { InternalTeamBilling } from "@calcom/ee/billing/teams/internal-team-billing"; +import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { IS_SELF_HOSTED } from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; -import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository"; import { prisma } from "@calcom/prisma"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; diff --git a/packages/trpc/server/routers/viewer/teams/update.handler.ts b/packages/trpc/server/routers/viewer/teams/update.handler.ts index 9d3cec5adc..55022aad5a 100644 --- a/packages/trpc/server/routers/viewer/teams/update.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/update.handler.ts @@ -1,10 +1,10 @@ import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { IS_TEAM_BILLING_ENABLED } from "@calcom/lib/constants"; import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema"; import { validateIntervalLimitOrder } from "@calcom/lib/intervalLimits/validateIntervalLimitOrder"; import { uploadLogo } from "@calcom/lib/server/avatar"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { prisma } from "@calcom/prisma"; import type { Prisma } from "@calcom/prisma/client"; import { MembershipRole, RedirectType, RRTimestampBasis } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts b/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts index 52ee9bce61..ac0b2f3cab 100644 --- a/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts +++ b/packages/trpc/server/routers/viewer/workflows/activateEventType.handler.ts @@ -1,9 +1,9 @@ +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { scheduleEmailReminder } from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager"; import { scheduleSMSReminder } from "@calcom/features/ee/workflows/lib/reminders/smsReminderManager"; import { scheduleWhatsappReminder } from "@calcom/features/ee/workflows/lib/reminders/whatsappReminderManager"; -import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; +import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import { prisma } from "@calcom/prisma"; import { BookingStatus } from "@calcom/prisma/enums"; diff --git a/packages/trpc/server/routers/viewer/workflows/delete.handler.ts b/packages/trpc/server/routers/viewer/workflows/delete.handler.ts index 1d8e6e89df..d9d0efdf0c 100644 --- a/packages/trpc/server/routers/viewer/workflows/delete.handler.ts +++ b/packages/trpc/server/routers/viewer/workflows/delete.handler.ts @@ -1,9 +1,9 @@ import { createDefaultAIPhoneServiceProvider } from "@calcom/features/calAIPhone"; import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; +import logger from "@calcom/lib/logger"; import { prisma } from "@calcom/prisma"; import { WorkflowActions } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/types"; -import logger from "@calcom/lib/logger"; import { TRPCError } from "@trpc/server"; diff --git a/packages/trpc/server/routers/viewer/workflows/list.handler.ts b/packages/trpc/server/routers/viewer/workflows/list.handler.ts index 82118b0d88..393487c6f8 100644 --- a/packages/trpc/server/routers/viewer/workflows/list.handler.ts +++ b/packages/trpc/server/routers/viewer/workflows/list.handler.ts @@ -1,6 +1,6 @@ +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import type { WorkflowType } from "@calcom/features/ee/workflows/components/WorkflowListPage"; import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; // import dayjs from "@calcom/dayjs"; // import { getErrorFromUnknown } from "@calcom/lib/errors"; import { addPermissionsToWorkflows } from "@calcom/lib/server/repository/workflow-permissions"; diff --git a/packages/trpc/server/routers/viewer/workflows/update.handler.ts b/packages/trpc/server/routers/viewer/workflows/update.handler.ts index 935bf7259e..ee00d0ba92 100755 --- a/packages/trpc/server/routers/viewer/workflows/update.handler.ts +++ b/packages/trpc/server/routers/viewer/workflows/update.handler.ts @@ -1,4 +1,5 @@ import { createDefaultAIPhoneServiceProvider } from "@calcom/features/calAIPhone"; +import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { isEmailAction, isFormTrigger } from "@calcom/features/ee/workflows/lib/actionHelperFunctions"; import { WorkflowReminderRepository } from "@calcom/features/ee/workflows/lib/repository/workflowReminder"; import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; @@ -8,7 +9,6 @@ import { IS_SELF_HOSTED, SCANNING_WORKFLOW_STEPS } from "@calcom/lib/constants"; import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata"; import logger from "@calcom/lib/logger"; import { PrismaAgentRepository } from "@calcom/lib/server/repository/PrismaAgentRepository"; -import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository"; import { addPermissionsToWorkflow } from "@calcom/lib/server/repository/workflow-permissions"; import { WorkflowRelationsRepository } from "@calcom/lib/server/repository/workflowRelations"; import { WorkflowStepRepository } from "@calcom/lib/server/repository/workflowStep"; diff --git a/packages/trpc/server/routers/viewer/workflows/util.ts b/packages/trpc/server/routers/viewer/workflows/util.ts index 4d3e8c1ab8..ec7c1eaa7d 100644 --- a/packages/trpc/server/routers/viewer/workflows/util.ts +++ b/packages/trpc/server/routers/viewer/workflows/util.ts @@ -9,25 +9,22 @@ import emailRatingTemplate from "@calcom/ee/workflows/lib/reminders/templates/em import emailReminderTemplate from "@calcom/ee/workflows/lib/reminders/templates/emailReminderTemplate"; import { scheduleWhatsappReminder } from "@calcom/ee/workflows/lib/reminders/whatsappReminderManager"; import type { Workflow as WorkflowType } from "@calcom/ee/workflows/lib/types"; -import { - SMS_REMINDER_NUMBER_FIELD, - CAL_AI_AGENT_PHONE_NUMBER_FIELD, -} from "@calcom/lib/bookings/SystemField"; import { getSmsReminderNumberField, getSmsReminderNumberSource, getAIAgentCallPhoneNumberField, getAIAgentCallPhoneNumberSource, } from "@calcom/features/bookings/lib/getBookingFields"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; +import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; import { removeBookingField, upsertBookingField } from "@calcom/features/eventtypes/lib/bookingFieldsManager"; import type { PermissionString } from "@calcom/features/pbac/domain/types/permission-registry"; import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service"; +import { SMS_REMINDER_NUMBER_FIELD, CAL_AI_AGENT_PHONE_NUMBER_FIELD } from "@calcom/lib/bookings/SystemField"; import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId"; import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType"; import { getTranslation } from "@calcom/lib/server/i18n"; -import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import prisma from "@calcom/prisma"; import { WorkflowType as PrismaWorkflowType, type Workflow } from "@calcom/prisma/client"; diff --git a/packages/ui/components/avatar/UserAvatarGroup.tsx b/packages/ui/components/avatar/UserAvatarGroup.tsx index 27cbd6b5f0..b4701e4574 100644 --- a/packages/ui/components/avatar/UserAvatarGroup.tsx +++ b/packages/ui/components/avatar/UserAvatarGroup.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; -import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; +import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import type { User } from "@calcom/prisma/client"; import type { UserProfile } from "@calcom/types/UserProfile"; diff --git a/packages/ui/components/avatar/UserAvatarGroupWithOrg.tsx b/packages/ui/components/avatar/UserAvatarGroupWithOrg.tsx index be1db5b8b8..b37e77abbb 100644 --- a/packages/ui/components/avatar/UserAvatarGroupWithOrg.tsx +++ b/packages/ui/components/avatar/UserAvatarGroupWithOrg.tsx @@ -1,7 +1,7 @@ import { useIsEmbed } from "@calcom/embed-core/embed-iframe"; +import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; -import { getBookerBaseUrlSync } from "@calcom/features/ee/organizations/lib/getBookerBaseUrlSync"; import type { Team, User } from "@calcom/prisma/client"; import { AvatarGroup } from "./AvatarGroup"; diff --git a/packages/ui/components/form/inputs/TextField.tsx b/packages/ui/components/form/inputs/TextField.tsx index a5e1146a22..ec6ee1a503 100644 --- a/packages/ui/components/form/inputs/TextField.tsx +++ b/packages/ui/components/form/inputs/TextField.tsx @@ -125,7 +125,7 @@ export const InputField = forwardRef(function readOnly, showAsteriskIndicator, onClickAddon, - // eslint-disable-next-line @typescript-eslint/no-unused-vars + t: __t, dataTestid, size, diff --git a/scripts/seed-app-store.ts b/scripts/seed-app-store.ts index 85df186b5e..a69c30fdcd 100644 --- a/scripts/seed-app-store.ts +++ b/scripts/seed-app-store.ts @@ -12,166 +12,6 @@ import { AppCategories } from "@calcom/prisma/enums"; dotEnv.config({ path: path.resolve(__dirname, "../.env.appStore") }); -export const seededForm = { - id: "948ae412-d995-4865-875a-48302588de03", - name: "Seeded Form - Pro", -}; - -async function seedAppData() { - const form = await prisma.app_RoutingForms_Form.findUnique({ - where: { - id: seededForm.id, - }, - }); - if (form) { - console.log(`Skipping Routing Form - Form Seed, "Seeded Form - Pro" already exists`); - return; - } - - const proUser = await prisma.user.findFirst({ - where: { - username: "pro", - }, - }); - - if (!proUser) { - console.log(`Skipping Routing Form - Seeding - Pro User not found`); - return; - } - - const multiSelectLegacyFieldId = "d2292635-9f12-17b1-9153-c3a854649182"; - await prisma.app_RoutingForms_Form.create({ - data: { - id: seededForm.id, - routes: [ - { - id: "8a898988-89ab-4cde-b012-31823f708642", - action: { type: "eventTypeRedirectUrl", value: "pro/30min" }, - queryValue: { - id: "8a898988-89ab-4cde-b012-31823f708642", - type: "group", - children1: { - "8988bbb8-0123-4456-b89a-b1823f70c5ff": { - type: "rule", - properties: { - field: "c1296635-9f12-47b1-8153-c3a854649182", - value: ["event-routing"], - operator: "equal", - valueSrc: ["value"], - valueType: ["text"], - }, - }, - }, - }, - }, - { - id: "aa8aaba9-cdef-4012-b456-71823f70f7ef", - action: { type: "customPageMessage", value: "Custom Page Result" }, - queryValue: { - id: "aa8aaba9-cdef-4012-b456-71823f70f7ef", - type: "group", - children1: { - "b99b8a89-89ab-4cde-b012-31823f718ff5": { - type: "rule", - properties: { - field: "c1296635-9f12-47b1-8153-c3a854649182", - value: ["custom-page"], - operator: "equal", - valueSrc: ["value"], - valueType: ["text"], - }, - }, - }, - }, - }, - { - id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad", - action: { type: "externalRedirectUrl", value: "https://cal.com" }, - queryValue: { - id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad", - type: "group", - children1: { - "998b9b9a-0123-4456-b89a-b1823f7232b9": { - type: "rule", - properties: { - field: "c1296635-9f12-47b1-8153-c3a854649182", - value: ["external-redirect"], - operator: "equal", - valueSrc: ["value"], - valueType: ["text"], - }, - }, - }, - }, - }, - { - id: "aa8ba8b9-0123-4456-b89a-b182623406d8", - action: { type: "customPageMessage", value: "Multiselect chosen" }, - queryValue: { - id: "aa8ba8b9-0123-4456-b89a-b182623406d8", - type: "group", - children1: { - "b98a8abb-cdef-4012-b456-718262343d27": { - type: "rule", - properties: { - field: multiSelectLegacyFieldId, - value: [["Option-2"]], - operator: "multiselect_equals", - valueSrc: ["value"], - valueType: ["multiselect"], - }, - }, - }, - }, - }, - { - id: "898899aa-4567-489a-bcde-f1823f708646", - action: { type: "customPageMessage", value: "Fallback Message" }, - isFallback: true, - queryValue: { id: "898899aa-4567-489a-bcde-f1823f708646", type: "group" }, - }, - ], - fields: [ - { id: "c1296635-9f12-47b1-8153-c3a854649182", type: "text", label: "Test field", required: true }, - { - id: multiSelectLegacyFieldId, - type: "multiselect", - label: "Multi Select(with legacy `selectText`)", - identifier: "multi", - selectText: "Option-1\nOption-2", - required: false, - }, - { - id: "d3292635-9f12-17b1-9153-c3a854649182", - type: "multiselect", - label: "Multi Select", - identifier: "multi", - options: [ - { - id: "d1234635-9f12-17b1-9153-c3a854649182", - label: "Option-1", - }, - { - id: "d1235635-9f12-17b1-9153-c3a854649182", - label: "Option-2", - }, - ], - required: false, - }, - ], - user: { - connect: { - email_username: { - username: "pro", - email: "pro@example.com", - }, - }, - }, - name: seededForm.name, - }, - }); -} - async function createApp( /** The App identifier in the DB also used for public page in `/apps/[slug]` */ slug: Prisma.AppCreateInput["slug"], @@ -410,15 +250,18 @@ export default async function main() { app.isTemplate ); } - - await seedAppData(); } -main() - .catch((e) => { - console.error(e); - process.exit(1); - }) - .finally(async () => { - await prisma.$disconnect(); - }); +if (require.main === module) { + (async () => { + await main(); + await seedAppData(); + })() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(async () => { + await prisma.$disconnect(); + }); +} diff --git a/scripts/seed-insights.ts b/scripts/seed-insights.ts index 83a5237035..64413c8f9e 100644 --- a/scripts/seed-insights.ts +++ b/scripts/seed-insights.ts @@ -4,7 +4,7 @@ import { v4 as uuidv4 } from "uuid"; import dayjs from "@calcom/dayjs"; import { hashPassword } from "@calcom/lib/auth/hashPassword"; import type { Prisma } from "@calcom/prisma/client"; -import { PrismaClient } from "@calcom/prisma/client"; +import { prisma } from "@calcom/prisma/client"; import { BookingStatus, AssignmentReasonEnum } from "@calcom/prisma/enums"; import { seedAttributes, seedRoutingFormResponses, seedRoutingForms } from "./seed-utils"; @@ -132,7 +132,6 @@ async function seedBookingAssignments() { }); } -const prisma = new PrismaClient(); async function main() { // First find the organization we want to add insights to const organization = await prisma.team.findFirst({ @@ -366,7 +365,13 @@ async function main() { await seedBookingAssignments(); } -main() + +async function runMain() { + await prisma.$connect(); + await main(); +} + +runMain() .then(async () => { await prisma.$disconnect(); }) @@ -525,7 +530,12 @@ async function createPerformanceData() { } } -createPerformanceData() +async function runSeed() { + await prisma.$connect(); + await createPerformanceData(); +} + +runSeed() .then(async () => { await prisma.$disconnect(); }) diff --git a/scripts/seed.ts b/scripts/seed.ts index cb52433c21..8c40971880 100644 --- a/scripts/seed.ts +++ b/scripts/seed.ts @@ -556,6 +556,12 @@ async function createOrganizationAndAddMembersAndTeams({ ); const ownerForEvent = orgMembersInDBWithProfileId[0]; + if (!ownerForEvent) { + console.log( + `Warning: No organization members with profiles found for creating team event, skipping event creation for team ${team.teamData.slug}` + ); + continue; + } // Create event for each team await prisma.eventType.create({ data: { @@ -1364,11 +1370,178 @@ async function main() { }, ], }); + + const seededForm = { + id: "948ae412-d995-4865-875a-48302588de03", + name: "Seeded Form - Pro", + }; + + const form = await prisma.app_RoutingForms_Form.findUnique({ + where: { + id: seededForm.id, + }, + }); + if (form) { + console.log(`Skipping Routing Form - Form Seed, "Seeded Form - Pro" already exists`); + } else { + const proUser = await prisma.user.findFirst({ + where: { + username: "pro", + }, + }); + + if (!proUser) { + console.log(`Skipping Routing Form - Seeding - Pro User not found`); + } else { + const multiSelectLegacyFieldId = "d2292635-9f12-17b1-9153-c3a854649182"; + await prisma.app_RoutingForms_Form.create({ + data: { + id: seededForm.id, + routes: [ + { + id: "8a898988-89ab-4cde-b012-31823f708642", + action: { type: "eventTypeRedirectUrl", value: "pro/30min" }, + queryValue: { + id: "8a898988-89ab-4cde-b012-31823f708642", + type: "group", + children1: { + "8988bbb8-0123-4456-b89a-b1823f70c5ff": { + type: "rule", + properties: { + field: "c1296635-9f12-47b1-8153-c3a854649182", + value: ["event-routing"], + operator: "equal", + valueSrc: ["value"], + valueType: ["text"], + }, + }, + }, + }, + }, + { + id: "aa8aaba9-cdef-4012-b456-71823f70f7ef", + action: { type: "customPageMessage", value: "Custom Page Result" }, + queryValue: { + id: "aa8aaba9-cdef-4012-b456-71823f70f7ef", + type: "group", + children1: { + "b99b8a89-89ab-4cde-b012-31823f718ff5": { + type: "rule", + properties: { + field: "c1296635-9f12-47b1-8153-c3a854649182", + value: ["custom-page"], + operator: "equal", + valueSrc: ["value"], + valueType: ["text"], + }, + }, + }, + }, + }, + { + id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad", + action: { type: "externalRedirectUrl", value: "https://cal.com" }, + queryValue: { + id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad", + type: "group", + children1: { + "998b9b9a-0123-4456-b89a-b1823f7232b9": { + type: "rule", + properties: { + field: "c1296635-9f12-47b1-8153-c3a854649182", + value: ["external-redirect"], + operator: "equal", + valueSrc: ["value"], + valueType: ["text"], + }, + }, + }, + }, + }, + { + id: "aa8ba8b9-0123-4456-b89a-b182623406d8", + action: { type: "customPageMessage", value: "Multiselect chosen" }, + queryValue: { + id: "aa8ba8b9-0123-4456-b89a-b182623406d8", + type: "group", + children1: { + "b98a8abb-cdef-4012-b456-718262343d27": { + type: "rule", + properties: { + field: multiSelectLegacyFieldId, + value: [["Option-2"]], + operator: "multiselect_equals", + valueSrc: ["value"], + valueType: ["multiselect"], + }, + }, + }, + }, + }, + { + id: "898899aa-4567-489a-bcde-f1823f708646", + action: { type: "customPageMessage", value: "Fallback Message" }, + isFallback: true, + queryValue: { id: "898899aa-4567-489a-bcde-f1823f708646", type: "group" }, + }, + ], + fields: [ + { + id: "c1296635-9f12-47b1-8153-c3a854649182", + type: "text", + label: "Test field", + required: true, + }, + { + id: multiSelectLegacyFieldId, + type: "multiselect", + label: "Multi Select(with legacy `selectText`)", + identifier: "multi", + selectText: "Option-1\nOption-2", + required: false, + }, + { + id: "d3292635-9f12-17b1-9153-c3a854649182", + type: "multiselect", + label: "Multi Select", + identifier: "multi", + options: [ + { + id: "d1234635-9f12-17b1-9153-c3a854649182", + label: "Option-1", + }, + { + id: "d1235635-9f12-17b1-9153-c3a854649182", + label: "Option-2", + }, + ], + required: false, + }, + ], + user: { + connect: { + email_username: { + username: "pro", + email: "pro@example.com", + }, + }, + }, + name: seededForm.name, + }, + }); + } + } } -main() - .then(() => mainAppStore()) - .then(() => mainHugeEventTypesSeed()) +async function runSeed() { + await prisma.$connect(); + + await mainAppStore(); + await main(); + await mainHugeEventTypesSeed(); +} + +runSeed() .catch((e) => { console.error(e); process.exit(1); diff --git a/tests/libs/__mocks__/prisma.ts b/tests/libs/__mocks__/prisma.ts index ae47d5f0b4..54385db05b 100644 --- a/tests/libs/__mocks__/prisma.ts +++ b/tests/libs/__mocks__/prisma.ts @@ -1,20 +1,16 @@ -import { createPrismock } from "prismock"; +import { type DMMF } from "@prisma/client/runtime/client"; +import { getDMMF } from "@prisma/internals"; +import { readFileSync } from "fs"; import { beforeEach, vi } from "vitest"; +import { createPrismock } from "prismock/build/main/lib/client"; import logger from "@calcom/lib/logger"; -import { Prisma as PrismaType } from "@calcom/prisma/client"; +import type { PrismaClient } from "@calcom/prisma"; import * as selects from "@calcom/prisma/selects"; vi.stubEnv("DATABASE_URL", "postgresql://user:password@localhost:5432/testdb"); -vi.mock("@calcom/prisma", () => ({ - default: prismaMock, - prisma: prismaMock, - readonlyPrisma: prismaMock, - ...selects, -})); - -const handlePrismockBugs = () => { +const handlePrismockBugs = (prismock: any) => { const __findManyWebhook = prismock.webhook.findMany; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -30,16 +26,93 @@ const handlePrismockBugs = () => { }; }; -const PrismockClientConstructor = createPrismock(PrismaType); -const prismock = new PrismockClientConstructor(); +let prismockInstance: any; +const proxyTarget = {} as PrismaClient; -const prismaMock = prismock; - -beforeEach(() => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - prismock.reset(); - handlePrismockBugs(); +const prismaMockProxy = new Proxy(proxyTarget, { + get(target, prop) { + if (!prismockInstance) { + throw new Error("Prismock not initialized yet"); + } + if (prop in target) { + return (target as any)[prop]; + } + return prismockInstance[prop]; + }, + getOwnPropertyDescriptor(target, prop) { + if (!prismockInstance) { + return undefined; + } + const targetDescriptor = Object.getOwnPropertyDescriptor(target, prop); + if (targetDescriptor) { + return targetDescriptor; + } + return Object.getOwnPropertyDescriptor(prismockInstance, prop); + }, + has(target, prop) { + if (!prismockInstance) { + return false; + } + if (prop in target) { + return true; + } + return prop in prismockInstance; + }, + ownKeys(target) { + if (!prismockInstance) { + return []; + } + return Reflect.ownKeys(prismockInstance); + }, + set(target, prop, value) { + if (!prismockInstance) { + throw new Error("Prismock not initialized yet"); + } + (target as any)[prop] = value; + return true; + } }); -export default prismaMock; +vi.mock("@calcom/prisma", async (importOriginal) => { + const original = await importOriginal(); + const { Prisma } = original; + + const schemaContent = readFileSync("packages/prisma/schema.prisma", "utf-8"); + const dmmf = await getDMMF({ datamodel: schemaContent }); + const PrismaWithDMMF = { ...Prisma, dmmf }; + + const PrismockClientClass = createPrismock( + PrismaWithDMMF as unknown as typeof Prisma & { dmmf: DMMF.Document } + ); + + prismockInstance = new PrismockClientClass(); + + if (!prismockInstance.$queryRaw) { + Object.defineProperty(prismockInstance, "$queryRaw", { + value: async () => { + throw new Error("$queryRaw is not implemented in prismock. Use vi.spyOn to mock it in your test."); + }, + writable: true, + configurable: true, + enumerable: false, + }); + } + + return { + default: prismaMockProxy, + prisma: prismaMockProxy, + readonlyPrisma: prismaMockProxy, + ...selects, + }; +}); + +beforeEach(() => { + if (prismockInstance) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + prismockInstance.reset(); + handlePrismockBugs(prismockInstance); + } +}); + +export default prismaMockProxy; diff --git a/turbo.json b/turbo.json index 4faebfbf65..b4d4ca4c3b 100644 --- a/turbo.json +++ b/turbo.json @@ -289,7 +289,8 @@ "MICROSOFT_WEBHOOK_URL", "_CAL_INTERNAL_PAST_BOOKING_RESCHEDULE_CHANGE_TEAM_IDS", "ENTERPRISE_SLUGS", - "PLATFORM_ENTERPRISE_SLUGS" + "PLATFORM_ENTERPRISE_SLUGS", + "USE_POOL" ], "tasks": { "@calcom/web#copy-app-store-static": { @@ -381,7 +382,8 @@ "DATABASE_READ_URL", "DATABASE_WRITE_URL", "LOG_LEVEL", - "NEXTAUTH_SECRET" + "NEXTAUTH_SECRET", + "USE_POOL" ] }, "@calcom/ai#build": { diff --git a/yarn.lock b/yarn.lock index 1039e6a43f..bbf231c41a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3875,11 +3875,12 @@ __metadata: resolution: "@calcom/prisma@workspace:packages/prisma" dependencies: "@calcom/lib": "workspace:*" - "@prisma/client": ^6.7.0 + "@prisma/adapter-pg": ^6.16.0 + "@prisma/client": ^6.16.0 "@prisma/extension-accelerate": ^1.3.0 - "@prisma/generator-helper": ^6.7.0 + "@prisma/generator-helper": ^6.16.0 npm-run-all: ^4.1.5 - prisma: ^6.7.0 + prisma: ^6.16.0 prisma-kysely: 2.2.0 ts-node: ^10.9.1 zod: ^3.22.4 @@ -11496,6 +11497,17 @@ __metadata: languageName: node linkType: hard +"@prisma/adapter-pg@npm:^6.16.0": + version: 6.16.1 + resolution: "@prisma/adapter-pg@npm:6.16.1" + dependencies: + "@prisma/driver-adapter-utils": 6.16.1 + pg: ^8.11.3 + postgres-array: 3.0.4 + checksum: 8d09acaaddf4096bd4d65a8132875ffa8233065e18bac0060987c22f987dc949d0955b4c864d9c1e70fc330e0dfa78c3e2600eea260e086d8f2e07ef3d097dae + languageName: node + linkType: hard + "@prisma/client@npm:6.7.0": version: 6.7.0 resolution: "@prisma/client@npm:6.7.0" @@ -11511,9 +11523,9 @@ __metadata: languageName: node linkType: hard -"@prisma/client@npm:^6.7.0": - version: 6.8.2 - resolution: "@prisma/client@npm:6.8.2" +"@prisma/client@npm:^6.16.0": + version: 6.16.1 + resolution: "@prisma/client@npm:6.16.1" peerDependencies: prisma: "*" typescript: ">=5.1.0" @@ -11522,7 +11534,7 @@ __metadata: optional: true typescript: optional: true - checksum: e6acce8c93818a921b6db650bcca9df7c18965a32c697ed6b112705a28b926bcfa15fed4178c365251709b5f92625ef42c92096a60017a79a0e34b7c0e68131d + checksum: da713d17461226433cbf17e85fe2ac0ad0f589ec66e775723b1529b0f10632b6e6bc25ec119305baeea0616be1ded7d4a9135887d62a431373e0761da2c06fa8 languageName: node linkType: hard @@ -11538,6 +11550,30 @@ __metadata: languageName: node linkType: hard +"@prisma/config@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/config@npm:6.16.1" + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.16.12 + empathic: 2.0.0 + checksum: 1e2227fc4dd5def1d85528e356916e5b1a5087e9efd76d8fe797e9912afdc4e957d209e431e3fd424a5340a78466cbdf50bb3ebfb610ce6f232aee5bc4667937 + languageName: node + linkType: hard + +"@prisma/config@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/config@npm:6.16.2" + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.16.12 + empathic: 2.0.0 + checksum: 59a9d1a24fc686108b268eda8fa022475700837f404bf287025a600459f911df61c6b24395dd746e494c87eb0ddac748df1afc3681b761d8615cae7970b52092 + languageName: node + linkType: hard + "@prisma/config@npm:6.8.2": version: 6.8.2 resolution: "@prisma/config@npm:6.8.2" @@ -11561,6 +11597,20 @@ __metadata: languageName: node linkType: hard +"@prisma/debug@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/debug@npm:6.16.1" + checksum: 7ca097ff01e67d44a97f1dc24f14d2d4b276adffac967479168c015c6bcaaa859ed42a3655a5ec91f37ca6d9f4ad7b7288d442260e2443b5abdebc4b5e5706ea + languageName: node + linkType: hard + +"@prisma/debug@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/debug@npm:6.16.2" + checksum: 6ce1bfe29215d2ac8c6f708fec81a81b84f14603e09301dede0bbfbcdf4153e657274a182f13e2dd75e57960f9aeffc1e74543af0547c38f14ea8afbf1972e88 + languageName: node + linkType: hard + "@prisma/debug@npm:6.8.2": version: 6.8.2 resolution: "@prisma/debug@npm:6.8.2" @@ -11575,6 +11625,20 @@ __metadata: languageName: node linkType: hard +"@prisma/dmmf@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/dmmf@npm:6.16.1" + checksum: 1cc703ee233e3439c2fb094c61d59e7aca4484ef58a26eda586b07351b10a43061d5cccb40e0f48ce76c6c53143cf19540cf5f0a0703d8a6f899c798fae994d1 + languageName: node + linkType: hard + +"@prisma/dmmf@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/dmmf@npm:6.16.2" + checksum: ffb143e37d991ec9b6ae5ec265051e8a15e636752d363ef149a24e5c3d628a7eab558895902054c1128454c863edf52f4fe75061cd52639dd4a9b28a90350343 + languageName: node + linkType: hard + "@prisma/dmmf@npm:6.8.2": version: 6.8.2 resolution: "@prisma/dmmf@npm:6.8.2" @@ -11591,6 +11655,24 @@ __metadata: languageName: node linkType: hard +"@prisma/driver-adapter-utils@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/driver-adapter-utils@npm:6.16.1" + dependencies: + "@prisma/debug": 6.16.1 + checksum: 8c68391ff5555535aa6da7033ef7ddf97df0980cd1c2cefcec848b1e7e2b566f11fab551b14b40f8b8b9f44cd8d119841e3f9b353a644716e767e023ea15aebc + languageName: node + linkType: hard + +"@prisma/driver-adapter-utils@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/driver-adapter-utils@npm:6.16.2" + dependencies: + "@prisma/debug": 6.16.2 + checksum: 965aa80cca4b78bed6f6f0d6359b955b317972a69b3fcbb3d3fb11989fdad54b36f856234b72d20d818819a87d6f70e4ebbe1f4f3d78a00bcd1a9f7e72890ae7 + languageName: node + linkType: hard + "@prisma/engines-version@npm:5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2": version: 5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2 resolution: "@prisma/engines-version@npm:5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2" @@ -11605,6 +11687,13 @@ __metadata: languageName: node linkType: hard +"@prisma/engines-version@npm:6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43": + version: 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + resolution: "@prisma/engines-version@npm:6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43" + checksum: 87f53c054075e9fcc3ac580600c41c798fca1019ae69cbe61e207235585e0e762329aa87eb1f5c9bce114e6748aac16511617c3e7bb574a39b74c9ee7a5cf68f + languageName: node + linkType: hard + "@prisma/engines-version@npm:6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e": version: 6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e resolution: "@prisma/engines-version@npm:6.8.0-43.2060c79ba17c6bb9f5823312b6f6b7f4a845738e" @@ -11636,6 +11725,30 @@ __metadata: languageName: node linkType: hard +"@prisma/engines@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/engines@npm:6.16.1" + dependencies: + "@prisma/debug": 6.16.1 + "@prisma/engines-version": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + "@prisma/fetch-engine": 6.16.1 + "@prisma/get-platform": 6.16.1 + checksum: 1316e2e01e2e23929547ac411d67782ef06e5345e38e72729940a8a20802dad2f700c2618e59e5f106425daa91d3c647bf48eaa84038be9b93c6484fc2e261ff + languageName: node + linkType: hard + +"@prisma/engines@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/engines@npm:6.16.2" + dependencies: + "@prisma/debug": 6.16.2 + "@prisma/engines-version": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + "@prisma/fetch-engine": 6.16.2 + "@prisma/get-platform": 6.16.2 + checksum: dfe7ef818df719891882f107db15258f873d1f86baff336fae380144d2c9342772c77dd7d5e3955700caae66e99a769b699fad75b582b2001cf206d128dbbbbb + languageName: node + linkType: hard + "@prisma/engines@npm:6.8.2": version: 6.8.2 resolution: "@prisma/engines@npm:6.8.2" @@ -11679,6 +11792,28 @@ __metadata: languageName: node linkType: hard +"@prisma/fetch-engine@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/fetch-engine@npm:6.16.1" + dependencies: + "@prisma/debug": 6.16.1 + "@prisma/engines-version": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + "@prisma/get-platform": 6.16.1 + checksum: d8d329231b9ea2d6c9221e3c411d4fd30dc837cfd6cb663a1e3d363fbfc3c2035876bf305b3d72b255d88ae3a2dd638c440cbc5fca13c3856d5a6c2f18f7180d + languageName: node + linkType: hard + +"@prisma/fetch-engine@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/fetch-engine@npm:6.16.2" + dependencies: + "@prisma/debug": 6.16.2 + "@prisma/engines-version": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + "@prisma/get-platform": 6.16.2 + checksum: 0fe048e0df96d578d3aa2f8350804abd49e80bcf23b8bca756f9b67096dd74d6dd6a9100d5627762f56a4c391da24205be69dcd44b0ea7747ac400aa9521e5a4 + languageName: node + linkType: hard + "@prisma/fetch-engine@npm:6.8.2": version: 6.8.2 resolution: "@prisma/fetch-engine@npm:6.8.2" @@ -11710,7 +11845,29 @@ __metadata: languageName: node linkType: hard -"@prisma/generator-helper@npm:^6.3.0, @prisma/generator-helper@npm:^6.7.0": +"@prisma/generator-helper@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/generator-helper@npm:6.16.2" + dependencies: + "@prisma/debug": 6.16.2 + "@prisma/dmmf": 6.16.2 + "@prisma/generator": 6.16.2 + checksum: 284a7812b335e904399178415a4272fa59cbda4a37a3cbd0bc032f347f25a61a1afef1199bef7b454e769017e8b5f0612caf1b3ff9228a1904f6078122d2e79a + languageName: node + linkType: hard + +"@prisma/generator-helper@npm:^6.16.0": + version: 6.16.1 + resolution: "@prisma/generator-helper@npm:6.16.1" + dependencies: + "@prisma/debug": 6.16.1 + "@prisma/dmmf": 6.16.1 + "@prisma/generator": 6.16.1 + checksum: 337397ff7dbc14fd478e7158b75cdc1cafe7b8d417bb7826a7e58bdae35e3d73a2ab2c666d487a0a21c19df202bcfa7f05a101994c78729c6fa4e6d763401dff + languageName: node + linkType: hard + +"@prisma/generator-helper@npm:^6.3.0": version: 6.8.2 resolution: "@prisma/generator-helper@npm:6.8.2" dependencies: @@ -11728,6 +11885,20 @@ __metadata: languageName: node linkType: hard +"@prisma/generator@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/generator@npm:6.16.1" + checksum: 4e27447fdd42acf69518a6c6693ea80234008ea0bd52f3f13ad235b0376874b9b0c5cb148d306379904aea55bd9c2a29cbaa0c4075d0514ae9aac90fe3e439f7 + languageName: node + linkType: hard + +"@prisma/generator@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/generator@npm:6.16.2" + checksum: 4a01037d13bf34bddf41df5103d2a1fdab994604dee6c0ca0470e1958917c1c7fe1dba64a750b7de25cb19e1202e88c509a53d924b34aca29309a081b9e230e9 + languageName: node + linkType: hard + "@prisma/generator@npm:6.8.2": version: 6.8.2 resolution: "@prisma/generator@npm:6.8.2" @@ -11753,6 +11924,24 @@ __metadata: languageName: node linkType: hard +"@prisma/get-platform@npm:6.16.1": + version: 6.16.1 + resolution: "@prisma/get-platform@npm:6.16.1" + dependencies: + "@prisma/debug": 6.16.1 + checksum: 63e48e49a94197610707e128958be1f9d657f408aee2424d426c072c6d0aea43f37a36046d57d860a9c3c246219c34d1ce6f2138e2fbae9e26d13f1c17edda47 + languageName: node + linkType: hard + +"@prisma/get-platform@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/get-platform@npm:6.16.2" + dependencies: + "@prisma/debug": 6.16.2 + checksum: 427e044c9b171c95e6353123f749ee93d8b664b6fa601e9775628541cc20f5bcc0e0e57d6ef8d3b88b49827472edd7c65e604ee21b59078bbf66c244e4018ff1 + languageName: node + linkType: hard + "@prisma/get-platform@npm:6.8.2": version: 6.8.2 resolution: "@prisma/get-platform@npm:6.8.2" @@ -11828,6 +12017,33 @@ __metadata: languageName: node linkType: hard +"@prisma/internals@npm:^6.16.2": + version: 6.16.2 + resolution: "@prisma/internals@npm:6.16.2" + dependencies: + "@prisma/config": 6.16.2 + "@prisma/debug": 6.16.2 + "@prisma/dmmf": 6.16.2 + "@prisma/driver-adapter-utils": 6.16.2 + "@prisma/engines": 6.16.2 + "@prisma/fetch-engine": 6.16.2 + "@prisma/generator": 6.16.2 + "@prisma/generator-helper": 6.16.2 + "@prisma/get-platform": 6.16.2 + "@prisma/prisma-schema-wasm": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + "@prisma/schema-engine-wasm": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + "@prisma/schema-files-loader": 6.16.2 + arg: 5.0.2 + prompts: 2.4.2 + peerDependencies: + typescript: ">=5.1.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 0b638f692e9032d6745072e8c435e9bdecb4b1781ac2710a2e5436466b63a50933e4d90cdab4dfee8f9ad5ec6ee52c14d4d6f424c915905cd39b59366bd8887a + languageName: node + linkType: hard + "@prisma/nextjs-monorepo-workaround-plugin@npm:^6.16.1": version: 6.16.1 resolution: "@prisma/nextjs-monorepo-workaround-plugin@npm:6.16.1" @@ -11849,6 +12065,13 @@ __metadata: languageName: node linkType: hard +"@prisma/prisma-schema-wasm@npm:6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43": + version: 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + resolution: "@prisma/prisma-schema-wasm@npm:6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43" + checksum: 17326c084fd002475638ecece65dcf81927e5cb6bd76ca9b6fd3d7681b9467132b1a7756a331989ba8b827cf6299d5d1bbe641be53ba5d004723ab8bdb836e6c + languageName: node + linkType: hard + "@prisma/schema-engine-wasm@npm:6.15.0-5.85179d7826409ee107a6ba334b5e305ae3fba9fb": version: 6.15.0-5.85179d7826409ee107a6ba334b5e305ae3fba9fb resolution: "@prisma/schema-engine-wasm@npm:6.15.0-5.85179d7826409ee107a6ba334b5e305ae3fba9fb" @@ -11856,6 +12079,13 @@ __metadata: languageName: node linkType: hard +"@prisma/schema-engine-wasm@npm:6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43": + version: 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + resolution: "@prisma/schema-engine-wasm@npm:6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43" + checksum: 07017d00b8168e4f364ea692d486e5d2ef821430e9d23d0053154945aec0ae86285dd1e9cb24769d0d259f2cf3ec2c974fa7415764dedfec139c65a7a7af12e9 + languageName: node + linkType: hard + "@prisma/schema-files-loader@npm:5.22.0": version: 5.22.0 resolution: "@prisma/schema-files-loader@npm:5.22.0" @@ -11876,6 +12106,16 @@ __metadata: languageName: node linkType: hard +"@prisma/schema-files-loader@npm:6.16.2": + version: 6.16.2 + resolution: "@prisma/schema-files-loader@npm:6.16.2" + dependencies: + "@prisma/prisma-schema-wasm": 6.16.0-7.1c57fdcd7e44b29b9313256c76699e91c3ac3c43 + fs-extra: 11.3.0 + checksum: b3db96a505ad0dff6176f5d8f57141f6de3e76fb4facb7acfa1e9ce882fa19b099c47c8d2444ff564bb714d0063371153df01c3eb0559e06afb8cdff032cf59e + languageName: node + linkType: hard + "@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": version: 1.1.2 resolution: "@protobufjs/aspromise@npm:1.1.2" @@ -22141,6 +22381,7 @@ __metadata: "@jetstreamapp/soql-parser-js": ^6.1.0 "@next/third-parties": ^14.2.5 "@playwright/test": ^1.45.3 + "@prisma/internals": ^6.16.2 "@snaplet/copycat": ^4.1.0 "@testing-library/jest-dom": ^5.16.5 "@testing-library/react": ^16.0.1 @@ -39709,6 +39950,13 @@ __metadata: languageName: node linkType: hard +"postgres-array@npm:3.0.4": + version: 3.0.4 + resolution: "postgres-array@npm:3.0.4" + checksum: 9d0fed9f8a4674cbc31a4e568dc5d068f6e32b4b5c62deae2c4908c75303be0c5aef023fc04dfb8feaf6d63af1a17257e528ef606e8128bffe1f9d6844ad8ffa + languageName: node + linkType: hard + "postgres-array@npm:~2.0.0": version: 2.0.0 resolution: "postgres-array@npm:2.0.0" @@ -40036,6 +40284,23 @@ __metadata: languageName: node linkType: hard +"prisma@npm:^6.16.0": + version: 6.16.1 + resolution: "prisma@npm:6.16.1" + dependencies: + "@prisma/config": 6.16.1 + "@prisma/engines": 6.16.1 + peerDependencies: + typescript: ">=5.1.0" + peerDependenciesMeta: + typescript: + optional: true + bin: + prisma: build/index.js + checksum: 6d462b169c250b4c5b287ef52c33b4586a04e02a81ce0e2848f570ef844a67b61a79fadba96bcfe3db1100e59947ea3965cccf8c648a59eccc3f61dad95bb401 + languageName: node + linkType: hard + "prisma@npm:^6.7.0": version: 6.8.2 resolution: "prisma@npm:6.8.2"