refactor: circular deps between app store and lib [1] (#23653)

* move dailyApiFetcher.ts to app store package

* update imports

* bookingLocationService

* revert

* move findFieldValueByIdentifier

* wip

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* move to features package

* update imports

* update imports

* move

* fix typechecks

* move getCalendarLinks

* mv event test
This commit is contained in:
Benny Joo
2025-09-09 14:38:29 +00:00
committed by GitHub
parent 0fe775962f
commit d908403a99
39 changed files with 63 additions and 55 deletions
@@ -26,12 +26,12 @@ import {
SystemField,
TITLE_FIELD,
} from "@calcom/features/bookings/lib/SystemField";
import { getCalendarLinks, CalendarLinkType } from "@calcom/features/bookings/lib/getCalendarLinks";
import { RATING_OPTIONS, validateRating } from "@calcom/features/bookings/lib/rating";
import { getCalendarLinks, CalendarLinkType } from "@calcom/lib/bookings/getCalendarLinks";
import type { nameObjectSchema } from "@calcom/features/eventtypes/lib/eventNaming";
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import { APP_NAME } from "@calcom/lib/constants";
import { formatToLocalizedDate, formatToLocalizedTime, formatToLocalizedTimezone } from "@calcom/lib/dayjs";
import type { nameObjectSchema } from "@calcom/lib/event";
import { getEventName } from "@calcom/lib/event";
import useGetBrandingColours from "@calcom/lib/getBrandColours";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+1 -1
View File
@@ -35,7 +35,7 @@ vi.mock("@calcom/app-store/utils", () => ({
getEventTypeAppData: vi.fn(),
}));
vi.mock("@calcom/lib/event", () => ({
vi.mock("@calcom/features/eventtypes/lib/eventNaming", () => ({
getEventName: vi.fn(),
}));
@@ -1,7 +1,6 @@
import { z } from "zod";
import { getDailyAppKeys } from "@calcom/app-store/dailyvideo/lib/getDailyAppKeys";
import { fetcher } from "@calcom/lib/dailyApiFetcher";
import { prisma } from "@calcom/prisma";
import type { GetRecordingsResponseSchema, GetAccessLinkResponseSchema } from "@calcom/prisma/zod-utils";
import {
@@ -16,6 +15,7 @@ import type { VideoApiAdapter, VideoCallData } from "@calcom/types/VideoApiAdapt
import { ZSubmitBatchProcessorJobRes, ZGetTranscriptAccessLink } from "../zod";
import type { TSubmitBatchProcessorJobRes, TGetTranscriptAccessLink, batchProcessorBody } from "../zod";
import { fetcher } from "./dailyApiFetcher";
import {
dailyReturnTypeSchema,
getTranscripts,
@@ -1,6 +1,7 @@
import { getDailyAppKeys } from "@calcom/app-store/dailyvideo/lib/getDailyAppKeys";
import { handleErrorsJson } from "@calcom/lib/errors";
import { getDailyAppKeys } from "./getDailyAppKeys";
export const fetcher = async (endpoint: string, init?: RequestInit | undefined) => {
const { api_key } = await getDailyAppKeys();
return fetch(`https://api.daily.co/v1${endpoint}`, {
@@ -4,10 +4,10 @@ import { getSession } from "next-auth/react";
import { sanitizeValue } from "@calcom/lib/csvUtils";
import { entityPrismaWhereClause, canEditEntity } from "@calcom/lib/entityPermissionUtils.server";
import { getHumanReadableFieldResponseValue } from "@calcom/lib/server/service/routingForm/responseData/getHumanReadableFieldResponseValue";
import prisma from "@calcom/prisma";
import { getSerializableForm } from "../../lib/getSerializableForm";
import { getHumanReadableFieldResponseValue } from "../../lib/responseData/getHumanReadableFieldResponseValue";
import type { FormResponse, SerializableForm } from "../../types/types";
type Fields = NonNullable<SerializableForm<App_RoutingForms_Form>["fields"]>;
@@ -2,10 +2,11 @@ import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
import logger from "@calcom/lib/logger";
import { PrismaQueuedFormResponseRepository } from "@calcom/lib/server/repository/routingForm/queuedFormResponse/PrismaQueuedFormResponseRepository";
import { QueuedFormResponseService } from "@calcom/lib/server/service/routingForm/queuedFormResponse/QueuedFormResponseService";
import prisma from "@calcom/prisma";
import { PrismaQueuedFormResponseRepository } from "../lib/queuedFormResponse/PrismaQueuedFormResponseRepository";
import { QueuedFormResponseService } from "../lib/queuedFormResponse/QueuedFormResponseService";
function validateRequest(request: NextRequest) {
const apiKey = request.headers.get("authorization") || request.nextUrl.searchParams.get("apiKey");
@@ -1,6 +1,7 @@
import { describe, it, expect, beforeEach, vi } from "vitest";
import type { RoutingFormResponseRepositoryInterface } from "../../repository/RoutingFormResponseRepository.interface";
import type { RoutingFormResponseRepositoryInterface } from "@calcom/lib/server/repository/RoutingFormResponseRepository.interface";
import { RoutingFormResponseDataFactory } from "./RoutingFormResponseDataFactory";
import { parseRoutingFormResponse } from "./responseData/parseRoutingFormResponse";
@@ -1,6 +1,6 @@
import type logger from "@calcom/lib/logger";
import type { RoutingFormResponseRepositoryInterface } from "@calcom/lib/server/repository/RoutingFormResponseRepository.interface";
import type { RoutingFormResponseRepositoryInterface } from "../../repository/RoutingFormResponseRepository.interface";
import { parseRoutingFormResponse } from "./responseData/parseRoutingFormResponse";
interface Dependencies {
@@ -1,7 +1,7 @@
import { describe, it, expect } from "vitest";
import { findFieldValueByIdentifier } from "./findFieldValueByIdentifier";
import type { RoutingFormResponseData } from "./types";
import type { RoutingFormResponseData } from "./responseData/types";
describe("findFieldValueByIdentifier", () => {
const responseData: RoutingFormResponseData = {
@@ -1,6 +1,5 @@
import getFieldIdentifier from "@calcom/app-store/routing-forms/lib/getFieldIdentifier";
import type { RoutingFormResponseData } from "./types";
import getFieldIdentifier from "./getFieldIdentifier";
import type { RoutingFormResponseData } from "./responseData/types";
type FindFieldValueByIdentifierResult =
| { success: true; data: string | string[] | number | null }
@@ -1,3 +1,4 @@
import type { Prisma } from "@prisma/client";
import { describe, expect, beforeAll, afterAll, beforeEach, it } from "vitest";
import prisma from "@calcom/prisma";
@@ -32,7 +33,7 @@ const createTestForm = async (userId: number, overrides?: { name?: string }) =>
const createFormResponse = async (
formId: string,
overrides?: {
response?: Record<string, unknown>;
response?: Prisma.InputJsonValue;
chosenRouteId?: string;
}
) => {
@@ -48,7 +49,7 @@ const createFormResponse = async (
const createQueuedResponse = async (
formId: string,
overrides?: {
response?: Record<string, unknown>;
response?: Prisma.InputJsonValue;
chosenRouteId?: string;
actualResponseId?: number | null;
createdAt?: Date;
@@ -384,9 +385,15 @@ describe("PrismaQueuedFormResponseRepository Integration Tests", () => {
describe("deleteByIds", () => {
it("should delete queued responses by their ids", async () => {
// Create test queued responses
const response1 = await createQueuedResponse(testForm.id, { response: { field1: "value1" } });
const response2 = await createQueuedResponse(testForm.id, { response: { field1: "value2" } });
const response3 = await createQueuedResponse(testForm.id, { response: { field1: "value3" } });
const response1 = await createQueuedResponse(testForm.id, {
response: { field1: "value1" },
});
const response2 = await createQueuedResponse(testForm.id, {
response: { field1: "value2" },
});
const response3 = await createQueuedResponse(testForm.id, {
response: { field1: "value3" },
});
// Delete response1 and response2
const result = await repository.deleteByIds([response1.id, response2.id]);
@@ -411,7 +418,9 @@ describe("PrismaQueuedFormResponseRepository Integration Tests", () => {
});
it("should handle single id deletion", async () => {
const response = await createQueuedResponse(testForm.id, { response: { field1: "single-delete" } });
const response = await createQueuedResponse(testForm.id, {
response: { field1: "single-delete" },
});
const result = await repository.deleteByIds([response.id]);
@@ -422,7 +431,9 @@ describe("PrismaQueuedFormResponseRepository Integration Tests", () => {
});
it("should handle mix of existing and non-existing ids", async () => {
const response = await createQueuedResponse(testForm.id, { response: { field1: "mixed-delete" } });
const response = await createQueuedResponse(testForm.id, {
response: { field1: "mixed-delete" },
});
const result = await repository.deleteByIds([response.id, "non-existent-id"]);
@@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import type logger from "@calcom/lib/logger";
import type { QueuedFormResponseRepositoryInterface } from "../../repository/routingForm/queuedFormResponse/QueuedFormResponseRepository.interface";
import type { QueuedFormResponseRepositoryInterface } from "./QueuedFormResponseRepository.interface";
import { QueuedFormResponseService } from "./QueuedFormResponseService";
describe("QueuedFormResponseService", () => {
@@ -130,7 +130,7 @@ describe("QueuedFormResponseService", () => {
it("should stop when batch is not full", async () => {
// Return partial batch
mockRepo.findMany.mockResolvedValueOnce([{ id: "1" }, { id: "2" }, { id: "3" }]);
mockRepo.findMany.mockResolvedValueOnce([{ id: "1" }, { id: "2" }, { id: "3" }] as any);
mockRepo.deleteByIds.mockResolvedValueOnce({ count: 3 });
const result = await service.cleanupExpiredResponses({ batchSize: 5 });
@@ -1,6 +1,6 @@
import type logger from "@calcom/lib/logger";
import type { QueuedFormResponseRepositoryInterface } from "../../../repository/routingForm/queuedFormResponse/QueuedFormResponseRepository.interface";
import type { QueuedFormResponseRepositoryInterface } from "./QueuedFormResponseRepository.interface";
interface Dependencies {
logger: typeof logger;
@@ -1,7 +1,6 @@
import { describe, it, expect } from "vitest";
import type { Field, FormResponse } from "@calcom/app-store/routing-forms/types/types";
import type { Field, FormResponse } from "../../types/types";
import { getHumanReadableFieldResponseValue } from "./getHumanReadableFieldResponseValue";
describe("getHumanReadableFieldResponseValue", () => {
@@ -1,8 +1,8 @@
import { getHumanReadableFieldResponseValue } from "@calcom/lib/server/service/routingForm/responseData/getHumanReadableFieldResponseValue";
import slugify from "@calcom/lib/slugify";
import type { FormResponse, NonRouterRoute, Field } from "../types/types";
import getFieldIdentifier from "./getFieldIdentifier";
import { getHumanReadableFieldResponseValue } from "./responseData/getHumanReadableFieldResponseValue";
/**
* Substitues variables in the target URL identified by routeValue with values from response
@@ -3,6 +3,7 @@ import jsforce from "@jsforce/jsforce-node";
import { RRule } from "rrule";
import { z } from "zod";
import { RoutingFormResponseDataFactory } from "@calcom/app-store/routing-forms/lib/RoutingFormResponseDataFactory";
import { getLocation } from "@calcom/lib/CalEventParser";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { RetryableError } from "@calcom/lib/crmManager/errors";
@@ -11,8 +12,6 @@ import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { PrismaAssignmentReasonRepository } from "@calcom/lib/server/repository/PrismaAssignmentReasonRepository";
import { PrismaRoutingFormResponseRepository as RoutingFormResponseRepository } from "@calcom/lib/server/repository/PrismaRoutingFormResponseRepository";
import { RoutingFormResponseDataFactory } from "@calcom/lib/server/service/routingForm/RoutingFormResponseDataFactory";
import { findFieldValueByIdentifier } from "@calcom/lib/server/service/routingForm/responseData/findFieldValueByIdentifier";
import { prisma } from "@calcom/prisma";
import type { CalendarEvent, CalEventResponses } from "@calcom/types/Calendar";
import type { CredentialPayload } from "@calcom/types/Credential";
@@ -20,6 +19,7 @@ import type { CRM, Contact, CrmEvent } from "@calcom/types/CrmService";
import type { ParseRefreshTokenResponse } from "../../_utils/oauth/parseRefreshTokenResponse";
import parseRefreshTokenResponse from "../../_utils/oauth/parseRefreshTokenResponse";
import { findFieldValueByIdentifier } from "../../routing-forms/lib/findFieldValueByIdentifier";
import { default as appMeta } from "../config.json";
import type { writeToRecordDataSchema, appDataSchema, writeToBookingEntry } from "../zod";
import {
+2 -2
View File
@@ -4,8 +4,8 @@ import type { z } from "zod";
import dayjs from "@calcom/dayjs";
import type BaseEmail from "@calcom/emails/templates/_base-email";
import type { EventNameObjectType } from "@calcom/lib/event";
import { getEventName } from "@calcom/lib/event";
import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming";
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import { formatCalEvent } from "@calcom/lib/formatCalendarEvent";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
@@ -17,7 +17,7 @@ import {
sendAttendeeRequestEmailAndSMS,
} from "@calcom/emails";
import type { BookingType } from "@calcom/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils";
import type { EventNameObjectType } from "@calcom/lib/event";
import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming";
import { getPiiFreeCalendarEvent } from "@calcom/lib/piiFreeData";
import { safeStringify } from "@calcom/lib/safeStringify";
import { getTranslation } from "@calcom/lib/server/i18n";
@@ -6,12 +6,11 @@ import type { z } from "zod";
import type { Dayjs } from "@calcom/dayjs";
import dayjs from "@calcom/dayjs";
import type { nameObjectSchema } from "@calcom/lib/event";
import type { nameObjectSchema } from "@calcom/features/eventtypes/lib/eventNaming";
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
import type { RecurringEvent } from "@calcom/types/Calendar";
import { getEventName } from "../event";
type RecurringEventOrPrismaJsonObject = RecurringEvent | Prisma.JsonObject | null | undefined;
export const enum CalendarLinkType {
GOOGLE_CALENDAR = "googleCalendar",
@@ -23,6 +23,7 @@ import { handleWebhookTrigger } from "@calcom/features/bookings/lib/handleWebhoo
import { isEventTypeLoggingEnabled } from "@calcom/features/bookings/lib/isEventTypeLoggingEnabled";
import type { CacheService } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
import AssignmentReasonRecorder from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
import { getEventName, updateHostInEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import type { FeaturesRepository } from "@calcom/features/flags/features.repository";
import { getFullName } from "@calcom/features/form-builder/utils";
import { UsersRepository } from "@calcom/features/users/users.repository";
@@ -49,7 +50,6 @@ import { getCacheService } from "@calcom/lib/di/containers/Cache";
import { getLuckyUserService } from "@calcom/lib/di/containers/LuckyUser";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { getErrorFromUnknown } from "@calcom/lib/errors";
import { getEventName, updateHostInEventName } from "@calcom/lib/event";
import { extractBaseEmail } from "@calcom/lib/extract-base-email";
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
@@ -13,21 +13,21 @@ import { getEventTypesFromDB } from "@calcom/features/bookings/lib/handleNewBook
import AssignmentReasonRecorder, {
RRReassignmentType,
} from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
import { BookingLocationService } from "@calcom/features/ee/round-robin/lib/bookingLocationService";
import {
scheduleEmailReminder,
deleteScheduledEmailReminder,
} from "@calcom/features/ee/workflows/lib/reminders/emailReminderManager";
import { scheduleWorkflowReminders } from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
import { SENDER_NAME } from "@calcom/lib/constants";
import { enrichUserWithDelegationCredentialsIncludeServiceAccountKey } from "@calcom/lib/delegationCredential/server";
import { getEventName } from "@calcom/lib/event";
import { getBookerBaseUrl } from "@calcom/lib/getBookerUrl/server";
import { IdempotencyKeyService } from "@calcom/lib/idempotencyKey/idempotencyKeyService";
import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj";
import logger from "@calcom/lib/logger";
import { getTranslation } from "@calcom/lib/server/i18n";
import { BookingLocationService } from "@calcom/lib/server/service/bookingLocationService";
import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import { prisma } from "@calcom/prisma";
import { WorkflowActions, WorkflowMethods, WorkflowTriggerEvents } from "@calcom/prisma/enums";
@@ -16,13 +16,13 @@ import type { IsFixedAwareUser } from "@calcom/features/bookings/lib/handleNewBo
import AssignmentReasonRecorder, {
RRReassignmentType,
} from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import {
enrichHostsWithDelegationCredentials,
enrichUserWithDelegationCredentialsIncludeServiceAccountKey,
} from "@calcom/lib/delegationCredential/server";
import { getLuckyUserService } from "@calcom/lib/di/containers/LuckyUser";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { getEventName } from "@calcom/lib/event";
import { IdempotencyKeyService } from "@calcom/lib/idempotencyKey/idempotencyKeyService";
import { isPrismaObjOrUndefined } from "@calcom/lib/isPrismaObj";
import logger from "@calcom/lib/logger";
@@ -4,9 +4,9 @@ import { FormProvider } from "react-hook-form";
import { useForm, useFormContext } from "react-hook-form";
import { Dialog } from "@calcom/features/components/controlled-dialog";
import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming";
import { getEventName, validateCustomEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import type { InputClassNames } from "@calcom/features/eventtypes/lib/types";
import type { EventNameObjectType } from "@calcom/lib/event";
import { getEventName, validateCustomEventName } from "@calcom/lib/event";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import classNames from "@calcom/ui/classNames";
import { Button } from "@calcom/ui/components/button";
@@ -20,6 +20,8 @@ import {
allowDisablingHostConfirmationEmails,
} from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails";
import { MultiplePrivateLinksController } from "@calcom/features/eventtypes/components";
import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming";
import { getEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import type {
FormValues,
EventTypeSetupProps,
@@ -38,8 +40,6 @@ import {
APP_NAME,
MAX_SEATS_PER_TIME_SLOT,
} from "@calcom/lib/constants";
import type { EventNameObjectType } from "@calcom/lib/event";
import { getEventName } from "@calcom/lib/event";
import { generateHashedLink } from "@calcom/lib/generateHashedLink";
import { checkWCAGContrastColor } from "@calcom/lib/getBrandColours";
import { extractHostTimezone } from "@calcom/lib/hashedLinksUtils";
@@ -1,8 +1,8 @@
import type { TFunction } from "i18next";
import { describe, expect, it, vi } from "vitest";
import * as event from "./event";
import { updateHostInEventName } from "./event";
import * as event from "./eventNaming";
import { updateHostInEventName } from "./eventNaming";
describe("event tests", () => {
describe("fn: getEventName", () => {
@@ -1,4 +1,4 @@
import { fetcher } from "@calcom/lib/dailyApiFetcher";
import { fetcher } from "@calcom/app-store/dailyvideo/lib/dailyApiFetcher";
import { triggerNoShowPayloadSchema } from "./schema";
@@ -4,18 +4,15 @@ import { useForm } from "react-hook-form";
import { z } from "zod";
import checkForMultiplePaymentApps from "@calcom/app-store/_utils/payments/checkForMultiplePaymentApps";
import {
DEFAULT_PROMPT_VALUE,
DEFAULT_BEGIN_MESSAGE,
} from "@calcom/features/calAIPhone/promptTemplates";
import { DEFAULT_PROMPT_VALUE, DEFAULT_BEGIN_MESSAGE } from "@calcom/features/calAIPhone/promptTemplates";
import type { TemplateType } from "@calcom/features/calAIPhone/zod-utils";
import { sortHosts } from "@calcom/features/eventtypes/components/HostEditDialogs";
import { validateCustomEventName } from "@calcom/features/eventtypes/lib/eventNaming";
import type {
FormValues,
EventTypeSetupProps,
EventTypeUpdateInput,
} from "@calcom/features/eventtypes/lib/types";
import { validateCustomEventName } from "@calcom/lib/event";
import { locationsResolver } from "@calcom/lib/event-types/utils/locationsResolver";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { validateIntervalLimitOrder } from "@calcom/lib/intervalLimits/validateIntervalLimitOrder";
+1 -1
View File
@@ -18,7 +18,7 @@ export {
eventTypeLocations,
} from "@calcom/prisma/zod-utils";
export { validateCustomEventName } from "@calcom/lib/event";
export { validateCustomEventName } from "@calcom/features/eventtypes/lib/eventNaming";
export { EventManager };
export { getEventTypeById } from "@calcom/lib/event-types/getEventTypeById";
export { getEventTypesByViewer } from "@calcom/lib/event-types/getEventTypesByViewer";
+2 -2
View File
@@ -86,7 +86,7 @@ export { roundRobinManualReassignment } from "@calcom/features/ee/round-robin/ro
export { ErrorCode } from "@calcom/lib/errorCodes";
export { validateCustomEventName } from "@calcom/lib/event";
export { validateCustomEventName } from "@calcom/features/eventtypes/lib/eventNaming";
export type TeamQuery = Prisma.TeamGetPayload<{
select: {
@@ -120,7 +120,7 @@ export { getTeamMemberEmailForResponseOrContactUsingUrlQuery };
export { SelectedCalendarRepository } from "@calcom/lib/server/repository/selectedCalendar";
export { encryptServiceAccountKey } from "@calcom/lib/server/serviceAccountKey";
export { createHandler as createApiKeyHandler } from "@calcom/trpc/server/routers/viewer/apiKeys/create.handler";
export { getCalendarLinks } from "@calcom/lib/bookings/getCalendarLinks";
export { getCalendarLinks } from "@calcom/features/bookings/lib/getCalendarLinks";
export { findTeamMembersMatchingAttributeLogic } from "@calcom/lib/raqb/findTeamMembersMatchingAttributeLogic";
export type { TFindTeamMembersMatchingAttributeLogicInputSchema } from "@calcom/trpc/server/routers/viewer/attributes/findTeamMembersMatchingAttributeLogic.schema";