Skip to content

Commit

Permalink
chore: Move getRemindersFromRemovedTeams and deleteAllWorkflowReminde…
Browse files Browse the repository at this point in the history
…rs to workflow repo (#16861)

* wip

* move deleteAllWorkflowReminders to repo
  • Loading branch information
sean-brydon authored Sep 27, 2024
1 parent 4d9777a commit 20729b3
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 161 deletions.
8 changes: 3 additions & 5 deletions packages/features/bookings/lib/handleCancelBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getTranslation } from "@calcom/lib/server/i18n";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
import type { WebhookTriggerEvents } from "@calcom/prisma/enums";
Expand All @@ -32,10 +33,7 @@ import {
schemaBookingCancelParams,
} from "@calcom/prisma/zod-utils";
import type { EventTypeMetadata } from "@calcom/prisma/zod-utils";
import {
deleteAllWorkflowReminders,
getAllWorkflowsFromEventType,
} from "@calcom/trpc/server/routers/viewer/workflows/util";
import { getAllWorkflowsFromEventType } from "@calcom/trpc/server/routers/viewer/workflows/util";
import type { CalendarEvent } from "@calcom/types/Calendar";

import { getAllCredentials } from "./getAllCredentialsForUsersOnEvent/getAllCredentials";
Expand Down Expand Up @@ -520,7 +518,7 @@ async function handler(req: CustomRequest) {
webhookTriggerPromises.push(deleteWebhookScheduledTriggers({ booking }));

//Workflows - cancel all reminders for cancelled bookings
workflowReminderPromises.push(deleteAllWorkflowReminders(booking.workflowReminders));
workflowReminderPromises.push(WorkflowRepository.deleteAllWorkflowReminders(booking.workflowReminders));
}

await Promise.all([...webhookTriggerPromises, ...workflowReminderPromises]).catch((error) => {
Expand Down
8 changes: 3 additions & 5 deletions packages/features/bookings/lib/handleNewBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import { getPiiFreeCalendarEvent, getPiiFreeEventType, getPiiFreeUser } from "@c
import { safeStringify } from "@calcom/lib/safeStringify";
import { checkBookingLimits, checkDurationLimits, getLuckyUser } from "@calcom/lib/server";
import { getTranslation } from "@calcom/lib/server/i18n";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { slugify } from "@calcom/lib/slugify";
import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/SyncServiceManager";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
Expand All @@ -71,10 +72,7 @@ import { BookingStatus, SchedulingType, WebhookTriggerEvents } from "@calcom/pri
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import type { bookingCreateSchemaLegacyPropsForApi } from "@calcom/prisma/zod-utils";
import { userMetadata as userMetadataSchema } from "@calcom/prisma/zod-utils";
import {
deleteAllWorkflowReminders,
getAllWorkflowsFromEventType,
} from "@calcom/trpc/server/routers/viewer/workflows/util";
import { getAllWorkflowsFromEventType } from "@calcom/trpc/server/routers/viewer/workflows/util";
import type {
AdditionalInformation,
AppsStatus,
Expand Down Expand Up @@ -1173,7 +1171,7 @@ async function handler(
if (!eventType.seatsPerTimeSlot && originalRescheduledBooking?.uid) {
log.silly("Rescheduling booking", originalRescheduledBooking.uid);
// cancel workflow reminders from previous rescheduled booking
await deleteAllWorkflowReminders(originalRescheduledBooking.workflowReminders);
await WorkflowRepository.deleteAllWorkflowReminders(originalRescheduledBooking.workflowReminders);

evt = addVideoCallDataToEvent(originalRescheduledBooking.references, evt);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getTranslation } from "@calcom/lib/server/i18n";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import prisma from "@calcom/prisma";
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import { schemaBookingCancelParams } from "@calcom/prisma/zod-utils";
import type { EventTypeMetadata } from "@calcom/prisma/zod-utils";
import { deleteAllWorkflowReminders } from "@calcom/trpc/server/routers/viewer/workflows/util";
import type { CalendarEvent } from "@calcom/types/Calendar";

import type { CustomRequest } from "../../handleCancelBooking";
Expand Down Expand Up @@ -156,7 +156,7 @@ async function cancelAttendeeSeat(
bookingToDelete?.workflowReminders.filter((reminder) => reminder.seatReferenceId === seatReferenceUid) ??
null;

await deleteAllWorkflowReminders(workflowRemindersForAttendee);
await WorkflowRepository.deleteAllWorkflowReminders(workflowRemindersForAttendee);

return { success: true };
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import prisma from "@calcom/prisma";
import { deleteAllWorkflowReminders } from "@calcom/trpc/server/routers/viewer/workflows/util";

// cancel/delete all workflowReminders of the removed member that come from that team (org teams only)
export async function deleteWorkfowRemindersOfRemovedMember(
Expand Down Expand Up @@ -31,8 +31,7 @@ export async function deleteWorkfowRemindersOfRemovedMember(
method: true,
},
});

deleteAllWorkflowReminders(workflowRemindersToDelete);
await WorkflowRepository.deleteAllWorkflowReminders(workflowRemindersToDelete);
} else {
if (!team.parentId) return;

Expand Down Expand Up @@ -90,6 +89,6 @@ export async function deleteWorkfowRemindersOfRemovedMember(
method: true,
},
});
deleteAllWorkflowReminders(workflowRemindersToDelete);
await WorkflowRepository.deleteAllWorkflowReminders(workflowRemindersToDelete);
}
}
119 changes: 119 additions & 0 deletions packages/lib/server/repository/workflow.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { z } from "zod";

import type { WorkflowType } from "@calcom/ee/workflows/components/WorkflowListPage";
import { deleteScheduledEmailReminder } from "@calcom/ee/workflows/lib/reminders/emailReminderManager";
import { deleteScheduledSMSReminder } from "@calcom/ee/workflows/lib/reminders/smsReminderManager";
import { deleteScheduledWhatsappReminder } from "@calcom/ee/workflows/lib/reminders/whatsappReminderManager";
import type { WorkflowStep } from "@calcom/ee/workflows/lib/types";
import { hasFilter } from "@calcom/features/filters/lib/hasFilter";
import prisma from "@calcom/prisma";
import { MembershipRole } from "@calcom/prisma/client";
import { Prisma } from "@calcom/prisma/client";
import { WorkflowMethods } from "@calcom/prisma/enums";
import type { TFilteredListInputSchema } from "@calcom/trpc/server/routers/viewer/workflows/filteredList.schema";
import type { TGetVerifiedEmailsInputSchema } from "@calcom/trpc/server/routers/viewer/workflows/getVerifiedEmails.schema";
import type { TGetVerifiedNumbersInputSchema } from "@calcom/trpc/server/routers/viewer/workflows/getVerifiedNumbers.schema";

import logger from "../../logger";

export const ZGetInputSchema = z.object({
id: z.number(),
});
Expand Down Expand Up @@ -58,6 +65,8 @@ const { include: includedFields } = Prisma.validator<Prisma.WorkflowDefaultArgs>
});

export class WorkflowRepository {
private static log = logger.getSubLogger({ prefix: ["workflow"] });

static async getById({ id }: TGetInputSchema) {
return await prisma.workflow.findFirst({
where: {
Expand Down Expand Up @@ -276,4 +285,114 @@ export class WorkflowRepository {
};
}
}
static async getRemindersFromRemovedTeams(
removedTeams: number[],
workflowSteps: WorkflowStep[],
activeOn?: number[]
) {
const remindersToDeletePromise: Prisma.PrismaPromise<
{
id: number;
referenceId: string | null;
method: string;
}[]
>[] = [];

removedTeams.forEach((teamId) => {
const reminderToDelete = prisma.workflowReminder.findMany({
where: {
OR: [
{
//team event types + children managed event types
booking: {
eventType: {
OR: [{ teamId }, { teamId: null, parent: { teamId } }],
},
},
},
{
// user bookings
booking: {
user: {
AND: [
// user is part of team that got removed
{
teams: {
some: {
teamId: teamId,
},
},
},
// and user is not part of any team were the workflow is still active on
{
teams: {
none: {
teamId: {
in: activeOn,
},
},
},
},
],
},
eventType: {
teamId: null,
parentId: null, // children managed event types are handled above with team event types
},
},
},
],
workflowStepId: {
in: workflowSteps.map((step) => {
return step.id;
}),
},
},
select: {
id: true,
referenceId: true,
method: true,
},
});

remindersToDeletePromise.push(reminderToDelete);
});
const remindersToDelete = (await Promise.all(remindersToDeletePromise)).flat();
return remindersToDelete;
}

static async deleteAllWorkflowReminders(
remindersToDelete:
| {
id: number;
referenceId: string | null;
method: string;
}[]
| null
) {
const reminderMethods: {
[x: string]: (id: number, referenceId: string | null) => void;
} = {
[WorkflowMethods.EMAIL]: (id, referenceId) => deleteScheduledEmailReminder(id, referenceId),
[WorkflowMethods.SMS]: (id, referenceId) => deleteScheduledSMSReminder(id, referenceId),
[WorkflowMethods.WHATSAPP]: (id, referenceId) => deleteScheduledWhatsappReminder(id, referenceId),
};

if (!remindersToDelete) return Promise.resolve();

const results = await Promise.allSettled(
remindersToDelete.map((reminder) => {
return reminderMethods[reminder.method](reminder.id, reminder.referenceId);
})
);

results.forEach((result, index) => {
if (result.status !== "fulfilled") {
this.log.error(
`An error occurred when deleting reminder ${remindersToDelete[index].id}, method: ${remindersToDelete[index].method}`,
result.reason
);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getTranslation } from "@calcom/lib/server";
import { getUsersCredentials } from "@calcom/lib/server/getUsersCredentials";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { prisma } from "@calcom/prisma";
import type { WebhookTriggerEvents } from "@calcom/prisma/enums";
import { BookingStatus } from "@calcom/prisma/enums";
Expand All @@ -28,7 +29,6 @@ import type { CalendarEvent, Person } from "@calcom/types/Calendar";
import { TRPCError } from "@trpc/server";

import type { TrpcSessionUser } from "../../../trpc";
import { deleteAllWorkflowReminders } from "../workflows/util";
import type { TRequestRescheduleInputSchema } from "./requestReschedule.schema";
import type { PersonAttendeeCommonFields } from "./types";

Expand Down Expand Up @@ -159,7 +159,7 @@ export const requestRescheduleHandler = async ({ ctx, input }: RequestReschedule
});

//cancel workflow reminders of previous booking
await deleteAllWorkflowReminders(bookingToReschedule.workflowReminders);
await WorkflowRepository.deleteAllWorkflowReminders(bookingToReschedule.workflowReminders);

const [mainAttendee] = bookingToReschedule.attendees;
// @NOTE: Should we assume attendees language?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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 { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import { prisma } from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/client";
Expand All @@ -11,11 +12,7 @@ import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
import { TRPCError } from "@trpc/server";

import type { TActivateEventTypeInputSchema } from "./activateEventType.schema";
import {
deleteAllWorkflowReminders,
removeSmsReminderFieldForEventTypes,
upsertSmsReminderFieldForEventTypes,
} from "./util";
import { removeSmsReminderFieldForEventTypes, upsertSmsReminderFieldForEventTypes } from "./util";

type ActivateEventTypeOptions = {
ctx: {
Expand Down Expand Up @@ -120,7 +117,7 @@ export const activateEventTypeHandler = async ({ ctx, input }: ActivateEventType
},
});

await deleteAllWorkflowReminders(remindersToDelete);
await WorkflowRepository.deleteAllWorkflowReminders(remindersToDelete);

await prisma.workflowsOnEventTypes.deleteMany({
where: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import { prisma } from "@calcom/prisma";
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";

import { TRPCError } from "@trpc/server";

import type { TDeleteInputSchema } from "./delete.schema";
import { deleteAllWorkflowReminders, isAuthorized, removeSmsReminderFieldForEventTypes } from "./util";
import { isAuthorized, removeSmsReminderFieldForEventTypes } from "./util";

type DeleteOptions = {
ctx: {
Expand Down Expand Up @@ -50,7 +51,7 @@ export const deleteHandler = async ({ ctx, input }: DeleteOptions) => {
});

//cancel workflow reminders of deleted workflow
await deleteAllWorkflowReminders(scheduledReminders);
await WorkflowRepository.deleteAllWorkflowReminders(scheduledReminders);

const isOrg = workflowToDelete.team?.isOrganization ?? false;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { isSMSOrWhatsappAction } from "@calcom/features/ee/workflows/lib/actionHelperFunctions";
import { IS_SELF_HOSTED } from "@calcom/lib/constants";
import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata";
import { WorkflowRepository } from "@calcom/lib/server/repository/workflow";
import type { PrismaClient } from "@calcom/prisma";
import { WorkflowActions } from "@calcom/prisma/enums";
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
Expand All @@ -15,7 +16,6 @@ import {
upsertSmsReminderFieldForEventTypes,
deleteRemindersOfActiveOnIds,
isAuthorizedToAddActiveOnIds,
deleteAllWorkflowReminders,
scheduleWorkflowNotifications,
verifyEmailSender,
removeSmsReminderFieldForEventTypes,
Expand Down Expand Up @@ -324,7 +324,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
//step was deleted
if (!newStep) {
// cancel all workflow reminders from deleted steps
await deleteAllWorkflowReminders(remindersFromStep);
await WorkflowRepository.deleteAllWorkflowReminders(remindersFromStep);

await ctx.prisma.workflowStep.delete({
where: {
Expand Down Expand Up @@ -367,7 +367,7 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
});

// cancel all notifications of edited step
await deleteAllWorkflowReminders(remindersFromStep);
await WorkflowRepository.deleteAllWorkflowReminders(remindersFromStep);

// schedule notifications for edited steps
await scheduleWorkflowNotifications(
Expand Down
Loading

0 comments on commit 20729b3

Please sign in to comment.