Compare commits
5 Commits
main
...
perf/testi
Author | SHA1 | Date |
---|---|---|
Sean Brydon | 33f8f288e3 | |
Sean Brydon | 63b1af5e3c | |
Sean Brydon | e3fdad6f28 | |
Sean Brydon | aa498139d7 | |
Sean Brydon | 6b24acd64e |
|
@ -0,0 +1 @@
|
|||
# packages
|
|
@ -0,0 +1 @@
|
|||
# kysely
|
|
@ -0,0 +1,35 @@
|
|||
import { Kysely, PostgresDialect } from "kysely";
|
||||
import { Pool } from "pg";
|
||||
|
||||
import type { DB } from "./src/generated/types";
|
||||
|
||||
if (!process.env.DATABASE_URL) {
|
||||
throw new Error("DATABASE_URL is not defined");
|
||||
}
|
||||
|
||||
const dialect = new PostgresDialect({
|
||||
pool: new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
}),
|
||||
});
|
||||
|
||||
class Database {
|
||||
private static instance: Kysely<DB>;
|
||||
|
||||
private constructor(dialect: PostgresDialect) {
|
||||
Database.instance = new Kysely<DB>({
|
||||
dialect,
|
||||
});
|
||||
}
|
||||
|
||||
public static getInstance(): Kysely<DB> {
|
||||
if (!Database.instance) {
|
||||
console.log("Creating new database instance");
|
||||
new Database(dialect);
|
||||
}
|
||||
console.log("Reusing old db instance");
|
||||
return Database.instance;
|
||||
}
|
||||
}
|
||||
|
||||
export const db = Database.getInstance();
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "@calcom/kysely",
|
||||
"packageManager": "yarn@3.4.1",
|
||||
"dependencies": {
|
||||
"kysely": "^0.26.3",
|
||||
"pg": "^8.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/pg": "^8.10.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
export const SchedulingType = {
|
||||
ROUND_ROBIN: "roundRobin",
|
||||
COLLECTIVE: "collective",
|
||||
MANAGED: "managed",
|
||||
} as const;
|
||||
export type SchedulingType = (typeof SchedulingType)[keyof typeof SchedulingType];
|
||||
export const PeriodType = {
|
||||
UNLIMITED: "unlimited",
|
||||
ROLLING: "rolling",
|
||||
RANGE: "range",
|
||||
} as const;
|
||||
export type PeriodType = (typeof PeriodType)[keyof typeof PeriodType];
|
||||
export const IdentityProvider = {
|
||||
CAL: "CAL",
|
||||
GOOGLE: "GOOGLE",
|
||||
SAML: "SAML",
|
||||
} as const;
|
||||
export type IdentityProvider = (typeof IdentityProvider)[keyof typeof IdentityProvider];
|
||||
export const UserPermissionRole = {
|
||||
USER: "USER",
|
||||
ADMIN: "ADMIN",
|
||||
} as const;
|
||||
export type UserPermissionRole = (typeof UserPermissionRole)[keyof typeof UserPermissionRole];
|
||||
export const MembershipRole = {
|
||||
MEMBER: "MEMBER",
|
||||
ADMIN: "ADMIN",
|
||||
OWNER: "OWNER",
|
||||
} as const;
|
||||
export type MembershipRole = (typeof MembershipRole)[keyof typeof MembershipRole];
|
||||
export const BookingStatus = {
|
||||
CANCELLED: "cancelled",
|
||||
ACCEPTED: "accepted",
|
||||
REJECTED: "rejected",
|
||||
PENDING: "pending",
|
||||
} as const;
|
||||
export type BookingStatus = (typeof BookingStatus)[keyof typeof BookingStatus];
|
||||
export const EventTypeCustomInputType = {
|
||||
TEXT: "text",
|
||||
TEXTLONG: "textLong",
|
||||
NUMBER: "number",
|
||||
BOOL: "bool",
|
||||
RADIO: "radio",
|
||||
PHONE: "phone",
|
||||
} as const;
|
||||
export type EventTypeCustomInputType =
|
||||
(typeof EventTypeCustomInputType)[keyof typeof EventTypeCustomInputType];
|
||||
export const ReminderType = {
|
||||
PENDING_BOOKING_CONFIRMATION: "PENDING_BOOKING_CONFIRMATION",
|
||||
} as const;
|
||||
export type ReminderType = (typeof ReminderType)[keyof typeof ReminderType];
|
||||
export const PaymentOption = {
|
||||
ON_BOOKING: "ON_BOOKING",
|
||||
HOLD: "HOLD",
|
||||
} as const;
|
||||
export type PaymentOption = (typeof PaymentOption)[keyof typeof PaymentOption];
|
||||
export const WebhookTriggerEvents = {
|
||||
BOOKING_CREATED: "BOOKING_CREATED",
|
||||
BOOKING_PAID: "BOOKING_PAID",
|
||||
BOOKING_RESCHEDULED: "BOOKING_RESCHEDULED",
|
||||
BOOKING_REQUESTED: "BOOKING_REQUESTED",
|
||||
BOOKING_CANCELLED: "BOOKING_CANCELLED",
|
||||
BOOKING_REJECTED: "BOOKING_REJECTED",
|
||||
FORM_SUBMITTED: "FORM_SUBMITTED",
|
||||
MEETING_ENDED: "MEETING_ENDED",
|
||||
RECORDING_READY: "RECORDING_READY",
|
||||
} as const;
|
||||
export type WebhookTriggerEvents = (typeof WebhookTriggerEvents)[keyof typeof WebhookTriggerEvents];
|
||||
export const AppCategories = {
|
||||
calendar: "calendar",
|
||||
messaging: "messaging",
|
||||
other: "other",
|
||||
payment: "payment",
|
||||
video: "video",
|
||||
web3: "web3",
|
||||
automation: "automation",
|
||||
analytics: "analytics",
|
||||
conferencing: "conferencing",
|
||||
crm: "crm",
|
||||
} as const;
|
||||
export type AppCategories = (typeof AppCategories)[keyof typeof AppCategories];
|
||||
export const WorkflowTriggerEvents = {
|
||||
BEFORE_EVENT: "BEFORE_EVENT",
|
||||
EVENT_CANCELLED: "EVENT_CANCELLED",
|
||||
NEW_EVENT: "NEW_EVENT",
|
||||
AFTER_EVENT: "AFTER_EVENT",
|
||||
RESCHEDULE_EVENT: "RESCHEDULE_EVENT",
|
||||
} as const;
|
||||
export type WorkflowTriggerEvents = (typeof WorkflowTriggerEvents)[keyof typeof WorkflowTriggerEvents];
|
||||
export const WorkflowActions = {
|
||||
EMAIL_HOST: "EMAIL_HOST",
|
||||
EMAIL_ATTENDEE: "EMAIL_ATTENDEE",
|
||||
SMS_ATTENDEE: "SMS_ATTENDEE",
|
||||
SMS_NUMBER: "SMS_NUMBER",
|
||||
EMAIL_ADDRESS: "EMAIL_ADDRESS",
|
||||
WHATSAPP_ATTENDEE: "WHATSAPP_ATTENDEE",
|
||||
WHATSAPP_NUMBER: "WHATSAPP_NUMBER",
|
||||
} as const;
|
||||
export type WorkflowActions = (typeof WorkflowActions)[keyof typeof WorkflowActions];
|
||||
export const TimeUnit = {
|
||||
DAY: "day",
|
||||
HOUR: "hour",
|
||||
MINUTE: "minute",
|
||||
} as const;
|
||||
export type TimeUnit = (typeof TimeUnit)[keyof typeof TimeUnit];
|
||||
export const WorkflowTemplates = {
|
||||
REMINDER: "REMINDER",
|
||||
CUSTOM: "CUSTOM",
|
||||
CANCELLED: "CANCELLED",
|
||||
RESCHEDULED: "RESCHEDULED",
|
||||
COMPLETED: "COMPLETED",
|
||||
} as const;
|
||||
export type WorkflowTemplates = (typeof WorkflowTemplates)[keyof typeof WorkflowTemplates];
|
||||
export const WorkflowMethods = {
|
||||
EMAIL: "EMAIL",
|
||||
SMS: "SMS",
|
||||
WHATSAPP: "WHATSAPP",
|
||||
} as const;
|
||||
export type WorkflowMethods = (typeof WorkflowMethods)[keyof typeof WorkflowMethods];
|
||||
export const FeatureType = {
|
||||
RELEASE: "RELEASE",
|
||||
EXPERIMENT: "EXPERIMENT",
|
||||
OPERATIONAL: "OPERATIONAL",
|
||||
KILL_SWITCH: "KILL_SWITCH",
|
||||
PERMISSION: "PERMISSION",
|
||||
} as const;
|
||||
export type FeatureType = (typeof FeatureType)[keyof typeof FeatureType];
|
|
@ -0,0 +1,604 @@
|
|||
import type { ColumnType } from "kysely";
|
||||
|
||||
import type {
|
||||
SchedulingType,
|
||||
PeriodType,
|
||||
IdentityProvider,
|
||||
UserPermissionRole,
|
||||
MembershipRole,
|
||||
BookingStatus,
|
||||
EventTypeCustomInputType,
|
||||
ReminderType,
|
||||
PaymentOption,
|
||||
WebhookTriggerEvents,
|
||||
AppCategories,
|
||||
WorkflowTriggerEvents,
|
||||
WorkflowActions,
|
||||
TimeUnit,
|
||||
WorkflowTemplates,
|
||||
WorkflowMethods,
|
||||
FeatureType,
|
||||
} from "./enums";
|
||||
|
||||
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
|
||||
? ColumnType<S, I | undefined, U>
|
||||
: ColumnType<T, T | undefined, T>;
|
||||
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
|
||||
|
||||
export type Account = {
|
||||
id: string;
|
||||
userId: number;
|
||||
type: string;
|
||||
provider: string;
|
||||
providerAccountId: string;
|
||||
refresh_token: string | null;
|
||||
access_token: string | null;
|
||||
expires_at: number | null;
|
||||
token_type: string | null;
|
||||
scope: string | null;
|
||||
id_token: string | null;
|
||||
session_state: string | null;
|
||||
};
|
||||
export type ApiKey = {
|
||||
id: string;
|
||||
userId: number;
|
||||
teamId: number | null;
|
||||
note: string | null;
|
||||
createdAt: Generated<Timestamp>;
|
||||
expiresAt: Timestamp | null;
|
||||
lastUsedAt: Timestamp | null;
|
||||
hashedKey: string;
|
||||
appId: string | null;
|
||||
};
|
||||
export type App = {
|
||||
slug: string;
|
||||
dirName: string;
|
||||
keys: unknown | null;
|
||||
categories: AppCategories[];
|
||||
createdAt: Generated<Timestamp>;
|
||||
updatedAt: Timestamp;
|
||||
enabled: Generated<boolean>;
|
||||
};
|
||||
export type App_RoutingForms_Form = {
|
||||
id: string;
|
||||
description: string | null;
|
||||
position: Generated<number>;
|
||||
routes: unknown | null;
|
||||
createdAt: Generated<Timestamp>;
|
||||
updatedAt: Timestamp;
|
||||
name: string;
|
||||
fields: unknown | null;
|
||||
userId: number;
|
||||
teamId: number | null;
|
||||
disabled: Generated<boolean>;
|
||||
/**
|
||||
* @zod.custom(imports.RoutingFormSettings)
|
||||
*/
|
||||
settings: unknown | null;
|
||||
};
|
||||
export type App_RoutingForms_FormResponse = {
|
||||
id: Generated<number>;
|
||||
formFillerId: string;
|
||||
formId: string;
|
||||
response: unknown;
|
||||
createdAt: Generated<Timestamp>;
|
||||
};
|
||||
export type Attendee = {
|
||||
id: Generated<number>;
|
||||
email: string;
|
||||
name: string;
|
||||
timeZone: string;
|
||||
locale: Generated<string | null>;
|
||||
bookingId: number | null;
|
||||
};
|
||||
export type Availability = {
|
||||
id: Generated<number>;
|
||||
userId: number | null;
|
||||
eventTypeId: number | null;
|
||||
days: number[];
|
||||
startTime: Timestamp;
|
||||
endTime: Timestamp;
|
||||
date: Timestamp | null;
|
||||
scheduleId: number | null;
|
||||
};
|
||||
export type Booking = {
|
||||
id: Generated<number>;
|
||||
uid: string;
|
||||
userId: number | null;
|
||||
eventTypeId: number | null;
|
||||
title: string;
|
||||
description: string | null;
|
||||
customInputs: unknown | null;
|
||||
/**
|
||||
* @zod.custom(imports.bookingResponses)
|
||||
*/
|
||||
responses: unknown | null;
|
||||
startTime: Timestamp;
|
||||
endTime: Timestamp;
|
||||
location: string | null;
|
||||
createdAt: Generated<Timestamp>;
|
||||
updatedAt: Timestamp | null;
|
||||
status: Generated<BookingStatus>;
|
||||
paid: Generated<boolean>;
|
||||
destinationCalendarId: number | null;
|
||||
cancellationReason: string | null;
|
||||
rejectionReason: string | null;
|
||||
dynamicEventSlugRef: string | null;
|
||||
dynamicGroupSlugRef: string | null;
|
||||
rescheduled: boolean | null;
|
||||
fromReschedule: string | null;
|
||||
recurringEventId: string | null;
|
||||
smsReminderNumber: string | null;
|
||||
scheduledJobs: string[];
|
||||
/**
|
||||
* @zod.custom(imports.bookingMetadataSchema)
|
||||
*/
|
||||
metadata: unknown | null;
|
||||
isRecorded: Generated<boolean>;
|
||||
};
|
||||
export type BookingReference = {
|
||||
id: Generated<number>;
|
||||
/**
|
||||
* @zod.min(1)
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* @zod.min(1)
|
||||
*/
|
||||
uid: string;
|
||||
meetingId: string | null;
|
||||
meetingPassword: string | null;
|
||||
meetingUrl: string | null;
|
||||
bookingId: number | null;
|
||||
externalCalendarId: string | null;
|
||||
deleted: boolean | null;
|
||||
credentialId: number | null;
|
||||
};
|
||||
export type BookingSeat = {
|
||||
id: Generated<number>;
|
||||
referenceUid: string;
|
||||
bookingId: number;
|
||||
attendeeId: number;
|
||||
data: unknown | null;
|
||||
};
|
||||
export type BookingTimeStatus = {
|
||||
id: number;
|
||||
uid: string | null;
|
||||
eventTypeId: number | null;
|
||||
title: string | null;
|
||||
description: string | null;
|
||||
startTime: Timestamp | null;
|
||||
endTime: Timestamp | null;
|
||||
createdAt: Timestamp | null;
|
||||
location: string | null;
|
||||
paid: boolean | null;
|
||||
status: BookingStatus | null;
|
||||
rescheduled: boolean | null;
|
||||
userId: number | null;
|
||||
teamId: number | null;
|
||||
eventLength: number | null;
|
||||
timeStatus: string | null;
|
||||
eventParentId: number | null;
|
||||
};
|
||||
export type Credential = {
|
||||
id: Generated<number>;
|
||||
type: string;
|
||||
key: unknown;
|
||||
userId: number | null;
|
||||
teamId: number | null;
|
||||
appId: string | null;
|
||||
invalid: Generated<boolean | null>;
|
||||
};
|
||||
export type Deployment = {
|
||||
/**
|
||||
* This is a single row table, so we use a fixed id
|
||||
*/
|
||||
id: Generated<number>;
|
||||
logo: string | null;
|
||||
/**
|
||||
* @zod.custom(imports.DeploymentTheme)
|
||||
*/
|
||||
theme: unknown | null;
|
||||
licenseKey: string | null;
|
||||
agreedLicenseAt: Timestamp | null;
|
||||
};
|
||||
export type DestinationCalendar = {
|
||||
id: Generated<number>;
|
||||
integration: string;
|
||||
externalId: string;
|
||||
userId: number | null;
|
||||
eventTypeId: number | null;
|
||||
credentialId: number | null;
|
||||
};
|
||||
export type EventType = {
|
||||
id: Generated<number>;
|
||||
/**
|
||||
* @zod.min(1)
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* @zod.custom(imports.eventTypeSlug)
|
||||
*/
|
||||
slug: string;
|
||||
description: string | null;
|
||||
position: Generated<number>;
|
||||
/**
|
||||
* @zod.custom(imports.eventTypeLocations)
|
||||
*/
|
||||
locations: unknown | null;
|
||||
/**
|
||||
* @zod.min(1)
|
||||
*/
|
||||
length: number;
|
||||
offsetStart: Generated<number>;
|
||||
hidden: Generated<boolean>;
|
||||
userId: number | null;
|
||||
teamId: number | null;
|
||||
eventName: string | null;
|
||||
parentId: number | null;
|
||||
/**
|
||||
* @zod.custom(imports.eventTypeBookingFields)
|
||||
*/
|
||||
bookingFields: unknown | null;
|
||||
timeZone: string | null;
|
||||
periodType: Generated<PeriodType>;
|
||||
/**
|
||||
* @zod.custom(imports.coerceToDate)
|
||||
*/
|
||||
periodStartDate: Timestamp | null;
|
||||
/**
|
||||
* @zod.custom(imports.coerceToDate)
|
||||
*/
|
||||
periodEndDate: Timestamp | null;
|
||||
periodDays: number | null;
|
||||
periodCountCalendarDays: boolean | null;
|
||||
requiresConfirmation: Generated<boolean>;
|
||||
requiresBookerEmailVerification: Generated<boolean>;
|
||||
/**
|
||||
* @zod.custom(imports.recurringEventType)
|
||||
*/
|
||||
recurringEvent: unknown | null;
|
||||
disableGuests: Generated<boolean>;
|
||||
hideCalendarNotes: Generated<boolean>;
|
||||
/**
|
||||
* @zod.min(0)
|
||||
*/
|
||||
minimumBookingNotice: Generated<number>;
|
||||
beforeEventBuffer: Generated<number>;
|
||||
afterEventBuffer: Generated<number>;
|
||||
seatsPerTimeSlot: number | null;
|
||||
seatsShowAttendees: Generated<boolean | null>;
|
||||
seatsShowAvailabilityCount: Generated<boolean | null>;
|
||||
schedulingType: SchedulingType | null;
|
||||
scheduleId: number | null;
|
||||
price: Generated<number>;
|
||||
currency: Generated<string>;
|
||||
slotInterval: number | null;
|
||||
/**
|
||||
* @zod.custom(imports.EventTypeMetaDataSchema)
|
||||
*/
|
||||
metadata: unknown | null;
|
||||
/**
|
||||
* @zod.custom(imports.successRedirectUrl)
|
||||
*/
|
||||
successRedirectUrl: string | null;
|
||||
/**
|
||||
* @zod.custom(imports.intervalLimitsType)
|
||||
*/
|
||||
bookingLimits: unknown | null;
|
||||
/**
|
||||
* @zod.custom(imports.intervalLimitsType)
|
||||
*/
|
||||
durationLimits: unknown | null;
|
||||
};
|
||||
export type EventTypeCustomInput = {
|
||||
id: Generated<number>;
|
||||
eventTypeId: number;
|
||||
label: string;
|
||||
type: EventTypeCustomInputType;
|
||||
/**
|
||||
* @zod.custom(imports.customInputOptionSchema)
|
||||
*/
|
||||
options: unknown | null;
|
||||
required: boolean;
|
||||
placeholder: Generated<string>;
|
||||
};
|
||||
export type Feature = {
|
||||
slug: string;
|
||||
enabled: Generated<boolean>;
|
||||
description: string | null;
|
||||
type: Generated<FeatureType | null>;
|
||||
stale: Generated<boolean | null>;
|
||||
lastUsedAt: Timestamp | null;
|
||||
createdAt: Generated<Timestamp | null>;
|
||||
updatedAt: Generated<Timestamp | null>;
|
||||
updatedBy: number | null;
|
||||
};
|
||||
export type Feedback = {
|
||||
id: Generated<number>;
|
||||
date: Generated<Timestamp>;
|
||||
userId: number;
|
||||
rating: string;
|
||||
comment: string | null;
|
||||
};
|
||||
export type HashedLink = {
|
||||
id: Generated<number>;
|
||||
link: string;
|
||||
eventTypeId: number;
|
||||
};
|
||||
export type Host = {
|
||||
userId: number;
|
||||
eventTypeId: number;
|
||||
isFixed: Generated<boolean>;
|
||||
};
|
||||
export type Impersonations = {
|
||||
id: Generated<number>;
|
||||
createdAt: Generated<Timestamp>;
|
||||
impersonatedUserId: number;
|
||||
impersonatedById: number;
|
||||
};
|
||||
export type Membership = {
|
||||
id: Generated<number>;
|
||||
teamId: number;
|
||||
userId: number;
|
||||
accepted: Generated<boolean>;
|
||||
role: MembershipRole;
|
||||
disableImpersonation: Generated<boolean>;
|
||||
};
|
||||
export type Payment = {
|
||||
id: Generated<number>;
|
||||
uid: string;
|
||||
appId: string | null;
|
||||
bookingId: number;
|
||||
amount: number;
|
||||
fee: number;
|
||||
currency: string;
|
||||
success: boolean;
|
||||
refunded: boolean;
|
||||
data: unknown;
|
||||
externalId: string;
|
||||
paymentOption: Generated<PaymentOption | null>;
|
||||
};
|
||||
export type ReminderMail = {
|
||||
id: Generated<number>;
|
||||
referenceId: number;
|
||||
reminderType: ReminderType;
|
||||
elapsedMinutes: number;
|
||||
createdAt: Generated<Timestamp>;
|
||||
};
|
||||
export type ResetPasswordRequest = {
|
||||
id: string;
|
||||
createdAt: Generated<Timestamp>;
|
||||
updatedAt: Timestamp;
|
||||
email: string;
|
||||
expires: Timestamp;
|
||||
};
|
||||
export type Schedule = {
|
||||
id: Generated<number>;
|
||||
userId: number;
|
||||
name: string;
|
||||
timeZone: string | null;
|
||||
};
|
||||
export type SelectedCalendar = {
|
||||
userId: number;
|
||||
integration: string;
|
||||
externalId: string;
|
||||
};
|
||||
export type SelectedSlots = {
|
||||
id: Generated<number>;
|
||||
eventTypeId: number;
|
||||
userId: number;
|
||||
slotUtcStartDate: Timestamp;
|
||||
slotUtcEndDate: Timestamp;
|
||||
uid: string;
|
||||
releaseAt: Timestamp;
|
||||
isSeat: Generated<boolean>;
|
||||
};
|
||||
export type Session = {
|
||||
id: string;
|
||||
sessionToken: string;
|
||||
userId: number;
|
||||
expires: Timestamp;
|
||||
};
|
||||
export type Team = {
|
||||
id: Generated<number>;
|
||||
/**
|
||||
* @zod.min(1)
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* @zod.min(1)
|
||||
*/
|
||||
slug: string | null;
|
||||
logo: string | null;
|
||||
appLogo: string | null;
|
||||
appIconLogo: string | null;
|
||||
bio: string | null;
|
||||
hideBranding: Generated<boolean>;
|
||||
isPrivate: Generated<boolean>;
|
||||
hideBookATeamMember: Generated<boolean>;
|
||||
createdAt: Generated<Timestamp>;
|
||||
/**
|
||||
* @zod.custom(imports.teamMetadataSchema)
|
||||
*/
|
||||
metadata: unknown | null;
|
||||
theme: string | null;
|
||||
brandColor: Generated<string>;
|
||||
darkBrandColor: Generated<string>;
|
||||
parentId: number | null;
|
||||
timeFormat: number | null;
|
||||
timeZone: Generated<string>;
|
||||
weekStart: Generated<string>;
|
||||
};
|
||||
export type User = {
|
||||
id: Generated<number>;
|
||||
username: string | null;
|
||||
name: string | null;
|
||||
/**
|
||||
* @zod.email()
|
||||
*/
|
||||
email: string;
|
||||
emailVerified: Timestamp | null;
|
||||
password: string | null;
|
||||
bio: string | null;
|
||||
avatar: string | null;
|
||||
timeZone: Generated<string>;
|
||||
weekStart: Generated<string>;
|
||||
startTime: Generated<number>;
|
||||
endTime: Generated<number>;
|
||||
bufferTime: Generated<number>;
|
||||
hideBranding: Generated<boolean>;
|
||||
theme: string | null;
|
||||
created: Generated<Timestamp>;
|
||||
trialEndsAt: Timestamp | null;
|
||||
defaultScheduleId: number | null;
|
||||
completedOnboarding: Generated<boolean>;
|
||||
locale: string | null;
|
||||
timeFormat: Generated<number | null>;
|
||||
twoFactorSecret: string | null;
|
||||
twoFactorEnabled: Generated<boolean>;
|
||||
backupCodes: string | null;
|
||||
identityProvider: Generated<IdentityProvider>;
|
||||
identityProviderId: string | null;
|
||||
invitedTo: number | null;
|
||||
brandColor: Generated<string>;
|
||||
darkBrandColor: Generated<string>;
|
||||
away: Generated<boolean>;
|
||||
allowDynamicBooking: Generated<boolean | null>;
|
||||
allowSEOIndexing: Generated<boolean | null>;
|
||||
/**
|
||||
* @zod.custom(imports.userMetadata)
|
||||
*/
|
||||
metadata: unknown | null;
|
||||
verified: Generated<boolean | null>;
|
||||
role: Generated<UserPermissionRole>;
|
||||
disableImpersonation: Generated<boolean>;
|
||||
organizationId: number | null;
|
||||
};
|
||||
export type user_eventtype = {
|
||||
A: number;
|
||||
B: number;
|
||||
};
|
||||
export type VerificationToken = {
|
||||
id: Generated<number>;
|
||||
identifier: string;
|
||||
token: string;
|
||||
expires: Timestamp;
|
||||
expiresInDays: number | null;
|
||||
createdAt: Generated<Timestamp>;
|
||||
updatedAt: Timestamp;
|
||||
teamId: number | null;
|
||||
};
|
||||
export type VerifiedNumber = {
|
||||
id: Generated<number>;
|
||||
userId: number | null;
|
||||
teamId: number | null;
|
||||
phoneNumber: string;
|
||||
};
|
||||
export type Webhook = {
|
||||
id: string;
|
||||
userId: number | null;
|
||||
teamId: number | null;
|
||||
eventTypeId: number | null;
|
||||
/**
|
||||
* @zod.url()
|
||||
*/
|
||||
subscriberUrl: string;
|
||||
payloadTemplate: string | null;
|
||||
createdAt: Generated<Timestamp>;
|
||||
active: Generated<boolean>;
|
||||
eventTriggers: WebhookTriggerEvents[];
|
||||
appId: string | null;
|
||||
secret: string | null;
|
||||
};
|
||||
export type WebhookScheduledTriggers = {
|
||||
id: Generated<number>;
|
||||
jobName: string;
|
||||
subscriberUrl: string;
|
||||
payload: string;
|
||||
startAfter: Timestamp;
|
||||
retryCount: Generated<number>;
|
||||
createdAt: Generated<Timestamp | null>;
|
||||
};
|
||||
export type Workflow = {
|
||||
id: Generated<number>;
|
||||
position: Generated<number>;
|
||||
name: string;
|
||||
userId: number | null;
|
||||
teamId: number | null;
|
||||
trigger: WorkflowTriggerEvents;
|
||||
time: number | null;
|
||||
timeUnit: TimeUnit | null;
|
||||
};
|
||||
export type WorkflowReminder = {
|
||||
id: Generated<number>;
|
||||
bookingUid: string | null;
|
||||
method: WorkflowMethods;
|
||||
scheduledDate: Timestamp;
|
||||
referenceId: string | null;
|
||||
scheduled: boolean;
|
||||
workflowStepId: number | null;
|
||||
cancelled: boolean | null;
|
||||
seatReferenceId: string | null;
|
||||
};
|
||||
export type WorkflowsOnEventTypes = {
|
||||
id: Generated<number>;
|
||||
workflowId: number;
|
||||
eventTypeId: number;
|
||||
};
|
||||
export type WorkflowStep = {
|
||||
id: Generated<number>;
|
||||
stepNumber: number;
|
||||
action: WorkflowActions;
|
||||
workflowId: number;
|
||||
sendTo: string | null;
|
||||
reminderBody: string | null;
|
||||
emailSubject: string | null;
|
||||
template: Generated<WorkflowTemplates>;
|
||||
numberRequired: boolean | null;
|
||||
sender: string | null;
|
||||
numberVerificationPending: Generated<boolean>;
|
||||
includeCalendarEvent: Generated<boolean>;
|
||||
};
|
||||
export type DB = {
|
||||
_user_eventtype: user_eventtype;
|
||||
Account: Account;
|
||||
ApiKey: ApiKey;
|
||||
App: App;
|
||||
App_RoutingForms_Form: App_RoutingForms_Form;
|
||||
App_RoutingForms_FormResponse: App_RoutingForms_FormResponse;
|
||||
Attendee: Attendee;
|
||||
Availability: Availability;
|
||||
Booking: Booking;
|
||||
BookingReference: BookingReference;
|
||||
BookingSeat: BookingSeat;
|
||||
BookingTimeStatus: BookingTimeStatus;
|
||||
Credential: Credential;
|
||||
Deployment: Deployment;
|
||||
DestinationCalendar: DestinationCalendar;
|
||||
EventType: EventType;
|
||||
EventTypeCustomInput: EventTypeCustomInput;
|
||||
Feature: Feature;
|
||||
Feedback: Feedback;
|
||||
HashedLink: HashedLink;
|
||||
Host: Host;
|
||||
Impersonations: Impersonations;
|
||||
Membership: Membership;
|
||||
Payment: Payment;
|
||||
ReminderMail: ReminderMail;
|
||||
ResetPasswordRequest: ResetPasswordRequest;
|
||||
Schedule: Schedule;
|
||||
SelectedCalendar: SelectedCalendar;
|
||||
SelectedSlots: SelectedSlots;
|
||||
Session: Session;
|
||||
Team: Team;
|
||||
users: User;
|
||||
VerificationToken: VerificationToken;
|
||||
VerifiedNumber: VerifiedNumber;
|
||||
Webhook: Webhook;
|
||||
WebhookScheduledTriggers: WebhookScheduledTriggers;
|
||||
Workflow: Workflow;
|
||||
WorkflowReminder: WorkflowReminder;
|
||||
WorkflowsOnEventTypes: WorkflowsOnEventTypes;
|
||||
WorkflowStep: WorkflowStep;
|
||||
};
|
|
@ -27,6 +27,7 @@
|
|||
"@prisma/client": "^5.0.0",
|
||||
"@prisma/generator-helper": "^5.0.0",
|
||||
"prisma": "^5.0.0",
|
||||
"prisma-kysely": "^1.7.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"zod": "^3.22.2",
|
||||
"zod-prisma": "^0.5.4"
|
||||
|
|
|
@ -22,6 +22,13 @@ generator enums {
|
|||
provider = "ts-node --transpile-only ./enum-generator"
|
||||
}
|
||||
|
||||
generator kysely {
|
||||
provider = "prisma-kysely"
|
||||
output = "../kysely/src/generated"
|
||||
fileName = "types.ts"
|
||||
enumFileName = "enums.ts"
|
||||
}
|
||||
|
||||
enum SchedulingType {
|
||||
ROUND_ROBIN @map("roundRobin")
|
||||
COLLECTIVE @map("collective")
|
||||
|
|
|
@ -8,6 +8,7 @@ import { getUserAvailability } from "@calcom/core/getUserAvailability";
|
|||
import type { Dayjs } from "@calcom/dayjs";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { getSlugOrRequestedSlug, orgDomainConfig } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import { db } from "@calcom/kysely";
|
||||
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
|
||||
import isTimeOutOfBounds from "@calcom/lib/isOutOfBounds";
|
||||
import logger from "@calcom/lib/logger";
|
||||
|
@ -85,8 +86,8 @@ async function getEventTypeId({
|
|||
}) {
|
||||
if (!eventTypeSlug || !slug) return null;
|
||||
|
||||
let teamId;
|
||||
let userId;
|
||||
let teamId: number | undefined;
|
||||
let userId: number | undefined;
|
||||
if (isTeamEvent) {
|
||||
teamId = await getTeamIdFromSlug(
|
||||
slug,
|
||||
|
@ -98,16 +99,15 @@ async function getEventTypeId({
|
|||
organizationDetails ?? { currentOrgDomain: null, isValidOrgDomain: false }
|
||||
);
|
||||
}
|
||||
const eventType = await prisma.eventType.findFirst({
|
||||
where: {
|
||||
slug: eventTypeSlug,
|
||||
...(teamId ? { teamId } : {}),
|
||||
...(userId ? { userId } : {}),
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
console.time("getEventTypeId");
|
||||
const eventType = await db
|
||||
.selectFrom("EventType")
|
||||
.select("id")
|
||||
.$if(!!teamId, (qb) => qb.where("EventType.teamId", "=", teamId as number))
|
||||
.$if(!!userId, (qb) => qb.where("EventType.userId", "=", userId as number))
|
||||
.executeTakeFirst();
|
||||
console.timeEnd("getEventTypeId");
|
||||
|
||||
if (!eventType) {
|
||||
throw new TRPCError({ code: "NOT_FOUND" });
|
||||
}
|
||||
|
@ -133,6 +133,33 @@ export async function getEventType(
|
|||
return null;
|
||||
}
|
||||
|
||||
console.time("getEventType");
|
||||
const eventTypeTwo = await db
|
||||
.selectFrom("EventType")
|
||||
.where("EventType.id", "=", eventTypeId)
|
||||
.select([
|
||||
"id",
|
||||
"slug",
|
||||
"minimumBookingNotice",
|
||||
"length",
|
||||
"offsetStart",
|
||||
"seatsPerTimeSlot",
|
||||
"timeZone",
|
||||
"slotInterval",
|
||||
"beforeEventBuffer",
|
||||
"afterEventBuffer",
|
||||
"bookingLimits",
|
||||
"durationLimits",
|
||||
"schedulingType",
|
||||
"periodType",
|
||||
"periodStartDate",
|
||||
"periodEndDate",
|
||||
"periodCountCalendarDays",
|
||||
"periodDays",
|
||||
"metadata",
|
||||
])
|
||||
.executeTakeFirst();
|
||||
|
||||
const eventType = await prisma.eventType.findUnique({
|
||||
where: {
|
||||
id: eventTypeId,
|
||||
|
@ -193,6 +220,7 @@ export async function getEventType(
|
|||
if (!eventType) {
|
||||
return null;
|
||||
}
|
||||
console.timeEnd("getEventType");
|
||||
|
||||
return {
|
||||
...eventType,
|
||||
|
@ -533,14 +561,31 @@ async function getTeamIdFromSlug(
|
|||
organizationDetails: { currentOrgDomain: string | null; isValidOrgDomain: boolean }
|
||||
) {
|
||||
const { currentOrgDomain, isValidOrgDomain } = organizationDetails;
|
||||
const team = await prisma.team.findFirst({
|
||||
where: {
|
||||
slug,
|
||||
parent: isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: handle orgs
|
||||
const parentId = isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null;
|
||||
const team = await db
|
||||
.selectFrom("Team")
|
||||
.select("id")
|
||||
.where(({ and, eb }) =>
|
||||
and([
|
||||
eb("slug", "=", slug),
|
||||
// eb(
|
||||
// "parentId",
|
||||
// "=",
|
||||
// isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null
|
||||
// ),
|
||||
])
|
||||
)
|
||||
.executeTakeFirst();
|
||||
// const team = await prisma.team.findFirst({
|
||||
// where: {
|
||||
// slug,
|
||||
// parent: isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null,
|
||||
// },
|
||||
// select: {
|
||||
// id: true,
|
||||
// },
|
||||
// });
|
||||
return team?.id;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue