From 9036080fcf370190f324125008ebfa3b9fa004cf Mon Sep 17 00:00:00 2001 From: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Date: Tue, 24 Dec 2024 21:21:43 +0530 Subject: [PATCH] fix: metadata is overwritten for child managed eventType when updating parent (#18059) * fix: metadata is overwirten * Update * type error * Update * fix test * fix type error --- .../test/lib/handleChildrenEventTypes.test.ts | 29 +++++++++++++++---- .../lib/handleChildrenEventTypes.ts | 28 ++++++++++++++++-- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/apps/web/test/lib/handleChildrenEventTypes.test.ts b/apps/web/test/lib/handleChildrenEventTypes.test.ts index b7ede1e8ed..3edfde66d7 100644 --- a/apps/web/test/lib/handleChildrenEventTypes.test.ts +++ b/apps/web/test/lib/handleChildrenEventTypes.test.ts @@ -7,6 +7,7 @@ import { describe, expect, it, vi } from "vitest"; import updateChildrenEventTypes from "@calcom/features/ee/managed-event-types/lib/handleChildrenEventTypes"; import { buildEventType } from "@calcom/lib/test/builder"; import type { Prisma } from "@calcom/prisma/client"; +import { SchedulingType } from "@calcom/prisma/enums"; import type { CompleteEventType, CompleteWorkflowsOnEventTypes } from "@calcom/prisma/zod"; const mockFindFirstEventType = (data?: Partial) => { @@ -401,7 +402,27 @@ describe("handleChildrenEventTypes", () => { } as CompleteWorkflowsOnEventTypes, ], }); - prismaMock.$transaction.mockResolvedValue([{ id: 2 }]); + + // Mock the event type that will be returned for existing users + const mockUpdatedEventType = { + id: 2, + userId: 4, + timeZone: "UTC", + teamId: 1, + autoTranslateDescriptionEnabled: false, + secondaryEmailId: null, + schedulingType: SchedulingType.MANAGED, + requiresBookerEmailVerification: false, + lockTimeZoneToggleOnBookingPage: false, + useEventTypeDestinationCalendarEmail: false, + workflows: [], + parentId: 1, + locations: [], + ...evType, + }; + + prismaMock.eventType.update.mockResolvedValue(mockUpdatedEventType); + await updateChildrenEventTypes({ eventTypeId: 1, oldEventType: { children: [{ userId: 4 }], team: { name: "" } }, @@ -430,11 +451,7 @@ describe("handleChildrenEventTypes", () => { parentId: 1, userId: 5, users: { - connect: [ - { - id: 5, - }, - ], + connect: [{ id: 5 }], }, workflows: { create: [{ workflowId: 11 }], diff --git a/packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts b/packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts index 8dff66c8ff..c7a1354c21 100644 --- a/packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts +++ b/packages/features/ee/managed-event-types/lib/handleChildrenEventTypes.ts @@ -7,6 +7,7 @@ import { getTranslation } from "@calcom/lib/server/i18n"; import type { PrismaClient } from "@calcom/prisma"; import { SchedulingType } from "@calcom/prisma/enums"; import { _EventTypeModel } from "@calcom/prisma/zod"; +import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { allManagedEventTypeProps, unlockedManagedEventTypeProps } from "@calcom/prisma/zod-utils"; interface handleChildrenEventTypesProps { @@ -225,9 +226,23 @@ export default async function handleChildrenEventTypes({ .filter(([key, _]) => key !== "children") .reduce((newObj, [key, value]) => ({ ...newObj, [key]: value }), {}); // Update event types for old users - const oldEventTypes = await prisma.$transaction( - oldUserIds.map((userId) => { - return prisma.eventType.update({ + const oldEventTypes = await Promise.all( + oldUserIds.map(async (userId) => { + const existingEventType = await prisma.eventType.findUnique({ + where: { + userId_parentId: { + userId, + parentId, + }, + }, + select: { + metadata: true, + }, + }); + + const metadata = EventTypeMetaDataSchema.parse(existingEventType?.metadata || {}); + + return await prisma.eventType.update({ where: { userId_parentId: { userId, @@ -242,6 +257,13 @@ export default async function handleChildrenEventTypes({ : { deleteMany: {}, }, + metadata: { + ...(eventType.metadata as Prisma.JsonObject), + ...(metadata?.multipleDuration && "length" in unlockedFieldProps + ? { multipleDuration: metadata.multipleDuration } + : {}), + ...(metadata?.apps && "apps" in unlockedFieldProps ? { apps: metadata.apps } : {}), + }, }, }); })