fix: fetch workflows on the backend (#15796)

* fix: fetch workflows on the router

* chore: remove workflows

* chore: import zod

* chore: move to repository
This commit is contained in:
Udit Takkar
2024-07-17 07:02:22 +00:00
committed by GitHub
parent b7bfd77f95
commit e960b8ad10
6 changed files with 258 additions and 219 deletions
@@ -859,7 +859,7 @@ const EventTypePageWrapper: React.FC<PageProps> & {
const { data: workflows } = trpc.viewer.workflows.getAllActiveWorkflows.useQuery({
eventType: {
workflows: eventType.workflows,
id: props.type,
teamId: eventType.teamId,
userId: eventType.userId,
parent: eventType.parent,
+2 -210
View File
@@ -7,6 +7,7 @@ import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/
import { parseBookingLimit, parseDurationLimit, parseRecurringEvent } from "@calcom/lib";
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
import { getTranslation } from "@calcom/lib/server/i18n";
import { EventTypeRepository } from "@calcom/lib/server/repository/eventType";
import { UserRepository } from "@calcom/lib/server/repository/user";
import type { PrismaClient } from "@calcom/prisma";
import { SchedulingType, MembershipRole } from "@calcom/prisma/enums";
@@ -46,216 +47,7 @@ export const getEventTypeById = async ({
defaultScheduleId: true,
});
const rawEventType = await prisma.eventType.findFirst({
where: {
AND: [
{
OR: [
{
users: {
some: {
id: userId,
},
},
},
{
team: {
members: {
some: {
userId: userId,
},
},
},
},
{
userId: userId,
},
],
},
{
id: eventTypeId,
},
],
},
select: {
id: true,
title: true,
slug: true,
description: true,
length: true,
isInstantEvent: true,
instantMeetingExpiryTimeOffsetInSeconds: true,
aiPhoneCallConfig: true,
offsetStart: true,
hidden: true,
locations: true,
eventName: true,
customInputs: true,
timeZone: true,
periodType: true,
metadata: true,
periodDays: true,
periodStartDate: true,
periodEndDate: true,
periodCountCalendarDays: true,
lockTimeZoneToggleOnBookingPage: true,
requiresConfirmation: true,
requiresBookerEmailVerification: true,
recurringEvent: true,
hideCalendarNotes: true,
disableGuests: true,
minimumBookingNotice: true,
beforeEventBuffer: true,
afterEventBuffer: true,
slotInterval: true,
hashedLink: true,
bookingLimits: true,
onlyShowFirstAvailableSlot: true,
durationLimits: true,
assignAllTeamMembers: true,
successRedirectUrl: true,
forwardParamsSuccessRedirect: true,
currency: true,
bookingFields: true,
useEventTypeDestinationCalendarEmail: true,
owner: {
select: {
id: true,
},
},
parent: {
select: {
id: true,
teamId: true,
},
},
teamId: true,
team: {
select: {
id: true,
name: true,
slug: true,
parentId: true,
parent: {
select: {
slug: true,
organizationSettings: {
select: {
lockEventTypeCreationForUsers: true,
},
},
},
},
members: {
select: {
role: true,
accepted: true,
user: {
select: {
...userSelect,
eventTypes: {
select: {
slug: true,
},
},
},
},
},
},
},
},
users: {
select: userSelect,
},
schedulingType: true,
schedule: {
select: {
id: true,
name: true,
},
},
hosts: {
select: {
isFixed: true,
userId: true,
priority: true,
},
},
userId: true,
price: true,
children: {
select: {
owner: {
select: {
avatarUrl: true,
name: true,
username: true,
email: true,
id: true,
},
},
hidden: true,
slug: true,
},
},
destinationCalendar: true,
seatsPerTimeSlot: true,
seatsShowAttendees: true,
seatsShowAvailabilityCount: true,
webhooks: {
select: {
id: true,
subscriberUrl: true,
payloadTemplate: true,
active: true,
eventTriggers: true,
secret: true,
eventTypeId: true,
},
},
workflows: {
include: {
workflow: {
select: {
name: true,
id: true,
trigger: true,
time: true,
timeUnit: true,
userId: true,
teamId: true,
team: {
select: {
id: true,
slug: true,
name: true,
members: true,
},
},
activeOn: {
select: {
eventType: {
select: {
id: true,
title: true,
parentId: true,
_count: {
select: {
children: true,
},
},
},
},
},
},
steps: true,
},
},
},
},
secondaryEmailId: true,
},
});
const rawEventType = await EventTypeRepository.findById({ id: eventTypeId, userId });
if (!rawEventType) {
if (isTrpcCall) {
+225
View File
@@ -194,6 +194,231 @@ export class EventTypeRepository {
});
}
static async findById({ id, userId }: { id: number; userId: number }) {
const userSelect = Prisma.validator<Prisma.UserSelect>()({
name: true,
avatarUrl: true,
username: true,
id: true,
email: true,
locale: true,
defaultScheduleId: true,
});
const CompleteEventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
id: true,
title: true,
slug: true,
description: true,
length: true,
isInstantEvent: true,
instantMeetingExpiryTimeOffsetInSeconds: true,
aiPhoneCallConfig: true,
offsetStart: true,
hidden: true,
locations: true,
eventName: true,
customInputs: true,
timeZone: true,
periodType: true,
metadata: true,
periodDays: true,
periodStartDate: true,
periodEndDate: true,
periodCountCalendarDays: true,
lockTimeZoneToggleOnBookingPage: true,
requiresConfirmation: true,
requiresBookerEmailVerification: true,
recurringEvent: true,
hideCalendarNotes: true,
disableGuests: true,
minimumBookingNotice: true,
beforeEventBuffer: true,
afterEventBuffer: true,
slotInterval: true,
hashedLink: true,
bookingLimits: true,
onlyShowFirstAvailableSlot: true,
durationLimits: true,
assignAllTeamMembers: true,
successRedirectUrl: true,
forwardParamsSuccessRedirect: true,
currency: true,
bookingFields: true,
useEventTypeDestinationCalendarEmail: true,
owner: {
select: {
id: true,
},
},
parent: {
select: {
id: true,
teamId: true,
},
},
teamId: true,
team: {
select: {
id: true,
name: true,
slug: true,
parentId: true,
parent: {
select: {
slug: true,
organizationSettings: {
select: {
lockEventTypeCreationForUsers: true,
},
},
},
},
members: {
select: {
role: true,
accepted: true,
user: {
select: {
...userSelect,
eventTypes: {
select: {
slug: true,
},
},
},
},
},
},
},
},
users: {
select: userSelect,
},
schedulingType: true,
schedule: {
select: {
id: true,
name: true,
},
},
hosts: {
select: {
isFixed: true,
userId: true,
priority: true,
},
},
userId: true,
price: true,
children: {
select: {
owner: {
select: {
avatarUrl: true,
name: true,
username: true,
email: true,
id: true,
},
},
hidden: true,
slug: true,
},
},
destinationCalendar: true,
seatsPerTimeSlot: true,
seatsShowAttendees: true,
seatsShowAvailabilityCount: true,
webhooks: {
select: {
id: true,
subscriberUrl: true,
payloadTemplate: true,
active: true,
eventTriggers: true,
secret: true,
eventTypeId: true,
},
},
workflows: {
include: {
workflow: {
select: {
name: true,
id: true,
trigger: true,
time: true,
timeUnit: true,
userId: true,
teamId: true,
team: {
select: {
id: true,
slug: true,
name: true,
members: true,
},
},
activeOn: {
select: {
eventType: {
select: {
id: true,
title: true,
parentId: true,
_count: {
select: {
children: true,
},
},
},
},
},
},
steps: true,
},
},
},
},
secondaryEmailId: true,
});
return await prisma.eventType.findFirst({
where: {
AND: [
{
OR: [
{
users: {
some: {
id: userId,
},
},
},
{
team: {
members: {
some: {
userId: userId,
},
},
},
},
{
userId: userId,
},
],
},
{
id,
},
],
},
select: CompleteEventTypeSelect,
});
}
static async findAllByTeamIdIncludeManagedEventTypes({ teamId }: { teamId?: number }) {
return await prisma.eventType.findMany({
where: {
@@ -4,7 +4,7 @@ import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
import { TRPCError } from "@trpc/server";
import type { TGetAllActiveWorkflowsInputSchema } from "./getAllActiveWorkflows.schema";
import { getAllWorkflowsFromEventType } from "./util";
import { getAllWorkflowsFromEventType, getEventTypeWorkflows } from "./util";
type GetAllActiveWorkflowsOptions = {
ctx: {
@@ -15,6 +15,14 @@ type GetAllActiveWorkflowsOptions = {
export const getAllActiveWorkflowsHandler = async ({ input, ctx }: GetAllActiveWorkflowsOptions) => {
const { eventType } = input;
const workflows = await getEventTypeWorkflows(ctx.user.id, eventType.id);
const completeEventType = {
workflows,
teamId: eventType.teamId,
userId: eventType.userId,
parent: eventType.parent,
metadata: eventType.metadata,
};
if (eventType.userId && eventType.userId !== ctx.user.id) {
throw new TRPCError({
@@ -32,7 +40,7 @@ export const getAllActiveWorkflowsHandler = async ({ input, ctx }: GetAllActiveW
if (!team) throw new TRPCError({ code: "UNAUTHORIZED" });
}
const allActiveWorkflows = await getAllWorkflowsFromEventType(eventType, eventType.userId);
const allActiveWorkflows = await getAllWorkflowsFromEventType(completeEventType, eventType.userId);
return allActiveWorkflows;
};
@@ -32,14 +32,16 @@ const ZWorkflow = z.object({
.array(),
});
export const ZWorkflows = z
.object({
workflow: ZWorkflow,
})
.array()
.optional();
export const ZGetAllActiveWorkflowsInputSchema = z.object({
eventType: z.object({
workflows: z
.object({
workflow: ZWorkflow,
})
.array()
.optional(),
id: z.number(),
teamId: z.number().optional().nullable(),
parent: z
.object({
@@ -1,4 +1,5 @@
import type { Workflow } from "@prisma/client";
import type { z } from "zod";
import { isSMSOrWhatsappAction } from "@calcom/ee/workflows/lib/actionHelperFunctions";
import { getAllWorkflows } from "@calcom/ee/workflows/lib/getAllWorkflows";
@@ -25,6 +26,7 @@ import { SENDER_ID, SENDER_NAME } from "@calcom/lib/constants";
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType";
import logger from "@calcom/lib/logger";
import { EventTypeRepository } from "@calcom/lib/server/repository/eventType";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import prisma from "@calcom/prisma";
import type { Prisma, WorkflowStep } from "@calcom/prisma/client";
@@ -40,6 +42,8 @@ import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { TRPCError } from "@trpc/server";
import type { ZWorkflows } from "./getAllActiveWorkflows.schema";
const log = logger.getSubLogger({ prefix: ["workflow"] });
export const bookingSelect = {
@@ -804,3 +808,11 @@ export async function getAllWorkflowsFromEventType(
return allWorkflows;
}
export const getEventTypeWorkflows = async (
userId: number,
eventTypeId: number
): Promise<z.infer<typeof ZWorkflows>> => {
const rawEventType = await EventTypeRepository.findById({ id: eventTypeId, userId });
return rawEventType?.workflows;
};