refactor: Move attribute and routing-forms code from app-store/lib to features (#26025)

* mv

* wip

* wip

* wip

* wip

* plural

* fix: resolve TypeScript type errors for attribute refactoring

- Add TransformedAttributeOption type to handle transformed contains field
- Update imports to use routing-forms Attribute type where needed
- Fix getValueOfAttributeOption to use TransformedAttributeOption type
- Update AttributeOptionValueWithType to use TransformedAttributeOption
- Fix pre-existing lint warnings (any -> unknown, proper type casting)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

* cleanup

* cleanup

* fix

* fix

* fix

* fix

* fix

* fix: add explicit type annotation to reduce callback in getAttributes.ts

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: use RouterOutputs from @calcom/trpc/react for consistent type inference

- Update AppPage.tsx to use RouterOutputs from @calcom/trpc/react instead of inferRouterOutputs<AppRouter>
- Update MultiDisconnectIntegration.tsx to use the same RouterOutputs type source
- Add eslint-disable comments for pre-existing warnings (useEffect deps, img elements)

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: explicitly type attribute property in AttributeOptionAssignment

The attribute property from Pick<AttributeOption, 'attribute'> was typed as
'unknown' because Prisma relations don't have explicit types when picked.
This explicitly defines the attribute shape with id, type, and isLocked
properties that are used in assignValueToUser.ts.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: remove unused assignedUsers from AttributeOptionAssignment Pick

The assignedUsers property was not being used in the code but was required
by the Pick type, causing a type mismatch when the actual data from the
database query didn't include it.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix: update import path for AttributeOptionAssignment and BulkAttributeAssigner types

The types.d.ts file was moved from packages/lib/service/attribute/ to
packages/app-store/routing-forms/types/. Updated the import path in utils.ts
to point to the new location.

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Benny Joo
2025-12-29 21:51:06 -03:00
committed by GitHub
co-authored by Devin AI
parent 5f0e408d2f
commit 00e5770273
37 changed files with 130 additions and 136 deletions
@@ -4,11 +4,11 @@ import { unstable_cache } from "next/cache";
import { headers, cookies } from "next/headers";
import { redirect } from "next/navigation";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { getTeamMemberPermissions } from "@calcom/features/pbac/lib/team-member-permissions";
import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory";
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
import { prisma } from "@calcom/prisma";
import { viewerTeamsRouter } from "@calcom/trpc/server/routers/viewer/teams/_router";
import { TeamMembersView } from "@calcom/web/modules/ee/teams/views/team-members-view";
@@ -4,11 +4,11 @@ import { unstable_cache } from "next/cache";
import { headers, cookies } from "next/headers";
import { redirect } from "next/navigation";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { Resource, CustomAction, CrudAction } from "@calcom/features/pbac/domain/types/permission-registry";
import { getSpecificPermissions } from "@calcom/features/pbac/lib/resource-permissions";
import { RoleManagementFactory } from "@calcom/features/pbac/services/role-management.factory";
import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
import { prisma } from "@calcom/prisma";
import { MembershipRole } from "@calcom/prisma/enums";
import { viewerOrganizationsRouter } from "@calcom/trpc/server/routers/viewer/organizations/_router";
+5 -5
View File
@@ -14,10 +14,8 @@ import { getAppOnboardingUrl } from "@calcom/lib/apps/getAppOnboardingUrl";
import { APP_NAME, COMPANY_NAME, SUPPORT_MAIL_ADDRESS, WEBAPP_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import type { AppRouter } from "@calcom/trpc/types/server/routers/_app";
import { trpc, type RouterOutputs } from "@calcom/trpc/react";
import type { App as AppType } from "@calcom/types/App";
import type { inferRouterOutputs } from "@trpc/server";
import classNames from "@calcom/ui/classNames";
import { Badge } from "@calcom/ui/components/badge";
import { Button } from "@calcom/ui/components/button";
@@ -147,8 +145,7 @@ export const AppPage = ({
useGrouping: false,
}).format(price);
type RouterOutput = inferRouterOutputs<AppRouter>;
type Credentials = RouterOutput["viewer"]["apps"]["appCredentialsByType"]["credentials"];
type Credentials = RouterOutputs["viewer"]["apps"]["appCredentialsByType"]["credentials"];
const [existingCredentials, setExistingCredentials] = useState<Credentials>([]);
@@ -199,6 +196,7 @@ export const AppPage = ({
if (searchParams?.get("defaultInstall") === "true") {
mutation.mutate({ type, variant, slug, defaultInstall: true });
}
// eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally run only once on mount
}, []);
const installOrDisconnectAppButton = () => {
@@ -317,6 +315,7 @@ export const AppPage = ({
<iframe allowFullScreen {...descriptionItem.iframe} />
</div>
) : (
// eslint-disable-next-line @next/next/no-img-element -- external app screenshots with unknown dimensions
<img
key={descriptionItem}
src={descriptionItem}
@@ -338,6 +337,7 @@ export const AppPage = ({
<div className="mb-8 flex pt-4">
<header>
<div className="mb-4 flex items-center">
{/* eslint-disable-next-line @next/next/no-img-element -- external app logo with unknown dimensions */}
<img
className={classNames(logo.includes("-dark") && "dark:invert", "min-h-16 min-w-16 h-16 w-16")}
src={logo}
@@ -2,8 +2,7 @@ import { useState } from "react";
import { Dialog } from "@calcom/features/components/controlled-dialog";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import type { AppRouter } from "@calcom/trpc/types/server/routers/_app";
import { trpc, type RouterOutputs } from "@calcom/trpc/react";
import { Button } from "@calcom/ui/components/button";
import { ConfirmationDialogContent } from "@calcom/ui/components/dialog";
import {
@@ -16,10 +15,7 @@ import {
} from "@calcom/ui/components/dropdown";
import { showToast } from "@calcom/ui/components/toast";
import type { inferRouterOutputs } from "@trpc/server";
type RouterOutput = inferRouterOutputs<AppRouter>;
type Credentials = RouterOutput["viewer"]["apps"]["appCredentialsByType"]["credentials"];
type Credentials = RouterOutputs["viewer"]["apps"]["appCredentialsByType"]["credentials"];
interface Props {
credentials: Credentials;
@@ -10,13 +10,13 @@ import type { z } from "zod";
import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
import { handleStripePaymentSuccess } from "@calcom/features/ee/payments/api/webhook";
import { distributedTracing } from "@calcom/lib/tracing/factory";
import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository";
import { weekdayToWeekIndex, type WeekDays } from "@calcom/lib/dayjs";
import type { HttpError } from "@calcom/lib/http-error";
import type { IntervalLimit } from "@calcom/lib/intervalLimits/intervalLimitSchema";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { distributedTracing } from "@calcom/lib/tracing/factory";
import type { BookingReference, Attendee, Booking, Membership } from "@calcom/prisma/client";
import type { Prisma } from "@calcom/prisma/client";
import type { WebhookTriggerEvents } from "@calcom/prisma/client";
@@ -73,7 +73,7 @@ vi.mock("@calcom/app-store/video.adapters.generated", () => ({
}));
// We don't need to test it. Also, it causes Formbricks error when imported
vi.mock("@calcom/lib/raqb/findTeamMembersMatchingAttributeLogic", () => ({
vi.mock("@calcom/features/routing-forms/lib/findTeamMembersMatchingAttributeLogic", () => ({
default: {},
}));
@@ -2289,7 +2289,10 @@ export async function mockPaymentSuccessWebhookFromStripe({ externalId }: { exte
let webhookResponse = null;
try {
const traceContext = distributedTracing.createTrace("test_stripe_webhook");
await handleStripePaymentSuccess(getMockedStripePaymentEvent({ paymentIntentId: externalId }), traceContext);
await handleStripePaymentSuccess(
getMockedStripePaymentEvent({ paymentIntentId: externalId }),
traceContext
);
} catch (e) {
log.silly("mockPaymentSuccessWebhookFromStripe:catch", JSON.stringify(e));
webhookResponse = e as HttpError;
@@ -6,16 +6,16 @@
import type { JsonGroup, JsonItem, JsonRule, JsonTree } from "react-awesome-query-builder";
import { getQueryBuilderConfigForAttributes } from "@calcom/app-store/routing-forms/lib/getQueryBuilderConfig";
import type { LocalRoute } from "@calcom/app-store/routing-forms/types/types";
import { resolveQueryValue } from "@calcom/lib/raqb/resolveQueryValue";
import { resolveQueryValue } from "@calcom/app-store/routing-forms/lib/resolveQueryValue";
import type {
LocalRoute,
Attribute,
AttributeOptionValueWithType,
AttributeOptionValue,
} from "@calcom/app-store/routing-forms/types/types";
import type { dynamicFieldValueOperands } from "@calcom/lib/raqb/types";
import { caseInsensitive } from "@calcom/lib/raqb/utils";
import { safeStringify } from "@calcom/lib/safeStringify";
import type {
AttributeOptionValueWithType,
AttributeOptionValue,
Attribute,
} from "@calcom/lib/service/attribute/server/getAttributes";
import { AttributeType } from "@calcom/prisma/enums";
function ensureArray(value: string | string[]) {
@@ -1,7 +1,7 @@
import { expect, describe, it, vi } from "vitest";
import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import type { AttributesQueryValue, RaqbChild } from "@calcom/lib/raqb/types";
import type { Attribute } from "@calcom/lib/service/attribute/server/getAttributes";
import { AttributeType } from "@calcom/prisma/enums";
import { RoutingFormFieldType } from "@calcom/routing-forms/lib/FieldTypes";
@@ -1,9 +1,9 @@
import { expect, describe, it } from "vitest";
import { RoutingFormFieldType } from "@calcom/app-store/routing-forms/lib/FieldTypes";
import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import type { AttributesQueryValue, RaqbChild } from "@calcom/lib/raqb/types";
import type { Attribute } from "@calcom/lib/service/attribute/server/getAttributes";
import { AttributeType } from "@calcom/prisma/enums";
import { RoutingFormFieldType } from "@calcom/routing-forms/lib/FieldTypes";
import { resolveQueryValue } from "./resolveQueryValue";
@@ -1,9 +1,8 @@
import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import logger from "@calcom/lib/logger";
import type { dynamicFieldValueOperands, dynamicFieldValueOperandsResponse } from "@calcom/lib/raqb/types";
import type { AttributesQueryValue } from "@calcom/lib/raqb/types";
import type { Attribute } from "@calcom/lib/service/attribute/server/getAttributes";
import { caseInsensitive } from "./utils";
import { caseInsensitive } from "@calcom/lib/raqb/utils";
// Type for JSON values that can be in the query
type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };
+33 -1
View File
@@ -2,7 +2,7 @@ import type { ImmutableTree, Config } from "react-awesome-query-builder";
import type z from "zod";
import type { App_RoutingForms_Form } from "@calcom/prisma/client";
import type { AttributeType } from "@calcom/prisma/client";
import type { AttributeType, AttributeToUser, AttributeOption } from "@calcom/prisma/client";
import type { RoutingFormSettings } from "@calcom/prisma/zod-utils";
import type QueryBuilderInitialConfig from "../components/react-awesome-query-builder/config/config";
@@ -78,6 +78,38 @@ export type Attribute = {
}[];
};
export type AttributeName = string;
export type AttributeId = string;
export type BulkAttributeAssigner =
| {
dsyncId: string;
}
| {
userId: number;
};
export type AttributeOptionAssignment = AttributeToUser & {
attributeOption: Pick<AttributeOption, "slug"> & {
label: string;
attribute: {
id: string;
type: AttributeType;
isLocked: boolean;
};
};
};
export type AttributeOptionValue = {
isGroup: boolean;
value: string;
contains: { id: string; value: string; slug: string }[];
};
export type AttributeOptionValueWithType = {
type: AttributeType;
attributeOption: AttributeOptionValue | AttributeOptionValue[];
};
export type AttributesQueryValue = NonNullable<LocalRoute["attributesQueryValue"]>;
export type FormFieldsQueryValue = LocalRoute["queryValue"];
export type SerializableField = NonNullable<SerializableForm<App_RoutingForms_Form>["fields"]>[number];
@@ -1,11 +1,11 @@
import prismock from "../../../../../tests/libs/__mocks__/prisma";
import prismock from "../../../../tests/libs/__mocks__/prisma";
import { describe, expect, it, beforeEach } from "vitest";
import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import type { AttributeOption } from "@calcom/prisma/client";
import { AttributeType, MembershipRole } from "@calcom/prisma/enums";
import type { Attribute } from "./getAttributes";
import { getAttributesForTeam, getAttributesAssignmentData, getUsersAttributes } from "./getAttributes";
// Helper functions to create test data
@@ -1,14 +1,14 @@
// TODO: Queries in this file are not optimized. Need to optimize them.
import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import type { AttributeId, AttributeOptionValueWithType } from "@calcom/app-store/routing-forms/types/types";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import { PrismaAttributeToUserRepository } from "@calcom/features/attributes/repositories/PrismaAttributeToUserRepository";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import type { AttributeToUser } from "@calcom/prisma/client";
import type { AttributeType } from "@calcom/prisma/enums";
import { PrismaAttributeRepository } from "../../../server/repository/PrismaAttributeRepository";
import { PrismaAttributeToUserRepository } from "../../../server/repository/PrismaAttributeToUserRepository";
import type { AttributeId } from "../types";
type UserId = number;
type OrgMembershipId = number;
type AttributeOptionId = string;
@@ -28,18 +28,6 @@ type AssignmentForTheTeam = {
};
};
export type Attribute = {
name: string;
slug: string;
type: AttributeType;
id: string;
options: {
id: string;
value: string;
slug: string;
}[];
};
type FullAttribute = {
name: string;
slug: string;
@@ -54,21 +42,6 @@ type FullAttribute = {
}[];
};
export type AttributeOptionValue = {
value: string;
isGroup: boolean;
contains: {
id: string;
slug: string;
value: string;
}[];
};
export type AttributeOptionValueWithType = {
type: Attribute["type"];
attributeOption: AttributeOptionValue | AttributeOptionValue[];
};
async function _findMembershipsForBothOrgAndTeam({ orgId, teamId }: { orgId: number; teamId: number }) {
const memberships = await prisma.membership.findMany({
where: {
@@ -80,7 +53,10 @@ async function _findMembershipsForBothOrgAndTeam({ orgId, teamId }: { orgId: num
type Membership = (typeof memberships)[number];
const { teamMemberships, orgMemberships } = memberships.reduce(
const { teamMemberships, orgMemberships } = memberships.reduce<{
teamMemberships: Membership[];
orgMemberships: Membership[];
}>(
(acc, membership) => {
if (membership.teamId === teamId) {
acc.teamMemberships.push(membership);
@@ -89,7 +65,7 @@ async function _findMembershipsForBothOrgAndTeam({ orgId, teamId }: { orgId: num
}
return acc;
},
{ teamMemberships: [] as Membership[], orgMemberships: [] as Membership[] }
{ teamMemberships: [], orgMemberships: [] }
);
return {
@@ -1,4 +1,4 @@
import { PrismaAttributeToUserRepository } from "../../../server/repository/PrismaAttributeToUserRepository";
import { PrismaAttributeToUserRepository } from "@calcom/features/attributes/repositories/PrismaAttributeToUserRepository";
export const getWhereClauseForAttributeOptionsManagedByCalcom = () => {
// Neither created nor updated by DSync
@@ -1,4 +1,4 @@
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
export class PrismaAttributeOptionRepository {
@@ -1,4 +1,4 @@
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
export class PrismaAttributeToUserRepository {
@@ -2,6 +2,7 @@ import { acrossQueryValueCompatiblity } from "@calcom/app-store/_utils/raqb/raqb
import type { FormResponse, Fields } from "@calcom/app-store/routing-forms/types/types";
import { zodRoutes } from "@calcom/app-store/routing-forms/zod";
import dayjs from "@calcom/dayjs";
import type { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository";
import { getBusyCalendarTimes } from "@calcom/features/calendars/lib/CalendarManager";
import type { HostRepository } from "@calcom/features/host/repositories/HostRepository";
@@ -11,7 +12,6 @@ import type { UserRepository } from "@calcom/features/users/repositories/UserRep
import logger from "@calcom/lib/logger";
import { raqbQueryValueSchema } from "@calcom/lib/raqb/zod";
import { safeStringify } from "@calcom/lib/safeStringify";
import type { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
import type { Prisma } from "@calcom/prisma/client";
import type { User, Booking, SelectedCalendar } from "@calcom/prisma/client";
import type { AttributeType } from "@calcom/prisma/enums";
+2 -2
View File
@@ -1,6 +1,6 @@
import { DI_TOKENS } from "@calcom/features/di/tokens";
import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import { moduleLoader as prismaModuleLoader } from "@calcom/features/di/modules/Prisma";
import { DI_TOKENS } from "@calcom/features/di/tokens";
import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di";
@@ -1,15 +1,17 @@
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { PrismaAttributeOptionRepository } from "@calcom/lib/server/repository/PrismaAttributeOptionRepository";
import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
import { findAssignmentsForMember } from "@calcom/lib/service/attribute/server/utils";
import type {
AttributeId,
AttributeName,
BulkAttributeAssigner,
AttributeOptionAssignment,
} from "@calcom/lib/service/attribute/types";
} from "@calcom/app-store/routing-forms/types/types";
import { findAssignmentsForMember } from "@calcom/features/attributes/lib/utils";
import { PrismaAttributeOptionRepository } from "@calcom/features/attributes/repositories/PrismaAttributeOptionRepository";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import prisma from "@calcom/prisma";
import {
doesSupportMultipleValues,
isAssignmentForLockedAttribute,
@@ -17,8 +19,7 @@ import {
isAssignmentSame,
buildSlugFromValue,
canSetValueBeyondOptions,
} from "@calcom/lib/service/attribute/utils";
import prisma from "@calcom/prisma";
} from "./assignValueToUserUtils";
const log = logger.getSubLogger({ prefix: ["entity/attribute"] });
@@ -1,11 +1,13 @@
/**
* Utility functions for attribute service. Shared across server and client.
*/
import type {
AttributeOptionAssignment,
BulkAttributeAssigner,
} from "@calcom/app-store/routing-forms/types/types";
import slugify from "@calcom/lib/slugify";
import { AttributeType } from "@calcom/prisma/enums";
import type { AttributeOptionAssignment, BulkAttributeAssigner } from "./types";
/**
* What is a pool?
* There can be two pools:
@@ -1,8 +1,8 @@
import { acrossQueryValueCompatiblity } from "@calcom/app-store/_utils/raqb/raqbUtils.server";
import type { FormResponse, Fields } from "@calcom/app-store/routing-forms/types/types";
import { zodRoutes } from "@calcom/app-store/routing-forms/zod";
import { getUsersAttributes } from "@calcom/features/attributes/lib/getAttributes";
import { withReporting } from "@calcom/lib/sentryWrapper";
import { getUsersAttributes } from "@calcom/lib/service/attribute/server/getAttributes";
import prisma from "@calcom/prisma";
import { AssignmentReasonEnum } from "@calcom/prisma/enums";
@@ -1,18 +1,19 @@
import type { BaseWidget } from "react-awesome-query-builder";
import { describe, it, expect, vi, beforeEach } from "vitest";
import {
findTeamMembersMatchingAttributeLogic,
TroubleshooterCase,
} from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
import { RouteActionType } from "@calcom/app-store/routing-forms/zod";
import * as getAttributesModule from "@calcom/features/attributes/lib/getAttributes";
import { RaqbLogicResult } from "@calcom/lib/raqb/evaluateRaqbLogic";
import * as getAttributesModule from "@calcom/lib/service/attribute/server/getAttributes";
import type { AttributeType } from "@calcom/prisma/enums";
import { RoutingFormFieldType } from "@calcom/routing-forms/lib/FieldTypes";
import type { AttributesQueryValue, FormFieldsQueryValue } from "@calcom/routing-forms/types/types";
vi.mock("@calcom/lib/service/attribute/server/getAttributes", () => {
import {
findTeamMembersMatchingAttributeLogic,
TroubleshooterCase,
} from "./findTeamMembersMatchingAttributeLogic";
vi.mock("@calcom/features/attributes/lib/getAttributes", () => {
return {
getAttributesAssignmentData: vi.fn(),
};
@@ -3,13 +3,12 @@ import type { ImmutableTree, JsonLogicResult, JsonTree } from "react-awesome-que
import type { Config } from "react-awesome-query-builder/lib";
import { Utils as QbUtils } from "react-awesome-query-builder/lib";
import { acrossQueryValueCompatiblity, raqbQueryValueUtils } from "@calcom/app-store/_utils/raqb/raqbUtils";
import type { Attribute } from "@calcom/app-store/routing-forms/types/types";
import { getAttributesAssignmentData } from "@calcom/features/attributes/lib/getAttributes";
import { RaqbLogicResult } from "@calcom/lib/raqb/evaluateRaqbLogic";
import jsonLogic from "@calcom/lib/raqb/jsonLogic";
import type { dynamicFieldValueOperands, AttributesQueryValue } from "@calcom/lib/raqb/types";
import { getAttributesAssignmentData } from "@calcom/lib/service/attribute/server/getAttributes";
import type { Attribute } from "@calcom/lib/service/attribute/server/getAttributes";
import { acrossQueryValueCompatiblity, raqbQueryValueUtils } from "./raqbUtils";
const {
getAttributesData: getAttributes,
@@ -7,7 +7,6 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
import { getAbsoluteEventTypeRedirectUrlWithEmbedSupport } from "@calcom/app-store/routing-forms/getEventTypeRedirectUrl";
import { getResponseToStore } from "@calcom/app-store/routing-forms/lib/getResponseToStore";
import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm";
import { handleResponse } from "@calcom/app-store/routing-forms/lib/handleResponse";
import { findMatchingRoute } from "@calcom/app-store/routing-forms/lib/processRoute";
import { substituteVariables } from "@calcom/app-store/routing-forms/lib/substituteVariables";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
@@ -18,11 +17,12 @@ import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowE
import { getRoutedUrl } from "./getRoutedUrl";
import { getUrlSearchParamsToForward } from "./getUrlSearchParamsToForward";
import { handleResponse } from "./handleResponse";
// Mock dependencies
vi.mock("./getUrlSearchParamsToForward");
vi.mock("./handleResponse");
vi.mock("@calcom/lib/checkRateLimitAndThrowError");
vi.mock("@calcom/app-store/routing-forms/lib/handleResponse");
vi.mock("@calcom/features/routing-forms/repositories/PrismaRoutingFormRepository");
vi.mock("@calcom/features/users/repositories/UserRepository", () => {
return {
@@ -10,7 +10,6 @@ import { getAbsoluteEventTypeRedirectUrlWithEmbedSupport } from "@calcom/app-sto
import { getResponseToStore } from "@calcom/app-store/routing-forms/lib/getResponseToStore";
import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm";
import { getServerTimingHeader } from "@calcom/app-store/routing-forms/lib/getServerTimingHeader";
import { handleResponse } from "@calcom/app-store/routing-forms/lib/handleResponse";
import { findMatchingRoute } from "@calcom/app-store/routing-forms/lib/processRoute";
import { substituteVariables } from "@calcom/app-store/routing-forms/lib/substituteVariables";
import type { FormResponse } from "@calcom/app-store/routing-forms/types/types";
@@ -28,6 +27,7 @@ import prisma from "@calcom/prisma";
import { TRPCError } from "@trpc/server";
import { getUrlSearchParamsToForward } from "./getUrlSearchParamsToForward";
import { handleResponse } from "./handleResponse";
const log = logger.getSubLogger({ prefix: ["[routing-forms]", "[router]"] });
const querySchema = z
@@ -3,16 +3,16 @@ import { prisma } from "@calcom/prisma/__mocks__/prisma";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
import routerGetCrmContactOwnerEmail from "@calcom/app-store/routing-forms/lib/crmRouting/routerGetCrmContactOwnerEmail";
import type { TargetRoutingFormForResponse } from "@calcom/app-store/routing-forms/lib/formSubmissionUtils";
import { onSubmissionOfFormResponse } from "@calcom/app-store/routing-forms/lib/formSubmissionUtils";
import isRouter from "@calcom/app-store/routing-forms/lib/isRouter";
import { RoutingFormResponseRepository } from "@calcom/lib/server/repository/formResponse";
import isRouter from "../lib/isRouter";
import routerGetCrmContactOwnerEmail from "./crmRouting/routerGetCrmContactOwnerEmail";
import type { TargetRoutingFormForResponse } from "./formSubmissionUtils";
import { onSubmissionOfFormResponse } from "./formSubmissionUtils";
import { findTeamMembersMatchingAttributeLogic } from "./findTeamMembersMatchingAttributeLogic";
import { handleResponse } from "./handleResponse";
vi.mock("@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic", () => ({
vi.mock("./findTeamMembersMatchingAttributeLogic", () => ({
findTeamMembersMatchingAttributeLogic: vi.fn(),
}));
@@ -23,15 +23,15 @@ const mockRoutingFormResponseRepository = {
recordFormResponse: vi.fn(),
};
vi.mock("./crmRouting/routerGetCrmContactOwnerEmail", () => ({
vi.mock("@calcom/app-store/routing-forms/lib/crmRouting/routerGetCrmContactOwnerEmail", () => ({
default: vi.fn(),
}));
vi.mock("./formSubmissionUtils", () => ({
vi.mock("@calcom/app-store/routing-forms/lib/formSubmissionUtils", () => ({
onSubmissionOfFormResponse: vi.fn(),
}));
vi.mock("../lib/isRouter", () => ({
vi.mock("@calcom/app-store/routing-forms/lib/isRouter", () => ({
default: vi.fn(),
}));
@@ -1,6 +1,11 @@
import { z } from "zod";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
import routerGetCrmContactOwnerEmail from "@calcom/app-store/routing-forms/lib/crmRouting/routerGetCrmContactOwnerEmail";
import {
onSubmissionOfFormResponse,
type TargetRoutingFormForResponse,
} from "@calcom/app-store/routing-forms/lib/formSubmissionUtils";
import isRouter from "@calcom/app-store/routing-forms/lib/isRouter";
import { emailSchema } from "@calcom/lib/emailSchema";
import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";
@@ -10,9 +15,7 @@ import { RoutingFormResponseRepository } from "@calcom/lib/server/repository/for
import { prisma } from "@calcom/prisma";
import { Prisma } from "@calcom/prisma/client";
import isRouter from "../lib/isRouter";
import routerGetCrmContactOwnerEmail from "./crmRouting/routerGetCrmContactOwnerEmail";
import { onSubmissionOfFormResponse, type TargetRoutingFormForResponse } from "./formSubmissionUtils";
import { findTeamMembersMatchingAttributeLogic } from "./findTeamMembersMatchingAttributeLogic";
const moduleLogger = logger.getSubLogger({ prefix: ["routing-forms/lib/handleResponse"] });
@@ -1,5 +1,5 @@
import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
import { enrichHostsWithDelegationCredentials } from "@calcom/app-store/delegationCredential";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/features/routing-forms/lib/findTeamMembersMatchingAttributeLogic";
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
import logger from "@calcom/lib/logger";
import type { AttributesQueryValue } from "@calcom/lib/raqb/types";
-18
View File
@@ -1,18 +0,0 @@
import type { Attribute, AttributeToUser, AttributeOption } from "@calcom/prisma/client";
export type AttributeName = string;
export type AttributeId = string;
export type BulkAttributeAssigner =
| {
dsyncId: string;
}
| {
userId: number;
};
export type AttributeOptionAssignment = AttributeToUser & {
attributeOption: Omit<AttributeOption, "value" | "isGroup" | "contains" | "id" | "attributeId"> & {
label: string;
attribute: Attribute;
};
};
+1 -1
View File
@@ -119,7 +119,7 @@ export { encryptServiceAccountKey } from "@calcom/lib/server/serviceAccountKey";
export { createHandler as createApiKeyHandler } from "@calcom/trpc/server/routers/viewer/apiKeys/create.handler";
export { getCalendarLinks } from "@calcom/features/bookings/lib/getCalendarLinks";
export { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
export { findTeamMembersMatchingAttributeLogic } from "@calcom/features/routing-forms/lib/findTeamMembersMatchingAttributeLogic";
export type { TFindTeamMembersMatchingAttributeLogicInputSchema } from "@calcom/trpc/server/routers/viewer/attributes/findTeamMembersMatchingAttributeLogic.schema";
export { checkAdminOrOwner } from "@calcom/features/auth/lib/checkAdminOrOwner";
+1 -1
View File
@@ -1,4 +1,4 @@
export { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
export { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
export { PrismaOOORepository } from "@calcom/features/ooo/repositories/PrismaOOORepository";
export { PrismaHolidayRepository } from "@calcom/features/holidays/repositories/PrismaHolidayRepository";
export { ScheduleRepository as PrismaScheduleRepository } from "@calcom/features/schedules/repositories/ScheduleRepository";
@@ -1,5 +1,5 @@
import { getAttributesForTeam } from "@calcom/features/attributes/lib/getAttributes";
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
import { getAttributesForTeam } from "@calcom/lib/service/attribute/server/getAttributes";
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
import { TRPCError } from "@trpc/server";
@@ -1,4 +1,4 @@
import { getWhereClauseForAttributeOptionsManagedByCalcom } from "@calcom/lib/service/attribute/server/utils";
import { getWhereClauseForAttributeOptionsManagedByCalcom } from "@calcom/features/attributes/lib/utils";
import slugify from "@calcom/lib/slugify";
import prisma from "@calcom/prisma";
@@ -1,7 +1,7 @@
import type { ServerResponse } from "http";
import type { NextApiResponse } from "next";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/features/routing-forms/lib/findTeamMembersMatchingAttributeLogic";
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
import type { PrismaClient } from "@calcom/prisma";
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
@@ -1,4 +1,4 @@
import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
import { PrismaAttributeRepository } from "@calcom/features/attributes/repositories/PrismaAttributeRepository";
import prisma from "@calcom/prisma";
import { TRPCError } from "@trpc/server";
@@ -6,12 +6,12 @@
import type { ServerResponse } from "http";
import type { NextApiResponse } from "next";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/app-store/_utils/raqb/findTeamMembersMatchingAttributeLogic";
import { enrichHostsWithDelegationCredentials } from "@calcom/app-store/delegationCredential";
import { enrichFormWithMigrationData } from "@calcom/app-store/routing-forms/enrichFormWithMigrationData";
import { getLuckyUserService } from "@calcom/features/di/containers/LuckyUser";
import { EventTypeRepository } from "@calcom/features/eventtypes/repositories/eventTypeRepository";
import { entityPrismaWhereClause } from "@calcom/features/pbac/lib/entityPermissionUtils.server";
import { findTeamMembersMatchingAttributeLogic } from "@calcom/features/routing-forms/lib/findTeamMembersMatchingAttributeLogic";
import { getUrlSearchParamsToForwardForTestPreview } from "@calcom/features/routing-forms/lib/getUrlSearchParamsToForward";
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
import { fromEntriesWithDuplicateKeys } from "@calcom/lib/fromEntriesWithDuplicateKeys";
@@ -1,5 +1,5 @@
import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm";
import { handleResponse } from "@calcom/app-store/routing-forms/lib/handleResponse";
import { handleResponse } from "@calcom/features/routing-forms/lib/handleResponse";
import type { PrismaClient } from "@calcom/prisma";
import { TRPCError } from "@trpc/server";