Files
devin-ai-integration[bot]GitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>[email protected] <[email protected]>Morgan
1d1a242a72 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>

* 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: [email protected] <[email protected]>
Co-authored-by: Morgan <[email protected]>
2025-07-31 20:39:27 +03:00

101 lines
3.4 KiB
TypeScript

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";
import authedProcedure, { authedOrgAdminProcedure } from "../../../procedures/authedProcedure";
import { router } from "../../../trpc";
import {
DelegationCredentialCreateSchema,
DelegationCredentialUpdateSchema,
DelegationCredentialDeleteSchema,
DelegationCredentialToggleEnabledSchema,
DelegationCredentialGetAffectedMembersForDisableSchema,
} from "./schema";
const checkDelegationCredentialFeature = async ({
ctx,
next,
}: {
ctx: { user: { id: number; locale?: string; organizationId: number | null } };
next: () => Promise<any>;
}) => {
const user = ctx.user;
const t = await getTranslation(user.locale ?? "en", "common");
const featureRepo = new FeaturesRepository(prisma);
if (!user.organizationId) {
throw new TRPCError({
code: "FORBIDDEN",
message: t("no_organization_found"),
});
}
const hasDelegationCredential = await featureRepo.checkIfTeamHasFeature(
user.organizationId,
"delegation-credential"
);
if (!hasDelegationCredential) {
throw new TRPCError({
code: "FORBIDDEN",
message: t("delegation_credential_feature_not_enabled"),
});
}
return next();
};
export const delegationCredentialRouter = router({
check: authedOrgAdminProcedure.query(async (opts) => {
return await checkDelegationCredentialFeature({
ctx: opts.ctx,
next: async () => ({
hasDelegationCredential: true,
}),
});
}),
list: authedOrgAdminProcedure.use(checkDelegationCredentialFeature).query(async (opts) => {
const handler = await import("./list.handler").then((mod) => mod.default);
return handler(opts);
}),
update: authedOrgAdminProcedure
.use(checkDelegationCredentialFeature)
.input(DelegationCredentialUpdateSchema)
.mutation(async (opts) => {
const handler = await import("./update.handler").then((mod) => mod.default);
return handler(opts);
}),
add: authedOrgAdminProcedure
.use(checkDelegationCredentialFeature)
.input(DelegationCredentialCreateSchema)
.mutation(async (opts) => {
const handler = await import("./add.handler").then((mod) => mod.default);
return handler(opts);
}),
toggleEnabled: authedOrgAdminProcedure
.use(checkDelegationCredentialFeature)
.input(DelegationCredentialToggleEnabledSchema)
.mutation(async (opts) => {
const handler = await import("./toggleEnabled.handler").then((mod) => mod.default);
return handler(opts);
}),
getAffectedMembersForDisable: authedOrgAdminProcedure
.use(checkDelegationCredentialFeature)
.input(DelegationCredentialGetAffectedMembersForDisableSchema)
.query(async (opts) => {
const handler = await import("./getAffectedMembersForDisable.handler").then((mod) => mod.default);
return handler(opts);
}),
delete: authedOrgAdminProcedure
.use(checkDelegationCredentialFeature)
.input(DelegationCredentialDeleteSchema)
.mutation(async (opts) => {
const handler = await import("./delete.handler").then((mod) => mod.default);
return handler(opts);
}),
listWorkspacePlatforms: authedProcedure.use(checkDelegationCredentialFeature).query(async () => {
const handler = await import("./listWorkspacePlatforms.handler").then((mod) => mod.default);
return handler();
}),
});