0ad4367005
* chore: save progress * chore: * feat: add input dialog * fix: type error * feat: mass apply dialog * test: per host location * test: fix test * fix: address Cubic AI review feedback (confidence >= 9/10) - Remove PII (address, phone number) from tracing logs in RegularBookingService.ts - Constrain HostLocation.type to EventLocationType["type"] for compile-time validation Co-Authored-By: unknown <> * fix: translation * refactor: improvements * fix: correct grammar in custom host locations tooltip Change 'custom host locations is enabled' to 'custom host locations are enabled' (plural subject requires plural verb). Addresses Cubic AI review feedback (confidence 9/10). Co-Authored-By: unknown <> * refactor: improvements * fix: auth * fix: check * refactor: improvements * fix: address Cubic AI review feedback (confidence >= 9/10) - Add scheduleId to newly created hosts in update.handler.ts to persist host-specific schedules during create operations - Change host location deletion filter from !host.location to host.location === null to only delete when explicitly set to null - Fix static-link per-host locations to use actual link instead of type in locationBodyString for bookingLocationService.ts Co-Authored-By: unknown <> * fix: preserve existing host scheduleId when not explicitly provided Change scheduleId handling for existing hosts from 'host.scheduleId ?? null' to 'host.scheduleId === undefined ? undefined : host.scheduleId' so that when the client doesn't provide a scheduleId, the existing value is preserved instead of being cleared to null. Co-Authored-By: unknown <> * fix; type erro * fix; type erro * fix; type erro * refactor: move repository * refactor: move repository * fix: add singular/plural translations for location_applied_to_hosts Addresses Cubic AI review feedback (confidence 9/10) to fix '1 hosts' rendering as '1 host' by using i18next plural format with _one and _other suffixes. Co-Authored-By: unknown <> * refactor: feedback * fix: type err * fix: use uuid in schema and remove attendee locaiton * fix: type err * fix: type err * fix: validate eventTypeId as integer in massApplyHostLocation schema Co-Authored-By: unknown <> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
172 lines
4.0 KiB
TypeScript
172 lines
4.0 KiB
TypeScript
import { AppCategories } from "@calcom/prisma/enums";
|
|
import type { PrismaClient } from "@calcom/prisma";
|
|
import { safeCredentialSelect } from "@calcom/prisma/selects/credential";
|
|
|
|
export class HostRepository {
|
|
constructor(private prismaClient: PrismaClient) {}
|
|
|
|
async updateHostsSchedule(userId: number, oldScheduleId: number, newScheduleId: number) {
|
|
return await this.prismaClient.host.updateMany({
|
|
where: {
|
|
userId,
|
|
scheduleId: oldScheduleId,
|
|
},
|
|
data: {
|
|
scheduleId: newScheduleId,
|
|
},
|
|
});
|
|
}
|
|
|
|
async findHostsCreatedInInterval({
|
|
eventTypeId,
|
|
userIds,
|
|
startDate,
|
|
}: {
|
|
eventTypeId: number;
|
|
userIds: number[];
|
|
startDate: Date;
|
|
}) {
|
|
return await this.prismaClient.host.findMany({
|
|
where: {
|
|
userId: {
|
|
in: userIds,
|
|
},
|
|
eventTypeId,
|
|
isFixed: false,
|
|
createdAt: {
|
|
gte: startDate,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
async findHostsWithLocationOptions(eventTypeId: number) {
|
|
return await this.prismaClient.host.findMany({
|
|
where: {
|
|
eventTypeId,
|
|
},
|
|
select: {
|
|
userId: true,
|
|
isFixed: true,
|
|
priority: true,
|
|
location: {
|
|
select: {
|
|
id: true,
|
|
type: true,
|
|
credentialId: true,
|
|
link: true,
|
|
address: true,
|
|
phoneNumber: true,
|
|
},
|
|
},
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
avatarUrl: true,
|
|
metadata: true,
|
|
credentials: {
|
|
where: {
|
|
app: {
|
|
categories: {
|
|
hasSome: [AppCategories.conferencing, AppCategories.video],
|
|
},
|
|
},
|
|
},
|
|
select: safeCredentialSelect,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
orderBy: [{ user: { name: "asc" } }, { priority: "desc" }],
|
|
});
|
|
}
|
|
|
|
async findHostsWithLocationOptionsPaginated({
|
|
eventTypeId,
|
|
cursor,
|
|
limit = 10,
|
|
}: {
|
|
eventTypeId: number;
|
|
cursor?: number;
|
|
limit?: number;
|
|
}) {
|
|
const hosts = await this.prismaClient.host.findMany({
|
|
where: {
|
|
eventTypeId,
|
|
...(cursor && { userId: { gt: cursor } }),
|
|
},
|
|
take: limit + 1,
|
|
select: {
|
|
userId: true,
|
|
isFixed: true,
|
|
priority: true,
|
|
location: {
|
|
select: {
|
|
id: true,
|
|
type: true,
|
|
credentialId: true,
|
|
link: true,
|
|
address: true,
|
|
phoneNumber: true,
|
|
},
|
|
},
|
|
user: {
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
avatarUrl: true,
|
|
metadata: true,
|
|
credentials: {
|
|
where: {
|
|
app: {
|
|
categories: {
|
|
hasSome: [AppCategories.conferencing, AppCategories.video],
|
|
},
|
|
},
|
|
},
|
|
select: safeCredentialSelect,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
orderBy: [{ userId: "asc" }],
|
|
});
|
|
|
|
const hasMore = hosts.length > limit;
|
|
const items = hasMore ? hosts.slice(0, -1) : hosts;
|
|
const nextCursor = hasMore ? items[items.length - 1].userId : undefined;
|
|
|
|
return { items, nextCursor, hasMore };
|
|
}
|
|
|
|
async findHostsWithConferencingCredentials(eventTypeId: number) {
|
|
return await this.prismaClient.host.findMany({
|
|
where: { eventTypeId },
|
|
select: {
|
|
userId: true,
|
|
user: {
|
|
select: {
|
|
credentials: {
|
|
where: {
|
|
app: {
|
|
categories: {
|
|
hasSome: [AppCategories.conferencing, AppCategories.video],
|
|
},
|
|
},
|
|
},
|
|
select: {
|
|
id: true,
|
|
type: true,
|
|
appId: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
}
|