refactor: convert getShouldServeCache to CacheService with dependency injection (#22814)
* refactor: convert getShouldServeCache to CacheService with dependency injection - Create CacheService class following AvailableSlotsService DI pattern - Add FeaturesRepository and CacheService to DI tokens and modules - Create cache container with proper dependency injection setup - Update handleNewBooking.ts and slots/util.ts to use new service - Maintain backward compatibility with error-throwing wrapper function - Follow established service patterns for clean architecture Co-Authored-By: morgan@cal.com <morgan@cal.com> * feat: inject CacheService into AvailableSlotsService via dependency injection - Add cacheService to IAvailableSlotsService interface - Update available-slots container to load cache modules - Update available-slots module to inject CacheService dependency - Replace direct getShouldServeCache call with injected service method - Add CacheService import to util.ts for proper typing Co-Authored-By: morgan@cal.com <morgan@cal.com> * chore: DI api v2 cache service * refactor: convert FeaturesRepository to use factory pattern in DI - Change from constructor injection to factory pattern to avoid PRISMA_CLIENT binding issues in tests - FeaturesRepository now uses default prisma instance instead of DI injection - Resolves test failures while maintaining DI container compatibility - Tests reduced from 123+ failures to only 5 unrelated failures Co-Authored-By: morgan@cal.com <morgan@cal.com> * revert: use direct FeaturesRepository instantiation in most usage points - Revert getFeaturesRepository() calls back to new FeaturesRepository() - Tests require direct instantiation for mocking compatibility - Keep DI container for specific use cases that need dependency injection - Resolves test failures while maintaining both DI and direct usage patterns Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: resolve FeaturesRepository DI container issues - Update cache module to use factory pattern with proper ICacheService interface - Remove featuresModule loading from cache and available-slots containers - Use direct FeaturesRepository instantiation via getFeaturesRepository() - Resolves 'No binding found for key: Symbol(FeaturesRepository)' errors - Reduces test failures from 125 to 7 (remaining failures appear unrelated) Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: update all FeaturesRepository instantiations to include prisma parameter - Add prisma parameter to all new FeaturesRepository() calls across the codebase - Update API v2 services to match main repo interfaces - Fix PrismaFeaturesRepository to implement IFeaturesRepository directly - Update CacheService in API v2 to expose required dependencies and getShouldServeCache - Implement CheckBookingLimitsService in API v2 with proper interface - Resolves type assignment errors between API v2 and main repo implementations Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: add prisma parameter to remaining FeaturesRepository instantiations in apps/web/lib - Update getServerSideProps files to pass prisma parameter to FeaturesRepository - Ensures all FeaturesRepository instantiations follow the new constructor pattern - Completes the refactoring to use direct instantiation with prisma parameter Co-Authored-By: morgan@cal.com <morgan@cal.com> * refactor clean and fix devin issues * chore: bump platform libs * chore: bump platform libs * chore: bump platform libs * chore: bump platform libs * fix: missing di * fix workflow test * fix workflow test * fix integration test --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: morgan@cal.com <morgan@cal.com> Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
This commit is contained in:
co-authored by
morgan@cal.com
Morgan
parent
ad4af64036
commit
1d1a242a72
@@ -38,7 +38,7 @@
|
||||
"@axiomhq/winston": "^1.2.0",
|
||||
"@calcom/platform-constants": "*",
|
||||
"@calcom/platform-enums": "*",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.271",
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.276",
|
||||
"@calcom/platform-types": "*",
|
||||
"@calcom/platform-utils": "*",
|
||||
"@calcom/prisma": "*",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository";
|
||||
import { PrismaEventTypeRepository } from "@/lib/repositories/prisma-event-type.repository";
|
||||
import { PrismaFeaturesRepository } from "@/lib/repositories/prisma-features.repository";
|
||||
import { PrismaOOORepository } from "@/lib/repositories/prisma-ooo.repository";
|
||||
import { PrismaRoutingFormResponseRepository } from "@/lib/repositories/prisma-routing-form-response.repository";
|
||||
import { PrismaScheduleRepository } from "@/lib/repositories/prisma-schedule.repository";
|
||||
@@ -7,6 +8,7 @@ import { PrismaSelectedSlotRepository } from "@/lib/repositories/prisma-selected
|
||||
import { PrismaTeamRepository } from "@/lib/repositories/prisma-team.repository";
|
||||
import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository";
|
||||
import { AvailableSlotsService } from "@/lib/services/available-slots.service";
|
||||
import { CacheService } from "@/lib/services/cache.service";
|
||||
import { CheckBookingLimitsService } from "@/lib/services/check-booking-limits.service";
|
||||
import { PrismaModule } from "@/modules/prisma/prisma.module";
|
||||
import { Module } from "@nestjs/common";
|
||||
@@ -22,7 +24,9 @@ import { Module } from "@nestjs/common";
|
||||
PrismaEventTypeRepository,
|
||||
PrismaRoutingFormResponseRepository,
|
||||
PrismaTeamRepository,
|
||||
PrismaFeaturesRepository,
|
||||
CheckBookingLimitsService,
|
||||
CacheService,
|
||||
AvailableSlotsService,
|
||||
],
|
||||
exports: [AvailableSlotsService],
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { PrismaWriteService } from "@/modules/prisma/prisma-write.service";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
import { PrismaFeaturesRepository as PrismaFeaturesRepositoryLib } from "@calcom/platform-libraries/repositories";
|
||||
import { PrismaClient } from "@calcom/prisma";
|
||||
|
||||
@Injectable()
|
||||
export class PrismaFeaturesRepository extends PrismaFeaturesRepositoryLib {
|
||||
constructor(private readonly dbWrite: PrismaWriteService) {
|
||||
super(dbWrite.prisma as unknown as PrismaClient);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository";
|
||||
import { PrismaEventTypeRepository } from "@/lib/repositories/prisma-event-type.repository";
|
||||
import { PrismaFeaturesRepository } from "@/lib/repositories/prisma-features.repository";
|
||||
import { PrismaOOORepository } from "@/lib/repositories/prisma-ooo.repository";
|
||||
import { PrismaRoutingFormResponseRepository } from "@/lib/repositories/prisma-routing-form-response.repository";
|
||||
import { PrismaScheduleRepository } from "@/lib/repositories/prisma-schedule.repository";
|
||||
import { PrismaSelectedSlotRepository } from "@/lib/repositories/prisma-selected-slot.repository";
|
||||
import { PrismaTeamRepository } from "@/lib/repositories/prisma-team.repository";
|
||||
import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository";
|
||||
import { CacheService } from "@/lib/services/cache.service";
|
||||
import { CheckBookingLimitsService } from "@/lib/services/check-booking-limits.service";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
@@ -21,7 +23,8 @@ export class AvailableSlotsService extends BaseAvailableSlotsService {
|
||||
bookingRepository: PrismaBookingRepository,
|
||||
selectedSlotRepository: PrismaSelectedSlotRepository,
|
||||
eventTypeRepository: PrismaEventTypeRepository,
|
||||
userRepository: PrismaUserRepository
|
||||
userRepository: PrismaUserRepository,
|
||||
featuresRepository: PrismaFeaturesRepository
|
||||
) {
|
||||
super({
|
||||
oooRepo: oooRepoDependency,
|
||||
@@ -32,7 +35,8 @@ export class AvailableSlotsService extends BaseAvailableSlotsService {
|
||||
selectedSlotRepo: selectedSlotRepository,
|
||||
eventTypeRepo: eventTypeRepository,
|
||||
userRepo: userRepository,
|
||||
checkBookingLimitsService: new CheckBookingLimitsService(bookingRepository),
|
||||
checkBookingLimitsService: new CheckBookingLimitsService(bookingRepository) as any,
|
||||
cacheService: new CacheService(featuresRepository),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { PrismaFeaturesRepository } from "@/lib/repositories/prisma-features.repository";
|
||||
import { Injectable } from "@nestjs/common";
|
||||
|
||||
import { CacheService as BaseCacheService } from "@calcom/platform-libraries";
|
||||
|
||||
@Injectable()
|
||||
export class CacheService extends BaseCacheService {
|
||||
constructor(featuresRepository: PrismaFeaturesRepository) {
|
||||
super({ featuresRepository });
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import { cookies, headers } from "next/headers";
|
||||
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { loadTranslations } from "@calcom/lib/server/i18n";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import { buildLegacyCtx, decodeParams } from "@lib/buildLegacyCtx";
|
||||
import { getServerSideProps } from "@lib/team/[slug]/[type]/getServerSideProps";
|
||||
@@ -17,7 +18,7 @@ import type { PageProps as LegacyPageProps } from "~/team/type-view";
|
||||
import CachedTeamBooker, { generateMetadata as generateCachedMetadata } from "./pageWithCachedData";
|
||||
|
||||
async function isCachedTeamBookingEnabled(searchParams: SearchParams): Promise<boolean> {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const isGloballyEnabled = await featuresRepository.checkIfFeatureIsEnabledGlobally(
|
||||
"team-booking-page-cache"
|
||||
);
|
||||
|
||||
@@ -102,7 +102,7 @@ export async function getEnrichedEventType({
|
||||
}
|
||||
|
||||
export async function shouldUseApiV2ForTeamSlots(teamId: number): Promise<boolean> {
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const teamHasApiV2Route = await featureRepo.checkIfTeamHasFeature(teamId, "use-api-v2-for-team-slots");
|
||||
const useApiV2 = teamHasApiV2Route && Boolean(process.env.NEXT_PUBLIC_API_V2_URL);
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ import { notFound } from "next/navigation";
|
||||
import { CTA_CONTAINER_CLASS_NAME } from "@calcom/features/data-table/lib/utils";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import Shell from "@calcom/features/shell/Shell";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import UpgradeTipWrapper from "./UpgradeTipWrapper";
|
||||
|
||||
export default async function InsightsLayout({ children }: { children: React.ReactNode }) {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const insightsEnabled = await featuresRepository.checkIfFeatureIsEnabledGlobally("insights");
|
||||
|
||||
if (!insightsEnabled) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { PermissionMapper } from "@calcom/features/pbac/domain/mappers/PermissionMapper";
|
||||
import { Resource, CrudAction } from "@calcom/features/pbac/domain/types/permission-registry";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
||||
|
||||
@@ -17,7 +18,7 @@ import SettingsLayoutAppDirClient from "./SettingsLayoutAppDirClient";
|
||||
|
||||
const getTeamFeatures = unstable_cache(
|
||||
async (teamId: number) => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
return await featuresRepository.getTeamFeatures(teamId);
|
||||
},
|
||||
["team-features"],
|
||||
|
||||
+2
-1
@@ -11,6 +11,7 @@ import { Resource, CrudAction } from "@calcom/features/pbac/domain/types/permiss
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import { RoleService } from "@calcom/features/pbac/services/role.service";
|
||||
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
||||
|
||||
@@ -29,7 +30,7 @@ const getCachedTeamRoles = unstable_cache(
|
||||
|
||||
const getCachedTeamFeature = unstable_cache(
|
||||
async (teamId: number, feature: keyof AppFlags) => {
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const res = await featureRepo.checkIfTeamHasFeature(teamId, feature);
|
||||
return res;
|
||||
},
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ import { PermissionCheckService } from "@calcom/features/pbac/services/permissio
|
||||
import { RoleService } from "@calcom/features/pbac/services/role.service";
|
||||
import SettingsHeader from "@calcom/features/settings/appDir/SettingsHeader";
|
||||
import { getTeamWithMembers } from "@calcom/lib/server/queries/teams";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
||||
|
||||
@@ -32,7 +33,7 @@ const getCachedTeamRoles = (teamId: number) =>
|
||||
const getCachedTeamFeature = (teamId: number, feature: keyof AppFlags) =>
|
||||
unstable_cache(
|
||||
async () => {
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const res = await featureRepo.checkIfTeamHasFeature(teamId, feature);
|
||||
return res;
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ import getIP from "@calcom/lib/getIP";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { checkCfTurnstileToken } from "@calcom/lib/server/checkCfTurnstileToken";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { signupSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
async function ensureSignupIsEnabled(body: Record<string, string>) {
|
||||
@@ -22,7 +23,7 @@ async function ensureSignupIsEnabled(body: Record<string, string>) {
|
||||
// Still allow signups if there is a team invite
|
||||
if (token) return;
|
||||
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const signupDisabled = await featuresRepository.checkIfFeatureIsEnabledGlobally("disable-signup");
|
||||
|
||||
if (process.env.NEXT_PUBLIC_DISABLE_SIGNUP === "true" || signupDisabled) {
|
||||
|
||||
@@ -120,7 +120,7 @@ async function getUserPageProps(context: GetServerSidePropsContext) {
|
||||
// Check if team has API v2 feature flag enabled (same logic as team pages)
|
||||
let useApiV2 = false;
|
||||
if (isTeamEvent && hashedLink.eventType.team?.id) {
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const teamHasApiV2Route = await featureRepo.checkIfTeamHasFeature(
|
||||
hashedLink.eventType.team.id,
|
||||
"use-api-v2-for-team-slots"
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import type { GetServerSidePropsResult } from "next";
|
||||
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
export const getServerSideProps = async (): Promise<GetServerSidePropsResult<{ isOrg: boolean }>> => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const organizations = await featuresRepository.checkIfFeatureIsEnabledGlobally("organizations");
|
||||
// Check if organizations are enabled
|
||||
if (!organizations) {
|
||||
|
||||
@@ -24,7 +24,7 @@ const querySchema = z.object({
|
||||
|
||||
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const emailVerificationEnabled = await featuresRepository.checkIfFeatureIsEnabledGlobally(
|
||||
"email-verification"
|
||||
);
|
||||
|
||||
@@ -127,7 +127,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||
const organizationSettings = getOrganizationSEOSettings(team);
|
||||
const allowSEOIndexing = organizationSettings?.allowSEOIndexing ?? false;
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const teamHasApiV2Route = await featureRepo.checkIfTeamHasFeature(team.id, "use-api-v2-for-team-slots");
|
||||
const useApiV2 = teamHasApiV2Route && hasApiV2RouteInEnv();
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
||||
|
||||
// Provided by Rewrite from next.config.js
|
||||
const isOrgProfile = context.query?.isOrgProfile === "1";
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const organizationsEnabled = await featuresRepository.checkIfFeatureIsEnabledGlobally("organizations");
|
||||
|
||||
log.debug("getServerSideProps", {
|
||||
|
||||
@@ -247,7 +247,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
|
||||
const videoReference = getCalVideoReference(bookingObj.references);
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const displayLogInOverlay = profile?.organizationId
|
||||
? await featureRepo.checkIfTeamHasFeature(profile.organizationId, "cal-video-log-in-overlay")
|
||||
: false;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
import isSmsCalEmail from "@calcom/lib/isSmsCalEmail";
|
||||
import { serverConfig } from "@calcom/lib/serverConfig";
|
||||
import { setTestEmail } from "@calcom/lib/testEmails";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
import { sanitizeDisplayName } from "../lib/sanitizeDisplayName";
|
||||
|
||||
@@ -29,7 +30,7 @@ export default class BaseEmail {
|
||||
return {};
|
||||
}
|
||||
public async sendEmail() {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const emailsDisabled = await featuresRepository.checkIfFeatureIsEnabledGlobally("emails");
|
||||
/** If email kill switch exists and is active, we prevent emails being sent. */
|
||||
if (emailsDisabled) {
|
||||
|
||||
@@ -34,7 +34,7 @@ export const sendEmailVerification = async ({
|
||||
}: VerifyEmailType) => {
|
||||
const token = randomBytes(32).toString("hex");
|
||||
const translation = await getTranslation(language ?? "en", "common");
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const emailVerification = await featuresRepository.checkIfFeatureIsEnabledGlobally("email-verification");
|
||||
|
||||
if (!emailVerification) {
|
||||
@@ -127,7 +127,7 @@ interface ChangeOfEmail {
|
||||
export const sendChangeOfEmailVerification = async ({ user, language }: ChangeOfEmail) => {
|
||||
const token = randomBytes(32).toString("hex");
|
||||
const translation = await getTranslation(language ?? "en", "common");
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const emailVerification = await featuresRepository.checkIfFeatureIsEnabledGlobally("email-verification");
|
||||
|
||||
if (!emailVerification) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import getICalUID from "@calcom/emails/lib/getICalUID";
|
||||
import { CalendarEventBuilder } from "@calcom/features/CalendarEventBuilder";
|
||||
import { handleWebhookTrigger } from "@calcom/features/bookings/lib/handleWebhookTrigger";
|
||||
import { isEventTypeLoggingEnabled } from "@calcom/features/bookings/lib/isEventTypeLoggingEnabled";
|
||||
import { getShouldServeCache } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
|
||||
import AssignmentReasonRecorder from "@calcom/features/ee/round-robin/assignmentReason/AssignmentReasonRecorder";
|
||||
import {
|
||||
allowDisablingAttendeeConfirmationEmails,
|
||||
@@ -52,6 +51,7 @@ import {
|
||||
getFirstDelegationConferencingCredentialAppLocation,
|
||||
} from "@calcom/lib/delegationCredential/server";
|
||||
import { getCheckBookingAndDurationLimitsService } from "@calcom/lib/di/containers/booking-limits";
|
||||
import { getCacheService } from "@calcom/lib/di/containers/cache";
|
||||
import { ErrorCode } from "@calcom/lib/errorCodes";
|
||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
import { getEventName, updateHostInEventName } from "@calcom/lib/event";
|
||||
@@ -539,7 +539,8 @@ async function handler(
|
||||
}
|
||||
}
|
||||
|
||||
const shouldServeCache = await getShouldServeCache(_shouldServeCache, eventType.team?.id);
|
||||
const cacheService = getCacheService();
|
||||
const shouldServeCache = await cacheService.getShouldServeCache(_shouldServeCache, eventType.team?.id);
|
||||
|
||||
const isTeamEventType =
|
||||
!!eventType.schedulingType && ["COLLECTIVE", "ROUND_ROBIN"].includes(eventType.schedulingType);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { getCredentialForCalendarCache } from "@calcom/lib/delegationCredential/server";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { Calendar } from "@calcom/types/Calendar";
|
||||
|
||||
import { CalendarCacheRepository } from "./calendar-cache.repository";
|
||||
@@ -20,7 +21,7 @@ export class CalendarCache {
|
||||
return await CalendarCache.init(calendarForCalendarCache);
|
||||
}
|
||||
static async init(calendar: Calendar | null): Promise<ICalendarCacheRepository> {
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const isCalendarCacheEnabledGlobally = await featureRepo.checkIfFeatureIsEnabledGlobally(
|
||||
"calendar-cache"
|
||||
);
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import type { IFeaturesRepository } from "@calcom/features/flags/features.repository.interface";
|
||||
|
||||
export async function getShouldServeCache(shouldServeCache?: boolean | undefined, teamId?: number) {
|
||||
if (typeof shouldServeCache === "boolean") return shouldServeCache;
|
||||
if (!teamId) return undefined;
|
||||
const featureRepo = new FeaturesRepository();
|
||||
return await featureRepo.checkIfTeamHasFeature(teamId, "calendar-cache-serve");
|
||||
export interface ICacheService {
|
||||
featuresRepository: IFeaturesRepository;
|
||||
}
|
||||
|
||||
export class CacheService {
|
||||
constructor(private readonly dependencies: ICacheService) {}
|
||||
|
||||
async getShouldServeCache(shouldServeCache?: boolean | undefined, teamId?: number) {
|
||||
if (typeof shouldServeCache === "boolean") return shouldServeCache;
|
||||
if (!teamId) return undefined;
|
||||
return await this.dependencies.featuresRepository.checkIfTeamHasFeature(teamId, "calendar-cache-serve");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { MembershipRole } from "@calcom/prisma/client";
|
||||
|
||||
export const getServerSideProps = async ({ req }: GetServerSidePropsContext) => {
|
||||
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const organizationsEnabled = await featuresRepository.checkIfFeatureIsEnabledGlobally("organizations");
|
||||
// Check if organizations are enabled
|
||||
if (!organizationsEnabled) {
|
||||
|
||||
@@ -277,7 +277,7 @@ export const scheduleEmailReminder = async (args: scheduleEmailReminderArgs) =>
|
||||
|
||||
const isSendgridEnabled = !!(process.env.SENDGRID_API_KEY && process.env.SENDGRID_EMAIL);
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
|
||||
const isWorkflowSmtpEmailsEnabled = teamId
|
||||
? await featureRepo.checkIfTeamHasFeature(teamId, "workflow-smtp-emails")
|
||||
|
||||
@@ -1103,7 +1103,6 @@ describe("Workflow SMTP Emails Feature Flag", () => {
|
||||
});
|
||||
|
||||
test("should use SMTP when team has workflow-smtp-emails feature", async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
vi.spyOn(FeaturesRepository.prototype, "checkIfTeamHasFeature").mockResolvedValue(true);
|
||||
|
||||
await scheduleEmailReminder({
|
||||
@@ -1115,7 +1114,6 @@ describe("Workflow SMTP Emails Feature Flag", () => {
|
||||
});
|
||||
|
||||
test("should use SMTP when user has workflow-smtp-emails feature", async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
vi.spyOn(FeaturesRepository.prototype, "checkIfUserHasFeature").mockResolvedValue(true);
|
||||
|
||||
await scheduleEmailReminder({
|
||||
@@ -1127,7 +1125,6 @@ describe("Workflow SMTP Emails Feature Flag", () => {
|
||||
});
|
||||
|
||||
test("should use SendGrid when workflow-smtp-emails feature is not enabled for team", async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
vi.spyOn(FeaturesRepository.prototype, "checkIfTeamHasFeature").mockResolvedValue(false);
|
||||
|
||||
await scheduleEmailReminder({
|
||||
@@ -1140,7 +1137,6 @@ describe("Workflow SMTP Emails Feature Flag", () => {
|
||||
});
|
||||
|
||||
test("should use SendGrid when workflow-smtp-emails feature is not enabled for user", async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
vi.spyOn(FeaturesRepository.prototype, "checkIfUserHasFeature").mockResolvedValue(false);
|
||||
|
||||
await scheduleEmailReminder({
|
||||
@@ -1153,9 +1149,9 @@ describe("Workflow SMTP Emails Feature Flag", () => {
|
||||
});
|
||||
|
||||
test("should use SMTP when SendGrid is not configured", async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
vi.spyOn(featuresRepository, "checkIfTeamHasFeature").mockResolvedValue(false);
|
||||
vi.spyOn(featuresRepository, "checkIfUserHasFeature").mockResolvedValue(false);
|
||||
vi.spyOn(FeaturesRepository.prototype, "checkIfTeamHasFeature").mockResolvedValue(false);
|
||||
|
||||
vi.spyOn(FeaturesRepository.prototype, "checkIfUserHasFeature").mockResolvedValue(false);
|
||||
|
||||
delete process.env.SENDGRID_API_KEY;
|
||||
delete process.env.SENDGRID_EMAIL;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { describe, expect, beforeAll, afterAll, beforeEach, it } from "vitest";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import type { AppFlags } from "./config";
|
||||
import { FeaturesRepository } from "./features.repository";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
|
||||
// Access private clearCache method through type assertion
|
||||
const clearCache = () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { captureException } from "@sentry/nextjs";
|
||||
|
||||
import db from "@calcom/prisma";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
|
||||
import type { AppFlags, TeamFeatures } from "./config";
|
||||
import type { IFeaturesRepository } from "./features.repository.interface";
|
||||
@@ -18,6 +18,8 @@ interface CacheOptions {
|
||||
export class FeaturesRepository implements IFeaturesRepository {
|
||||
private static featuresCache: { data: any[]; expiry: number } | null = null;
|
||||
|
||||
constructor(private prismaClient: PrismaClient) {}
|
||||
|
||||
private clearCache() {
|
||||
FeaturesRepository.featuresCache = null;
|
||||
}
|
||||
@@ -32,7 +34,7 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
return FeaturesRepository.featuresCache.data;
|
||||
}
|
||||
|
||||
const features = await db.feature.findMany({
|
||||
const features = await this.prismaClient.feature.findMany({
|
||||
orderBy: { slug: "asc" },
|
||||
cacheStrategy: { swr: 300, ttl: 300 },
|
||||
});
|
||||
@@ -64,7 +66,7 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
* @returns Promise<{ [slug: string]: boolean } | null>
|
||||
*/
|
||||
public async getTeamFeatures(teamId: number) {
|
||||
const result = await db.teamFeatures.findMany({
|
||||
const result = await this.prismaClient.teamFeatures.findMany({
|
||||
where: {
|
||||
teamId,
|
||||
},
|
||||
@@ -122,7 +124,7 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
* FIXME refactor when upgrading prismock
|
||||
* https://github.com/morintd/prismock/issues/592
|
||||
*/
|
||||
const userHasFeature = await db.userFeatures.findFirst({
|
||||
const userHasFeature = await this.prismaClient.userFeatures.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
featureId: slug,
|
||||
@@ -180,7 +182,7 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
LIMIT 1;
|
||||
`;
|
||||
|
||||
const result = await db.$queryRaw<unknown[]>(query);
|
||||
const result = await this.prismaClient.$queryRaw<unknown[]>(query);
|
||||
return result.length > 0;
|
||||
} catch (err) {
|
||||
captureException(err);
|
||||
@@ -199,7 +201,7 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
async checkIfTeamHasFeature(teamId: number, featureId: keyof AppFlags): Promise<boolean> {
|
||||
try {
|
||||
// Early return if team has feature directly assigned
|
||||
const teamHasFeature = await db.teamFeatures.findUnique({
|
||||
const teamHasFeature = await this.prismaClient.teamFeatures.findUnique({
|
||||
where: {
|
||||
teamId_featureId: {
|
||||
teamId,
|
||||
@@ -238,7 +240,7 @@ export class FeaturesRepository implements IFeaturesRepository {
|
||||
LIMIT 1;
|
||||
`;
|
||||
|
||||
const result = await db.$queryRaw<unknown[]>(query);
|
||||
const result = await this.prismaClient.$queryRaw<unknown[]>(query);
|
||||
return result.length > 0;
|
||||
} catch (err) {
|
||||
captureException(err);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { startSpan } from "@sentry/nextjs";
|
||||
|
||||
import { FeaturesRepository } from "../features.repository";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
|
||||
/**
|
||||
* Use Cases represent individual operations, like "Create Feature" or "Sign In" or "Toggle Feature".
|
||||
@@ -11,7 +12,7 @@ import { FeaturesRepository } from "../features.repository";
|
||||
*/
|
||||
export function checkIfUserHasFeatureUseCase(userId: number, slug: string): Promise<boolean> {
|
||||
return startSpan({ name: "checkIfUserHasFeature UseCase", op: "function" }, async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
|
||||
return await featuresRepository.checkIfUserHasFeature(userId, slug);
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import prisma from "@calcom/prisma";
|
||||
import publicProcedure from "@calcom/trpc/server/procedures/publicProcedure";
|
||||
|
||||
import { FeaturesRepository } from "../../features.repository";
|
||||
|
||||
/**
|
||||
* TRPC procedure that returns a map of all feature flags and their enabled status.
|
||||
* Uses the FeaturesRepository to handle caching and database access.
|
||||
*/
|
||||
export const map = publicProcedure.query(async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
return featuresRepository.getFeatureFlagMap();
|
||||
});
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import type { AppFlags } from "@calcom/features/flags/config";
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import publicProcedure from "@calcom/trpc/server/procedures/publicProcedure";
|
||||
import { router } from "@calcom/trpc/server/trpc";
|
||||
|
||||
import { FeaturesRepository } from "../features.repository";
|
||||
import { map } from "./procedures/map";
|
||||
|
||||
export const featureFlagRouter = router({
|
||||
list: publicProcedure.query(async () => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
return featuresRepository.getAllFeatures();
|
||||
}),
|
||||
checkTeamFeature: publicProcedure
|
||||
@@ -20,7 +21,7 @@ export const featureFlagRouter = router({
|
||||
})
|
||||
)
|
||||
.query(async ({ input }) => {
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
return featuresRepository.checkIfTeamHasFeature(input.teamId, input.feature as keyof AppFlags);
|
||||
}),
|
||||
map,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
import { PermissionMapper } from "../domain/mappers/PermissionMapper";
|
||||
@@ -53,7 +54,7 @@ export const getResourcePermissions = async ({
|
||||
userRole,
|
||||
fallbackRoles = {},
|
||||
}: ResourcePermissionsOptions): Promise<ResourcePermissions> => {
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const permissionService = new PermissionCheckService();
|
||||
|
||||
const pbacEnabled = await featureRepo.checkIfTeamHasFeature(teamId, "pbac");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { MembershipRepository } from "@calcom/lib/server/repository/membership";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
import { PermissionMapper } from "../domain/mappers/PermissionMapper";
|
||||
@@ -24,7 +25,7 @@ export class PermissionCheckService {
|
||||
|
||||
constructor(
|
||||
private readonly repository: IPermissionRepository = new PermissionRepository(),
|
||||
featuresRepository: FeaturesRepository = new FeaturesRepository(),
|
||||
featuresRepository: FeaturesRepository = new FeaturesRepository(prisma),
|
||||
permissionService: PermissionService = new PermissionService()
|
||||
) {
|
||||
this.featuresRepository = featuresRepository;
|
||||
|
||||
@@ -150,8 +150,7 @@ export class RoleManagementFactory {
|
||||
private permissionCheckService: PermissionCheckService;
|
||||
|
||||
private constructor() {
|
||||
this.featuresRepository = new FeaturesRepository();
|
||||
this.roleService = new RoleService();
|
||||
(this.featuresRepository = new FeaturesRepository(prisma)), (this.roleService = new RoleService());
|
||||
this.permissionCheckService = new PermissionCheckService();
|
||||
}
|
||||
|
||||
|
||||
@@ -1153,7 +1153,7 @@ export default class EventManager {
|
||||
private async createAllCRMEvents(event: CalendarEvent) {
|
||||
const createdEvents = [];
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const isTaskerEnabledForSalesforceCrm = event.team?.id
|
||||
? await featureRepo.checkIfTeamHasFeature(event.team.id, "salesforce-crm-tasker")
|
||||
: false;
|
||||
|
||||
@@ -6,8 +6,10 @@ import type { AvailableSlotsService } from "@calcom/trpc/server/routers/viewer/s
|
||||
|
||||
import { availableSlotsModule } from "../modules/available-slots";
|
||||
import { bookingRepositoryModule } from "../modules/booking";
|
||||
import { cacheModule } from "../modules/cache";
|
||||
import { checkBookingLimitsModule } from "../modules/check-booking-limits";
|
||||
import { eventTypeRepositoryModule } from "../modules/eventType";
|
||||
import { featuresRepositoryModule } from "../modules/features";
|
||||
import { oooRepositoryModule } from "../modules/ooo";
|
||||
import { routingFormResponseRepositoryModule } from "../modules/routingFormResponse";
|
||||
import { scheduleRepositoryModule } from "../modules/schedule";
|
||||
@@ -25,6 +27,8 @@ container.load(DI_TOKENS.USER_REPOSITORY_MODULE, userRepositoryModule);
|
||||
container.load(DI_TOKENS.BOOKING_REPOSITORY_MODULE, bookingRepositoryModule);
|
||||
container.load(DI_TOKENS.EVENT_TYPE_REPOSITORY_MODULE, eventTypeRepositoryModule);
|
||||
container.load(DI_TOKENS.ROUTING_FORM_RESPONSE_REPOSITORY_MODULE, routingFormResponseRepositoryModule);
|
||||
container.load(DI_TOKENS.FEATURES_REPOSITORY_MODULE, featuresRepositoryModule);
|
||||
container.load(DI_TOKENS.CACHE_SERVICE_MODULE, cacheModule);
|
||||
container.load(DI_TOKENS.CHECK_BOOKING_LIMITS_SERVICE_MODULE, checkBookingLimitsModule);
|
||||
container.load(DI_TOKENS.AVAILABLE_SLOTS_SERVICE_MODULE, availableSlotsModule);
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { createContainer } from "@evyweb/ioctopus";
|
||||
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { prismaModule } from "@calcom/prisma/prisma.module";
|
||||
|
||||
import type { CacheService } from "../../../features/calendar-cache/lib/getShouldServeCache";
|
||||
import { cacheModule } from "../modules/cache";
|
||||
import { featuresRepositoryModule } from "../modules/features";
|
||||
|
||||
const container = createContainer();
|
||||
container.load(DI_TOKENS.PRISMA_MODULE, prismaModule);
|
||||
container.load(DI_TOKENS.FEATURES_REPOSITORY_MODULE, featuresRepositoryModule);
|
||||
container.load(DI_TOKENS.CACHE_SERVICE_MODULE, cacheModule);
|
||||
|
||||
export function getCacheService() {
|
||||
return container.get<CacheService>(DI_TOKENS.CACHE_SERVICE);
|
||||
}
|
||||
@@ -15,5 +15,6 @@ availableSlotsModule.bind(DI_TOKENS.AVAILABLE_SLOTS_SERVICE).toClass(AvailableSl
|
||||
bookingRepo: DI_TOKENS.BOOKING_REPOSITORY,
|
||||
eventTypeRepo: DI_TOKENS.EVENT_TYPE_REPOSITORY,
|
||||
routingFormResponseRepo: DI_TOKENS.ROUTING_FORM_RESPONSE_REPOSITORY,
|
||||
cacheService: DI_TOKENS.CACHE_SERVICE,
|
||||
checkBookingLimitsService: DI_TOKENS.CHECK_BOOKING_LIMITS_SERVICE,
|
||||
} satisfies Record<keyof IAvailableSlotsService, symbol>);
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { createModule } from "@evyweb/ioctopus";
|
||||
|
||||
import type { ICacheService } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
|
||||
import { CacheService } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
|
||||
|
||||
import { DI_TOKENS } from "../tokens";
|
||||
|
||||
export const cacheModule = createModule();
|
||||
cacheModule.bind(DI_TOKENS.CACHE_SERVICE).toClass(CacheService, {
|
||||
featuresRepository: DI_TOKENS.FEATURES_REPOSITORY,
|
||||
} satisfies Record<keyof ICacheService, symbol>);
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createModule } from "@evyweb/ioctopus";
|
||||
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
|
||||
export const featuresRepositoryModule = createModule();
|
||||
featuresRepositoryModule
|
||||
.bind(DI_TOKENS.FEATURES_REPOSITORY)
|
||||
.toClass(FeaturesRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
@@ -22,6 +22,10 @@ export const DI_TOKENS = {
|
||||
AVAILABLE_SLOTS_SERVICE_MODULE: Symbol("AvailableSlotsModule"),
|
||||
INSIGHTS_ROUTING_SERVICE: Symbol("InsightsRoutingService"),
|
||||
INSIGHTS_ROUTING_SERVICE_MODULE: Symbol("InsightsRoutingServiceModule"),
|
||||
FEATURES_REPOSITORY: Symbol("FeaturesRepository"),
|
||||
FEATURES_REPOSITORY_MODULE: Symbol("FeaturesRepositoryModule"),
|
||||
CACHE_SERVICE: Symbol("CacheService"),
|
||||
CACHE_SERVICE_MODULE: Symbol("CacheServiceModule"),
|
||||
CHECK_BOOKING_LIMITS_SERVICE: Symbol("CheckBookingLimitsService"),
|
||||
CHECK_BOOKING_LIMITS_SERVICE_MODULE: Symbol("CheckBookingLimitsServiceModule"),
|
||||
CHECK_BOOKING_AND_DURATION_LIMITS_SERVICE: Symbol("CheckBookingAndDurationLimitsService"),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
/**
|
||||
* Checks if the restriction schedule feature is enabled for a team
|
||||
@@ -10,6 +11,6 @@ export async function isRestrictionScheduleEnabled(teamId?: number): Promise<boo
|
||||
return false; // Personal events don't have restriction schedules
|
||||
}
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
return await featureRepo.checkIfTeamHasFeature(teamId, "restriction-schedule");
|
||||
}
|
||||
|
||||
@@ -119,3 +119,5 @@ export type { TFindTeamMembersMatchingAttributeLogicInputSchema } from "@calcom/
|
||||
export { checkAdminOrOwner } from "@calcom/features/auth/lib/checkAdminOrOwner";
|
||||
|
||||
export { verifyPhoneNumber, sendVerificationCode };
|
||||
|
||||
export { CacheService } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
|
||||
|
||||
@@ -6,3 +6,4 @@ export { RoutingFormResponseRepository as PrismaRoutingFormResponseRepository }
|
||||
export { PrismaSelectedSlotRepository } from "@calcom/lib/server/repository/PrismaSelectedSlotRepository";
|
||||
export { TeamRepository as PrismaTeamRepository } from "@calcom/lib/server/repository/team";
|
||||
export { UserRepository as PrismaUserRepository } from "@calcom/lib/server/repository/user";
|
||||
export { FeaturesRepository as PrismaFeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
@@ -22,7 +23,7 @@ const checkDelegationCredentialFeature = async ({
|
||||
}) => {
|
||||
const user = ctx.user;
|
||||
const t = await getTranslation(user.locale ?? "en", "common");
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
|
||||
if (!user.organizationId) {
|
||||
throw new TRPCError({
|
||||
|
||||
@@ -40,7 +40,7 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions)
|
||||
const billingService = new StripeBillingService();
|
||||
const userMetadata = handleUserMetadata({ ctx, input });
|
||||
const locale = input.locale || user.locale;
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const emailVerification = await featuresRepository.checkIfFeatureIsEnabledGlobally("email-verification");
|
||||
|
||||
const { travelSchedules, ...rest } = input;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { OrganizationRepository } from "@calcom/lib/server/repository/organization";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
@@ -26,7 +27,7 @@ export const listHandler = async ({ ctx }: ListHandlerInput) => {
|
||||
return currentOrg;
|
||||
}
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const hasDelegationCredential = await featureRepo.checkIfTeamHasFeature(
|
||||
organizationId,
|
||||
"delegation-credential"
|
||||
|
||||
@@ -39,7 +39,7 @@ export const listMembersHandler = async ({ ctx, input }: GetOptions) => {
|
||||
const expand = input.expand;
|
||||
const filters = input.filters || [];
|
||||
|
||||
const featuresRepository = new FeaturesRepository();
|
||||
const featuresRepository = new FeaturesRepository(prisma);
|
||||
const pbacFeatureEnabled = await featuresRepository.checkIfTeamHasFeature(organizationId, "pbac");
|
||||
|
||||
const allAttributeOptions = await prisma.attributeOption.findMany({
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Resource, CrudAction, CustomAction } from "@calcom/features/pbac/domain
|
||||
import type { PermissionString } from "@calcom/features/pbac/domain/types/permission-registry";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import { RoleService } from "@calcom/features/pbac/services/role.service";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { RoleType, MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
import authedProcedure from "../../../procedures/authedProcedure";
|
||||
@@ -193,7 +194,7 @@ export const permissionsRouter = router({
|
||||
throw new Error("Unauthorized");
|
||||
}
|
||||
|
||||
const featureRepo = new FeaturesRepository();
|
||||
const featureRepo = new FeaturesRepository(prisma);
|
||||
const teamHasPBACFeature = await featureRepo.checkIfTeamHasFeature(input.teamId, "pbac");
|
||||
|
||||
if (!teamHasPBACFeature) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import dayjs from "@calcom/dayjs";
|
||||
import { orgDomainConfig } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { checkForConflicts } from "@calcom/features/bookings/lib/conflictChecker/checkForConflicts";
|
||||
import { isEventTypeLoggingEnabled } from "@calcom/features/bookings/lib/isEventTypeLoggingEnabled";
|
||||
import { getShouldServeCache } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
|
||||
import type { CacheService } from "@calcom/features/calendar-cache/lib/getShouldServeCache";
|
||||
import { findQualifiedHostsWithDelegationCredentials } from "@calcom/lib/bookings/findQualifiedHostsWithDelegationCredentials";
|
||||
import { shouldIgnoreContactOwner } from "@calcom/lib/bookings/routing/utils";
|
||||
import { RESERVED_SUBDOMAINS } from "@calcom/lib/constants";
|
||||
@@ -99,6 +99,7 @@ export interface IAvailableSlotsService {
|
||||
bookingRepo: BookingRepository;
|
||||
eventTypeRepo: EventTypeRepository;
|
||||
routingFormResponseRepo: RoutingFormResponseRepository;
|
||||
cacheService: CacheService;
|
||||
checkBookingLimitsService: CheckBookingLimitsService;
|
||||
}
|
||||
|
||||
@@ -909,8 +910,10 @@ export class AvailableSlotsService {
|
||||
throw new TRPCError({ code: "NOT_FOUND" });
|
||||
}
|
||||
|
||||
// TODO: DI getShouldServeCache
|
||||
const shouldServeCache = await getShouldServeCache(_shouldServeCache, eventType.team?.id);
|
||||
const shouldServeCache = await this.dependencies.cacheService.getShouldServeCache(
|
||||
_shouldServeCache,
|
||||
eventType.team?.id
|
||||
);
|
||||
if (isEventTypeLoggingEnabled({ eventTypeId: eventType.id })) {
|
||||
logger.settings.minLevel = 2;
|
||||
}
|
||||
|
||||
@@ -2519,7 +2519,7 @@ __metadata:
|
||||
"@axiomhq/winston": ^1.2.0
|
||||
"@calcom/platform-constants": "*"
|
||||
"@calcom/platform-enums": "*"
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.271"
|
||||
"@calcom/platform-libraries": "npm:@calcom/platform-libraries@0.0.276"
|
||||
"@calcom/platform-types": "*"
|
||||
"@calcom/platform-utils": "*"
|
||||
"@calcom/prisma": "*"
|
||||
@@ -3575,13 +3575,13 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.271":
|
||||
version: 0.0.271
|
||||
resolution: "@calcom/platform-libraries@npm:0.0.271"
|
||||
"@calcom/platform-libraries@npm:@calcom/platform-libraries@0.0.276":
|
||||
version: 0.0.276
|
||||
resolution: "@calcom/platform-libraries@npm:0.0.276"
|
||||
dependencies:
|
||||
"@calcom/features": "*"
|
||||
"@calcom/lib": "*"
|
||||
checksum: 5b55a05c5cd1d471fe36c90b8b2f16e70f6155065b3b13e12c06bde73f3ceffde74de3921c3a9fe05d04eed7fb587836ac79a46a521d35fe83812d66b13d8733
|
||||
checksum: 4effc186c0301ec35496ebffbe32280f26261667b60057d18207b30636b038cdcc3783b95390eecc8460f3203d0cfe5d732e3b3f89031ff064b1a556321779a8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user