Files
calendar/packages/features/ee/workflows/lib/getWorkflowReminders.ts
T
8ad442f2be feat: Upgrade to Next 15 (#18834)
* wip

* update layoutHOC

* wip

* remove app router related code no longer used

* remove more

* await cookies, headers, params, serachparams

* update yarn.lock

* await cookies, headers, params, serachparams more

* update yarn lock again

* downgrade next-auth to 4.22.1

* update yarn lock

* fix

* update yarn lock

* fix type checks

* update yarn lock

* await headers and cookies

* restore pages folder

* restore yarn.lock

* update yarn.lock

* await headers and cookies

* remove

* await params in API routes

* updates

* restore next.config.js

* remove i18n from next.config.js

* Fixed tests

* Fixed types

* Removed duplicate favicon.ico

* Fixing more types

* ImageResponse moved to next/og

* Fixed prisma import issues

* dynamic import for @ewsjs/xhr

* remove deasync dep

* dynamic import for @tryvital/vital-node

* fix type checks

* add back turbopack command

* Type fix

* Removed unneeded file

* fix turbopack relative path errors

* add comments

* remove unneeded code

* Fixed build errors

* await apis

* use Promise<Params> type in defaultResponderForAppDir util

* refactor scim api route

* fix type checks

* separate app-routing.config into client-config and server-config

* wip

* refactor routing forms components

* revert unneeded changes for easier review

* fix

* fix

* use CustomTrans

* fix type

* fix unit tests

* fix type error

* fix build error

* fix build error

* fix build error

* fix warnings

* fix warnings

* upgrade @tremor/react and tailwindcss

* numCols -> numItems

* fix forgot-password e2e test

* fix 1 more e2e test

* fix login e2e test

* fix e2e tests

* fix e2e tests

* clean up

* remove error

* use tremor/react 2.11.0

* fix

* rename CustomTrans to ServerTrans

* address comment

* fix test

* fix ServerTrans

* fix

* fix type

* fix ServerTrans usages 1

* fix translations

* fix type checks

* fix type checks

* link styling

* fix

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-03-20 21:30:51 -03:00

213 lines
5.3 KiB
TypeScript

import dayjs from "@calcom/dayjs";
import prisma from "@calcom/prisma";
import type { EventType, User, WorkflowReminder, WorkflowStep } from "@calcom/prisma/client";
import { Prisma } from "@calcom/prisma/client";
import { WorkflowMethods } from "@calcom/prisma/enums";
type PartialWorkflowStep =
| (Partial<WorkflowStep> & { workflow: { userId?: number; teamId?: number } })
| null;
type Booking = Prisma.BookingGetPayload<{
include: {
attendees: true;
};
}>;
type PartialBooking =
| (Pick<
Booking,
| "startTime"
| "endTime"
| "location"
| "description"
| "metadata"
| "customInputs"
| "responses"
| "uid"
| "attendees"
| "userPrimaryEmail"
| "smsReminderNumber"
| "title"
> & {
eventType:
| (Partial<EventType> & {
slug: string;
team: { parentId?: number; hideBranding: boolean };
hosts: { user: { email: string; destinationCalendar?: { primaryEmail: string } } }[] | undefined;
})
| null;
} & {
user: Partial<User> | null;
})
| null;
export type PartialWorkflowReminder = Pick<
WorkflowReminder,
"id" | "isMandatoryReminder" | "scheduledDate"
> & {
booking: PartialBooking | null;
} & { workflowStep: PartialWorkflowStep };
async function getWorkflowReminders<T extends Prisma.WorkflowReminderSelect>(
filter: Prisma.WorkflowReminderWhereInput,
select: T
): Promise<Array<Prisma.WorkflowReminderGetPayload<{ select: T }>>> {
const pageSize = 90;
let pageNumber = 0;
const filteredWorkflowReminders: Array<Prisma.WorkflowReminderGetPayload<{ select: T }>> = [];
while (true) {
const newFilteredWorkflowReminders = await prisma.workflowReminder.findMany({
where: filter,
select: select,
skip: pageNumber * pageSize,
take: pageSize,
});
if (newFilteredWorkflowReminders.length === 0) {
break;
}
filteredWorkflowReminders.push(
...(newFilteredWorkflowReminders as Array<Prisma.WorkflowReminderGetPayload<{ select: T }>>)
);
pageNumber++;
}
return filteredWorkflowReminders;
}
type RemindersToDeleteType = { referenceId: string | null };
export async function getAllRemindersToDelete(): Promise<RemindersToDeleteType[]> {
const whereFilter: Prisma.WorkflowReminderWhereInput = {
method: WorkflowMethods.EMAIL,
cancelled: true,
scheduledDate: {
lt: dayjs().toISOString(),
},
};
const select = Prisma.validator<Prisma.WorkflowReminderSelect>()({
referenceId: true,
});
const remindersToDelete = await getWorkflowReminders(whereFilter, select);
return remindersToDelete;
}
type RemindersToCancelType = { referenceId: string | null; id: number };
export async function getAllRemindersToCancel(): Promise<RemindersToCancelType[]> {
const whereFilter: Prisma.WorkflowReminderWhereInput = {
cancelled: true,
scheduled: true, //if it is false then they are already cancelled
scheduledDate: {
lte: dayjs().add(1, "hour").toISOString(),
},
};
const select = Prisma.validator<Prisma.WorkflowReminderSelect>()({
referenceId: true,
id: true,
});
const remindersToCancel = await getWorkflowReminders(whereFilter, select);
return remindersToCancel;
}
export const select = Prisma.validator<Prisma.WorkflowReminderSelect>()({
id: true,
scheduledDate: true,
isMandatoryReminder: true,
workflowStep: {
select: {
action: true,
sendTo: true,
reminderBody: true,
emailSubject: true,
template: true,
sender: true,
includeCalendarEvent: true,
workflow: {
select: {
userId: true,
teamId: true,
},
},
},
},
booking: {
select: {
startTime: true,
endTime: true,
location: true,
description: true,
smsReminderNumber: true,
userPrimaryEmail: true,
user: {
select: {
email: true,
name: true,
timeZone: true,
locale: true,
username: true,
timeFormat: true,
hideBranding: true,
},
},
metadata: true,
uid: true,
customInputs: true,
responses: true,
attendees: true,
eventType: {
select: {
bookingFields: true,
title: true,
slug: true,
hosts: {
select: {
user: {
select: {
email: true,
destinationCalendar: {
select: {
primaryEmail: true,
},
},
},
},
},
},
recurringEvent: true,
team: {
select: {
parentId: true,
hideBranding: true,
},
},
},
},
},
},
});
export async function getAllUnscheduledReminders(): Promise<PartialWorkflowReminder[]> {
const whereFilter: Prisma.WorkflowReminderWhereInput = {
method: WorkflowMethods.EMAIL,
scheduled: false,
scheduledDate: {
lte: dayjs().add(2, "hour").toISOString(),
},
OR: [{ cancelled: false }, { cancelled: null }],
};
const unscheduledReminders = (await getWorkflowReminders(whereFilter, select)) as PartialWorkflowReminder[];
return unscheduledReminders;
}