Files
calendar/packages/ee/prisma-extensions/usage-tracking.ts
T
Volnei MunhozGitHubVolnei MunhozDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c6ad767565 refactor: decouple @calcom/prisma from @calcom/features, @calcom/ee, and @calcom/lib (#24802)
* refactor: decouple @calcom/prisma from @calcom/features, @calcom/ee, and @calcom/lib

- Inline helper functions in zod-utils.ts (emailSchema, slugify, getValidRhfFieldName, isPasswordValid, intervalLimitsType, zodAttributesQueryValue)
- Update schema.prisma @zod.import comments to reference zod-utils instead of @calcom/lib
- Inline idempotency key generation in booking-idempotency-key extension using uuid v5
- Move usage-tracking extension to @calcom/ee/prisma-extensions/
- Remove usage-tracking extension from packages/prisma/index.ts
- Move Prisma DI module from @calcom/prisma to @calcom/features/di/modules/Prisma.ts
- Update 20 import paths in @calcom/features to use new Prisma DI module
- Remove @calcom/lib dependency from @calcom/prisma package.json
- Add uuid dependency to @calcom/prisma package.json

This reduces the dependency footprint of @calcom/prisma and breaks circular dependencies between packages.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add EE-specific Prisma DI module with usage tracking

Create packages/ee/di/modules/PrismaEE.ts to apply the usage-tracking extension in EE contexts. This module:
- Imports the base prisma client from @calcom/prisma
- Applies the usageTrackingExtention from @calcom/ee/prisma-extensions/usage-tracking
- Exports the same DI tokens as the base Prisma module for override in EE containers

This ensures usage tracking functionality is preserved in EE builds while keeping the base @calcom/prisma package free of EE dependencies.

Note: EE containers should load this module after the base Prisma module to override the bindings.
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-11-04 06:51:13 -03:00

56 lines
1.8 KiB
TypeScript

import { waitUntil } from "@vercel/functions";
import { UsageEvent, LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService";
import type { IDeploymentRepository } from "@calcom/lib/server/repository/deployment.interface";
import { Prisma } from "@calcom/prisma/client";
import type { PrismaClient } from "@calcom/prisma/client";
class InlineDeploymentRepository implements IDeploymentRepository {
constructor(private prisma: PrismaClient) {}
async getLicenseKeyWithId(id: number): Promise<string | null> {
const deployment = await this.prisma.deployment.findUnique({
where: { id },
select: { licenseKey: true },
});
return deployment?.licenseKey || null;
}
async getSignatureToken(id: number): Promise<string | null> {
const deployment = await this.prisma.deployment.findUnique({
where: { id },
select: { signatureTokenEncrypted: true },
});
return deployment?.signatureTokenEncrypted || null;
}
}
async function incrementUsage(prismaClient: PrismaClient, event?: UsageEvent) {
const deploymentRepo = new InlineDeploymentRepository(prismaClient);
try {
const licenseKeyService = await LicenseKeySingleton.getInstance(deploymentRepo);
await licenseKeyService.incrementUsage(event);
} catch (e) {
console.log(e);
}
}
export function usageTrackingExtention(prismaClient: PrismaClient) {
return Prisma.defineExtension({
query: {
booking: {
async create({ args, query }) {
waitUntil(incrementUsage(prismaClient, UsageEvent.BOOKING));
return query(args);
},
},
user: {
async create({ args, query }) {
waitUntil(incrementUsage(prismaClient, UsageEvent.USER));
return query(args);
},
},
},
});
}