refactor: decouple @calcom/features from @calcom/trpc/server (#27751)

* make GetPublicEventInput

* space

* mv feature flags router to trpc

* remove trpc imports

* wip

* mv OrgMembershipLookup to features

* fix

* fix

* update

* fix

* revert formatting-only changes to improve PR reviewability

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Benny Joo
2026-02-10 09:28:37 -03:00
committed by GitHub
co-authored by Devin AI
parent c0504993a6
commit 431fbe44fc
26 changed files with 196 additions and 210 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import { featureFlagRouter } from "@calcom/features/flags/server/router";
import { createNextApiHandler } from "@calcom/trpc/server/createNextApiHandler";
import { featureFlagRouter } from "@calcom/trpc/server/routers/features/_router";
export default createNextApiHandler(featureFlagRouter, true, "features");
@@ -2,7 +2,26 @@ import { useMemo } from "react";
import dayjs from "@calcom/dayjs";
import type { CalendarAvailableTimeslots } from "@calcom/features/calendars/weeklyview/types/state";
import type { IGetAvailableSlots } from "@calcom/trpc/server/routers/viewer/slots/util";
import type { IFromUser, IToUser } from "@calcom/features/availability/lib/getUserAvailability";
export interface IGetAvailableSlots {
slots: Record<
string,
{
time: string;
attendees?: number | undefined;
bookingUid?: string | undefined;
away?: boolean | undefined;
fromUser?: IFromUser | undefined;
toUser?: IToUser | undefined;
reason?: string | undefined;
emoji?: string | undefined;
showNotePublicly?: boolean | undefined;
}[]
>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
troubleshooter?: any;
}
interface UseAvailableTimeSlotsProps {
eventDuration: number;
@@ -27,4 +46,4 @@ export const useAvailableTimeSlots = ({ schedule, eventDuration }: UseAvailableT
return availableTimeslots;
}, [schedule, eventDuration]);
};
};
@@ -1,9 +1,16 @@
import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository";
import type { OrgMembershipLookup } from "@calcom/trpc/server/routers/viewer/slots/util";
import { createModule, type Module } from "../di";
import { DI_TOKENS } from "../tokens";
/**
* Minimal capability interface for looking up a user's organization membership.
* Used as a fallback when org context can't be determined from request or eventType.
*/
export interface OrgMembershipLookup {
findFirstOrganizationIdForUser(args: { userId: number }): Promise<number | null>;
}
/**
* Adapter that wraps ProfileRepository's static method to satisfy the OrgMembershipLookup interface.
* This lives in the composition root where implementation details are wired together.
@@ -4,6 +4,7 @@ import {
ConditionIdentifierEnum,
ConditionOperatorEnum,
type IAttributeSyncRule,
type ICreateAttributeSyncInput,
type IFieldMapping,
type IFieldMappingFormState,
type IFieldMappingWithOptionalId,
@@ -80,3 +81,13 @@ export const syncFormDataSchema: z.ZodType<ISyncFormData> = z.object({
rule: attributeSyncRuleSchema,
syncFieldMappings: z.array(z.union([fieldMappingSchema, newFieldMappingSchema])),
});
export const createAttributeSyncSchema: z.ZodType<ICreateAttributeSyncInput> = z.object({
name: z.string().min(1, "Name is required"),
credentialId: z.number(),
rule: attributeSyncRuleSchema,
syncFieldMappings: z.array(newFieldMappingSchema),
enabled: z.boolean(),
});
export type ZCreateAttributeSyncSchema = ICreateAttributeSyncInput;
@@ -1,6 +1,5 @@
import type { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository";
import type { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
import type { ZCreateAttributeSyncSchema } from "@calcom/trpc/server/routers/viewer/attribute-sync/createAttributeSync.schema";
import { enabledAppSlugs } from "../constants";
import {
@@ -11,7 +10,7 @@ import {
AttributeSyncIntegrations,
ConditionIdentifierEnum,
} from "../repositories/IIntegrationAttributeSyncRepository";
import { attributeSyncRuleSchema } from "../schemas/zod";
import { attributeSyncRuleSchema, type ZCreateAttributeSyncSchema } from "../schemas/zod";
export class DuplicateAttributeWithinSyncError extends Error {
constructor(public attributeId: string) {
@@ -5,8 +5,17 @@ import { renameDomain } from "@calcom/lib/domainManager/organization";
import { getMetadataHelpers } from "@calcom/lib/getMetadataHelpers";
import { HttpError } from "@calcom/lib/http-error";
import type { Prisma, PrismaClient } from "@calcom/prisma/client";
import { teamMetadataStrictSchema } from "@calcom/prisma/zod-utils";
import type { TAdminUpdate } from "@calcom/trpc/server/routers/viewer/organizations/adminUpdate.schema";
import { orgSettingsSchema, teamMetadataStrictSchema } from "@calcom/prisma/zod-utils";
import { z } from "zod";
export const ZAdminUpdate = z.object({
id: z.number(),
name: z.string().optional(),
slug: z.string().nullish(),
organizationSettings: orgSettingsSchema.unwrap().optional(),
});
export type TAdminUpdate = z.infer<typeof ZAdminUpdate>;
type AdminOrganizationUpdateServiceDeps = {
prismaClient: PrismaClient;
@@ -13,6 +13,8 @@ import type { TimeUnit, WorkflowTemplates, WorkflowTriggerEvents } from "@calcom
import { WorkflowActions } from "@calcom/prisma/enums";
import type { CalEventResponses, RecurringEvent } from "@calcom/types/Calendar";
import type { MultiSelectCheckboxesOptionType as Option } from "@calcom/ui/components/form";
import { z } from "zod";
import { TIME_UNIT, WORKFLOW_ACTIONS, WORKFLOW_TEMPLATES, WORKFLOW_TRIGGER_EVENTS } from "./constants";
export type Workflow = {
id: number;
@@ -39,6 +41,31 @@ export type WorkflowStep = {
verifiedAt?: Date | null;
};
export const ZWorkflow: z.ZodType<Workflow> = z.object({
id: z.number(),
name: z.string(),
trigger: z.enum(WORKFLOW_TRIGGER_EVENTS),
time: z.number().nullable(),
timeUnit: z.enum(TIME_UNIT).nullable(),
userId: z.number().nullable(),
teamId: z.number().nullable(),
steps: z
.object({
id: z.number(),
action: z.enum(WORKFLOW_ACTIONS),
sendTo: z.string().nullable(),
template: z.enum(WORKFLOW_TEMPLATES),
reminderBody: z.string().nullable(),
emailSubject: z.string().nullable(),
numberRequired: z.boolean().nullable(),
sender: z.string().nullable(),
includeCalendarEvent: z.boolean(),
numberVerificationPending: z.boolean(),
verifiedAt: z.coerce.date().nullable().optional(),
})
.array(),
});
export type FormSubmissionData = {
responses: FORM_SUBMITTED_WEBHOOK_RESPONSES;
routedEventTypeId: number | null;
@@ -3,6 +3,7 @@ import { deleteScheduledAIPhoneCall } from "@calcom/ee/workflows/lib/reminders/a
import { deleteScheduledEmailReminder } from "@calcom/ee/workflows/lib/reminders/emailReminderManager";
import { deleteScheduledSMSReminder } from "@calcom/ee/workflows/lib/reminders/smsReminderManager";
import type { WorkflowStep, WorkflowListType as WorkflowType } from "@calcom/ee/workflows/lib/types";
import type { filterQuerySchemaStrict } from "@calcom/features/filters/lib/getTeamsFiltersFromQuery";
import { hasFilter } from "@calcom/features/filters/lib/hasFilter";
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
import { HttpError } from "@calcom/lib/http-error";
@@ -16,15 +17,29 @@ import {
WorkflowMethods,
type WorkflowTriggerEvents,
} 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 { z } from "zod";
export const ZGetInputSchema = z.object({
id: z.number(),
});
export type TGetInputSchema = z.infer<typeof ZGetInputSchema>;
export type TFilteredListInputSchema =
| {
filters?: z.infer<typeof filterQuerySchemaStrict>;
}
| null
| undefined;
export type TGetVerifiedEmailsInputSchema = {
teamId?: number;
};
export type TGetVerifiedNumbersInputSchema = {
teamId?: number;
};
const excludeFormTriggersWhereClause = {
trigger: {
not: {
@@ -40,8 +55,6 @@ const getWorkflowType = (trigger: WorkflowTriggerEvents): PrismaWorkflowType =>
return PrismaWorkflowType.EVENT_TYPE;
};
export type TGetInputSchema = z.infer<typeof ZGetInputSchema>;
const deleteScheduledWhatsappReminder = deleteScheduledSMSReminder;
const includedFields = {
@@ -1,9 +1,16 @@
import { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEvent";
import prisma from "@calcom/prisma";
import type { TEventInputSchema } from "@calcom/trpc/server/routers/publicViewer/event.schema";
export type GetPublicEventInput = {
username: string;
eventSlug: string;
isTeamEvent?: boolean;
org: string | null;
fromRedirectOfNonOrgLink: boolean;
};
export class EventRepository {
static async getPublicEvent(input: TEventInputSchema, userId?: number) {
static async getPublicEvent(input: GetPublicEventInput, userId?: number) {
const event = await getPublicEvent(
input.username,
input.eventSlug,
+27 -1
View File
@@ -26,8 +26,34 @@ import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat";
import { prisma } from "@calcom/prisma";
import { WebhookTriggerEvents, WorkflowTriggerEvents } from "@calcom/prisma/enums";
import { bookingMetadataSchema, type PlatformClientParams } from "@calcom/prisma/zod-utils";
import type { TNoShowInputSchema } from "@calcom/trpc/server/routers/loggedInViewer/markNoShow.schema";
import type { TFunction } from "i18next";
import { z } from "zod";
export const ZNoShowInputSchema = z
.object({
bookingUid: z.string(),
attendees: z
.array(
z.object({
email: z.string(),
noShow: z.boolean(),
})
)
.optional(),
noShowHost: z.boolean().optional(),
})
.refine(
(data) => {
return (data.attendees && data.attendees.length > 0) || data.noShowHost !== undefined;
},
{
message: "At least one of 'attendees' or 'noShowHost' must be provided",
path: ["attendees", "noShowHost"],
}
);
export type TNoShowInputSchema = z.infer<typeof ZNoShowInputSchema>;
import handleSendingAttendeeNoShowDataToApps from "./noShow/handleSendingAttendeeNoShowDataToApps";
export type NoShowAttendees = { email: string; noShow: boolean }[];
@@ -1,13 +1,40 @@
import { getAvailabilityFromSchedule } from "@calcom/lib/availability";
import { timeZoneSchema } from "@calcom/lib/dayjs/timeZone.schema";
import { hasEditPermissionForUserID } from "@calcom/lib/hasEditPermissionForUser";
import { HttpError } from "@calcom/lib/http-error";
import { transformScheduleToAvailabilityForAtom } from "@calcom/lib/schedules/transformers/for-atom";
import type { PrismaClient } from "@calcom/prisma";
import type { TUpdateInputSchema } from "@calcom/trpc/server/routers/viewer/availability/schedule/update.schema";
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
import { z } from "zod";
import { ScheduleRepository } from "../repositories/ScheduleRepository";
export const ZUpdateInputSchema = z.object({
scheduleId: z.number(),
timeZone: timeZoneSchema.optional(),
name: z.string().trim().min(1, "Schedule name cannot be empty").optional(),
isDefault: z.boolean().optional(),
schedule: z
.array(
z.array(
z.object({
start: z.date(),
end: z.date(),
})
)
)
.optional(),
dateOverrides: z
.array(
z.object({
start: z.date(),
end: z.date(),
})
)
.optional(),
});
export type TUpdateInputSchema = z.infer<typeof ZUpdateInputSchema>;
interface IUpdateScheduleOptions {
input: TUpdateInputSchema;
user: Pick<NonNullable<TrpcSessionUser>, "id" | "defaultScheduleId" | "timeZone">;
@@ -3,9 +3,9 @@ import { z } from "zod";
import type { FORM_SUBMITTED_WEBHOOK_RESPONSES } from "@calcom/app-store/routing-forms/lib/formSubmissionUtils";
import { scheduleWorkflowReminders } from "@calcom/ee/workflows/lib/reminders/reminderScheduler";
import type { Workflow } from "@calcom/ee/workflows/lib/types";
import { ZWorkflow } from "@calcom/ee/workflows/lib/types";
import { CreditService } from "@calcom/features/ee/billing/credit-service";
import logger from "@calcom/lib/logger";
import { ZWorkflow } from "@calcom/trpc/server/routers/viewer/workflows/getAllActiveWorkflows.schema";
import { shouldTriggerFormSubmittedNoEvent } from "./formSubmissionValidation";
+1 -1
View File
@@ -130,4 +130,4 @@ export { verifyCodeChallenge } from "@calcom/lib/pkce";
export { validateUrlForSSRFSync } from "@calcom/lib/ssrfProtection";
export { checkEmailVerificationRequired } from "@calcom/trpc/server/routers/publicViewer/checkIfUserEmailVerificationRequired.handler";
export { verifyCode as verifyCodeAuthenticated } from "@calcom/trpc/server/routers/viewer/organizations/verifyCode.handler";
export type { OrgMembershipLookup } from "@calcom/trpc/server/routers/viewer/slots/util";
export type { OrgMembershipLookup } from "@calcom/features/di/modules/OrgMembershipLookup";
@@ -3,7 +3,7 @@ import type { AppFlags } from "@calcom/features/flags/config";
import publicProcedure from "@calcom/trpc/server/procedures/publicProcedure";
import { router } from "@calcom/trpc/server/trpc";
import { z } from "zod";
import { map } from "./procedures/map";
import { map } from "./map";
export const featureFlagRouter = router({
list: publicProcedure.query(async () => {
@@ -1,26 +1 @@
import { z } from "zod";
export const ZNoShowInputSchema = z
.object({
bookingUid: z.string(),
attendees: z
.array(
z.object({
email: z.string(),
noShow: z.boolean(),
})
)
.optional(),
noShowHost: z.boolean().optional(),
})
.refine(
(data) => {
return (data.attendees && data.attendees.length > 0) || data.noShowHost !== undefined;
},
{
message: "At least one of 'attendees' or 'noShowHost' must be provided",
path: ["attendees", "noShowHost"],
}
);
export type TNoShowInputSchema = z.infer<typeof ZNoShowInputSchema>;
export { type TNoShowInputSchema, ZNoShowInputSchema } from "@calcom/features/handleMarkNoShow";
@@ -1,4 +1,5 @@
import z from "zod";
import type { GetPublicEventInput } from "@calcom/features/eventtypes/repositories/EventRepository";
// Note: fromRedirectOfNonOrgLink has .default(false), so input has it optional but output has it required
@@ -10,13 +11,7 @@ export type TEventInputSchemaInput = {
fromRedirectOfNonOrgLink?: boolean;
};
export type TEventInputSchema = {
username: string;
eventSlug: string;
isTeamEvent?: boolean;
org: string | null;
fromRedirectOfNonOrgLink: boolean;
};
export type TEventInputSchema = GetPublicEventInput;
export const ZEventInputSchema: z.ZodType<TEventInputSchema, z.ZodTypeDef, TEventInputSchemaInput> = z.object({
username: z.string(),
@@ -1,6 +1,6 @@
import { featureFlagRouter } from "@calcom/features/flags/server/router";
import { router } from "../../trpc";
import app_RoutingForms from "../apps/routing-forms/_router";
import { featureFlagRouter } from "../features/_router";
import { loggedInViewerRouter } from "../loggedInViewer/_router";
import { publicViewerRouter } from "../publicViewer/_router";
import { timezonesRouter } from "../publicViewer/timezones/_router";
@@ -1,17 +1,4 @@
import { z } from "zod";
import type { ICreateAttributeSyncInput } from "@calcom/features/ee/integration-attribute-sync/repositories/IIntegrationAttributeSyncRepository";
import {
attributeSyncRuleSchema,
newFieldMappingSchema,
export {
createAttributeSyncSchema,
type ZCreateAttributeSyncSchema,
} from "@calcom/features/ee/integration-attribute-sync/schemas/zod";
export const createAttributeSyncSchema: z.ZodType<ICreateAttributeSyncInput> = z.object({
name: z.string().min(1, "Name is required"),
credentialId: z.number(),
rule: attributeSyncRuleSchema,
syncFieldMappings: z.array(newFieldMappingSchema),
enabled: z.boolean(),
});
export type ZCreateAttributeSyncSchema = ICreateAttributeSyncInput;
@@ -1,30 +1,4 @@
import { z } from "zod";
import { timeZoneSchema } from "@calcom/lib/dayjs/timeZone.schema";
export const ZUpdateInputSchema = z.object({
scheduleId: z.number(),
timeZone: timeZoneSchema.optional(),
name: z.string().trim().min(1, "Schedule name cannot be empty").optional(),
isDefault: z.boolean().optional(),
schedule: z
.array(
z.array(
z.object({
start: z.date(),
end: z.date(),
})
)
)
.optional(),
dateOverrides: z
.array(
z.object({
start: z.date(),
end: z.date(),
})
)
.optional(),
});
export type TUpdateInputSchema = z.infer<typeof ZUpdateInputSchema>;
export {
type TUpdateInputSchema,
ZUpdateInputSchema,
} from "@calcom/features/schedules/services/ScheduleService";
@@ -1,12 +1,4 @@
import { z } from "zod";
import { orgSettingsSchema } from "@calcom/prisma/zod-utils";
export const ZAdminUpdate = z.object({
id: z.number(),
name: z.string().optional(),
slug: z.string().nullish(),
organizationSettings: orgSettingsSchema.unwrap().optional(),
});
export type TAdminUpdate = z.infer<typeof ZAdminUpdate>;
export {
type TAdminUpdate,
ZAdminUpdate,
} from "@calcom/features/ee/organizations/lib/service/AdminOrganizationUpdateService";
@@ -7,8 +7,6 @@ import type {
CurrentSeats,
EventType,
GetAvailabilityUser,
IFromUser,
IToUser,
UserAvailabilityService,
} from "@calcom/features/availability/lib/getUserAvailability";
import type { CheckBookingLimitsService } from "@calcom/features/bookings/lib/checkBookingLimits";
@@ -59,6 +57,8 @@ import type { Logger } from "tslog";
import { v4 as uuid } from "uuid";
import type { TGetScheduleInputSchema } from "./getSchedule.schema";
import type { GetScheduleOptions } from "./types";
import type { OrgMembershipLookup } from "@calcom/features/di/modules/OrgMembershipLookup";
import type { IGetAvailableSlots } from "@calcom/features/bookings/Booker/hooks/useAvailableTimeSlots";
const log = logger.getSubLogger({ prefix: ["[slots/util]"] });
const DEFAULT_SLOTS_CACHE_TTL = 2000;
@@ -67,37 +67,10 @@ type GetAvailabilityUserWithDelegationCredentials = Omit<NonNullable<GetAvailabi
credentials: CredentialForCalendarService[];
};
export interface IGetAvailableSlots {
slots: Record<
string,
{
time: string;
attendees?: number | undefined;
bookingUid?: string | undefined;
away?: boolean | undefined;
fromUser?: IFromUser | undefined;
toUser?: IToUser | undefined;
reason?: string | undefined;
emoji?: string | undefined;
showNotePublicly?: boolean | undefined;
}[]
>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
troubleshooter?: any;
}
export type GetAvailableSlotsResponse = Awaited<
ReturnType<(typeof AvailableSlotsService)["prototype"]["_getAvailableSlots"]>
>;
/**
* Minimal capability interface for looking up a user's organization membership.
* Used as a fallback when org context can't be determined from request or eventType.
*/
export interface OrgMembershipLookup {
findFirstOrganizationIdForUser(args: { userId: number }): Promise<number | null>;
}
export interface IAvailableSlotsService {
oooRepo: PrismaOOORepository;
scheduleRepo: ScheduleRepository;
@@ -2,12 +2,13 @@
import { z } from "zod";
import type { TFilteredListInputSchema } from "@calcom/features/ee/workflows/repositories/WorkflowRepository";
import { filterQuerySchemaStrict } from "@calcom/features/filters/lib/getTeamsFiltersFromQuery";
export const ZFilteredListInputSchema = z
export const ZFilteredListInputSchema: z.ZodType<TFilteredListInputSchema> = z
.object({
filters: filterQuerySchemaStrict.optional(),
})
.nullish();
export type TFilteredListInputSchema = z.infer<typeof ZFilteredListInputSchema>;
export type { TFilteredListInputSchema };
@@ -1,63 +1,9 @@
import type { Workflow } from "@calcom/ee/workflows/lib/types";
import { ZWorkflow } from "@calcom/ee/workflows/lib/types";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { z } from "zod";
import {
TIME_UNIT,
WORKFLOW_ACTIONS,
WORKFLOW_TEMPLATES,
WORKFLOW_TRIGGER_EVENTS,
} from "@calcom/ee/workflows/lib/constants";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
// Define types first to use with z.ZodType annotations
type TWorkflow = {
id: number;
name: string;
trigger: (typeof WORKFLOW_TRIGGER_EVENTS)[number];
time: number | null;
timeUnit: (typeof TIME_UNIT)[number] | null;
userId: number | null;
teamId: number | null;
steps: {
id: number;
action: (typeof WORKFLOW_ACTIONS)[number];
sendTo: string | null;
template: (typeof WORKFLOW_TEMPLATES)[number];
reminderBody: string | null;
emailSubject: string | null;
numberRequired: boolean | null;
sender: string | null;
includeCalendarEvent: boolean;
numberVerificationPending: boolean;
verifiedAt?: Date | null;
}[];
};
export const ZWorkflow: z.ZodType<TWorkflow> = z.object({
id: z.number(),
name: z.string(),
trigger: z.enum(WORKFLOW_TRIGGER_EVENTS),
time: z.number().nullable(),
timeUnit: z.enum(TIME_UNIT).nullable(),
userId: z.number().nullable(),
teamId: z.number().nullable(),
steps: z
.object({
id: z.number(),
action: z.enum(WORKFLOW_ACTIONS),
sendTo: z.string().nullable(),
template: z.enum(WORKFLOW_TEMPLATES),
reminderBody: z.string().nullable(),
emailSubject: z.string().nullable(),
numberRequired: z.boolean().nullable(),
sender: z.string().nullable(),
includeCalendarEvent: z.boolean(),
numberVerificationPending: z.boolean(),
verifiedAt: z.coerce.date().nullable().optional(),
})
.array(),
});
type TWorkflows = { workflow: TWorkflow }[] | undefined;
type TWorkflows = { workflow: Workflow }[] | undefined;
export const ZWorkflows: z.ZodType<TWorkflows> = z
.object({
@@ -1,9 +1,8 @@
import type { TGetVerifiedEmailsInputSchema } from "@calcom/features/ee/workflows/repositories/WorkflowRepository";
import { z } from "zod";
export type TGetVerifiedEmailsInputSchema = {
teamId?: number;
};
export const ZGetVerifiedEmailsInputSchema: z.ZodType<TGetVerifiedEmailsInputSchema> = z.object({
teamId: z.number().optional(),
});
export type { TGetVerifiedEmailsInputSchema };
@@ -1,9 +1,8 @@
import type { TGetVerifiedNumbersInputSchema } from "@calcom/features/ee/workflows/repositories/WorkflowRepository";
import { z } from "zod";
export type TGetVerifiedNumbersInputSchema = {
teamId?: number;
};
export const ZGetVerifiedNumbersInputSchema: z.ZodType<TGetVerifiedNumbersInputSchema> = z.object({
teamId: z.number().optional(),
});
export type { TGetVerifiedNumbersInputSchema };