From 0915a37ce94a8270e1b3ab54aea218e3c80807e2 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Mon, 20 Jan 2025 18:24:53 +0400 Subject: [PATCH 01/24] migration and init to accept creationSource for new bookings --- packages/features/bookings/lib/handleNewBooking.ts | 3 +++ .../bookings/lib/handleNewBooking/createBooking.ts | 6 ++++++ .../migration.sql | 8 ++++++++ packages/prisma/schema.prisma | 8 ++++++++ 4 files changed, 25 insertions(+) create mode 100644 packages/prisma/migrations/20250120135752_add_creation_source_for_bookings_and_users/migration.sql diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index f1e2a64077bcc4..34521e56f126f7 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -68,6 +68,7 @@ import { WorkflowRepository } from "@calcom/lib/server/repository/workflow"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; import prisma from "@calcom/prisma"; import { BookingStatus, SchedulingType, WebhookTriggerEvents } from "@calcom/prisma/enums"; +import { CreationSource } from "@calcom/prisma/enums"; import { eventTypeAppMetadataOptionalSchema, eventTypeMetaDataSchemaWithTypedApps, @@ -277,6 +278,7 @@ const buildDryRunBooking = ({ ratingFeedback: null, noShowHost: null, cancelledBy: null, + creationSource: CreationSource.WEBAPP, } as CreatedBooking; /** @@ -350,6 +352,7 @@ async function handler( req: NextApiRequest & PlatformClientParams & { userId?: number | undefined; + creationSource?: CreationSource; }, bookingDataSchemaGetter: BookingDataSchemaGetter = getBookingDataSchema ) { diff --git a/packages/features/bookings/lib/handleNewBooking/createBooking.ts b/packages/features/bookings/lib/handleNewBooking/createBooking.ts index 8019d7875d65a1..370e250ee196c2 100644 --- a/packages/features/bookings/lib/handleNewBooking/createBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking/createBooking.ts @@ -7,6 +7,7 @@ import dayjs from "@calcom/dayjs"; import { isPrismaObjOrUndefined } from "@calcom/lib"; import prisma from "@calcom/prisma"; import { BookingStatus } from "@calcom/prisma/enums"; +import type { CreationSource } from "@calcom/prisma/enums"; import type { CalendarEvent } from "@calcom/types/Calendar"; import type { TgetBookingDataSchema } from "../getBookingDataSchema"; @@ -51,6 +52,7 @@ type CreateBookingParams = { }; evt: CalendarEvent; originalRescheduledBooking: OriginalRescheduledBooking; + creationSource?: CreationSource; }; function updateEventDetails( @@ -85,6 +87,7 @@ export async function createBooking({ routingFormResponseId, reroutingFormResponses, rescheduledBy, + creationSource, }: CreateBookingParams & { rescheduledBy: string | undefined }) { updateEventDetails(evt, originalRescheduledBooking, input.changedOrganizer); const associatedBookingForFormResponse = routingFormResponseId @@ -101,6 +104,7 @@ export async function createBooking({ input, evt, originalRescheduledBooking, + creationSource, }); return await saveBooking( @@ -211,6 +215,7 @@ function buildNewBookingData(params: CreateBookingParams) { routingFormResponseId, reroutingFormResponses, rescheduledBy, + creationSource, } = params; const attendeesData = getAttendeesData(evt); @@ -258,6 +263,7 @@ function buildNewBookingData(params: CreateBookingParams) { routedFromRoutingFormReponse: routingFormResponseId ? { connect: { id: routingFormResponseId } } : undefined, + creationSource, }; if (reqBody.recurringEventId) { diff --git a/packages/prisma/migrations/20250120135752_add_creation_source_for_bookings_and_users/migration.sql b/packages/prisma/migrations/20250120135752_add_creation_source_for_bookings_and_users/migration.sql new file mode 100644 index 00000000000000..3e622ecd2af8da --- /dev/null +++ b/packages/prisma/migrations/20250120135752_add_creation_source_for_bookings_and_users/migration.sql @@ -0,0 +1,8 @@ +-- CreateEnum +CREATE TYPE "CreationSource" AS ENUM ('api_v1', 'api_v2', 'webapp'); + +-- AlterTable +ALTER TABLE "Booking" ADD COLUMN "creationSource" "CreationSource"; + +-- AlterTable +ALTER TABLE "users" ADD COLUMN "creationSource" "CreationSource"; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index f3b3a7a9a46455..60ac89ff39356b 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -42,6 +42,12 @@ enum PeriodType { RANGE @map("range") } +enum CreationSource { + API_V1 @map("api_v1") + API_V2 @map("api_v2") + WEBAPP @map("webapp") +} + model Host { user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId Int @@ -366,6 +372,7 @@ model User { updatedTranslations EventTypeTranslation[] @relation("UpdatedEventTypeTranslations") createdWatchlists Watchlist[] @relation("CreatedWatchlists") updatedWatchlists Watchlist[] @relation("UpdatedWatchlists") + creationSource CreationSource? @@unique([email]) @@unique([email, username]) @@ -668,6 +675,7 @@ model Booking { // Ah, made a typo here. Should have been routedFromRoutingFormRe"s"ponse. Live with it :( routedFromRoutingFormReponse App_RoutingForms_FormResponse? assignmentReason AssignmentReason[] + creationSource CreationSource? @@index([eventTypeId]) @@index([userId]) From ee38a81501ed1dc2fa4806693089618c0e179201 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Mon, 20 Jan 2025 19:04:40 +0400 Subject: [PATCH 02/24] V1 create booking --- apps/api/v1/pages/api/bookings/_post.ts | 2 ++ packages/features/bookings/lib/handleNewBooking.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/apps/api/v1/pages/api/bookings/_post.ts b/apps/api/v1/pages/api/bookings/_post.ts index 1d43e41fd86cd6..07666e36aba9d6 100644 --- a/apps/api/v1/pages/api/bookings/_post.ts +++ b/apps/api/v1/pages/api/bookings/_post.ts @@ -5,6 +5,7 @@ import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { HttpError } from "@calcom/lib/http-error"; import { defaultResponder } from "@calcom/lib/server"; +import { CreationSource } from "@calcom/prisma/enums"; import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers"; @@ -213,6 +214,7 @@ import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers"; */ async function handler(req: NextApiRequest) { const { userId, isSystemWideAdmin, isOrganizationOwnerOrAdmin } = req; + req.creationSource = CreationSource.API_V1; if (isSystemWideAdmin) req.userId = req.body.userId || userId; if (isOrganizationOwnerOrAdmin) { diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index 34521e56f126f7..bbc6437531952c 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -1198,6 +1198,7 @@ async function handler( }, evt, originalRescheduledBooking, + creationSource: req.creationSource, }); if (booking?.userId) { From 8c2136aafa74e2c9ebf1791f3ec683d92e64542e Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Mon, 20 Jan 2025 19:08:54 +0400 Subject: [PATCH 03/24] V1 user creation --- apps/api/v1/pages/api/users/_post.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/api/v1/pages/api/users/_post.ts b/apps/api/v1/pages/api/users/_post.ts index a8e3fbfae9a6ec..8bdffe59f1e991 100644 --- a/apps/api/v1/pages/api/users/_post.ts +++ b/apps/api/v1/pages/api/users/_post.ts @@ -3,6 +3,7 @@ import type { NextApiRequest } from "next"; import { HttpError } from "@calcom/lib/http-error"; import { defaultResponder } from "@calcom/lib/server"; import prisma from "@calcom/prisma"; +import { CreationSource } from "@calcom/prisma/enums"; import { schemaUserCreateBodyParams } from "~/lib/validations/user"; @@ -94,6 +95,7 @@ async function postHandler(req: NextApiRequest) { const data = await schemaUserCreateBodyParams.parseAsync(req.body); const user = await prisma.user.create({ data }); req.statusCode = 201; + req.creationSource = CreationSource.API_V1; return { user }; } From 51978a992b771d98627db682d0b3a101474904ed Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Mon, 20 Jan 2025 20:11:08 +0400 Subject: [PATCH 04/24] webapp booking + V1 user --- apps/api/v1/pages/api/users/_post.ts | 3 +-- apps/web/pages/api/book/event.ts | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/api/v1/pages/api/users/_post.ts b/apps/api/v1/pages/api/users/_post.ts index 8bdffe59f1e991..88a79fba54bb22 100644 --- a/apps/api/v1/pages/api/users/_post.ts +++ b/apps/api/v1/pages/api/users/_post.ts @@ -93,9 +93,8 @@ async function postHandler(req: NextApiRequest) { // If user is not ADMIN, return unauthorized. if (!isSystemWideAdmin) throw new HttpError({ statusCode: 401, message: "You are not authorized" }); const data = await schemaUserCreateBodyParams.parseAsync(req.body); - const user = await prisma.user.create({ data }); + const user = await prisma.user.create({ ...data, creationSource: CreationSource.API_V1 }); req.statusCode = 201; - req.creationSource = CreationSource.API_V1; return { user }; } diff --git a/apps/web/pages/api/book/event.ts b/apps/web/pages/api/book/event.ts index 21654b543e76ed..b3f815224663e4 100644 --- a/apps/web/pages/api/book/event.ts +++ b/apps/web/pages/api/book/event.ts @@ -6,6 +6,7 @@ import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import getIP from "@calcom/lib/getIP"; import { defaultResponder } from "@calcom/lib/server"; +import { CreationSource } from "@calcom/prisma/enums"; async function handler(req: NextApiRequest & { userId?: number }, res: NextApiResponse) { const userIp = getIP(req); @@ -18,6 +19,7 @@ async function handler(req: NextApiRequest & { userId?: number }, res: NextApiRe const session = await getServerSession({ req, res }); /* To mimic API behavior and comply with types */ req.userId = session?.user?.id || -1; + req.creationSource = CreationSource.WEBAPP; const booking = await handleNewBooking(req); return booking; } From 6a8e9d6b4b3e5eb57f1fcc9f1319ed6b2e8864a2 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Mon, 20 Jan 2025 20:23:02 +0400 Subject: [PATCH 05/24] user creation in V1, V2 and webapp --- .../repositories/organizations-users.repository.ts | 4 +++- apps/api/v2/src/modules/users/users.repository.ts | 3 +++ apps/web/pages/api/auth/setup.ts | 2 ++ packages/features/auth/lib/next-auth-options.ts | 2 ++ packages/features/auth/signup/handlers/calcomHandler.ts | 2 ++ packages/features/ee/dsync/lib/createUserAndInviteToOrg.ts | 2 ++ .../features/ee/dsync/lib/users/createUsersAndConnectToOrg.ts | 2 ++ packages/features/ee/users/server/trpc-router.ts | 3 ++- packages/lib/server/repository/user.ts | 2 ++ 9 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts b/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts index b126a001e4467e..95527a1533551a 100644 --- a/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts +++ b/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts @@ -4,6 +4,8 @@ import { PrismaReadService } from "@/modules/prisma/prisma-read.service"; import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable } from "@nestjs/common"; +import { CreationSource } from "@calcom/prisma/enums"; + @Injectable() export class OrganizationsUsersRepository { constructor(private readonly dbRead: PrismaReadService, private readonly dbWrite: PrismaWriteService) {} @@ -70,7 +72,7 @@ export class OrganizationsUsersRepository { async createOrganizationUser(orgId: number, createUserBody: CreateOrganizationUserInput) { const createdUser = await this.dbWrite.prisma.user.create({ - data: createUserBody, + data: { ...createUserBody, creationSource: CreationSource.API_V2 }, }); return createdUser; diff --git a/apps/api/v2/src/modules/users/users.repository.ts b/apps/api/v2/src/modules/users/users.repository.ts index f113708d3d0e0a..25ff60086bf171 100644 --- a/apps/api/v2/src/modules/users/users.repository.ts +++ b/apps/api/v2/src/modules/users/users.repository.ts @@ -5,6 +5,8 @@ import { UpdateManagedUserInput } from "@/modules/users/inputs/update-managed-us import { Injectable, NotFoundException } from "@nestjs/common"; import type { Profile, User, Team, Prisma } from "@prisma/client"; +import { CreationSource } from "@calcom/prisma/enums"; + export type UserWithProfile = User & { movedToProfile?: (Profile & { organization: Pick }) | null; profiles?: (Profile & { organization: Pick })[]; @@ -30,6 +32,7 @@ export class UsersRepository { connect: { id: oAuthClientId }, }, isPlatformManaged, + creationSource: CreationSource.API_V2, }, }); } diff --git a/apps/web/pages/api/auth/setup.ts b/apps/web/pages/api/auth/setup.ts index c092a7505ae349..f6a6222ed5b532 100644 --- a/apps/web/pages/api/auth/setup.ts +++ b/apps/web/pages/api/auth/setup.ts @@ -9,6 +9,7 @@ import { defaultHandler, defaultResponder } from "@calcom/lib/server"; import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; import { IdentityProvider } from "@calcom/prisma/enums"; +import { CreationSource } from "@calcom/prisma/enums"; const querySchema = z.object({ username: z @@ -48,6 +49,7 @@ async function handler(req: NextApiRequest) { emailVerified: new Date(), locale: "en", // TODO: We should revisit this identityProvider: IdentityProvider.CAL, + creationSource: CreationSource.WEBAPP, }, }); diff --git a/packages/features/auth/lib/next-auth-options.ts b/packages/features/auth/lib/next-auth-options.ts index 9c69c37c14588b..82751db5e33a78 100644 --- a/packages/features/auth/lib/next-auth-options.ts +++ b/packages/features/auth/lib/next-auth-options.ts @@ -36,6 +36,7 @@ import { ProfileRepository } from "@calcom/lib/server/repository/profile"; import { UserRepository } from "@calcom/lib/server/repository/user"; import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; +import { CreationSource } from "@calcom/prisma/enums"; import { IdentityProvider, MembershipRole } from "@calcom/prisma/enums"; import { teamMetadataSchema, userMetadata } from "@calcom/prisma/zod-utils"; @@ -979,6 +980,7 @@ export const getOptions = ({ create: { role: MembershipRole.MEMBER, accepted: true, team: { connect: { id: orgId } } }, }, }), + creationSource: CreationSource.WEBAPP, }, }); diff --git a/packages/features/auth/signup/handlers/calcomHandler.ts b/packages/features/auth/signup/handlers/calcomHandler.ts index a4ef504b1df17d..b95a8d13d05908 100644 --- a/packages/features/auth/signup/handlers/calcomHandler.ts +++ b/packages/features/auth/signup/handlers/calcomHandler.ts @@ -14,6 +14,7 @@ import logger from "@calcom/lib/logger"; import { usernameHandler, type RequestWithUsernameStatus } from "@calcom/lib/server/username"; import { validateAndGetCorrectedUsernameAndEmail } from "@calcom/lib/validateUsername"; import { prisma } from "@calcom/prisma"; +import { CreationSource } from "@calcom/prisma/enums"; import { IdentityProvider } from "@calcom/prisma/enums"; import { signupSchema } from "@calcom/prisma/zod-utils"; @@ -199,6 +200,7 @@ async function handler(req: RequestWithUsernameStatus, res: NextApiResponse) { stripeCustomerId: customer.id, checkoutSessionId, }, + creationSource: CreationSource.WEBAPP, }, }); if (process.env.AVATARAPI_USERNAME && process.env.AVATARAPI_PASSWORD) { diff --git a/packages/features/ee/dsync/lib/createUserAndInviteToOrg.ts b/packages/features/ee/dsync/lib/createUserAndInviteToOrg.ts index 9533f7e90c56cf..18cc3648ed1507 100644 --- a/packages/features/ee/dsync/lib/createUserAndInviteToOrg.ts +++ b/packages/features/ee/dsync/lib/createUserAndInviteToOrg.ts @@ -3,6 +3,7 @@ import type { TFunction } from "next-i18next"; import { ProfileRepository } from "@calcom/lib/server/repository/profile"; import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; +import { CreationSource } from "@calcom/prisma/enums"; import { MembershipRole } from "@calcom/prisma/enums"; import type { getTeamOrThrow } from "@calcom/trpc/server/routers/viewer/teams/inviteMember/utils"; import { sendSignupToOrganizationEmail } from "@calcom/trpc/server/routers/viewer/teams/inviteMember/utils"; @@ -46,6 +47,7 @@ const createUserAndInviteToOrg = async ({ ], }, }, + creationSource: CreationSource.WEBAPP, }, }); diff --git a/packages/features/ee/dsync/lib/users/createUsersAndConnectToOrg.ts b/packages/features/ee/dsync/lib/users/createUsersAndConnectToOrg.ts index 9bd07ce4a9317b..37710c12bc160c 100644 --- a/packages/features/ee/dsync/lib/users/createUsersAndConnectToOrg.ts +++ b/packages/features/ee/dsync/lib/users/createUsersAndConnectToOrg.ts @@ -2,6 +2,7 @@ import { createOrUpdateMemberships } from "@calcom/features/auth/signup/utils/cr import slugify from "@calcom/lib/slugify"; import prisma from "@calcom/prisma"; import type { IdentityProvider } from "@calcom/prisma/enums"; +import { CreationSource } from "@calcom/prisma/enums"; import dSyncUserSelect from "./dSyncUserSelect"; @@ -37,6 +38,7 @@ const createUsersAndConnectToOrg = async ( organizationId, identityProvider, identityProviderId, + creationSource: CreationSource.WEBAPP, }; }), }); diff --git a/packages/features/ee/users/server/trpc-router.ts b/packages/features/ee/users/server/trpc-router.ts index 4647604bca9383..20399911ceffa1 100644 --- a/packages/features/ee/users/server/trpc-router.ts +++ b/packages/features/ee/users/server/trpc-router.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains"; +import { CreationSource } from "@calcom/prisma/enums"; import { RedirectType } from "@calcom/prisma/enums"; import { _UserModel as User } from "@calcom/prisma/zod"; import type { inferRouterOutputs } from "@calcom/trpc"; @@ -63,7 +64,7 @@ export const userAdminRouter = router({ }), add: authedAdminProcedure.input(userBodySchema).mutation(async ({ ctx, input }) => { const { prisma } = ctx; - const user = await prisma.user.create({ data: input }); + const user = await prisma.user.create({ data: { ...input, creationSource: CreationSource.WEBAPP } }); return { user, message: `User with id: ${user.id} added successfully` }; }), update: authedAdminProcedureWithRequestedUser diff --git a/packages/lib/server/repository/user.ts b/packages/lib/server/repository/user.ts index 6790097004a2ce..e36d24670b8c8a 100644 --- a/packages/lib/server/repository/user.ts +++ b/packages/lib/server/repository/user.ts @@ -9,6 +9,7 @@ import prisma from "@calcom/prisma"; import { availabilityUserSelect } from "@calcom/prisma"; import { Prisma } from "@calcom/prisma/client"; import type { User as UserType } from "@calcom/prisma/client"; +import { CreationSource } from "@calcom/prisma/enums"; import { MembershipRole } from "@calcom/prisma/enums"; import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential"; import { userMetadata } from "@calcom/prisma/zod-utils"; @@ -624,6 +625,7 @@ export class UserRepository { }, } : undefined, + creationSource: CreationSource.WEBAPP, }, }); } From dadd358fc5b39d244ae6f2f493603b0fd1be48c4 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Mon, 20 Jan 2025 20:29:45 +0400 Subject: [PATCH 06/24] booking source V2 and fix for v1 user --- apps/api/v1/pages/api/users/_post.ts | 2 +- .../bookings/2024-04-15/controllers/bookings.controller.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/api/v1/pages/api/users/_post.ts b/apps/api/v1/pages/api/users/_post.ts index 88a79fba54bb22..8331005acd1eb2 100644 --- a/apps/api/v1/pages/api/users/_post.ts +++ b/apps/api/v1/pages/api/users/_post.ts @@ -93,7 +93,7 @@ async function postHandler(req: NextApiRequest) { // If user is not ADMIN, return unauthorized. if (!isSystemWideAdmin) throw new HttpError({ statusCode: 401, message: "You are not authorized" }); const data = await schemaUserCreateBodyParams.parseAsync(req.body); - const user = await prisma.user.create({ ...data, creationSource: CreationSource.API_V1 }); + const user = await prisma.user.create({ data: { ...data, creationSource: CreationSource.API_V1 } }); req.statusCode = 201; return { user }; } diff --git a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts index af70edb760f7ef..a830b8f8409cd7 100644 --- a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts @@ -383,7 +383,11 @@ export class BookingsController_2024_04_15 { ...oAuthParams, }); Object.assign(clone, { userId, ...oAuthParams, platformBookingLocation }); - clone.body = { ...clone.body, noEmail: !oAuthParams.arePlatformEmailsEnabled }; + clone.body = { + ...clone.body, + noEmail: !oAuthParams.arePlatformEmailsEnabled, + creationSource: CreationSource.API_V2, + }; return clone as unknown as NextApiRequest & { userId?: number } & OAuthRequestParams; } From 6b331bb1f5ae920f545deea185b716ec83e42f15 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 08:30:51 +0400 Subject: [PATCH 07/24] fit type --- apps/api/v1/pages/api/bookings/_post.ts | 5 ++++- packages/lib/test/builder.ts | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/api/v1/pages/api/bookings/_post.ts b/apps/api/v1/pages/api/bookings/_post.ts index 07666e36aba9d6..307591a9f24968 100644 --- a/apps/api/v1/pages/api/bookings/_post.ts +++ b/apps/api/v1/pages/api/bookings/_post.ts @@ -214,7 +214,10 @@ import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers"; */ async function handler(req: NextApiRequest) { const { userId, isSystemWideAdmin, isOrganizationOwnerOrAdmin } = req; - req.creationSource = CreationSource.API_V1; + req.body = { + ...req.body, + creationSource: CreationSource.API_V1, + }; if (isSystemWideAdmin) req.userId = req.body.userId || userId; if (isOrganizationOwnerOrAdmin) { diff --git a/packages/lib/test/builder.ts b/packages/lib/test/builder.ts index c6de3193ad3a2b..2263f51e778099 100644 --- a/packages/lib/test/builder.ts +++ b/packages/lib/test/builder.ts @@ -3,6 +3,7 @@ import type { Booking, EventType, Prisma, Webhook, BookingReference } from "@pri import type { TFunction } from "next-i18next"; import getICalUID from "@calcom/emails/lib/getICalUID"; +import { CreationSource } from "@calcom/prisma/enums"; import { BookingStatus } from "@calcom/prisma/enums"; import type { CalendarEvent, Person, VideoCallData } from "@calcom/types/Calendar"; @@ -76,6 +77,7 @@ export const buildBooking = ( ratingFeedback: null, attendees: [], oneTimePassword: null, + creationSource: CreationSource.WEBAPP, ...booking, }; }; From 046ee53e4074e5dcf66c1461fe0d5832b22afd41 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 08:40:47 +0400 Subject: [PATCH 08/24] --fix type --- apps/web/pages/api/book/event.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/web/pages/api/book/event.ts b/apps/web/pages/api/book/event.ts index b3f815224663e4..b2ef6b416a61be 100644 --- a/apps/web/pages/api/book/event.ts +++ b/apps/web/pages/api/book/event.ts @@ -19,7 +19,10 @@ async function handler(req: NextApiRequest & { userId?: number }, res: NextApiRe const session = await getServerSession({ req, res }); /* To mimic API behavior and comply with types */ req.userId = session?.user?.id || -1; - req.creationSource = CreationSource.WEBAPP; + req.body = { + ...req.body, + creationSource: CreationSource.WEBAPP, + }; const booking = await handleNewBooking(req); return booking; } From 5a7b42bfd4cfacf092391d2ca7d162d75204b6ca Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 10:03:07 +0400 Subject: [PATCH 09/24] add test -- WIP --- apps/api/v1/test/lib/bookings/_post.test.ts | 29 +++++++ .../features/bookings/lib/handleNewBooking.ts | 3 +- .../test/fresh-booking.test.ts | 80 +++++++++++++++++++ 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/apps/api/v1/test/lib/bookings/_post.test.ts b/apps/api/v1/test/lib/bookings/_post.test.ts index 7950446044ff2c..9aa9b516d73ef2 100644 --- a/apps/api/v1/test/lib/bookings/_post.test.ts +++ b/apps/api/v1/test/lib/bookings/_post.test.ts @@ -12,6 +12,7 @@ import { ErrorCode } from "@calcom/lib/errorCodes"; import { buildBooking, buildEventType, buildWebhook } from "@calcom/lib/test/builder"; import prisma from "@calcom/prisma"; import type { Booking } from "@calcom/prisma/client"; +import { CreationSource } from "@calcom/prisma/enums"; import handler from "../../../pages/api/bookings/_post"; @@ -220,6 +221,34 @@ describe.skipIf(true)("POST /api/bookings", () => { }); expect(previousBooking?.status).toBe("cancelled"); }); + + test("Creates source as api_v1", async () => { + const { req, res } = createMocks({ + method: "POST", + body: { + name: "test", + start: dayjs().format(), + end: dayjs().add(1, "day").format(), + eventTypeId: 2, + email: "test@example.com", + location: "Cal.com Video", + timeZone: "America/Montevideo", + language: "en", + customInputs: [], + metadata: {}, + userId: 4, + }, + prisma, + }); + + prismaMock.eventType.findUniqueOrThrow.mockResolvedValue(buildEventType()); + prismaMock.booking.findMany.mockResolvedValue([]); + + await handler(req, res); + createdBooking = JSON.parse(res._getData()); + expect(createdBooking.creationSource).toEqual(CreationSource.API_V1); + expect(prismaMock.booking.create).toHaveBeenCalledTimes(1); + }); }); describe("Recurring event-type", () => { diff --git a/packages/features/bookings/lib/handleNewBooking.ts b/packages/features/bookings/lib/handleNewBooking.ts index bbc6437531952c..3d0fde73fd3894 100644 --- a/packages/features/bookings/lib/handleNewBooking.ts +++ b/packages/features/bookings/lib/handleNewBooking.ts @@ -352,7 +352,6 @@ async function handler( req: NextApiRequest & PlatformClientParams & { userId?: number | undefined; - creationSource?: CreationSource; }, bookingDataSchemaGetter: BookingDataSchemaGetter = getBookingDataSchema ) { @@ -1198,7 +1197,7 @@ async function handler( }, evt, originalRescheduledBooking, - creationSource: req.creationSource, + creationSource: req.body.creationSource, }); if (booking?.userId) { 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 6de0113f786d15..6d025ed437ac59 100644 --- a/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts +++ b/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts @@ -1549,6 +1549,86 @@ describe("handleNewBooking", () => { ); }); + describe("Creation source tests", () => { + test( + `should create a booking with creation source as WEBAPP`, + async ({ emails }) => { + const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).default; + const booker = getBooker({ + email: "booker@example.com", + name: "Booker", + }); + + const organizer = getOrganizer({ + name: "Organizer", + email: "organizer@example.com", + id: 101, + schedules: [TestData.schedules.IstWorkHours], + credentials: [getZoomAppCredential()], + selectedCalendars: [TestData.selectedCalendars.google], + }); + + const { req } = createMockNextJsRequest({ + method: "POST", + body: getMockRequestDataForBooking({ + data: { + eventTypeId: 1, + responses: { + email: booker.email, + name: booker.name, + }, + creationSource: "CreationSource.WEBAPP", + }, + }), + }); + + const scenarioData = getScenarioData({ + webhooks: [ + { + userId: organizer.id, + eventTriggers: ["BOOKING_CREATED"], + subscriberUrl: "http://my-webhook.example.com", + active: true, + eventTypeId: 1, + appId: null, + }, + ], + eventTypes: [ + { + id: 1, + slotInterval: 30, + length: 30, + users: [ + { + id: 101, + }, + ], + locations: [ + { + type: BookingLocations.ZoomVideo, + }, + ], + }, + ], + organizer, + apps: [TestData.apps["zoomvideo"]], + }); + + mockSuccessfulVideoMeetingCreation({ + metadataLookupKey: "zoomvideo", + }); + await createBookingScenario(scenarioData); + const createdBooking = await handleNewBooking(req); + expect(createdBooking).toEqual( + expect.objectContaining({ + creationSource: "CreationSource.WEBAPP", + }) + ); + }, + timeout + ); + }); + describe( "Availability Check during booking", () => { From 5d8374d95a664ee119c42184f77df03f4e39e51f Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 10:12:10 +0400 Subject: [PATCH 10/24] fix type --- .../test/utils/bookingScenario/getMockRequestDataForBooking.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts b/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts index f610db925b15ca..33440defe5efce 100644 --- a/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts +++ b/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts @@ -1,6 +1,7 @@ import { getDate } from "@calcom/web/test/utils/bookingScenario/bookingScenario"; import type { SchedulingType } from "@calcom/prisma/client"; +import type { CreationSource } from "@calcom/prisma/enums"; export const DEFAULT_TIMEZONE_BOOKER = "Asia/Kolkata"; export function getBasicMockRequestDataForBooking() { @@ -55,6 +56,7 @@ export function getMockRequestDataForDynamicGroupBooking({ eventTypeId: 0; eventTypeSlug: string; user: string; + creationSource?: CreationSource; } & CommonPropsMockRequestData; }) { return { From 0f1e6542dc7e5dadee988d65001263ea731fc876 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 10:25:48 +0400 Subject: [PATCH 11/24] fix type --- .../test/utils/bookingScenario/getMockRequestDataForBooking.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts b/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts index 33440defe5efce..28fd3c105244fc 100644 --- a/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts +++ b/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts @@ -1,7 +1,6 @@ import { getDate } from "@calcom/web/test/utils/bookingScenario/bookingScenario"; import type { SchedulingType } from "@calcom/prisma/client"; -import type { CreationSource } from "@calcom/prisma/enums"; export const DEFAULT_TIMEZONE_BOOKER = "Asia/Kolkata"; export function getBasicMockRequestDataForBooking() { @@ -41,6 +40,7 @@ export function getMockRequestDataForBooking({ data: Partial> & { eventTypeId: number; user?: string; + creationSource?: CreationSource; } & CommonPropsMockRequestData; }) { return { @@ -56,7 +56,6 @@ export function getMockRequestDataForDynamicGroupBooking({ eventTypeId: 0; eventTypeSlug: string; user: string; - creationSource?: CreationSource; } & CommonPropsMockRequestData; }) { return { From 7b798c0782bf6a897d39a1630fb16527cce38af3 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 10:38:25 +0400 Subject: [PATCH 12/24] ^ --- .../test/utils/bookingScenario/getMockRequestDataForBooking.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts b/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts index 28fd3c105244fc..60e8ebf2fddb71 100644 --- a/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts +++ b/apps/web/test/utils/bookingScenario/getMockRequestDataForBooking.ts @@ -1,6 +1,7 @@ import { getDate } from "@calcom/web/test/utils/bookingScenario/bookingScenario"; import type { SchedulingType } from "@calcom/prisma/client"; +import type { CreationSource } from "@calcom/prisma/enums"; export const DEFAULT_TIMEZONE_BOOKER = "Asia/Kolkata"; export function getBasicMockRequestDataForBooking() { From 696a36b80d2c230725f184f83e6aaa326a4f7b70 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 10:49:47 +0400 Subject: [PATCH 13/24] Need more sleep zzz --- .../bookings/lib/handleNewBooking/test/fresh-booking.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 6d025ed437ac59..df08d080569bc3 100644 --- a/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts +++ b/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts @@ -1577,7 +1577,7 @@ describe("handleNewBooking", () => { email: booker.email, name: booker.name, }, - creationSource: "CreationSource.WEBAPP", + creationSource: CreationSource.WEBAPP, }, }), }); @@ -1621,7 +1621,7 @@ describe("handleNewBooking", () => { const createdBooking = await handleNewBooking(req); expect(createdBooking).toEqual( expect.objectContaining({ - creationSource: "CreationSource.WEBAPP", + creationSource: CreationSource.WEBAPP, }) ); }, From 8444bfca58085865d1002efea70e739fb0824223 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 10:57:27 +0400 Subject: [PATCH 14/24] -_- --- .../bookings/lib/handleNewBooking/test/fresh-booking.test.ts | 1 + 1 file changed, 1 insertion(+) 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 df08d080569bc3..72f021324104bf 100644 --- a/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts +++ b/packages/features/bookings/lib/handleNewBooking/test/fresh-booking.test.ts @@ -56,6 +56,7 @@ import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData"; import { WEBSITE_URL, WEBAPP_URL } from "@calcom/lib/constants"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { resetTestEmails } from "@calcom/lib/testEmails"; +import { CreationSource } from "@calcom/prisma/enums"; import { BookingStatus } from "@calcom/prisma/enums"; import { test } from "@calcom/web/test/fixtures/fixtures"; From 59966530794a3989d82c5f8d01a15bfa8776b863 Mon Sep 17 00:00:00 2001 From: Morgan Vernay Date: Tue, 21 Jan 2025 15:59:19 +0200 Subject: [PATCH 15/24] bump libraries platform --- apps/api/v2/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/v2/package.json b/apps/api/v2/package.json index d3c48f3772bbd4..e88688684555e3 100644 --- a/apps/api/v2/package.json +++ b/apps/api/v2/package.json @@ -29,7 +29,7 @@ "@axiomhq/winston": "^1.2.0", "@calcom/platform-constants": "*", "@calcom/platform-enums": "*", - "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.86", + "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.89", "@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2", "@calcom/platform-types": "*", "@calcom/platform-utils": "*", From f263546ad058a56ccf2a5cb2c29edb12f49e8b06 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 19:07:28 +0400 Subject: [PATCH 16/24] adds for v2 recurring booking --- .../ee/bookings/2024-04-15/controllers/bookings.controller.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts index a830b8f8409cd7..12be195a6f95af 100644 --- a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts @@ -59,6 +59,7 @@ import { } from "@calcom/platform-types"; import { ApiResponse } from "@calcom/platform-types"; import { PrismaClient } from "@calcom/prisma"; +import { CreationSource } from "@calcom/prisma/enums"; type BookingRequest = Request & { userId?: number; @@ -415,6 +416,7 @@ export class BookingsController_2024_04_15 { ...oAuthParams, platformBookingLocation, noEmail: !oAuthParams.arePlatformEmailsEnabled, + creationSource: CreationSource.API_V2, }); return clone as unknown as NextApiRequest & { userId?: number } & OAuthRequestParams; } From 4d7ea3af3549b44212206fbbd6850513b56e202f Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 19:09:45 +0400 Subject: [PATCH 17/24] fix lint --- apps/web/pages/api/book/event.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/pages/api/book/event.ts b/apps/web/pages/api/book/event.ts index ad99f9716de91c..51fa497462a43e 100644 --- a/apps/web/pages/api/book/event.ts +++ b/apps/web/pages/api/book/event.ts @@ -6,8 +6,8 @@ import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking"; import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import getIP from "@calcom/lib/getIP"; import { defaultResponder } from "@calcom/lib/server"; -import { CreationSource } from "@calcom/prisma/enums"; import { checkCfTurnstileToken } from "@calcom/lib/server/checkCfTurnstileToken"; +import { CreationSource } from "@calcom/prisma/enums"; async function handler(req: NextApiRequest & { userId?: number }, res: NextApiResponse) { const userIp = getIP(req); From 73f17e1cc8b98b65368a1eac46ebb50e51250119 Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 19:19:10 +0400 Subject: [PATCH 18/24] instant meetings --- apps/web/pages/api/book/instant-event.ts | 2 ++ packages/features/instant-meeting/handleInstantMeeting.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/apps/web/pages/api/book/instant-event.ts b/apps/web/pages/api/book/instant-event.ts index 57fa795f5d1c19..697007e7f16248 100644 --- a/apps/web/pages/api/book/instant-event.ts +++ b/apps/web/pages/api/book/instant-event.ts @@ -5,6 +5,7 @@ import handleInstantMeeting from "@calcom/features/instant-meeting/handleInstant import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError"; import getIP from "@calcom/lib/getIP"; import { defaultResponder } from "@calcom/lib/server"; +import { CreationSource } from "@calcom/prisma/enums"; async function handler(req: NextApiRequest & { userId?: number }, res: NextApiResponse) { const userIp = getIP(req); @@ -16,6 +17,7 @@ async function handler(req: NextApiRequest & { userId?: number }, res: NextApiRe const session = await getServerSession({ req, res }); req.userId = session?.user?.id || -1; + req.body.creationSource = CreationSource.WEBAPP; const booking = await handleInstantMeeting(req); return booking; } diff --git a/packages/features/instant-meeting/handleInstantMeeting.ts b/packages/features/instant-meeting/handleInstantMeeting.ts index d06eee70288139..1297c5b5ebd732 100644 --- a/packages/features/instant-meeting/handleInstantMeeting.ts +++ b/packages/features/instant-meeting/handleInstantMeeting.ts @@ -261,6 +261,7 @@ async function handler(req: NextApiRequest) { data: attendeesList, }, }, + creationSource: req.body.creationSource, }; const createBookingObj = { From 6ec734331730dffd993407bade0622959884a374 Mon Sep 17 00:00:00 2001 From: Morgan Vernay Date: Tue, 21 Jan 2025 17:19:13 +0200 Subject: [PATCH 19/24] fix: api v2 creation source --- .../src/ee/bookings/2024-08-13/services/input.service.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts index 17465cf751f4a4..456c8d818a0e73 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts @@ -33,6 +33,7 @@ import { RescheduleSeatedBookingInput_2024_08_13, } from "@calcom/platform-types"; import { EventType, PlatformOAuthClient } from "@calcom/prisma/client"; +import { CreationSource } from "@calcom/prisma/enums"; type BookingRequest = NextApiRequest & { userId: number | undefined } & OAuthRequestParams; @@ -97,10 +98,14 @@ export class InputBookingsService_2024_08_13 { if (oAuthClientParams) { Object.assign(newRequest, { userId, ...oAuthClientParams, platformBookingLocation: location }); - newRequest.body = { ...bodyTransformed, noEmail: !oAuthClientParams.arePlatformEmailsEnabled }; + newRequest.body = { + ...bodyTransformed, + noEmail: !oAuthClientParams.arePlatformEmailsEnabled, + creationSource: CreationSource.API_V2, + }; } else { Object.assign(newRequest, { userId, platformBookingLocation: location }); - newRequest.body = { ...bodyTransformed, noEmail: false }; + newRequest.body = { ...bodyTransformed, noEmail: false, creationSource: CreationSource.API_V2 }; } return newRequest as unknown as BookingRequest; From 47bc8887c5fd57d7efb802f90f7720c2e8b84241 Mon Sep 17 00:00:00 2001 From: Morgan Vernay Date: Tue, 21 Jan 2025 17:37:25 +0200 Subject: [PATCH 20/24] fixup! fix: api v2 creation source --- .../ee/bookings/2024-04-15/controllers/bookings.controller.ts | 2 +- .../v2/src/ee/bookings/2024-08-13/services/input.service.ts | 2 +- .../repositories/organizations-users.repository.ts | 3 +-- apps/api/v2/src/modules/users/users.repository.ts | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts index 12be195a6f95af..20f621e6ca82c9 100644 --- a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts @@ -33,6 +33,7 @@ import { import { ConfigService } from "@nestjs/config"; import { ApiQuery, ApiExcludeController as DocsExcludeController } from "@nestjs/swagger"; import { User } from "@prisma/client"; +import { CreationSource } from "@prisma/client"; import { Request } from "express"; import { NextApiRequest } from "next/types"; import { v4 as uuidv4 } from "uuid"; @@ -59,7 +60,6 @@ import { } from "@calcom/platform-types"; import { ApiResponse } from "@calcom/platform-types"; import { PrismaClient } from "@calcom/prisma"; -import { CreationSource } from "@calcom/prisma/enums"; type BookingRequest = Request & { userId?: number; diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts index 456c8d818a0e73..91a525b4f64878 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts @@ -12,6 +12,7 @@ import { OAuthFlowService } from "@/modules/oauth-clients/services/oauth-flow.se import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common"; import { Logger } from "@nestjs/common"; import { ConfigService } from "@nestjs/config"; +import { CreationSource } from "@prisma/client"; import { Request } from "express"; import { DateTime } from "luxon"; import { NextApiRequest } from "next/types"; @@ -33,7 +34,6 @@ import { RescheduleSeatedBookingInput_2024_08_13, } from "@calcom/platform-types"; import { EventType, PlatformOAuthClient } from "@calcom/prisma/client"; -import { CreationSource } from "@calcom/prisma/enums"; type BookingRequest = NextApiRequest & { userId: number | undefined } & OAuthRequestParams; diff --git a/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts b/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts index 95527a1533551a..d2d007ccae35e3 100644 --- a/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts +++ b/apps/api/v2/src/modules/organizations/repositories/organizations-users.repository.ts @@ -3,8 +3,7 @@ import { UpdateOrganizationUserInput } from "@/modules/organizations/inputs/upda import { PrismaReadService } from "@/modules/prisma/prisma-read.service"; import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable } from "@nestjs/common"; - -import { CreationSource } from "@calcom/prisma/enums"; +import { CreationSource } from "@prisma/client"; @Injectable() export class OrganizationsUsersRepository { diff --git a/apps/api/v2/src/modules/users/users.repository.ts b/apps/api/v2/src/modules/users/users.repository.ts index 25ff60086bf171..365bbf39e3e03b 100644 --- a/apps/api/v2/src/modules/users/users.repository.ts +++ b/apps/api/v2/src/modules/users/users.repository.ts @@ -4,8 +4,7 @@ import { CreateManagedUserInput } from "@/modules/users/inputs/create-managed-us import { UpdateManagedUserInput } from "@/modules/users/inputs/update-managed-user.input"; import { Injectable, NotFoundException } from "@nestjs/common"; import type { Profile, User, Team, Prisma } from "@prisma/client"; - -import { CreationSource } from "@calcom/prisma/enums"; +import { CreationSource } from "@prisma/client"; export type UserWithProfile = User & { movedToProfile?: (Profile & { organization: Pick }) | null; From 4d122e38d8cfc4b20c16b847fa57687877666cc6 Mon Sep 17 00:00:00 2001 From: Morgan Vernay Date: Tue, 21 Jan 2025 18:03:01 +0200 Subject: [PATCH 21/24] bump libraries --- apps/api/v2/package.json | 2 +- .../src/ee/bookings/2024-08-13/services/input.service.ts | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/api/v2/package.json b/apps/api/v2/package.json index e88688684555e3..79fd35384eb190 100644 --- a/apps/api/v2/package.json +++ b/apps/api/v2/package.json @@ -29,7 +29,7 @@ "@axiomhq/winston": "^1.2.0", "@calcom/platform-constants": "*", "@calcom/platform-enums": "*", - "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.89", + "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.90", "@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2", "@calcom/platform-types": "*", "@calcom/platform-utils": "*", diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts index 91a525b4f64878..9f4b56ff932688 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts @@ -225,6 +225,7 @@ export class InputBookingsService_2024_08_13 { newRequest.body = bodyTransformed.map((event) => ({ ...event, + creationSource: CreationSource.API_V2, })); return newRequest as unknown as BookingRequest; @@ -322,10 +323,14 @@ export class InputBookingsService_2024_08_13 { const location = await this.getRescheduleBookingLocation(bookingUid); if (oAuthClientParams) { Object.assign(newRequest, { userId, ...oAuthClientParams, platformBookingLocation: location }); - newRequest.body = { ...bodyTransformed, noEmail: !oAuthClientParams.arePlatformEmailsEnabled }; + newRequest.body = { + ...bodyTransformed, + noEmail: !oAuthClientParams.arePlatformEmailsEnabled, + creationSource: CreationSource.API_V2, + }; } else { Object.assign(newRequest, { userId, platformBookingLocation: location }); - newRequest.body = { ...bodyTransformed, noEmail: false }; + newRequest.body = { ...bodyTransformed, noEmail: false, creationSource: CreationSource.API_V2 }; } return newRequest as unknown as BookingRequest; From 0c2a90f7f4081c7b0637612cba21a21e2e617e8d Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Tue, 21 Jan 2025 23:18:42 +0400 Subject: [PATCH 22/24] add user --- .../oauth-clients/services/oauth-clients-users.service.ts | 3 ++- .../organizations/services/organizations-users-service.ts | 3 ++- .../viewer/teams/inviteMember/inviteMember.handler.ts | 2 ++ .../trpc/server/routers/viewer/teams/inviteMember/utils.ts | 7 +++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts b/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts index 9e64bcf40c9147..338361ca78ac72 100644 --- a/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts +++ b/apps/api/v2/src/modules/oauth-clients/services/oauth-clients-users.service.ts @@ -6,7 +6,7 @@ import { CreateManagedUserInput } from "@/modules/users/inputs/create-managed-us import { UpdateManagedUserInput } from "@/modules/users/inputs/update-managed-user.input"; import { UsersRepository } from "@/modules/users/users.repository"; import { BadRequestException, ConflictException, Injectable } from "@nestjs/common"; -import { User } from "@prisma/client"; +import { User, CreationSource } from "@prisma/client"; import { createNewUsersConnectToOrgIfExists, slugify } from "@calcom/platform-libraries"; @@ -46,6 +46,7 @@ export class OAuthClientUsersService { role: "MEMBER", }, ], + creationSource: CreationSource.API_V2, teamId: organizationId, isOrg: true, parentId: null, diff --git a/apps/api/v2/src/modules/organizations/services/organizations-users-service.ts b/apps/api/v2/src/modules/organizations/services/organizations-users-service.ts index 3a1003ad852aea..0fe739eb828f73 100644 --- a/apps/api/v2/src/modules/organizations/services/organizations-users-service.ts +++ b/apps/api/v2/src/modules/organizations/services/organizations-users-service.ts @@ -5,10 +5,10 @@ import { OrganizationsUsersRepository } from "@/modules/organizations/repositori import { OrganizationsTeamsService } from "@/modules/organizations/services/organizations-teams.service"; import { CreateUserInput } from "@/modules/users/inputs/create-user.input"; import { Injectable, ConflictException } from "@nestjs/common"; +import { Team, CreationSource } from "@prisma/client"; import { plainToInstance } from "class-transformer"; import { createNewUsersConnectToOrgIfExists } from "@calcom/platform-libraries"; -import { Team } from "@calcom/prisma/client"; @Injectable() export class OrganizationsUsersService { @@ -56,6 +56,7 @@ export class OrganizationsUsersService { }, ], teamId: org.id, + creationSource: CreationSource.API_V2, isOrg: true, parentId: null, autoAcceptEmailDomain: "not-required-for-this-endpoint", 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 19c0403fcd7f6f..c3c642224887fb 100644 --- a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts +++ b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts @@ -8,6 +8,7 @@ import { getTranslation } from "@calcom/lib/server/i18n"; import { isOrganisationOwner } from "@calcom/lib/server/queries/organisations"; import { UserRepository } from "@calcom/lib/server/repository/user"; import { MembershipRole } from "@calcom/prisma/enums"; +import { CreationSource } from "@calcom/prisma/enums"; import type { TrpcSessionUser } from "@calcom/trpc/server/trpc"; import { TRPCError } from "@trpc/server"; @@ -188,6 +189,7 @@ export const inviteMembersWithNoInviterPermissionCheck = async ( isOrg: isTeamAnOrg, inviter, autoAcceptEmailDomain: orgState.autoAcceptEmailDomain, + creationSource: CreationSource.WEBAPP, }); } diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts index 31b8005ea416a0..9129c6a8652fd4 100644 --- a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts +++ b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts @@ -20,6 +20,7 @@ import { prisma } from "@calcom/prisma"; import type { Membership, OrganizationSettings, Team } from "@calcom/prisma/client"; import { type User as UserType, type UserPassword, Prisma } from "@calcom/prisma/client"; import type { Profile as ProfileType } from "@calcom/prisma/client"; +import type { CreationSource } from "@calcom/prisma/enums"; import { MembershipRole } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; @@ -274,6 +275,7 @@ export async function createNewUsersConnectToOrgIfExists({ weekStart, timeZone, language, + creationSource, }: { invitations: Invitation[]; isOrg: boolean; @@ -286,6 +288,7 @@ export async function createNewUsersConnectToOrgIfExists({ weekStart?: string; timeZone?: string; language: string; + creationSource: CreationSource; }) { // fail if we have invalid emails invitations.forEach((invitation) => checkInputEmailIsValid(invitation.usernameOrEmail)); @@ -323,6 +326,7 @@ export async function createNewUsersConnectToOrgIfExists({ timeFormat, weekStart, timeZone, + creationSource, organizationId: orgId || null, // If the user is invited to a child team, they are automatically added to the parent org ...(orgId ? { @@ -911,6 +915,7 @@ export async function handleNewUsersInvites({ isOrg, autoAcceptEmailDomain, inviter, + creationSource, }: { invitationsForNewUsers: Invitation[]; teamId: number; @@ -922,6 +927,7 @@ export async function handleNewUsersInvites({ name: string | null; }; isOrg: boolean; + creationSource: CreationSource; }) { const translation = await getTranslation(language, "common"); @@ -933,6 +939,7 @@ export async function handleNewUsersInvites({ autoAcceptEmailDomain: autoAcceptEmailDomain, parentId: team.parentId, language, + creationSource, }); const sendVerifyEmailsPromises = invitationsForNewUsers.map((invitation) => { From 10dde4c80bb7b4147d7ded047391c19b7109428a Mon Sep 17 00:00:00 2001 From: Syed Ali Shahbaz Date: Wed, 22 Jan 2025 06:44:26 +0400 Subject: [PATCH 23/24] fix test --- .../viewer/teams/inviteMember/inviteMember.handler.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.test.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.test.ts index 357c0cb44af86b..e91c332ac0c65f 100644 --- a/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.test.ts +++ b/packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.test.ts @@ -9,6 +9,7 @@ import { constantsScenarios } from "@calcom/lib/__mocks__/constants"; import { describe, it, expect, beforeEach, vi } from "vitest"; import type { Profile } from "@calcom/prisma/client"; +import { CreationSource } from "@calcom/prisma/enums"; import { IdentityProvider, MembershipRole } from "@calcom/prisma/enums"; import { TRPCError } from "@trpc/server"; @@ -164,6 +165,7 @@ describe("inviteMemberHandler", () => { }; expect(inviteMemberUtilsMock.handleNewUsersInvites).toHaveBeenCalledWith({ + creationSource: CreationSource.WEBAPP, invitationsForNewUsers: allExpectedInvitations, team: retValueOfGetTeamOrThrowError, orgConnectInfoByUsernameOrEmail: expectedConnectionInfoMap, @@ -276,6 +278,7 @@ describe("inviteMemberHandler", () => { }; expect(inviteMemberUtilsMock.handleNewUsersInvites).toHaveBeenCalledWith({ + creationSource: CreationSource.WEBAPP, invitationsForNewUsers: allExpectedInvitations.slice(1), team: retValueOfGetTeamOrThrowError, orgConnectInfoByUsernameOrEmail: expectedConnectionInfoMap, From bb5015812615fe9af73a83a6166aa21f34f7c72a Mon Sep 17 00:00:00 2001 From: Morgan Vernay Date: Wed, 22 Jan 2025 14:01:25 +0200 Subject: [PATCH 24/24] fixup! fix test --- apps/api/v2/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/v2/package.json b/apps/api/v2/package.json index 79fd35384eb190..3b62af50496e39 100644 --- a/apps/api/v2/package.json +++ b/apps/api/v2/package.json @@ -29,7 +29,7 @@ "@axiomhq/winston": "^1.2.0", "@calcom/platform-constants": "*", "@calcom/platform-enums": "*", - "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.90", + "@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.91", "@calcom/platform-libraries-0.0.2": "npm:@calcom/platform-libraries@0.0.2", "@calcom/platform-types": "*", "@calcom/platform-utils": "*",