diff --git a/apps/backend/prisma/complex.prisma b/apps/backend/prisma/complex.prisma index cb9a087..ba454b3 100644 --- a/apps/backend/prisma/complex.prisma +++ b/apps/backend/prisma/complex.prisma @@ -14,6 +14,7 @@ model Complex { users ComplexUser[] invitations ComplexInvitation[] courts Court[] + recurringGroups RecurringBookingGroup[] @@index([planCode]) @@index([complexSlug]) diff --git a/apps/backend/prisma/court.prisma b/apps/backend/prisma/court.prisma index 4dbe350..f9c33aa 100644 --- a/apps/backend/prisma/court.prisma +++ b/apps/backend/prisma/court.prisma @@ -15,6 +15,11 @@ enum CourtBookingStatus { NOSHOW } +enum RecurringBookingGroupStatus { + ACTIVE + CANCELLED +} + model Sport { id String @id @db.Uuid name String @unique @@ -44,6 +49,7 @@ model Court { priceRules CourtPriceRule[] bookings CourtBooking[] maintenances CourtMaintenance[] + recurringGroups RecurringBookingGroup[] @@index([complexId]) @@index([sportId]) @@ -95,23 +101,26 @@ model CourtPriceRule { } model CourtBooking { - id String @id @db.Uuid - bookingCode String @unique @map("booking_code") @db.VarChar(8) - courtId String @map("court_id") @db.Uuid - bookingDate DateTime @map("booking_date") @db.Date - startTime String @map("start_time") @db.VarChar(5) - endTime String @map("end_time") @db.VarChar(5) - customerName String @map("customer_name") @db.VarChar(120) - customerPhone String @map("customer_phone") @db.VarChar(30) - customerEmail String @map("customer_email") @db.VarChar(254) - status CourtBookingStatus @default(CONFIRMED) - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - court Court @relation(fields: [courtId], references: [id], onDelete: Cascade) + id String @id @db.Uuid + bookingCode String @unique @map("booking_code") @db.VarChar(8) + courtId String @map("court_id") @db.Uuid + bookingDate DateTime @map("booking_date") @db.Date + startTime String @map("start_time") @db.VarChar(5) + endTime String @map("end_time") @db.VarChar(5) + customerName String @map("customer_name") @db.VarChar(120) + customerPhone String @map("customer_phone") @db.VarChar(30) + customerEmail String @map("customer_email") @db.VarChar(254) + status CourtBookingStatus @default(CONFIRMED) + recurringGroupId String? @map("recurring_group_id") @db.Uuid + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + court Court @relation(fields: [courtId], references: [id], onDelete: Cascade) + recurringGroup RecurringBookingGroup? @relation(fields: [recurringGroupId], references: [id]) @@unique([courtId, bookingDate, startTime]) @@index([courtId, bookingDate]) @@index([bookingDate]) + @@index([recurringGroupId]) @@map("court_bookings") } @@ -132,3 +141,28 @@ model CourtBookingLog { @@map("court_booking_logs") @@index([courtId, newStatus]) } + +model RecurringBookingGroup { + id String @id @db.Uuid + complexId String @map("complex_id") @db.Uuid + courtId String @map("court_id") @db.Uuid + startTime String @map("start_time") @db.VarChar(5) + endTime String @map("end_time") @db.VarChar(5) + dayOfWeek DayOfWeek @map("day_of_week") + startDate DateTime @map("start_date") @db.Date + endDate DateTime? @map("end_date") @db.Date + status RecurringBookingGroupStatus @default(ACTIVE) + customerName String @map("customer_name") @db.VarChar(120) + customerPhone String @map("customer_phone") @db.VarChar(30) + customerEmail String @map("customer_email") @db.VarChar(254) + createdAt DateTime @default(now()) @map("created_at") + updatedAt DateTime @updatedAt @map("updated_at") + court Court @relation(fields: [courtId], references: [id], onDelete: Cascade) + complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade) + bookings CourtBooking[] + + @@index([complexId]) + @@index([courtId]) + @@index([status]) + @@map("recurring_booking_groups") +} diff --git a/apps/backend/prisma/migrations/20260616140153_add_recurring_bookings/migration.sql b/apps/backend/prisma/migrations/20260616140153_add_recurring_bookings/migration.sql new file mode 100644 index 0000000..6362e8d --- /dev/null +++ b/apps/backend/prisma/migrations/20260616140153_add_recurring_bookings/migration.sql @@ -0,0 +1,46 @@ +-- CreateEnum +CREATE TYPE "RecurringBookingGroupStatus" AS ENUM ('ACTIVE', 'CANCELLED'); + +-- AlterTable +ALTER TABLE "court_bookings" ADD COLUMN "recurring_group_id" UUID; + +-- CreateTable +CREATE TABLE "recurring_booking_groups" ( + "id" UUID NOT NULL, + "complex_id" UUID NOT NULL, + "court_id" UUID NOT NULL, + "start_time" VARCHAR(5) NOT NULL, + "end_time" VARCHAR(5) NOT NULL, + "day_of_week" "DayOfWeek" NOT NULL, + "start_date" DATE NOT NULL, + "end_date" DATE, + "status" "RecurringBookingGroupStatus" NOT NULL DEFAULT 'ACTIVE', + "customer_name" VARCHAR(120) NOT NULL, + "customer_phone" VARCHAR(30) NOT NULL, + "customer_email" VARCHAR(254) NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "recurring_booking_groups_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "recurring_booking_groups_complex_id_idx" ON "recurring_booking_groups"("complex_id"); + +-- CreateIndex +CREATE INDEX "recurring_booking_groups_court_id_idx" ON "recurring_booking_groups"("court_id"); + +-- CreateIndex +CREATE INDEX "recurring_booking_groups_status_idx" ON "recurring_booking_groups"("status"); + +-- CreateIndex +CREATE INDEX "court_bookings_recurring_group_id_idx" ON "court_bookings"("recurring_group_id"); + +-- AddForeignKey +ALTER TABLE "court_bookings" ADD CONSTRAINT "court_bookings_recurring_group_id_fkey" FOREIGN KEY ("recurring_group_id") REFERENCES "recurring_booking_groups"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "recurring_booking_groups" ADD CONSTRAINT "recurring_booking_groups_court_id_fkey" FOREIGN KEY ("court_id") REFERENCES "courts"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "recurring_booking_groups" ADD CONSTRAINT "recurring_booking_groups_complex_id_fkey" FOREIGN KEY ("complex_id") REFERENCES "complexes"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/apps/backend/prisma/plans.seed-data.ts b/apps/backend/prisma/plans.seed-data.ts index 242bf38..745c65d 100644 --- a/apps/backend/prisma/plans.seed-data.ts +++ b/apps/backend/prisma/plans.seed-data.ts @@ -21,6 +21,7 @@ export const planSeeds = [ publicBookingPage: true, advancedReports: false, whatsappReminders: false, + fixedSlots: false, }, pricing: { overrides: { @@ -51,6 +52,7 @@ export const planSeeds = [ publicBookingPage: true, advancedReports: true, whatsappReminders: true, + fixedSlots: true, }, pricing: { overrides: { @@ -81,6 +83,7 @@ export const planSeeds = [ publicBookingPage: true, advancedReports: true, whatsappReminders: true, + fixedSlots: true, }, pricing: { overrides: { diff --git a/apps/backend/src/generated/prisma/browser.ts b/apps/backend/src/generated/prisma/browser.ts index 5e1069b..e5ac584 100644 --- a/apps/backend/src/generated/prisma/browser.ts +++ b/apps/backend/src/generated/prisma/browser.ts @@ -87,6 +87,11 @@ export type CourtBooking = Prisma.CourtBookingModel * */ export type CourtBookingLog = Prisma.CourtBookingLogModel +/** + * Model RecurringBookingGroup + * + */ +export type RecurringBookingGroup = Prisma.RecurringBookingGroupModel /** * Model PasswordResetRequest * diff --git a/apps/backend/src/generated/prisma/client.ts b/apps/backend/src/generated/prisma/client.ts index 8577f9a..52733da 100644 --- a/apps/backend/src/generated/prisma/client.ts +++ b/apps/backend/src/generated/prisma/client.ts @@ -111,6 +111,11 @@ export type CourtBooking = Prisma.CourtBookingModel * */ export type CourtBookingLog = Prisma.CourtBookingLogModel +/** + * Model RecurringBookingGroup + * + */ +export type RecurringBookingGroup = Prisma.RecurringBookingGroupModel /** * Model PasswordResetRequest * diff --git a/apps/backend/src/generated/prisma/commonInputTypes.ts b/apps/backend/src/generated/prisma/commonInputTypes.ts index fc8670d..6289eb5 100644 --- a/apps/backend/src/generated/prisma/commonInputTypes.ts +++ b/apps/backend/src/generated/prisma/commonInputTypes.ts @@ -314,6 +314,18 @@ export type EnumCourtBookingStatusFilter<$PrismaModel = never> = { not?: Prisma.NestedEnumCourtBookingStatusFilter<$PrismaModel> | $Enums.CourtBookingStatus } +export type UuidNullableFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + mode?: Prisma.QueryMode + not?: Prisma.NestedUuidNullableFilter<$PrismaModel> | string | null +} + export type EnumCourtBookingStatusWithAggregatesFilter<$PrismaModel = never> = { equals?: $Enums.CourtBookingStatus | Prisma.EnumCourtBookingStatusFieldRefInput<$PrismaModel> in?: $Enums.CourtBookingStatus[] | Prisma.ListEnumCourtBookingStatusFieldRefInput<$PrismaModel> @@ -324,6 +336,38 @@ export type EnumCourtBookingStatusWithAggregatesFilter<$PrismaModel = never> = { _max?: Prisma.NestedEnumCourtBookingStatusFilter<$PrismaModel> } +export type UuidNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + mode?: Prisma.QueryMode + not?: Prisma.NestedUuidNullableWithAggregatesFilter<$PrismaModel> | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedStringNullableFilter<$PrismaModel> + _max?: Prisma.NestedStringNullableFilter<$PrismaModel> +} + +export type EnumRecurringBookingGroupStatusFilter<$PrismaModel = never> = { + equals?: $Enums.RecurringBookingGroupStatus | Prisma.EnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + in?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel> | $Enums.RecurringBookingGroupStatus +} + +export type EnumRecurringBookingGroupStatusWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.RecurringBookingGroupStatus | Prisma.EnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + in?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumRecurringBookingGroupStatusWithAggregatesFilter<$PrismaModel> | $Enums.RecurringBookingGroupStatus + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel> + _max?: Prisma.NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel> +} + export type JsonFilter<$PrismaModel = never> = | Prisma.PatchUndefined< Prisma.Either>, Exclude>, 'path'>>, @@ -686,6 +730,17 @@ export type NestedEnumCourtBookingStatusFilter<$PrismaModel = never> = { not?: Prisma.NestedEnumCourtBookingStatusFilter<$PrismaModel> | $Enums.CourtBookingStatus } +export type NestedUuidNullableFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + not?: Prisma.NestedUuidNullableFilter<$PrismaModel> | string | null +} + export type NestedEnumCourtBookingStatusWithAggregatesFilter<$PrismaModel = never> = { equals?: $Enums.CourtBookingStatus | Prisma.EnumCourtBookingStatusFieldRefInput<$PrismaModel> in?: $Enums.CourtBookingStatus[] | Prisma.ListEnumCourtBookingStatusFieldRefInput<$PrismaModel> @@ -696,6 +751,37 @@ export type NestedEnumCourtBookingStatusWithAggregatesFilter<$PrismaModel = neve _max?: Prisma.NestedEnumCourtBookingStatusFilter<$PrismaModel> } +export type NestedUuidNullableWithAggregatesFilter<$PrismaModel = never> = { + equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null + in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null + lt?: string | Prisma.StringFieldRefInput<$PrismaModel> + lte?: string | Prisma.StringFieldRefInput<$PrismaModel> + gt?: string | Prisma.StringFieldRefInput<$PrismaModel> + gte?: string | Prisma.StringFieldRefInput<$PrismaModel> + not?: Prisma.NestedUuidNullableWithAggregatesFilter<$PrismaModel> | string | null + _count?: Prisma.NestedIntNullableFilter<$PrismaModel> + _min?: Prisma.NestedStringNullableFilter<$PrismaModel> + _max?: Prisma.NestedStringNullableFilter<$PrismaModel> +} + +export type NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel = never> = { + equals?: $Enums.RecurringBookingGroupStatus | Prisma.EnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + in?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel> | $Enums.RecurringBookingGroupStatus +} + +export type NestedEnumRecurringBookingGroupStatusWithAggregatesFilter<$PrismaModel = never> = { + equals?: $Enums.RecurringBookingGroupStatus | Prisma.EnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + in?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + notIn?: $Enums.RecurringBookingGroupStatus[] | Prisma.ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> + not?: Prisma.NestedEnumRecurringBookingGroupStatusWithAggregatesFilter<$PrismaModel> | $Enums.RecurringBookingGroupStatus + _count?: Prisma.NestedIntFilter<$PrismaModel> + _min?: Prisma.NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel> + _max?: Prisma.NestedEnumRecurringBookingGroupStatusFilter<$PrismaModel> +} + export type NestedJsonFilter<$PrismaModel = never> = | Prisma.PatchUndefined< Prisma.Either>, Exclude>, 'path'>>, diff --git a/apps/backend/src/generated/prisma/enums.ts b/apps/backend/src/generated/prisma/enums.ts index b4c3c21..2045cb1 100644 --- a/apps/backend/src/generated/prisma/enums.ts +++ b/apps/backend/src/generated/prisma/enums.ts @@ -38,3 +38,11 @@ export const CourtBookingStatus = { } as const export type CourtBookingStatus = (typeof CourtBookingStatus)[keyof typeof CourtBookingStatus] + + +export const RecurringBookingGroupStatus = { + ACTIVE: 'ACTIVE', + CANCELLED: 'CANCELLED' +} as const + +export type RecurringBookingGroupStatus = (typeof RecurringBookingGroupStatus)[keyof typeof RecurringBookingGroupStatus] diff --git a/apps/backend/src/generated/prisma/internal/class.ts b/apps/backend/src/generated/prisma/internal/class.ts index b7c41c4..093d314 100644 --- a/apps/backend/src/generated/prisma/internal/class.ts +++ b/apps/backend/src/generated/prisma/internal/class.ts @@ -20,7 +20,7 @@ const config: runtime.GetPrismaClientConfig = { "clientVersion": "7.6.0", "engineVersion": "75cbdc1eb7150937890ad5465d861175c6624711", "activeProvider": "postgresql", - "inlineSchema": "model User {\n id String @id\n name String\n email String\n emailVerified Boolean @default(false)\n image String?\n phone String?\n banned Boolean @default(false)\n bannedAt DateTime?\n banReason String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n accounts Account[]\n role String @default(\"member\")\n complexes ComplexUser[]\n\n @@unique([email])\n @@map(\"users\")\n}\n\nmodel Session {\n id String @id\n expiresAt DateTime\n token String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n ipAddress String?\n userAgent String?\n country String?\n city String?\n countryCode String?\n latitude Float?\n longitude Float?\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([token])\n @@index([userId])\n @@map(\"sessions\")\n}\n\nmodel Account {\n id String @id\n accountId String\n providerId String\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n accessToken String?\n refreshToken String?\n idToken String?\n accessTokenExpiresAt DateTime?\n refreshTokenExpiresAt DateTime?\n scope String?\n password String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@map(\"accounts\")\n}\n\nmodel Verification {\n id String @id\n identifier String\n value String\n expiresAt DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([identifier])\n @@map(\"verification\")\n}\n\nmodel Complex {\n id String @id @db.Uuid\n complexName String @map(\"complex_name\")\n physicalAddress String? @map(\"physical_address\") @db.VarChar(200)\n city String? @map(\"city\") @db.VarChar(100)\n state String? @map(\"state\") @db.VarChar(100)\n country String? @map(\"country\") @db.VarChar(100)\n complexSlug String @unique @map(\"complex_slug\")\n adminEmail String @map(\"admin_email\")\n planCode String? @map(\"plan_code\") @db.VarChar(10)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n plan Plan? @relation(fields: [planCode], references: [code])\n users ComplexUser[]\n invitations ComplexInvitation[]\n courts Court[]\n\n @@index([planCode])\n @@index([complexSlug])\n @@map(\"complexes\")\n}\n\nenum ComplexUserRole {\n ADMIN\n EMPLOYEE\n}\n\nmodel ComplexUser {\n complexId String @map(\"complex_id\") @db.Uuid\n userId String @map(\"user_id\")\n role ComplexUserRole @default(ADMIN)\n createdAt DateTime @default(now()) @map(\"created_at\")\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@id([complexId, userId])\n @@index([userId])\n @@map(\"complex_users\")\n}\n\nmodel ComplexInvitation {\n id String @id @db.Uuid\n complexId String @map(\"complex_id\") @db.Uuid\n email String @db.VarChar(255)\n tokenHash String @unique @map(\"token_hash\")\n expiresAt DateTime @map(\"expires_at\")\n acceptedAt DateTime? @map(\"accepted_at\")\n revokedAt DateTime? @map(\"revoked_at\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n\n @@index([complexId, email])\n @@index([email])\n @@map(\"complex_invitations\")\n}\n\nenum DayOfWeek {\n MONDAY\n TUESDAY\n WEDNESDAY\n THURSDAY\n FRIDAY\n SATURDAY\n SUNDAY\n}\n\nenum CourtBookingStatus {\n CONFIRMED\n CANCELLED\n COMPLETED\n NOSHOW\n}\n\nmodel Sport {\n id String @id @db.Uuid\n name String @unique\n slug String @unique\n isActive Boolean @default(true) @map(\"is_active\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n courts Court[]\n\n @@map(\"sports\")\n}\n\nmodel Court {\n id String @id @db.Uuid\n complexId String @map(\"complex_id\") @db.Uuid\n sportId String @map(\"sport_id\") @db.Uuid\n name String\n slotDurationMinutes Int @map(\"slot_duration_minutes\")\n basePrice Decimal @map(\"base_price\") @db.Decimal(19, 2)\n isUnderMaintenance Boolean @default(false) @map(\"is_under_maintenance\")\n maintenanceReason String? @map(\"maintenance_reason\") @db.VarChar(500)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n sport Sport @relation(fields: [sportId], references: [id])\n availabilities CourtAvailability[]\n priceRules CourtPriceRule[]\n bookings CourtBooking[]\n maintenances CourtMaintenance[]\n\n @@index([complexId])\n @@index([sportId])\n @@map(\"courts\")\n}\n\nmodel CourtMaintenance {\n id String @id @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n startDate DateTime @map(\"start_date\") @db.Date\n startTime String? @map(\"start_time\") @db.VarChar(5)\n endTime String? @map(\"end_time\") @db.VarChar(5)\n reason String? @db.VarChar(500)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@index([courtId, startDate])\n @@map(\"court_maintenances\")\n}\n\nmodel CourtAvailability {\n id String @id @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n dayOfWeek DayOfWeek @map(\"day_of_week\")\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n createdAt DateTime @default(now()) @map(\"created_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@index([courtId, dayOfWeek])\n @@map(\"court_availabilities\")\n}\n\nmodel CourtPriceRule {\n id String @id @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n dayOfWeek DayOfWeek? @map(\"day_of_week\")\n startTime String? @map(\"start_time\") @db.VarChar(5)\n endTime String? @map(\"end_time\") @db.VarChar(5)\n price Decimal @db.Decimal(19, 2)\n isActive Boolean @default(true) @map(\"is_active\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@index([courtId, isActive])\n @@map(\"court_price_rules\")\n}\n\nmodel CourtBooking {\n id String @id @db.Uuid\n bookingCode String @unique @map(\"booking_code\") @db.VarChar(8)\n courtId String @map(\"court_id\") @db.Uuid\n bookingDate DateTime @map(\"booking_date\") @db.Date\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n customerName String @map(\"customer_name\") @db.VarChar(120)\n customerPhone String @map(\"customer_phone\") @db.VarChar(30)\n customerEmail String @map(\"customer_email\") @db.VarChar(254)\n status CourtBookingStatus @default(CONFIRMED)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@unique([courtId, bookingDate, startTime])\n @@index([courtId, bookingDate])\n @@index([bookingDate])\n @@map(\"court_bookings\")\n}\n\nmodel CourtBookingLog {\n id String @id @db.Uuid\n bookingCode String @map(\"booking_code\") @db.VarChar(8)\n courtId String @map(\"court_id\") @db.Uuid\n bookingDate DateTime @map(\"booking_date\") @db.Date\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n previousStatus CourtBookingStatus @map(\"previous_status\")\n newStatus CourtBookingStatus @map(\"new_status\")\n customerName String @map(\"customer_name\") @db.VarChar(120)\n customerPhone String @map(\"customer_phone\") @db.VarChar(30)\n customerEmail String @map(\"customer_email\") @db.VarChar(254)\n changedAt DateTime @default(now()) @map(\"changed_at\")\n\n @@index([courtId, newStatus])\n @@map(\"court_booking_logs\")\n}\n\nmodel PasswordResetRequest {\n id String @id @db.Uuid\n email String\n otpHash String @map(\"otp_hash\")\n otpExpiresAt DateTime @map(\"otp_expires_at\")\n otpAttempts Int @default(0) @map(\"otp_attempts\")\n otpLastSentAt DateTime @map(\"otp_last_sent_at\")\n otpResendCount Int @default(0) @map(\"otp_resend_count\")\n usedAt DateTime? @map(\"used_at\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n @@index([email])\n @@index([otpExpiresAt])\n @@map(\"password_reset_requests\")\n}\n\nmodel Plan {\n code String @id @db.VarChar(10)\n name String @db.VarChar(30)\n price Decimal @db.Decimal(19, 2)\n rules Json\n lastUpdatedAt DateTime @default(now()) @map(\"last_updated_at\")\n complexes Complex[]\n\n @@map(\"plans\")\n}\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../src/generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\n// User model is defined in auth.prisma (Better Auth schema).\n", + "inlineSchema": "model User {\n id String @id\n name String\n email String\n emailVerified Boolean @default(false)\n image String?\n phone String?\n banned Boolean @default(false)\n bannedAt DateTime?\n banReason String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n accounts Account[]\n role String @default(\"member\")\n complexes ComplexUser[]\n\n @@unique([email])\n @@map(\"users\")\n}\n\nmodel Session {\n id String @id\n expiresAt DateTime\n token String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n ipAddress String?\n userAgent String?\n country String?\n city String?\n countryCode String?\n latitude Float?\n longitude Float?\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@unique([token])\n @@index([userId])\n @@map(\"sessions\")\n}\n\nmodel Account {\n id String @id\n accountId String\n providerId String\n userId String\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n accessToken String?\n refreshToken String?\n idToken String?\n accessTokenExpiresAt DateTime?\n refreshTokenExpiresAt DateTime?\n scope String?\n password String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@map(\"accounts\")\n}\n\nmodel Verification {\n id String @id\n identifier String\n value String\n expiresAt DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([identifier])\n @@map(\"verification\")\n}\n\nmodel Complex {\n id String @id @db.Uuid\n complexName String @map(\"complex_name\")\n physicalAddress String? @map(\"physical_address\") @db.VarChar(200)\n city String? @map(\"city\") @db.VarChar(100)\n state String? @map(\"state\") @db.VarChar(100)\n country String? @map(\"country\") @db.VarChar(100)\n complexSlug String @unique @map(\"complex_slug\")\n adminEmail String @map(\"admin_email\")\n planCode String? @map(\"plan_code\") @db.VarChar(10)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n plan Plan? @relation(fields: [planCode], references: [code])\n users ComplexUser[]\n invitations ComplexInvitation[]\n courts Court[]\n recurringGroups RecurringBookingGroup[]\n\n @@index([planCode])\n @@index([complexSlug])\n @@map(\"complexes\")\n}\n\nenum ComplexUserRole {\n ADMIN\n EMPLOYEE\n}\n\nmodel ComplexUser {\n complexId String @map(\"complex_id\") @db.Uuid\n userId String @map(\"user_id\")\n role ComplexUserRole @default(ADMIN)\n createdAt DateTime @default(now()) @map(\"created_at\")\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@id([complexId, userId])\n @@index([userId])\n @@map(\"complex_users\")\n}\n\nmodel ComplexInvitation {\n id String @id @db.Uuid\n complexId String @map(\"complex_id\") @db.Uuid\n email String @db.VarChar(255)\n tokenHash String @unique @map(\"token_hash\")\n expiresAt DateTime @map(\"expires_at\")\n acceptedAt DateTime? @map(\"accepted_at\")\n revokedAt DateTime? @map(\"revoked_at\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n\n @@index([complexId, email])\n @@index([email])\n @@map(\"complex_invitations\")\n}\n\nenum DayOfWeek {\n MONDAY\n TUESDAY\n WEDNESDAY\n THURSDAY\n FRIDAY\n SATURDAY\n SUNDAY\n}\n\nenum CourtBookingStatus {\n CONFIRMED\n CANCELLED\n COMPLETED\n NOSHOW\n}\n\nenum RecurringBookingGroupStatus {\n ACTIVE\n CANCELLED\n}\n\nmodel Sport {\n id String @id @db.Uuid\n name String @unique\n slug String @unique\n isActive Boolean @default(true) @map(\"is_active\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n courts Court[]\n\n @@map(\"sports\")\n}\n\nmodel Court {\n id String @id @db.Uuid\n complexId String @map(\"complex_id\") @db.Uuid\n sportId String @map(\"sport_id\") @db.Uuid\n name String\n slotDurationMinutes Int @map(\"slot_duration_minutes\")\n basePrice Decimal @map(\"base_price\") @db.Decimal(19, 2)\n isUnderMaintenance Boolean @default(false) @map(\"is_under_maintenance\")\n maintenanceReason String? @map(\"maintenance_reason\") @db.VarChar(500)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n sport Sport @relation(fields: [sportId], references: [id])\n availabilities CourtAvailability[]\n priceRules CourtPriceRule[]\n bookings CourtBooking[]\n maintenances CourtMaintenance[]\n recurringGroups RecurringBookingGroup[]\n\n @@index([complexId])\n @@index([sportId])\n @@map(\"courts\")\n}\n\nmodel CourtMaintenance {\n id String @id @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n startDate DateTime @map(\"start_date\") @db.Date\n startTime String? @map(\"start_time\") @db.VarChar(5)\n endTime String? @map(\"end_time\") @db.VarChar(5)\n reason String? @db.VarChar(500)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@index([courtId, startDate])\n @@map(\"court_maintenances\")\n}\n\nmodel CourtAvailability {\n id String @id @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n dayOfWeek DayOfWeek @map(\"day_of_week\")\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n createdAt DateTime @default(now()) @map(\"created_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@index([courtId, dayOfWeek])\n @@map(\"court_availabilities\")\n}\n\nmodel CourtPriceRule {\n id String @id @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n dayOfWeek DayOfWeek? @map(\"day_of_week\")\n startTime String? @map(\"start_time\") @db.VarChar(5)\n endTime String? @map(\"end_time\") @db.VarChar(5)\n price Decimal @db.Decimal(19, 2)\n isActive Boolean @default(true) @map(\"is_active\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n\n @@index([courtId, isActive])\n @@map(\"court_price_rules\")\n}\n\nmodel CourtBooking {\n id String @id @db.Uuid\n bookingCode String @unique @map(\"booking_code\") @db.VarChar(8)\n courtId String @map(\"court_id\") @db.Uuid\n bookingDate DateTime @map(\"booking_date\") @db.Date\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n customerName String @map(\"customer_name\") @db.VarChar(120)\n customerPhone String @map(\"customer_phone\") @db.VarChar(30)\n customerEmail String @map(\"customer_email\") @db.VarChar(254)\n status CourtBookingStatus @default(CONFIRMED)\n recurringGroupId String? @map(\"recurring_group_id\") @db.Uuid\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n recurringGroup RecurringBookingGroup? @relation(fields: [recurringGroupId], references: [id])\n\n @@unique([courtId, bookingDate, startTime])\n @@index([courtId, bookingDate])\n @@index([bookingDate])\n @@index([recurringGroupId])\n @@map(\"court_bookings\")\n}\n\nmodel CourtBookingLog {\n id String @id @db.Uuid\n bookingCode String @map(\"booking_code\") @db.VarChar(8)\n courtId String @map(\"court_id\") @db.Uuid\n bookingDate DateTime @map(\"booking_date\") @db.Date\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n previousStatus CourtBookingStatus @map(\"previous_status\")\n newStatus CourtBookingStatus @map(\"new_status\")\n customerName String @map(\"customer_name\") @db.VarChar(120)\n customerPhone String @map(\"customer_phone\") @db.VarChar(30)\n customerEmail String @map(\"customer_email\") @db.VarChar(254)\n changedAt DateTime @default(now()) @map(\"changed_at\")\n\n @@index([courtId, newStatus])\n @@map(\"court_booking_logs\")\n}\n\nmodel RecurringBookingGroup {\n id String @id @db.Uuid\n complexId String @map(\"complex_id\") @db.Uuid\n courtId String @map(\"court_id\") @db.Uuid\n startTime String @map(\"start_time\") @db.VarChar(5)\n endTime String @map(\"end_time\") @db.VarChar(5)\n dayOfWeek DayOfWeek @map(\"day_of_week\")\n startDate DateTime @map(\"start_date\") @db.Date\n endDate DateTime? @map(\"end_date\") @db.Date\n status RecurringBookingGroupStatus @default(ACTIVE)\n customerName String @map(\"customer_name\") @db.VarChar(120)\n customerPhone String @map(\"customer_phone\") @db.VarChar(30)\n customerEmail String @map(\"customer_email\") @db.VarChar(254)\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n court Court @relation(fields: [courtId], references: [id], onDelete: Cascade)\n complex Complex @relation(fields: [complexId], references: [id], onDelete: Cascade)\n bookings CourtBooking[]\n\n @@index([complexId])\n @@index([courtId])\n @@index([status])\n @@map(\"recurring_booking_groups\")\n}\n\nmodel PasswordResetRequest {\n id String @id @db.Uuid\n email String\n otpHash String @map(\"otp_hash\")\n otpExpiresAt DateTime @map(\"otp_expires_at\")\n otpAttempts Int @default(0) @map(\"otp_attempts\")\n otpLastSentAt DateTime @map(\"otp_last_sent_at\")\n otpResendCount Int @default(0) @map(\"otp_resend_count\")\n usedAt DateTime? @map(\"used_at\")\n createdAt DateTime @default(now()) @map(\"created_at\")\n updatedAt DateTime @updatedAt @map(\"updated_at\")\n\n @@index([email])\n @@index([otpExpiresAt])\n @@map(\"password_reset_requests\")\n}\n\nmodel Plan {\n code String @id @db.VarChar(10)\n name String @db.VarChar(30)\n price Decimal @db.Decimal(19, 2)\n rules Json\n lastUpdatedAt DateTime @default(now()) @map(\"last_updated_at\")\n complexes Complex[]\n\n @@map(\"plans\")\n}\n\ngenerator client {\n provider = \"prisma-client\"\n output = \"../src/generated/prisma\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n}\n\n// User model is defined in auth.prisma (Better Auth schema).\n", "runtimeDataModel": { "models": {}, "enums": {}, @@ -32,10 +32,10 @@ const config: runtime.GetPrismaClientConfig = { } } -config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"phone\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"banned\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"bannedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"banReason\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"accounts\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToUser\"},{\"name\":\"role\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexes\",\"kind\":\"object\",\"type\":\"ComplexUser\",\"relationName\":\"ComplexUserToUser\"}],\"dbName\":\"users\"},\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"ipAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userAgent\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"country\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"city\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"countryCode\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"latitude\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"longitude\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":\"sessions\"},\"Account\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"accountId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"providerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"AccountToUser\"},{\"name\":\"accessToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"refreshToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"idToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"accessTokenExpiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenExpiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"scope\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":\"accounts\"},\"Verification\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"value\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":\"verification\"},\"Complex\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_name\"},{\"name\":\"physicalAddress\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"physical_address\"},{\"name\":\"city\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"city\"},{\"name\":\"state\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"state\"},{\"name\":\"country\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"country\"},{\"name\":\"complexSlug\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_slug\"},{\"name\":\"adminEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"admin_email\"},{\"name\":\"planCode\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"plan_code\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"plan\",\"kind\":\"object\",\"type\":\"Plan\",\"relationName\":\"ComplexToPlan\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"ComplexUser\",\"relationName\":\"ComplexToComplexUser\"},{\"name\":\"invitations\",\"kind\":\"object\",\"type\":\"ComplexInvitation\",\"relationName\":\"ComplexToComplexInvitation\"},{\"name\":\"courts\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"ComplexToCourt\"}],\"dbName\":\"complexes\"},\"ComplexUser\":{\"fields\":[{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"user_id\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"ComplexUserRole\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToComplexUser\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ComplexUserToUser\"}],\"dbName\":\"complex_users\"},\"ComplexInvitation\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tokenHash\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"token_hash\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"expires_at\"},{\"name\":\"acceptedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"accepted_at\"},{\"name\":\"revokedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"revoked_at\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToComplexInvitation\"}],\"dbName\":\"complex_invitations\"},\"Sport\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"slug\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isActive\",\"kind\":\"scalar\",\"type\":\"Boolean\",\"dbName\":\"is_active\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"courts\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToSport\"}],\"dbName\":\"sports\"},\"Court\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"sportId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"sport_id\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"slotDurationMinutes\",\"kind\":\"scalar\",\"type\":\"Int\",\"dbName\":\"slot_duration_minutes\"},{\"name\":\"basePrice\",\"kind\":\"scalar\",\"type\":\"Decimal\",\"dbName\":\"base_price\"},{\"name\":\"isUnderMaintenance\",\"kind\":\"scalar\",\"type\":\"Boolean\",\"dbName\":\"is_under_maintenance\"},{\"name\":\"maintenanceReason\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"maintenance_reason\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToCourt\"},{\"name\":\"sport\",\"kind\":\"object\",\"type\":\"Sport\",\"relationName\":\"CourtToSport\"},{\"name\":\"availabilities\",\"kind\":\"object\",\"type\":\"CourtAvailability\",\"relationName\":\"CourtToCourtAvailability\"},{\"name\":\"priceRules\",\"kind\":\"object\",\"type\":\"CourtPriceRule\",\"relationName\":\"CourtToCourtPriceRule\"},{\"name\":\"bookings\",\"kind\":\"object\",\"type\":\"CourtBooking\",\"relationName\":\"CourtToCourtBooking\"},{\"name\":\"maintenances\",\"kind\":\"object\",\"type\":\"CourtMaintenance\",\"relationName\":\"CourtToCourtMaintenance\"}],\"dbName\":\"courts\"},\"CourtMaintenance\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"startDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"start_date\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"reason\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtMaintenance\"}],\"dbName\":\"court_maintenances\"},\"CourtAvailability\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"dayOfWeek\",\"kind\":\"enum\",\"type\":\"DayOfWeek\",\"dbName\":\"day_of_week\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtAvailability\"}],\"dbName\":\"court_availabilities\"},\"CourtPriceRule\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"dayOfWeek\",\"kind\":\"enum\",\"type\":\"DayOfWeek\",\"dbName\":\"day_of_week\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"price\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"isActive\",\"kind\":\"scalar\",\"type\":\"Boolean\",\"dbName\":\"is_active\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtPriceRule\"}],\"dbName\":\"court_price_rules\"},\"CourtBooking\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bookingCode\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"booking_code\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"bookingDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"booking_date\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"customerName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_name\"},{\"name\":\"customerPhone\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_phone\"},{\"name\":\"customerEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_email\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"CourtBookingStatus\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtBooking\"}],\"dbName\":\"court_bookings\"},\"CourtBookingLog\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bookingCode\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"booking_code\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"bookingDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"booking_date\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"previousStatus\",\"kind\":\"enum\",\"type\":\"CourtBookingStatus\",\"dbName\":\"previous_status\"},{\"name\":\"newStatus\",\"kind\":\"enum\",\"type\":\"CourtBookingStatus\",\"dbName\":\"new_status\"},{\"name\":\"customerName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_name\"},{\"name\":\"customerPhone\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_phone\"},{\"name\":\"customerEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_email\"},{\"name\":\"changedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"changed_at\"}],\"dbName\":\"court_booking_logs\"},\"PasswordResetRequest\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"otpHash\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"otp_hash\"},{\"name\":\"otpExpiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"otp_expires_at\"},{\"name\":\"otpAttempts\",\"kind\":\"scalar\",\"type\":\"Int\",\"dbName\":\"otp_attempts\"},{\"name\":\"otpLastSentAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"otp_last_sent_at\"},{\"name\":\"otpResendCount\",\"kind\":\"scalar\",\"type\":\"Int\",\"dbName\":\"otp_resend_count\"},{\"name\":\"usedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"used_at\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"}],\"dbName\":\"password_reset_requests\"},\"Plan\":{\"fields\":[{\"name\":\"code\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"price\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"rules\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"lastUpdatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"last_updated_at\"},{\"name\":\"complexes\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToPlan\"}],\"dbName\":\"plans\"}},\"enums\":{},\"types\":{}}") +config.runtimeDataModel = JSON.parse("{\"models\":{\"User\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"emailVerified\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"image\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"phone\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"banned\",\"kind\":\"scalar\",\"type\":\"Boolean\"},{\"name\":\"bannedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"banReason\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"sessions\",\"kind\":\"object\",\"type\":\"Session\",\"relationName\":\"SessionToUser\"},{\"name\":\"accounts\",\"kind\":\"object\",\"type\":\"Account\",\"relationName\":\"AccountToUser\"},{\"name\":\"role\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexes\",\"kind\":\"object\",\"type\":\"ComplexUser\",\"relationName\":\"ComplexUserToUser\"}],\"dbName\":\"users\"},\"Session\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"token\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"ipAddress\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userAgent\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"country\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"city\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"countryCode\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"latitude\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"longitude\",\"kind\":\"scalar\",\"type\":\"Float\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"SessionToUser\"}],\"dbName\":\"sessions\"},\"Account\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"accountId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"providerId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"AccountToUser\"},{\"name\":\"accessToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"refreshToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"idToken\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"accessTokenExpiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"refreshTokenExpiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"scope\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"password\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":\"accounts\"},\"Verification\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"identifier\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"value\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\"}],\"dbName\":\"verification\"},\"Complex\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_name\"},{\"name\":\"physicalAddress\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"physical_address\"},{\"name\":\"city\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"city\"},{\"name\":\"state\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"state\"},{\"name\":\"country\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"country\"},{\"name\":\"complexSlug\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_slug\"},{\"name\":\"adminEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"admin_email\"},{\"name\":\"planCode\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"plan_code\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"plan\",\"kind\":\"object\",\"type\":\"Plan\",\"relationName\":\"ComplexToPlan\"},{\"name\":\"users\",\"kind\":\"object\",\"type\":\"ComplexUser\",\"relationName\":\"ComplexToComplexUser\"},{\"name\":\"invitations\",\"kind\":\"object\",\"type\":\"ComplexInvitation\",\"relationName\":\"ComplexToComplexInvitation\"},{\"name\":\"courts\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"ComplexToCourt\"},{\"name\":\"recurringGroups\",\"kind\":\"object\",\"type\":\"RecurringBookingGroup\",\"relationName\":\"ComplexToRecurringBookingGroup\"}],\"dbName\":\"complexes\"},\"ComplexUser\":{\"fields\":[{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"userId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"user_id\"},{\"name\":\"role\",\"kind\":\"enum\",\"type\":\"ComplexUserRole\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToComplexUser\"},{\"name\":\"user\",\"kind\":\"object\",\"type\":\"User\",\"relationName\":\"ComplexUserToUser\"}],\"dbName\":\"complex_users\"},\"ComplexInvitation\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"tokenHash\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"token_hash\"},{\"name\":\"expiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"expires_at\"},{\"name\":\"acceptedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"accepted_at\"},{\"name\":\"revokedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"revoked_at\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToComplexInvitation\"}],\"dbName\":\"complex_invitations\"},\"Sport\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"slug\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"isActive\",\"kind\":\"scalar\",\"type\":\"Boolean\",\"dbName\":\"is_active\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"courts\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToSport\"}],\"dbName\":\"sports\"},\"Court\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"sportId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"sport_id\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"slotDurationMinutes\",\"kind\":\"scalar\",\"type\":\"Int\",\"dbName\":\"slot_duration_minutes\"},{\"name\":\"basePrice\",\"kind\":\"scalar\",\"type\":\"Decimal\",\"dbName\":\"base_price\"},{\"name\":\"isUnderMaintenance\",\"kind\":\"scalar\",\"type\":\"Boolean\",\"dbName\":\"is_under_maintenance\"},{\"name\":\"maintenanceReason\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"maintenance_reason\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToCourt\"},{\"name\":\"sport\",\"kind\":\"object\",\"type\":\"Sport\",\"relationName\":\"CourtToSport\"},{\"name\":\"availabilities\",\"kind\":\"object\",\"type\":\"CourtAvailability\",\"relationName\":\"CourtToCourtAvailability\"},{\"name\":\"priceRules\",\"kind\":\"object\",\"type\":\"CourtPriceRule\",\"relationName\":\"CourtToCourtPriceRule\"},{\"name\":\"bookings\",\"kind\":\"object\",\"type\":\"CourtBooking\",\"relationName\":\"CourtToCourtBooking\"},{\"name\":\"maintenances\",\"kind\":\"object\",\"type\":\"CourtMaintenance\",\"relationName\":\"CourtToCourtMaintenance\"},{\"name\":\"recurringGroups\",\"kind\":\"object\",\"type\":\"RecurringBookingGroup\",\"relationName\":\"CourtToRecurringBookingGroup\"}],\"dbName\":\"courts\"},\"CourtMaintenance\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"startDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"start_date\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"reason\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtMaintenance\"}],\"dbName\":\"court_maintenances\"},\"CourtAvailability\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"dayOfWeek\",\"kind\":\"enum\",\"type\":\"DayOfWeek\",\"dbName\":\"day_of_week\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtAvailability\"}],\"dbName\":\"court_availabilities\"},\"CourtPriceRule\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"dayOfWeek\",\"kind\":\"enum\",\"type\":\"DayOfWeek\",\"dbName\":\"day_of_week\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"price\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"isActive\",\"kind\":\"scalar\",\"type\":\"Boolean\",\"dbName\":\"is_active\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtPriceRule\"}],\"dbName\":\"court_price_rules\"},\"CourtBooking\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bookingCode\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"booking_code\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"bookingDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"booking_date\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"customerName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_name\"},{\"name\":\"customerPhone\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_phone\"},{\"name\":\"customerEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_email\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"CourtBookingStatus\"},{\"name\":\"recurringGroupId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"recurring_group_id\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToCourtBooking\"},{\"name\":\"recurringGroup\",\"kind\":\"object\",\"type\":\"RecurringBookingGroup\",\"relationName\":\"CourtBookingToRecurringBookingGroup\"}],\"dbName\":\"court_bookings\"},\"CourtBookingLog\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"bookingCode\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"booking_code\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"bookingDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"booking_date\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"previousStatus\",\"kind\":\"enum\",\"type\":\"CourtBookingStatus\",\"dbName\":\"previous_status\"},{\"name\":\"newStatus\",\"kind\":\"enum\",\"type\":\"CourtBookingStatus\",\"dbName\":\"new_status\"},{\"name\":\"customerName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_name\"},{\"name\":\"customerPhone\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_phone\"},{\"name\":\"customerEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_email\"},{\"name\":\"changedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"changed_at\"}],\"dbName\":\"court_booking_logs\"},\"RecurringBookingGroup\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"complexId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"complex_id\"},{\"name\":\"courtId\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"court_id\"},{\"name\":\"startTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"start_time\"},{\"name\":\"endTime\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"end_time\"},{\"name\":\"dayOfWeek\",\"kind\":\"enum\",\"type\":\"DayOfWeek\",\"dbName\":\"day_of_week\"},{\"name\":\"startDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"start_date\"},{\"name\":\"endDate\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"end_date\"},{\"name\":\"status\",\"kind\":\"enum\",\"type\":\"RecurringBookingGroupStatus\"},{\"name\":\"customerName\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_name\"},{\"name\":\"customerPhone\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_phone\"},{\"name\":\"customerEmail\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"customer_email\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"},{\"name\":\"court\",\"kind\":\"object\",\"type\":\"Court\",\"relationName\":\"CourtToRecurringBookingGroup\"},{\"name\":\"complex\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToRecurringBookingGroup\"},{\"name\":\"bookings\",\"kind\":\"object\",\"type\":\"CourtBooking\",\"relationName\":\"CourtBookingToRecurringBookingGroup\"}],\"dbName\":\"recurring_booking_groups\"},\"PasswordResetRequest\":{\"fields\":[{\"name\":\"id\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"email\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"otpHash\",\"kind\":\"scalar\",\"type\":\"String\",\"dbName\":\"otp_hash\"},{\"name\":\"otpExpiresAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"otp_expires_at\"},{\"name\":\"otpAttempts\",\"kind\":\"scalar\",\"type\":\"Int\",\"dbName\":\"otp_attempts\"},{\"name\":\"otpLastSentAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"otp_last_sent_at\"},{\"name\":\"otpResendCount\",\"kind\":\"scalar\",\"type\":\"Int\",\"dbName\":\"otp_resend_count\"},{\"name\":\"usedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"used_at\"},{\"name\":\"createdAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"created_at\"},{\"name\":\"updatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"updated_at\"}],\"dbName\":\"password_reset_requests\"},\"Plan\":{\"fields\":[{\"name\":\"code\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"name\",\"kind\":\"scalar\",\"type\":\"String\"},{\"name\":\"price\",\"kind\":\"scalar\",\"type\":\"Decimal\"},{\"name\":\"rules\",\"kind\":\"scalar\",\"type\":\"Json\"},{\"name\":\"lastUpdatedAt\",\"kind\":\"scalar\",\"type\":\"DateTime\",\"dbName\":\"last_updated_at\"},{\"name\":\"complexes\",\"kind\":\"object\",\"type\":\"Complex\",\"relationName\":\"ComplexToPlan\"}],\"dbName\":\"plans\"}},\"enums\":{},\"types\":{}}") config.parameterizationSchema = { - strings: JSON.parse("[\"where\",\"orderBy\",\"cursor\",\"user\",\"sessions\",\"accounts\",\"complexes\",\"_count\",\"plan\",\"users\",\"complex\",\"invitations\",\"courts\",\"sport\",\"court\",\"availabilities\",\"priceRules\",\"bookings\",\"maintenances\",\"User.findUnique\",\"User.findUniqueOrThrow\",\"User.findFirst\",\"User.findFirstOrThrow\",\"User.findMany\",\"data\",\"User.createOne\",\"User.createMany\",\"User.createManyAndReturn\",\"User.updateOne\",\"User.updateMany\",\"User.updateManyAndReturn\",\"create\",\"update\",\"User.upsertOne\",\"User.deleteOne\",\"User.deleteMany\",\"having\",\"_min\",\"_max\",\"User.groupBy\",\"User.aggregate\",\"Session.findUnique\",\"Session.findUniqueOrThrow\",\"Session.findFirst\",\"Session.findFirstOrThrow\",\"Session.findMany\",\"Session.createOne\",\"Session.createMany\",\"Session.createManyAndReturn\",\"Session.updateOne\",\"Session.updateMany\",\"Session.updateManyAndReturn\",\"Session.upsertOne\",\"Session.deleteOne\",\"Session.deleteMany\",\"_avg\",\"_sum\",\"Session.groupBy\",\"Session.aggregate\",\"Account.findUnique\",\"Account.findUniqueOrThrow\",\"Account.findFirst\",\"Account.findFirstOrThrow\",\"Account.findMany\",\"Account.createOne\",\"Account.createMany\",\"Account.createManyAndReturn\",\"Account.updateOne\",\"Account.updateMany\",\"Account.updateManyAndReturn\",\"Account.upsertOne\",\"Account.deleteOne\",\"Account.deleteMany\",\"Account.groupBy\",\"Account.aggregate\",\"Verification.findUnique\",\"Verification.findUniqueOrThrow\",\"Verification.findFirst\",\"Verification.findFirstOrThrow\",\"Verification.findMany\",\"Verification.createOne\",\"Verification.createMany\",\"Verification.createManyAndReturn\",\"Verification.updateOne\",\"Verification.updateMany\",\"Verification.updateManyAndReturn\",\"Verification.upsertOne\",\"Verification.deleteOne\",\"Verification.deleteMany\",\"Verification.groupBy\",\"Verification.aggregate\",\"Complex.findUnique\",\"Complex.findUniqueOrThrow\",\"Complex.findFirst\",\"Complex.findFirstOrThrow\",\"Complex.findMany\",\"Complex.createOne\",\"Complex.createMany\",\"Complex.createManyAndReturn\",\"Complex.updateOne\",\"Complex.updateMany\",\"Complex.updateManyAndReturn\",\"Complex.upsertOne\",\"Complex.deleteOne\",\"Complex.deleteMany\",\"Complex.groupBy\",\"Complex.aggregate\",\"ComplexUser.findUnique\",\"ComplexUser.findUniqueOrThrow\",\"ComplexUser.findFirst\",\"ComplexUser.findFirstOrThrow\",\"ComplexUser.findMany\",\"ComplexUser.createOne\",\"ComplexUser.createMany\",\"ComplexUser.createManyAndReturn\",\"ComplexUser.updateOne\",\"ComplexUser.updateMany\",\"ComplexUser.updateManyAndReturn\",\"ComplexUser.upsertOne\",\"ComplexUser.deleteOne\",\"ComplexUser.deleteMany\",\"ComplexUser.groupBy\",\"ComplexUser.aggregate\",\"ComplexInvitation.findUnique\",\"ComplexInvitation.findUniqueOrThrow\",\"ComplexInvitation.findFirst\",\"ComplexInvitation.findFirstOrThrow\",\"ComplexInvitation.findMany\",\"ComplexInvitation.createOne\",\"ComplexInvitation.createMany\",\"ComplexInvitation.createManyAndReturn\",\"ComplexInvitation.updateOne\",\"ComplexInvitation.updateMany\",\"ComplexInvitation.updateManyAndReturn\",\"ComplexInvitation.upsertOne\",\"ComplexInvitation.deleteOne\",\"ComplexInvitation.deleteMany\",\"ComplexInvitation.groupBy\",\"ComplexInvitation.aggregate\",\"Sport.findUnique\",\"Sport.findUniqueOrThrow\",\"Sport.findFirst\",\"Sport.findFirstOrThrow\",\"Sport.findMany\",\"Sport.createOne\",\"Sport.createMany\",\"Sport.createManyAndReturn\",\"Sport.updateOne\",\"Sport.updateMany\",\"Sport.updateManyAndReturn\",\"Sport.upsertOne\",\"Sport.deleteOne\",\"Sport.deleteMany\",\"Sport.groupBy\",\"Sport.aggregate\",\"Court.findUnique\",\"Court.findUniqueOrThrow\",\"Court.findFirst\",\"Court.findFirstOrThrow\",\"Court.findMany\",\"Court.createOne\",\"Court.createMany\",\"Court.createManyAndReturn\",\"Court.updateOne\",\"Court.updateMany\",\"Court.updateManyAndReturn\",\"Court.upsertOne\",\"Court.deleteOne\",\"Court.deleteMany\",\"Court.groupBy\",\"Court.aggregate\",\"CourtMaintenance.findUnique\",\"CourtMaintenance.findUniqueOrThrow\",\"CourtMaintenance.findFirst\",\"CourtMaintenance.findFirstOrThrow\",\"CourtMaintenance.findMany\",\"CourtMaintenance.createOne\",\"CourtMaintenance.createMany\",\"CourtMaintenance.createManyAndReturn\",\"CourtMaintenance.updateOne\",\"CourtMaintenance.updateMany\",\"CourtMaintenance.updateManyAndReturn\",\"CourtMaintenance.upsertOne\",\"CourtMaintenance.deleteOne\",\"CourtMaintenance.deleteMany\",\"CourtMaintenance.groupBy\",\"CourtMaintenance.aggregate\",\"CourtAvailability.findUnique\",\"CourtAvailability.findUniqueOrThrow\",\"CourtAvailability.findFirst\",\"CourtAvailability.findFirstOrThrow\",\"CourtAvailability.findMany\",\"CourtAvailability.createOne\",\"CourtAvailability.createMany\",\"CourtAvailability.createManyAndReturn\",\"CourtAvailability.updateOne\",\"CourtAvailability.updateMany\",\"CourtAvailability.updateManyAndReturn\",\"CourtAvailability.upsertOne\",\"CourtAvailability.deleteOne\",\"CourtAvailability.deleteMany\",\"CourtAvailability.groupBy\",\"CourtAvailability.aggregate\",\"CourtPriceRule.findUnique\",\"CourtPriceRule.findUniqueOrThrow\",\"CourtPriceRule.findFirst\",\"CourtPriceRule.findFirstOrThrow\",\"CourtPriceRule.findMany\",\"CourtPriceRule.createOne\",\"CourtPriceRule.createMany\",\"CourtPriceRule.createManyAndReturn\",\"CourtPriceRule.updateOne\",\"CourtPriceRule.updateMany\",\"CourtPriceRule.updateManyAndReturn\",\"CourtPriceRule.upsertOne\",\"CourtPriceRule.deleteOne\",\"CourtPriceRule.deleteMany\",\"CourtPriceRule.groupBy\",\"CourtPriceRule.aggregate\",\"CourtBooking.findUnique\",\"CourtBooking.findUniqueOrThrow\",\"CourtBooking.findFirst\",\"CourtBooking.findFirstOrThrow\",\"CourtBooking.findMany\",\"CourtBooking.createOne\",\"CourtBooking.createMany\",\"CourtBooking.createManyAndReturn\",\"CourtBooking.updateOne\",\"CourtBooking.updateMany\",\"CourtBooking.updateManyAndReturn\",\"CourtBooking.upsertOne\",\"CourtBooking.deleteOne\",\"CourtBooking.deleteMany\",\"CourtBooking.groupBy\",\"CourtBooking.aggregate\",\"CourtBookingLog.findUnique\",\"CourtBookingLog.findUniqueOrThrow\",\"CourtBookingLog.findFirst\",\"CourtBookingLog.findFirstOrThrow\",\"CourtBookingLog.findMany\",\"CourtBookingLog.createOne\",\"CourtBookingLog.createMany\",\"CourtBookingLog.createManyAndReturn\",\"CourtBookingLog.updateOne\",\"CourtBookingLog.updateMany\",\"CourtBookingLog.updateManyAndReturn\",\"CourtBookingLog.upsertOne\",\"CourtBookingLog.deleteOne\",\"CourtBookingLog.deleteMany\",\"CourtBookingLog.groupBy\",\"CourtBookingLog.aggregate\",\"PasswordResetRequest.findUnique\",\"PasswordResetRequest.findUniqueOrThrow\",\"PasswordResetRequest.findFirst\",\"PasswordResetRequest.findFirstOrThrow\",\"PasswordResetRequest.findMany\",\"PasswordResetRequest.createOne\",\"PasswordResetRequest.createMany\",\"PasswordResetRequest.createManyAndReturn\",\"PasswordResetRequest.updateOne\",\"PasswordResetRequest.updateMany\",\"PasswordResetRequest.updateManyAndReturn\",\"PasswordResetRequest.upsertOne\",\"PasswordResetRequest.deleteOne\",\"PasswordResetRequest.deleteMany\",\"PasswordResetRequest.groupBy\",\"PasswordResetRequest.aggregate\",\"Plan.findUnique\",\"Plan.findUniqueOrThrow\",\"Plan.findFirst\",\"Plan.findFirstOrThrow\",\"Plan.findMany\",\"Plan.createOne\",\"Plan.createMany\",\"Plan.createManyAndReturn\",\"Plan.updateOne\",\"Plan.updateMany\",\"Plan.updateManyAndReturn\",\"Plan.upsertOne\",\"Plan.deleteOne\",\"Plan.deleteMany\",\"Plan.groupBy\",\"Plan.aggregate\",\"AND\",\"OR\",\"NOT\",\"code\",\"name\",\"price\",\"rules\",\"lastUpdatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"string_contains\",\"string_starts_with\",\"string_ends_with\",\"array_starts_with\",\"array_ends_with\",\"array_contains\",\"contains\",\"startsWith\",\"endsWith\",\"every\",\"some\",\"none\",\"id\",\"email\",\"otpHash\",\"otpExpiresAt\",\"otpAttempts\",\"otpLastSentAt\",\"otpResendCount\",\"usedAt\",\"createdAt\",\"updatedAt\",\"bookingCode\",\"courtId\",\"bookingDate\",\"startTime\",\"endTime\",\"CourtBookingStatus\",\"previousStatus\",\"newStatus\",\"customerName\",\"customerPhone\",\"customerEmail\",\"changedAt\",\"status\",\"DayOfWeek\",\"dayOfWeek\",\"isActive\",\"startDate\",\"reason\",\"complexId\",\"sportId\",\"slotDurationMinutes\",\"basePrice\",\"isUnderMaintenance\",\"maintenanceReason\",\"slug\",\"tokenHash\",\"expiresAt\",\"acceptedAt\",\"revokedAt\",\"userId\",\"ComplexUserRole\",\"role\",\"complexName\",\"physicalAddress\",\"city\",\"state\",\"country\",\"complexSlug\",\"adminEmail\",\"planCode\",\"identifier\",\"value\",\"accountId\",\"providerId\",\"accessToken\",\"refreshToken\",\"idToken\",\"accessTokenExpiresAt\",\"refreshTokenExpiresAt\",\"scope\",\"password\",\"token\",\"ipAddress\",\"userAgent\",\"countryCode\",\"latitude\",\"longitude\",\"emailVerified\",\"image\",\"phone\",\"banned\",\"bannedAt\",\"banReason\",\"courtId_bookingDate_startTime\",\"complexId_userId\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), - graph: "7QaQAYACEgQAAPkDACAFAAD6AwAgBgAA-wMAIJsCAAD3AwAwnAIAADwAEJ0CAAD3AwAwnwIBALoDACG3AgEAAAABuAIBAAAAAb8CQAC9AwAhwAJAAL0DACHgAgEAugMAIfoCIADnAwAh-wIBAPgDACH8AgEA-AMAIf0CIADnAwAh_gJAAMwDACH_AgEA-AMAIQEAAAABACARAwAAkgQAIJsCAACUBAAwnAIAAAMAEJ0CAACUBAAwtwIBALoDACG_AkAAvQMAIcACQAC9AwAh2wJAAL0DACHeAgEAugMAIeMCAQD4AwAh5QIBAPgDACH0AgEAugMAIfUCAQD4AwAh9gIBAPgDACH3AgEA-AMAIfgCCACVBAAh-QIIAJUEACEIAwAApQYAIOMCAACbBQAg5QIAAJsFACD1AgAAmwUAIPYCAACbBQAg9wIAAJsFACD4AgAAmwUAIPkCAACbBQAgEQMAAJIEACCbAgAAlAQAMJwCAAADABCdAgAAlAQAMLcCAQAAAAG_AkAAvQMAIcACQAC9AwAh2wJAAL0DACHeAgEAugMAIeMCAQD4AwAh5QIBAPgDACH0AgEAAAAB9QIBAPgDACH2AgEA-AMAIfcCAQD4AwAh-AIIAJUEACH5AggAlQQAIQMAAAADACABAAAEADACAAAFACARAwAAkgQAIJsCAACTBAAwnAIAAAcAEJ0CAACTBAAwtwIBALoDACG_AkAAvQMAIcACQAC9AwAh3gIBALoDACHrAgEAugMAIewCAQC6AwAh7QIBAPgDACHuAgEA-AMAIe8CAQD4AwAh8AJAAMwDACHxAkAAzAMAIfICAQD4AwAh8wIBAPgDACEIAwAApQYAIO0CAACbBQAg7gIAAJsFACDvAgAAmwUAIPACAACbBQAg8QIAAJsFACDyAgAAmwUAIPMCAACbBQAgEQMAAJIEACCbAgAAkwQAMJwCAAAHABCdAgAAkwQAMLcCAQAAAAG_AkAAvQMAIcACQAC9AwAh3gIBALoDACHrAgEAugMAIewCAQC6AwAh7QIBAPgDACHuAgEA-AMAIe8CAQD4AwAh8AJAAMwDACHxAkAAzAMAIfICAQD4AwAh8wIBAPgDACEDAAAABwAgAQAACAAwAgAACQAgCQMAAJIEACAKAACFBAAgmwIAAJAEADCcAgAACwAQnQIAAJAEADC_AkAAvQMAIdMCAQDKAwAh3gIBALoDACHgAgAAkQTgAiICAwAApQYAIAoAAJ0GACAKAwAAkgQAIAoAAIUEACCbAgAAkAQAMJwCAAALABCdAgAAkAQAML8CQAC9AwAh0wIBAMoDACHeAgEAugMAIeACAACRBOACIoEDAACPBAAgAwAAAAsAIAEAAAwAMAIAAA0AIAkGAAC-AwAgmwIAALkDADCcAgAADwAQnQIAALkDADCeAgEAugMAIZ8CAQC6AwAhoAIQALsDACGhAgAAvAMAIKICQAC9AwAhAQAAAA8AIBIIAACNBAAgCQAA-wMAIAsAAI4EACAMAADoAwAgmwIAAIwEADCcAgAAEQAQnQIAAIwEADC3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHhAgEAugMAIeICAQD4AwAh4wIBAPgDACHkAgEA-AMAIeUCAQD4AwAh5gIBALoDACHnAgEAugMAIegCAQD4AwAhCQgAAKMGACAJAACbBgAgCwAApAYAIAwAAM8FACDiAgAAmwUAIOMCAACbBQAg5AIAAJsFACDlAgAAmwUAIOgCAACbBQAgEggAAI0EACAJAAD7AwAgCwAAjgQAIAwAAOgDACCbAgAAjAQAMJwCAAARABCdAgAAjAQAMLcCAQAAAAG_AkAAvQMAIcACQAC9AwAh4QIBALoDACHiAgEA-AMAIeMCAQD4AwAh5AIBAPgDACHlAgEA-AMAIeYCAQAAAAHnAgEAugMAIegCAQD4AwAhAwAAABEAIAEAABIAMAIAABMAIAEAAAARACADAAAACwAgAQAADAAwAgAADQAgDQoAAIUEACCbAgAAiwQAMJwCAAAXABCdAgAAiwQAMLcCAQDKAwAhuAIBALoDACG_AkAAvQMAIcACQAC9AwAh0wIBAMoDACHaAgEAugMAIdsCQAC9AwAh3AJAAMwDACHdAkAAzAMAIQMKAACdBgAg3AIAAJsFACDdAgAAmwUAIA0KAACFBAAgmwIAAIsEADCcAgAAFwAQnQIAAIsEADC3AgEAAAABuAIBALoDACG_AkAAvQMAIcACQAC9AwAh0wIBAMoDACHaAgEAAAAB2wJAAL0DACHcAkAAzAMAId0CQADMAwAhAwAAABcAIAEAABgAMAIAABkAIBMKAACFBAAgDQAAhgQAIA8AAIcEACAQAACIBAAgEQAAiQQAIBIAAIoEACCbAgAAhAQAMJwCAAAbABCdAgAAhAQAMJ8CAQC6AwAhtwIBAMoDACG_AkAAvQMAIcACQAC9AwAh0wIBAMoDACHUAgEAygMAIdUCAgDLAwAh1gIQALsDACHXAiAA5wMAIdgCAQD4AwAhBwoAAJ0GACANAACeBgAgDwAAnwYAIBAAAKAGACARAAChBgAgEgAAogYAINgCAACbBQAgEwoAAIUEACANAACGBAAgDwAAhwQAIBAAAIgEACARAACJBAAgEgAAigQAIJsCAACEBAAwnAIAABsAEJ0CAACEBAAwnwIBALoDACG3AgEAAAABvwJAAL0DACHAAkAAvQMAIdMCAQDKAwAh1AIBAMoDACHVAgIAywMAIdYCEAC7AwAh1wIgAOcDACHYAgEA-AMAIQMAAAAbACABAAAcADACAAAdACADAAAAGwAgAQAAHAAwAgAAHQAgAQAAABsAIAoOAAD9AwAgmwIAAIIEADCcAgAAIQAQnQIAAIIEADC3AgEAygMAIb8CQAC9AwAhwgIBAMoDACHEAgEAugMAIcUCAQC6AwAhzwIAAIMEzwIiAQ4AAJwGACAKDgAA_QMAIJsCAACCBAAwnAIAACEAEJ0CAACCBAAwtwIBAAAAAb8CQAC9AwAhwgIBAMoDACHEAgEAugMAIcUCAQC6AwAhzwIAAIMEzwIiAwAAACEAIAEAACIAMAIAACMAIA0OAAD9AwAgmwIAAIAEADCcAgAAJQAQnQIAAIAEADCgAhAAuwMAIbcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIc8CAACBBM8CI9ACIADnAwAhBA4AAJwGACDEAgAAmwUAIMUCAACbBQAgzwIAAJsFACANDgAA_QMAIJsCAACABAAwnAIAACUAEJ0CAACABAAwoAIQALsDACG3AgEAAAABvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIc8CAACBBM8CI9ACIADnAwAhAwAAACUAIAEAACYAMAIAACcAIBAOAAD9AwAgmwIAAP8DADCcAgAAKQAQnQIAAP8DADC3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHBAgEAugMAIcICAQDKAwAhwwJAAL0DACHEAgEAugMAIcUCAQC6AwAhyQIBALoDACHKAgEAugMAIcsCAQC6AwAhzQIAANMDxwIiAQ4AAJwGACARDgAA_QMAIJsCAAD_AwAwnAIAACkAEJ0CAAD_AwAwtwIBAAAAAb8CQAC9AwAhwAJAAL0DACHBAgEAAAABwgIBAMoDACHDAkAAvQMAIcQCAQC6AwAhxQIBALoDACHJAgEAugMAIcoCAQC6AwAhywIBALoDACHNAgAA0wPHAiKAAwAA_gMAIAMAAAApACABAAAqADACAAArACAMDgAA_QMAIJsCAAD8AwAwnAIAAC0AEJ0CAAD8AwAwtwIBAMoDACG_AkAAvQMAIcACQAC9AwAhwgIBAMoDACHEAgEA-AMAIcUCAQD4AwAh0QJAAL0DACHSAgEA-AMAIQQOAACcBgAgxAIAAJsFACDFAgAAmwUAINICAACbBQAgDA4AAP0DACCbAgAA_AMAMJwCAAAtABCdAgAA_AMAMLcCAQAAAAG_AkAAvQMAIcACQAC9AwAhwgIBAMoDACHEAgEA-AMAIcUCAQD4AwAh0QJAAL0DACHSAgEA-AMAIQMAAAAtACABAAAuADACAAAvACABAAAAIQAgAQAAACUAIAEAAAApACABAAAALQAgAQAAAAsAIAEAAAAXACABAAAAGwAgAQAAAAMAIAEAAAAHACABAAAACwAgAQAAAAEAIBIEAAD5AwAgBQAA-gMAIAYAAPsDACCbAgAA9wMAMJwCAAA8ABCdAgAA9wMAMJ8CAQC6AwAhtwIBALoDACG4AgEAugMAIb8CQAC9AwAhwAJAAL0DACHgAgEAugMAIfoCIADnAwAh-wIBAPgDACH8AgEA-AMAIf0CIADnAwAh_gJAAMwDACH_AgEA-AMAIQcEAACZBgAgBQAAmgYAIAYAAJsGACD7AgAAmwUAIPwCAACbBQAg_gIAAJsFACD_AgAAmwUAIAMAAAA8ACABAAA9ADACAAABACADAAAAPAAgAQAAPQAwAgAAAQAgAwAAADwAIAEAAD0AMAIAAAEAIA8EAACWBgAgBQAAlwYAIAYAAJgGACCfAgEAAAABtwIBAAAAAbgCAQAAAAG_AkAAAAABwAJAAAAAAeACAQAAAAH6AiAAAAAB-wIBAAAAAfwCAQAAAAH9AiAAAAAB_gJAAAAAAf8CAQAAAAEBGAAAQQAgDJ8CAQAAAAG3AgEAAAABuAIBAAAAAb8CQAAAAAHAAkAAAAAB4AIBAAAAAfoCIAAAAAH7AgEAAAAB_AIBAAAAAf0CIAAAAAH-AkAAAAAB_wIBAAAAAQEYAABDADABGAAAQwAwDwQAAPIFACAFAADzBQAgBgAA9AUAIJ8CAQCbBAAhtwIBAJsEACG4AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHgAgEAmwQAIfoCIAC5BAAh-wIBAKkEACH8AgEAqQQAIf0CIAC5BAAh_gJAAIMFACH_AgEAqQQAIQIAAAABACAYAABGACAMnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhAgAAADwAIBgAAEgAIAIAAAA8ACAYAABIACADAAAAAQAgHwAAQQAgIAAARgAgAQAAAAEAIAEAAAA8ACAHBwAA7wUAICUAAPEFACAmAADwBQAg-wIAAJsFACD8AgAAmwUAIP4CAACbBQAg_wIAAJsFACAPmwIAAPYDADCcAgAATwAQnQIAAPYDADCfAgEArQMAIbcCAQCtAwAhuAIBAK0DACG_AkAAsAMAIcACQACwAwAh4AIBAK0DACH6AiAA2AMAIfsCAQDXAwAh_AIBANcDACH9AiAA2AMAIf4CQADCAwAh_wIBANcDACEDAAAAPAAgAQAATgAwJAAATwAgAwAAADwAIAEAAD0AMAIAAAEAIAEAAAAFACABAAAABQAgAwAAAAMAIAEAAAQAMAIAAAUAIAMAAAADACABAAAEADACAAAFACADAAAAAwAgAQAABAAwAgAABQAgDgMAAO4FACC3AgEAAAABvwJAAAAAAcACQAAAAAHbAkAAAAAB3gIBAAAAAeMCAQAAAAHlAgEAAAAB9AIBAAAAAfUCAQAAAAH2AgEAAAAB9wIBAAAAAfgCCAAAAAH5AggAAAABARgAAFcAIA23AgEAAAABvwJAAAAAAcACQAAAAAHbAkAAAAAB3gIBAAAAAeMCAQAAAAHlAgEAAAAB9AIBAAAAAfUCAQAAAAH2AgEAAAAB9wIBAAAAAfgCCAAAAAH5AggAAAABARgAAFkAMAEYAABZADAOAwAA7QUAILcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdsCQACdBAAh3gIBAJsEACHjAgEAqQQAIeUCAQCpBAAh9AIBAJsEACH1AgEAqQQAIfYCAQCpBAAh9wIBAKkEACH4AggA7AUAIfkCCADsBQAhAgAAAAUAIBgAAFwAIA23AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHbAkAAnQQAId4CAQCbBAAh4wIBAKkEACHlAgEAqQQAIfQCAQCbBAAh9QIBAKkEACH2AgEAqQQAIfcCAQCpBAAh-AIIAOwFACH5AggA7AUAIQIAAAADACAYAABeACACAAAAAwAgGAAAXgAgAwAAAAUAIB8AAFcAICAAAFwAIAEAAAAFACABAAAAAwAgDAcAAOcFACAlAADqBQAgJgAA6QUAIDcAAOgFACA4AADrBQAg4wIAAJsFACDlAgAAmwUAIPUCAACbBQAg9gIAAJsFACD3AgAAmwUAIPgCAACbBQAg-QIAAJsFACAQmwIAAPIDADCcAgAAZQAQnQIAAPIDADC3AgEArQMAIb8CQACwAwAhwAJAALADACHbAkAAsAMAId4CAQCtAwAh4wIBANcDACHlAgEA1wMAIfQCAQCtAwAh9QIBANcDACH2AgEA1wMAIfcCAQDXAwAh-AIIAPMDACH5AggA8wMAIQMAAAADACABAABkADAkAABlACADAAAAAwAgAQAABAAwAgAABQAgAQAAAAkAIAEAAAAJACADAAAABwAgAQAACAAwAgAACQAgAwAAAAcAIAEAAAgAMAIAAAkAIAMAAAAHACABAAAIADACAAAJACAOAwAA5gUAILcCAQAAAAG_AkAAAAABwAJAAAAAAd4CAQAAAAHrAgEAAAAB7AIBAAAAAe0CAQAAAAHuAgEAAAAB7wIBAAAAAfACQAAAAAHxAkAAAAAB8gIBAAAAAfMCAQAAAAEBGAAAbQAgDbcCAQAAAAG_AkAAAAABwAJAAAAAAd4CAQAAAAHrAgEAAAAB7AIBAAAAAe0CAQAAAAHuAgEAAAAB7wIBAAAAAfACQAAAAAHxAkAAAAAB8gIBAAAAAfMCAQAAAAEBGAAAbwAwARgAAG8AMA4DAADlBQAgtwIBAJsEACG_AkAAnQQAIcACQACdBAAh3gIBAJsEACHrAgEAmwQAIewCAQCbBAAh7QIBAKkEACHuAgEAqQQAIe8CAQCpBAAh8AJAAIMFACHxAkAAgwUAIfICAQCpBAAh8wIBAKkEACECAAAACQAgGAAAcgAgDbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAId4CAQCbBAAh6wIBAJsEACHsAgEAmwQAIe0CAQCpBAAh7gIBAKkEACHvAgEAqQQAIfACQACDBQAh8QJAAIMFACHyAgEAqQQAIfMCAQCpBAAhAgAAAAcAIBgAAHQAIAIAAAAHACAYAAB0ACADAAAACQAgHwAAbQAgIAAAcgAgAQAAAAkAIAEAAAAHACAKBwAA4gUAICUAAOQFACAmAADjBQAg7QIAAJsFACDuAgAAmwUAIO8CAACbBQAg8AIAAJsFACDxAgAAmwUAIPICAACbBQAg8wIAAJsFACAQmwIAAPEDADCcAgAAewAQnQIAAPEDADC3AgEArQMAIb8CQACwAwAhwAJAALADACHeAgEArQMAIesCAQCtAwAh7AIBAK0DACHtAgEA1wMAIe4CAQDXAwAh7wIBANcDACHwAkAAwgMAIfECQADCAwAh8gIBANcDACHzAgEA1wMAIQMAAAAHACABAAB6ADAkAAB7ACADAAAABwAgAQAACAAwAgAACQAgCZsCAADwAwAwnAIAAIEBABCdAgAA8AMAMLcCAQAAAAG_AkAAvQMAIcACQAC9AwAh2wJAAL0DACHpAgEAugMAIeoCAQC6AwAhAQAAAH4AIAEAAAB-ACAJmwIAAPADADCcAgAAgQEAEJ0CAADwAwAwtwIBALoDACG_AkAAvQMAIcACQAC9AwAh2wJAAL0DACHpAgEAugMAIeoCAQC6AwAhAAMAAACBAQAgAQAAggEAMAIAAH4AIAMAAACBAQAgAQAAggEAMAIAAH4AIAMAAACBAQAgAQAAggEAMAIAAH4AIAa3AgEAAAABvwJAAAAAAcACQAAAAAHbAkAAAAAB6QIBAAAAAeoCAQAAAAEBGAAAhgEAIAa3AgEAAAABvwJAAAAAAcACQAAAAAHbAkAAAAAB6QIBAAAAAeoCAQAAAAEBGAAAiAEAMAEYAACIAQAwBrcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdsCQACdBAAh6QIBAJsEACHqAgEAmwQAIQIAAAB-ACAYAACLAQAgBrcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdsCQACdBAAh6QIBAJsEACHqAgEAmwQAIQIAAACBAQAgGAAAjQEAIAIAAACBAQAgGAAAjQEAIAMAAAB-ACAfAACGAQAgIAAAiwEAIAEAAAB-ACABAAAAgQEAIAMHAADfBQAgJQAA4QUAICYAAOAFACAJmwIAAO8DADCcAgAAlAEAEJ0CAADvAwAwtwIBAK0DACG_AkAAsAMAIcACQACwAwAh2wJAALADACHpAgEArQMAIeoCAQCtAwAhAwAAAIEBACABAACTAQAwJAAAlAEAIAMAAACBAQAgAQAAggEAMAIAAH4AIAEAAAATACABAAAAEwAgAwAAABEAIAEAABIAMAIAABMAIAMAAAARACABAAASADACAAATACADAAAAEQAgAQAAEgAwAgAAEwAgDwgAAN4FACAJAACWBQAgCwAAlwUAIAwAAJgFACC3AgEAAAABvwJAAAAAAcACQAAAAAHhAgEAAAAB4gIBAAAAAeMCAQAAAAHkAgEAAAAB5QIBAAAAAeYCAQAAAAHnAgEAAAAB6AIBAAAAAQEYAACcAQAgC7cCAQAAAAG_AkAAAAABwAJAAAAAAeECAQAAAAHiAgEAAAAB4wIBAAAAAeQCAQAAAAHlAgEAAAAB5gIBAAAAAecCAQAAAAHoAgEAAAABARgAAJ4BADABGAAAngEAMAEAAAAPACAPCAAA3QUAIAkAAKsEACALAACsBAAgDAAArQQAILcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeECAQCbBAAh4gIBAKkEACHjAgEAqQQAIeQCAQCpBAAh5QIBAKkEACHmAgEAmwQAIecCAQCbBAAh6AIBAKkEACECAAAAEwAgGAAAogEAIAu3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHhAgEAmwQAIeICAQCpBAAh4wIBAKkEACHkAgEAqQQAIeUCAQCpBAAh5gIBAJsEACHnAgEAmwQAIegCAQCpBAAhAgAAABEAIBgAAKQBACACAAAAEQAgGAAApAEAIAEAAAAPACADAAAAEwAgHwAAnAEAICAAAKIBACABAAAAEwAgAQAAABEAIAgHAADaBQAgJQAA3AUAICYAANsFACDiAgAAmwUAIOMCAACbBQAg5AIAAJsFACDlAgAAmwUAIOgCAACbBQAgDpsCAADuAwAwnAIAAKwBABCdAgAA7gMAMLcCAQDAAwAhvwJAALADACHAAkAAsAMAIeECAQCtAwAh4gIBANcDACHjAgEA1wMAIeQCAQDXAwAh5QIBANcDACHmAgEArQMAIecCAQCtAwAh6AIBANcDACEDAAAAEQAgAQAAqwEAMCQAAKwBACADAAAAEQAgAQAAEgAwAgAAEwAgAQAAAA0AIAEAAAANACADAAAACwAgAQAADAAwAgAADQAgAwAAAAsAIAEAAAwAMAIAAA0AIAMAAAALACABAAAMADACAAANACAGAwAAlAUAIAoAANkFACC_AkAAAAAB0wIBAAAAAd4CAQAAAAHgAgAAAOACAgEYAAC0AQAgBL8CQAAAAAHTAgEAAAAB3gIBAAAAAeACAAAA4AICARgAALYBADABGAAAtgEAMAYDAACSBQAgCgAA2AUAIL8CQACdBAAh0wIBAJsEACHeAgEAmwQAIeACAACQBeACIgIAAAANACAYAAC5AQAgBL8CQACdBAAh0wIBAJsEACHeAgEAmwQAIeACAACQBeACIgIAAAALACAYAAC7AQAgAgAAAAsAIBgAALsBACADAAAADQAgHwAAtAEAICAAALkBACABAAAADQAgAQAAAAsAIAMHAADVBQAgJQAA1wUAICYAANYFACAHmwIAAOoDADCcAgAAwgEAEJ0CAADqAwAwvwJAALADACHTAgEAwAMAId4CAQCtAwAh4AIAAOsD4AIiAwAAAAsAIAEAAMEBADAkAADCAQAgAwAAAAsAIAEAAAwAMAIAAA0AIAEAAAAZACABAAAAGQAgAwAAABcAIAEAABgAMAIAABkAIAMAAAAXACABAAAYADACAAAZACADAAAAFwAgAQAAGAAwAgAAGQAgCgoAANQFACC3AgEAAAABuAIBAAAAAb8CQAAAAAHAAkAAAAAB0wIBAAAAAdoCAQAAAAHbAkAAAAAB3AJAAAAAAd0CQAAAAAEBGAAAygEAIAm3AgEAAAABuAIBAAAAAb8CQAAAAAHAAkAAAAAB0wIBAAAAAdoCAQAAAAHbAkAAAAAB3AJAAAAAAd0CQAAAAAEBGAAAzAEAMAEYAADMAQAwCgoAANMFACC3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh2gIBAJsEACHbAkAAnQQAIdwCQACDBQAh3QJAAIMFACECAAAAGQAgGAAAzwEAIAm3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh2gIBAJsEACHbAkAAnQQAIdwCQACDBQAh3QJAAIMFACECAAAAFwAgGAAA0QEAIAIAAAAXACAYAADRAQAgAwAAABkAIB8AAMoBACAgAADPAQAgAQAAABkAIAEAAAAXACAFBwAA0AUAICUAANIFACAmAADRBQAg3AIAAJsFACDdAgAAmwUAIAybAgAA6QMAMJwCAADYAQAQnQIAAOkDADC3AgEAwAMAIbgCAQCtAwAhvwJAALADACHAAkAAsAMAIdMCAQDAAwAh2gIBAK0DACHbAkAAsAMAIdwCQADCAwAh3QJAAMIDACEDAAAAFwAgAQAA1wEAMCQAANgBACADAAAAFwAgAQAAGAAwAgAAGQAgCgwAAOgDACCbAgAA5gMAMJwCAADeAQAQnQIAAOYDADCfAgEAAAABtwIBAAAAAb8CQAC9AwAhwAJAAL0DACHQAiAA5wMAIdkCAQAAAAEBAAAA2wEAIAEAAADbAQAgCgwAAOgDACCbAgAA5gMAMJwCAADeAQAQnQIAAOYDADCfAgEAugMAIbcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIdACIADnAwAh2QIBALoDACEBDAAAzwUAIAMAAADeAQAgAQAA3wEAMAIAANsBACADAAAA3gEAIAEAAN8BADACAADbAQAgAwAAAN4BACABAADfAQAwAgAA2wEAIAcMAADOBQAgnwIBAAAAAbcCAQAAAAG_AkAAAAABwAJAAAAAAdACIAAAAAHZAgEAAAABARgAAOMBACAGnwIBAAAAAbcCAQAAAAG_AkAAAAABwAJAAAAAAdACIAAAAAHZAgEAAAABARgAAOUBADABGAAA5QEAMAcMAADEBQAgnwIBAJsEACG3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHQAiAAuQQAIdkCAQCbBAAhAgAAANsBACAYAADoAQAgBp8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh0AIgALkEACHZAgEAmwQAIQIAAADeAQAgGAAA6gEAIAIAAADeAQAgGAAA6gEAIAMAAADbAQAgHwAA4wEAICAAAOgBACABAAAA2wEAIAEAAADeAQAgAwcAAMEFACAlAADDBQAgJgAAwgUAIAmbAgAA5QMAMJwCAADxAQAQnQIAAOUDADCfAgEArQMAIbcCAQDAAwAhvwJAALADACHAAkAAsAMAIdACIADYAwAh2QIBAK0DACEDAAAA3gEAIAEAAPABADAkAADxAQAgAwAAAN4BACABAADfAQAwAgAA2wEAIAEAAAAdACABAAAAHQAgAwAAABsAIAEAABwAMAIAAB0AIAMAAAAbACABAAAcADACAAAdACADAAAAGwAgAQAAHAAwAgAAHQAgEAoAAMAFACANAAD0BAAgDwAA9QQAIBAAAPYEACARAAD3BAAgEgAA-AQAIJ8CAQAAAAG3AgEAAAABvwJAAAAAAcACQAAAAAHTAgEAAAAB1AIBAAAAAdUCAgAAAAHWAhAAAAAB1wIgAAAAAdgCAQAAAAEBGAAA-QEAIAqfAgEAAAABtwIBAAAAAb8CQAAAAAHAAkAAAAAB0wIBAAAAAdQCAQAAAAHVAgIAAAAB1gIQAAAAAdcCIAAAAAHYAgEAAAABARgAAPsBADABGAAA-wEAMBAKAAC_BQAgDQAAuwQAIA8AALwEACAQAAC9BAAgEQAAvgQAIBIAAL8EACCfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh1AIBAJsEACHVAgIAuAQAIdYCEACcBAAh1wIgALkEACHYAgEAqQQAIQIAAAAdACAYAAD-AQAgCp8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh0wIBAJsEACHUAgEAmwQAIdUCAgC4BAAh1gIQAJwEACHXAiAAuQQAIdgCAQCpBAAhAgAAABsAIBgAAIACACACAAAAGwAgGAAAgAIAIAMAAAAdACAfAAD5AQAgIAAA_gEAIAEAAAAdACABAAAAGwAgBgcAALoFACAlAAC9BQAgJgAAvAUAIDcAALsFACA4AAC-BQAg2AIAAJsFACANmwIAAOQDADCcAgAAhwIAEJ0CAADkAwAwnwIBAK0DACG3AgEAwAMAIb8CQACwAwAhwAJAALADACHTAgEAwAMAIdQCAQDAAwAh1QICAMEDACHWAhAArgMAIdcCIADYAwAh2AIBANcDACEDAAAAGwAgAQAAhgIAMCQAAIcCACADAAAAGwAgAQAAHAAwAgAAHQAgAQAAAC8AIAEAAAAvACADAAAALQAgAQAALgAwAgAALwAgAwAAAC0AIAEAAC4AMAIAAC8AIAMAAAAtACABAAAuADACAAAvACAJDgAAuQUAILcCAQAAAAG_AkAAAAABwAJAAAAAAcICAQAAAAHEAgEAAAABxQIBAAAAAdECQAAAAAHSAgEAAAABARgAAI8CACAItwIBAAAAAb8CQAAAAAHAAkAAAAABwgIBAAAAAcQCAQAAAAHFAgEAAAAB0QJAAAAAAdICAQAAAAEBGAAAkQIAMAEYAACRAgAwCQ4AALgFACC3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHCAgEAmwQAIcQCAQCpBAAhxQIBAKkEACHRAkAAnQQAIdICAQCpBAAhAgAAAC8AIBgAAJQCACAItwIBAJsEACG_AkAAnQQAIcACQACdBAAhwgIBAJsEACHEAgEAqQQAIcUCAQCpBAAh0QJAAJ0EACHSAgEAqQQAIQIAAAAtACAYAACWAgAgAgAAAC0AIBgAAJYCACADAAAALwAgHwAAjwIAICAAAJQCACABAAAALwAgAQAAAC0AIAYHAAC1BQAgJQAAtwUAICYAALYFACDEAgAAmwUAIMUCAACbBQAg0gIAAJsFACALmwIAAOMDADCcAgAAnQIAEJ0CAADjAwAwtwIBAMADACG_AkAAsAMAIcACQACwAwAhwgIBAMADACHEAgEA1wMAIcUCAQDXAwAh0QJAALADACHSAgEA1wMAIQMAAAAtACABAACcAgAwJAAAnQIAIAMAAAAtACABAAAuADACAAAvACABAAAAIwAgAQAAACMAIAMAAAAhACABAAAiADACAAAjACADAAAAIQAgAQAAIgAwAgAAIwAgAwAAACEAIAEAACIAMAIAACMAIAcOAAC0BQAgtwIBAAAAAb8CQAAAAAHCAgEAAAABxAIBAAAAAcUCAQAAAAHPAgAAAM8CAgEYAAClAgAgBrcCAQAAAAG_AkAAAAABwgIBAAAAAcQCAQAAAAHFAgEAAAABzwIAAADPAgIBGAAApwIAMAEYAACnAgAwBw4AALMFACC3AgEAmwQAIb8CQACdBAAhwgIBAJsEACHEAgEAmwQAIcUCAQCbBAAhzwIAAPAEzwIiAgAAACMAIBgAAKoCACAGtwIBAJsEACG_AkAAnQQAIcICAQCbBAAhxAIBAJsEACHFAgEAmwQAIc8CAADwBM8CIgIAAAAhACAYAACsAgAgAgAAACEAIBgAAKwCACADAAAAIwAgHwAApQIAICAAAKoCACABAAAAIwAgAQAAACEAIAMHAACwBQAgJQAAsgUAICYAALEFACAJmwIAAN8DADCcAgAAswIAEJ0CAADfAwAwtwIBAMADACG_AkAAsAMAIcICAQDAAwAhxAIBAK0DACHFAgEArQMAIc8CAADgA88CIgMAAAAhACABAACyAgAwJAAAswIAIAMAAAAhACABAAAiADACAAAjACABAAAAJwAgAQAAACcAIAMAAAAlACABAAAmADACAAAnACADAAAAJQAgAQAAJgAwAgAAJwAgAwAAACUAIAEAACYAMAIAACcAIAoOAACvBQAgoAIQAAAAAbcCAQAAAAG_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_AkAAvQMAIcACQAC9AwAhAQAAAPsCACABAAAA-wIAIA2bAgAAyQMAMJwCAAD-AgAQnQIAAMkDADC3AgEAygMAIbgCAQC6AwAhuQIBALoDACG6AkAAvQMAIbsCAgDLAwAhvAJAAL0DACG9AgIAywMAIb4CQADMAwAhvwJAAL0DACHAAkAAvQMAIQG-AgAAmwUAIAMAAAD-AgAgAQAA_wIAMAIAAPsCACADAAAA_gIAIAEAAP8CADACAAD7AgAgAwAAAP4CACABAAD_AgAwAgAA-wIAIAq3AgEAAAABuAIBAAAAAbkCAQAAAAG6AkAAAAABuwICAAAAAbwCQAAAAAG9AgIAAAABvgJAAAAAAb8CQAAAAAHAAkAAAAABARgAAIMDACAKtwIBAAAAAbgCAQAAAAG5AgEAAAABugJAAAAAAbsCAgAAAAG8AkAAAAABvQICAAAAAb4CQAAAAAG_AkAAAAABwAJAAAAAAQEYAACFAwAwARgAAIUDADAKtwIBAJsEACG4AgEAmwQAIbkCAQCbBAAhugJAAJ0EACG7AgIAuAQAIbwCQACdBAAhvQICALgEACG-AkAAgwUAIb8CQACdBAAhwAJAAJ0EACECAAAA-wIAIBgAAIgDACAKtwIBAJsEACG4AgEAmwQAIbkCAQCbBAAhugJAAJ0EACG7AgIAuAQAIbwCQACdBAAhvQICALgEACG-AkAAgwUAIb8CQACdBAAhwAJAAJ0EACECAAAA_gIAIBgAAIoDACACAAAA_gIAIBgAAIoDACADAAAA-wIAIB8AAIMDACAgAACIAwAgAQAAAPsCACABAAAA_gIAIAYHAACcBQAgJQAAnwUAICYAAJ4FACA3AACdBQAgOAAAoAUAIL4CAACbBQAgDZsCAAC_AwAwnAIAAJEDABCdAgAAvwMAMLcCAQDAAwAhuAIBAK0DACG5AgEArQMAIboCQACwAwAhuwICAMEDACG8AkAAsAMAIb0CAgDBAwAhvgJAAMIDACG_AkAAsAMAIcACQACwAwAhAwAAAP4CACABAACQAwAwJAAAkQMAIAMAAAD-AgAgAQAA_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_AwAwnAIAAJEDABCdAgAAvwMAMLcCAQDAAwAhuAIBAK0DACG5AgEArQMAIboCQACwAwAhuwICAMEDACG8AkAAsAMAIb0CAgDBAwAhvgJAAMIDACG_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_AkAAsAMAIcACQACwAwAh2wJAALADACHpAgEArQMAIeoCAQCtAwAhCZsCAADwAwAwnAIAAIEBABCdAgAA8AMAMLcCAQC6AwAhvwJAAL0DACHAAkAAvQMAIdsCQAC9AwAh6QIBALoDACHqAgEAugMAIRCbAgAA8QMAMJwCAAB7ABCdAgAA8QMAMLcCAQCtAwAhvwJAALADACHAAkAAsAMAId4CAQCtAwAh6wIBAK0DACHsAgEArQMAIe0CAQDXAwAh7gIBANcDACHvAgEA1wMAIfACQADCAwAh8QJAAMIDACHyAgEA1wMAIfMCAQDXAwAhEJsCAADyAwAwnAIAAGUAEJ0CAADyAwAwtwIBAK0DACG_AkAAsAMAIcACQACwAwAh2wJAALADACHeAgEArQMAIeMCAQDXAwAh5QIBANcDACH0AgEArQMAIfUCAQDXAwAh9gIBANcDACH3AgEA1wMAIfgCCADzAwAh-QIIAPMDACENBwAAxAMAICUAAPUDACAmAAD1AwAgNwAA9QMAIDgAAPUDACCjAggAAAABpAIIAAAABaUCCAAAAAWmAggAAAABpwIIAAAAAagCCAAAAAGpAggAAAABqgIIAPQDACENBwAAxAMAICUAAPUDACAmAAD1AwAgNwAA9QMAIDgAAPUDACCjAggAAAABpAIIAAAABaUCCAAAAAWmAggAAAABpwIIAAAAAagCCAAAAAGpAggAAAABqgIIAPQDACEIowIIAAAAAaQCCAAAAAWlAggAAAAFpgIIAAAAAacCCAAAAAGoAggAAAABqQIIAAAAAaoCCAD1AwAhD5sCAAD2AwAwnAIAAE8AEJ0CAAD2AwAwnwIBAK0DACG3AgEArQMAIbgCAQCtAwAhvwJAALADACHAAkAAsAMAIeACAQCtAwAh-gIgANgDACH7AgEA1wMAIfwCAQDXAwAh_QIgANgDACH-AkAAwgMAIf8CAQDXAwAhEgQAAPkDACAFAAD6AwAgBgAA-wMAIJsCAAD3AwAwnAIAADwAEJ0CAAD3AwAwnwIBALoDACG3AgEAugMAIbgCAQC6AwAhvwJAAL0DACHAAkAAvQMAIeACAQC6AwAh-gIgAOcDACH7AgEA-AMAIfwCAQD4AwAh_QIgAOcDACH-AkAAzAMAIf8CAQD4AwAhC6MCAQAAAAGkAgEAAAAFpQIBAAAABaYCAQAAAAGnAgEAAAABqAIBAAAAAakCAQAAAAGqAgEA3AMAIbECAQAAAAGyAgEAAAABswIBAAAAAQO0AgAAAwAgtQIAAAMAILYCAAADACADtAIAAAcAILUCAAAHACC2AgAABwAgA7QCAAALACC1AgAACwAgtgIAAAsAIAwOAAD9AwAgmwIAAPwDADCcAgAALQAQnQIAAPwDADC3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHCAgEAygMAIcQCAQD4AwAhxQIBAPgDACHRAkAAvQMAIdICAQD4AwAhFQoAAIUEACANAACGBAAgDwAAhwQAIBAAAIgEACARAACJBAAgEgAAigQAIJsCAACEBAAwnAIAABsAEJ0CAACEBAAwnwIBALoDACG3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHTAgEAygMAIdQCAQDKAwAh1QICAMsDACHWAhAAuwMAIdcCIADnAwAh2AIBAPgDACGCAwAAGwAggwMAABsAIAPCAgEAAAABwwJAAAAAAcQCAQAAAAEQDgAA_QMAIJsCAAD_AwAwnAIAACkAEJ0CAAD_AwAwtwIBAMoDACG_AkAAvQMAIcACQAC9AwAhwQIBALoDACHCAgEAygMAIcMCQAC9AwAhxAIBALoDACHFAgEAugMAIckCAQC6AwAhygIBALoDACHLAgEAugMAIc0CAADTA8cCIg0OAAD9AwAgmwIAAIAEADCcAgAAJQAQnQIAAIAEADCgAhAAuwMAIbcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIc8CAACBBM8CI9ACIADnAwAhBKMCAAAAzwIDpAIAAADPAgmlAgAAAM8CCaoCAADeA88CIwoOAAD9AwAgmwIAAIIEADCcAgAAIQAQnQIAAIIEADC3AgEAygMAIb8CQAC9AwAhwgIBAMoDACHEAgEAugMAIcUCAQC6AwAhzwIAAIMEzwIiBKMCAAAAzwICpAIAAADPAgilAgAAAM8CCKoCAADiA88CIhMKAACFBAAgDQAAhgQAIA8AAIcEACAQAACIBAAgEQAAiQQAIBIAAIoEACCbAgAAhAQAMJwCAAAbABCdAgAAhAQAMJ8CAQC6AwAhtwIBAMoDACG_AkAAvQMAIcACQAC9AwAh0wIBAMoDACHUAgEAygMAIdUCAgDLAwAh1gIQALsDACHXAiAA5wMAIdgCAQD4AwAhFAgAAI0EACAJAAD7AwAgCwAAjgQAIAwAAOgDACCbAgAAjAQAMJwCAAARABCdAgAAjAQAMLcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIeECAQC6AwAh4gIBAPgDACHjAgEA-AMAIeQCAQD4AwAh5QIBAPgDACHmAgEAugMAIecCAQC6AwAh6AIBAPgDACGCAwAAEQAggwMAABEAIAwMAADoAwAgmwIAAOYDADCcAgAA3gEAEJ0CAADmAwAwnwIBALoDACG3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHQAiAA5wMAIdkCAQC6AwAhggMAAN4BACCDAwAA3gEAIAO0AgAAIQAgtQIAACEAILYCAAAhACADtAIAACUAILUCAAAlACC2AgAAJQAgA7QCAAApACC1AgAAKQAgtgIAACkAIAO0AgAALQAgtQIAAC0AILYCAAAtACANCgAAhQQAIJsCAACLBAAwnAIAABcAEJ0CAACLBAAwtwIBAMoDACG4AgEAugMAIb8CQAC9AwAhwAJAAL0DACHTAgEAygMAIdoCAQC6AwAh2wJAAL0DACHcAkAAzAMAId0CQADMAwAhEggAAI0EACAJAAD7AwAgCwAAjgQAIAwAAOgDACCbAgAAjAQAMJwCAAARABCdAgAAjAQAMLcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIeECAQC6AwAh4gIBAPgDACHjAgEA-AMAIeQCAQD4AwAh5QIBAPgDACHmAgEAugMAIecCAQC6AwAh6AIBAPgDACELBgAAvgMAIJsCAAC5AwAwnAIAAA8AEJ0CAAC5AwAwngIBALoDACGfAgEAugMAIaACEAC7AwAhoQIAALwDACCiAkAAvQMAIYIDAAAPACCDAwAADwAgA7QCAAAXACC1AgAAFwAgtgIAABcAIALTAgEAAAAB3gIBAAAAAQkDAACSBAAgCgAAhQQAIJsCAACQBAAwnAIAAAsAEJ0CAACQBAAwvwJAAL0DACHTAgEAygMAId4CAQC6AwAh4AIAAJEE4AIiBKMCAAAA4AICpAIAAADgAgilAgAAAOACCKoCAADtA-ACIhQEAAD5AwAgBQAA-gMAIAYAAPsDACCbAgAA9wMAMJwCAAA8ABCdAgAA9wMAMJ8CAQC6AwAhtwIBALoDACG4AgEAugMAIb8CQAC9AwAhwAJAAL0DACHgAgEAugMAIfoCIADnAwAh-wIBAPgDACH8AgEA-AMAIf0CIADnAwAh_gJAAMwDACH_AgEA-AMAIYIDAAA8ACCDAwAAPAAgEQMAAJIEACCbAgAAkwQAMJwCAAAHABCdAgAAkwQAMLcCAQC6AwAhvwJAAL0DACHAAkAAvQMAId4CAQC6AwAh6wIBALoDACHsAgEAugMAIe0CAQD4AwAh7gIBAPgDACHvAgEA-AMAIfACQADMAwAh8QJAAMwDACHyAgEA-AMAIfMCAQD4AwAhEQMAAJIEACCbAgAAlAQAMJwCAAADABCdAgAAlAQAMLcCAQC6AwAhvwJAAL0DACHAAkAAvQMAIdsCQAC9AwAh3gIBALoDACHjAgEA-AMAIeUCAQD4AwAh9AIBALoDACH1AgEA-AMAIfYCAQD4AwAh9wIBAPgDACH4AggAlQQAIfkCCACVBAAhCKMCCAAAAAGkAggAAAAFpQIIAAAABaYCCAAAAAGnAggAAAABqAIIAAAAAakCCAAAAAGqAggA9QMAIQAAAAAAAYcDAQAAAAEFhwMQAAAAAY0DEAAAAAGOAxAAAAABjwMQAAAAAZADEAAAAAEBhwNAAAAAAQsfAACfBAAwIAAApAQAMIQDAACgBAAwhQMAAKEEADCGAwAAogQAIIcDAACjBAAwiAMAAKMEADCJAwAAowQAMIoDAACjBAAwiwMAAKUEADCMAwAApgQAMA0JAACWBQAgCwAAlwUAIAwAAJgFACC3AgEAAAABvwJAAAAAAcACQAAAAAHhAgEAAAAB4gIBAAAAAeMCAQAAAAHkAgEAAAAB5QIBAAAAAeYCAQAAAAHnAgEAAAABAgAAABMAIB8AAJUFACADAAAAEwAgHwAAlQUAICAAAKoEACABGAAA7QYAMBIIAACNBAAgCQAA-wMAIAsAAI4EACAMAADoAwAgmwIAAIwEADCcAgAAEQAQnQIAAIwEADC3AgEAAAABvwJAAL0DACHAAkAAvQMAIeECAQC6AwAh4gIBAPgDACHjAgEA-AMAIeQCAQD4AwAh5QIBAPgDACHmAgEAAAAB5wIBALoDACHoAgEA-AMAIQIAAAATACAYAACqBAAgAgAAAKcEACAYAACoBAAgDpsCAACmBAAwnAIAAKcEABCdAgAApgQAMLcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIeECAQC6AwAh4gIBAPgDACHjAgEA-AMAIeQCAQD4AwAh5QIBAPgDACHmAgEAugMAIecCAQC6AwAh6AIBAPgDACEOmwIAAKYEADCcAgAApwQAEJ0CAACmBAAwtwIBAMoDACG_AkAAvQMAIcACQAC9AwAh4QIBALoDACHiAgEA-AMAIeMCAQD4AwAh5AIBAPgDACHlAgEA-AMAIeYCAQC6AwAh5wIBALoDACHoAgEA-AMAIQq3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHhAgEAmwQAIeICAQCpBAAh4wIBAKkEACHkAgEAqQQAIeUCAQCpBAAh5gIBAJsEACHnAgEAmwQAIQGHAwEAAAABDQkAAKsEACALAACsBAAgDAAArQQAILcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeECAQCbBAAh4gIBAKkEACHjAgEAqQQAIeQCAQCpBAAh5QIBAKkEACHmAgEAmwQAIecCAQCbBAAhCx8AAIYFADAgAACLBQAwhAMAAIcFADCFAwAAiAUAMIYDAACJBQAghwMAAIoFADCIAwAAigUAMIkDAACKBQAwigMAAIoFADCLAwAAjAUAMIwDAACNBQAwCx8AAPkEADAgAAD-BAAwhAMAAPoEADCFAwAA-wQAMIYDAAD8BAAghwMAAP0EADCIAwAA_QQAMIkDAAD9BAAwigMAAP0EADCLAwAA_wQAMIwDAACABQAwCx8AAK4EADAgAACzBAAwhAMAAK8EADCFAwAAsAQAMIYDAACxBAAghwMAALIEADCIAwAAsgQAMIkDAACyBAAwigMAALIEADCLAwAAtAQAMIwDAAC1BAAwDg0AAPQEACAPAAD1BAAgEAAA9gQAIBEAAPcEACASAAD4BAAgnwIBAAAAAbcCAQAAAAG_AkAAAAABwAJAAAAAAdQCAQAAAAHVAgIAAAAB1gIQAAAAAdcCIAAAAAHYAgEAAAABAgAAAB0AIB8AAPMEACADAAAAHQAgHwAA8wQAICAAALoEACABGAAA7AYAMBMKAACFBAAgDQAAhgQAIA8AAIcEACAQAACIBAAgEQAAiQQAIBIAAIoEACCbAgAAhAQAMJwCAAAbABCdAgAAhAQAMJ8CAQC6AwAhtwIBAAAAAb8CQAC9AwAhwAJAAL0DACHTAgEAygMAIdQCAQDKAwAh1QICAMsDACHWAhAAuwMAIdcCIADnAwAh2AIBAPgDACECAAAAHQAgGAAAugQAIAIAAAC2BAAgGAAAtwQAIA2bAgAAtQQAMJwCAAC2BAAQnQIAALUEADCfAgEAugMAIbcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIdMCAQDKAwAh1AIBAMoDACHVAgIAywMAIdYCEAC7AwAh1wIgAOcDACHYAgEA-AMAIQ2bAgAAtQQAMJwCAAC2BAAQnQIAALUEADCfAgEAugMAIbcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIdMCAQDKAwAh1AIBAMoDACHVAgIAywMAIdYCEAC7AwAh1wIgAOcDACHYAgEA-AMAIQmfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdQCAQCbBAAh1QICALgEACHWAhAAnAQAIdcCIAC5BAAh2AIBAKkEACEFhwMCAAAAAY0DAgAAAAGOAwIAAAABjwMCAAAAAZADAgAAAAEBhwMgAAAAAQ4NAAC7BAAgDwAAvAQAIBAAAL0EACARAAC-BAAgEgAAvwQAIJ8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh1AIBAJsEACHVAgIAuAQAIdYCEACcBAAh1wIgALkEACHYAgEAqQQAIQUfAADjBgAgIAAA6gYAIIQDAADkBgAghQMAAOkGACCKAwAA2wEAIAsfAADmBAAwIAAA6wQAMIQDAADnBAAwhQMAAOgEADCGAwAA6QQAIIcDAADqBAAwiAMAAOoEADCJAwAA6gQAMIoDAADqBAAwiwMAAOwEADCMAwAA7QQAMAsfAADZBAAwIAAA3gQAMIQDAADaBAAwhQMAANsEADCGAwAA3AQAIIcDAADdBAAwiAMAAN0EADCJAwAA3QQAMIoDAADdBAAwiwMAAN8EADCMAwAA4AQAMAsfAADMBAAwIAAA0QQAMIQDAADNBAAwhQMAAM4EADCGAwAAzwQAIIcDAADQBAAwiAMAANAEADCJAwAA0AQAMIoDAADQBAAwiwMAANIEADCMAwAA0wQAMAsfAADABAAwIAAAxQQAMIQDAADBBAAwhQMAAMIEADCGAwAAwwQAIIcDAADEBAAwiAMAAMQEADCJAwAAxAQAMIoDAADEBAAwiwMAAMYEADCMAwAAxwQAMAe3AgEAAAABvwJAAAAAAcACQAAAAAHEAgEAAAABxQIBAAAAAdECQAAAAAHSAgEAAAABAgAAAC8AIB8AAMsEACADAAAALwAgHwAAywQAICAAAMoEACABGAAA6AYAMAwOAAD9AwAgmwIAAPwDADCcAgAALQAQnQIAAPwDADC3AgEAAAABvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIdECQAC9AwAh0gIBAPgDACECAAAALwAgGAAAygQAIAIAAADIBAAgGAAAyQQAIAubAgAAxwQAMJwCAADIBAAQnQIAAMcEADC3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHCAgEAygMAIcQCAQD4AwAhxQIBAPgDACHRAkAAvQMAIdICAQD4AwAhC5sCAADHBAAwnAIAAMgEABCdAgAAxwQAMLcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIdECQAC9AwAh0gIBAPgDACEHtwIBAJsEACG_AkAAnQQAIcACQACdBAAhxAIBAKkEACHFAgEAqQQAIdECQACdBAAh0gIBAKkEACEHtwIBAJsEACG_AkAAnQQAIcACQACdBAAhxAIBAKkEACHFAgEAqQQAIdECQACdBAAh0gIBAKkEACEHtwIBAAAAAb8CQAAAAAHAAkAAAAABxAIBAAAAAcUCAQAAAAHRAkAAAAAB0gIBAAAAAQu3AgEAAAABvwJAAAAAAcACQAAAAAHBAgEAAAABwwJAAAAAAcQCAQAAAAHFAgEAAAAByQIBAAAAAcoCAQAAAAHLAgEAAAABzQIAAADHAgICAAAAKwAgHwAA2AQAIAMAAAArACAfAADYBAAgIAAA1wQAIAEYAADnBgAwEQ4AAP0DACCbAgAA_wMAMJwCAAApABCdAgAA_wMAMLcCAQAAAAG_AkAAvQMAIcACQAC9AwAhwQIBAAAAAcICAQDKAwAhwwJAAL0DACHEAgEAugMAIcUCAQC6AwAhyQIBALoDACHKAgEAugMAIcsCAQC6AwAhzQIAANMDxwIigAMAAP4DACACAAAAKwAgGAAA1wQAIAIAAADUBAAgGAAA1QQAIA-bAgAA0wQAMJwCAADUBAAQnQIAANMEADC3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHBAgEAugMAIcICAQDKAwAhwwJAAL0DACHEAgEAugMAIcUCAQC6AwAhyQIBALoDACHKAgEAugMAIcsCAQC6AwAhzQIAANMDxwIiD5sCAADTBAAwnAIAANQEABCdAgAA0wQAMLcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIcECAQC6AwAhwgIBAMoDACHDAkAAvQMAIcQCAQC6AwAhxQIBALoDACHJAgEAugMAIcoCAQC6AwAhywIBALoDACHNAgAA0wPHAiILtwIBAJsEACG_AkAAnQQAIcACQACdBAAhwQIBAJsEACHDAkAAnQQAIcQCAQCbBAAhxQIBAJsEACHJAgEAmwQAIcoCAQCbBAAhywIBAJsEACHNAgAA1gTHAiIBhwMAAADHAgILtwIBAJsEACG_AkAAnQQAIcACQACdBAAhwQIBAJsEACHDAkAAnQQAIcQCAQCbBAAhxQIBAJsEACHJAgEAmwQAIcoCAQCbBAAhywIBAJsEACHNAgAA1gTHAiILtwIBAAAAAb8CQAAAAAHAAkAAAAABwQIBAAAAAcMCQAAAAAHEAgEAAAABxQIBAAAAAckCAQAAAAHKAgEAAAABywIBAAAAAc0CAAAAxwICCKACEAAAAAG3AgEAAAABvwJAAAAAAcACQAAAAAHEAgEAAAABxQIBAAAAAc8CAAAAzwID0AIgAAAAAQIAAAAnACAfAADlBAAgAwAAACcAIB8AAOUEACAgAADkBAAgARgAAOYGADANDgAA_QMAIJsCAACABAAwnAIAACUAEJ0CAACABAAwoAIQALsDACG3AgEAAAABvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIc8CAACBBM8CI9ACIADnAwAhAgAAACcAIBgAAOQEACACAAAA4QQAIBgAAOIEACAMmwIAAOAEADCcAgAA4QQAEJ0CAADgBAAwoAIQALsDACG3AgEAygMAIb8CQAC9AwAhwAJAAL0DACHCAgEAygMAIcQCAQD4AwAhxQIBAPgDACHPAgAAgQTPAiPQAiAA5wMAIQybAgAA4AQAMJwCAADhBAAQnQIAAOAEADCgAhAAuwMAIbcCAQDKAwAhvwJAAL0DACHAAkAAvQMAIcICAQDKAwAhxAIBAPgDACHFAgEA-AMAIc8CAACBBM8CI9ACIADnAwAhCKACEACcBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAhxAIBAKkEACHFAgEAqQQAIc8CAADjBM8CI9ACIAC5BAAhAYcDAAAAzwIDCKACEACcBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAhxAIBAKkEACHFAgEAqQQAIc8CAADjBM8CI9ACIAC5BAAhCKACEAAAAAG3AgEAAAABvwJAAAAAAcACQAAAAAHEAgEAAAABxQIBAAAAAc8CAAAAzwID0AIgAAAAAQW3AgEAAAABvwJAAAAAAcQCAQAAAAHFAgEAAAABzwIAAADPAgICAAAAIwAgHwAA8gQAIAMAAAAjACAfAADyBAAgIAAA8QQAIAEYAADlBgAwCg4AAP0DACCbAgAAggQAMJwCAAAhABCdAgAAggQAMLcCAQAAAAG_AkAAvQMAIcICAQDKAwAhxAIBALoDACHFAgEAugMAIc8CAACDBM8CIgIAAAAjACAYAADxBAAgAgAAAO4EACAYAADvBAAgCZsCAADtBAAwnAIAAO4EABCdAgAA7QQAMLcCAQDKAwAhvwJAAL0DACHCAgEAygMAIcQCAQC6AwAhxQIBALoDACHPAgAAgwTPAiIJmwIAAO0EADCcAgAA7gQAEJ0CAADtBAAwtwIBAMoDACG_AkAAvQMAIcICAQDKAwAhxAIBALoDACHFAgEAugMAIc8CAACDBM8CIgW3AgEAmwQAIb8CQACdBAAhxAIBAJsEACHFAgEAmwQAIc8CAADwBM8CIgGHAwAAAM8CAgW3AgEAmwQAIb8CQACdBAAhxAIBAJsEACHFAgEAmwQAIc8CAADwBM8CIgW3AgEAAAABvwJAAAAAAcQCAQAAAAHFAgEAAAABzwIAAADPAgIODQAA9AQAIA8AAPUEACAQAAD2BAAgEQAA9wQAIBIAAPgEACCfAgEAAAABtwIBAAAAAb8CQAAAAAHAAkAAAAAB1AIBAAAAAdUCAgAAAAHWAhAAAAAB1wIgAAAAAdgCAQAAAAEDHwAA4wYAIIQDAADkBgAgigMAANsBACAEHwAA5gQAMIQDAADnBAAwhgMAAOkEACCKAwAA6gQAMAQfAADZBAAwhAMAANoEADCGAwAA3AQAIIoDAADdBAAwBB8AAMwEADCEAwAAzQQAMIYDAADPBAAgigMAANAEADAEHwAAwAQAMIQDAADBBAAwhgMAAMMEACCKAwAAxAQAMAi3AgEAAAABuAIBAAAAAb8CQAAAAAHAAkAAAAAB2gIBAAAAAdsCQAAAAAHcAkAAAAAB3QJAAAAAAQIAAAAZACAfAACFBQAgAwAAABkAIB8AAIUFACAgAACEBQAgARgAAOIGADANCgAAhQQAIJsCAACLBAAwnAIAABcAEJ0CAACLBAAwtwIBAAAAAbgCAQC6AwAhvwJAAL0DACHAAkAAvQMAIdMCAQDKAwAh2gIBAAAAAdsCQAC9AwAh3AJAAMwDACHdAkAAzAMAIQIAAAAZACAYAACEBQAgAgAAAIEFACAYAACCBQAgDJsCAACABQAwnAIAAIEFABCdAgAAgAUAMLcCAQDKAwAhuAIBALoDACG_AkAAvQMAIcACQAC9AwAh0wIBAMoDACHaAgEAugMAIdsCQAC9AwAh3AJAAMwDACHdAkAAzAMAIQybAgAAgAUAMJwCAACBBQAQnQIAAIAFADC3AgEAygMAIbgCAQC6AwAhvwJAAL0DACHAAkAAvQMAIdMCAQDKAwAh2gIBALoDACHbAkAAvQMAIdwCQADMAwAh3QJAAMwDACEItwIBAJsEACG4AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHaAgEAmwQAIdsCQACdBAAh3AJAAIMFACHdAkAAgwUAIQGHA0AAAAABCLcCAQCbBAAhuAIBAJsEACG_AkAAnQQAIcACQACdBAAh2gIBAJsEACHbAkAAnQQAIdwCQACDBQAh3QJAAIMFACEItwIBAAAAAbgCAQAAAAG_AkAAAAABwAJAAAAAAdoCAQAAAAHbAkAAAAAB3AJAAAAAAd0CQAAAAAEEAwAAlAUAIL8CQAAAAAHeAgEAAAAB4AIAAADgAgICAAAADQAgHwAAkwUAIAMAAAANACAfAACTBQAgIAAAkQUAIAEYAADhBgAwCgMAAJIEACAKAACFBAAgmwIAAJAEADCcAgAACwAQnQIAAJAEADC_AkAAvQMAIdMCAQDKAwAh3gIBALoDACHgAgAAkQTgAiKBAwAAjwQAIAIAAAANACAYAACRBQAgAgAAAI4FACAYAACPBQAgB5sCAACNBQAwnAIAAI4FABCdAgAAjQUAML8CQAC9AwAh0wIBAMoDACHeAgEAugMAIeACAACRBOACIgebAgAAjQUAMJwCAACOBQAQnQIAAI0FADC_AkAAvQMAIdMCAQDKAwAh3gIBALoDACHgAgAAkQTgAiIDvwJAAJ0EACHeAgEAmwQAIeACAACQBeACIgGHAwAAAOACAgQDAACSBQAgvwJAAJ0EACHeAgEAmwQAIeACAACQBeACIgUfAADcBgAgIAAA3wYAIIQDAADdBgAghQMAAN4GACCKAwAAAQAgBAMAAJQFACC_AkAAAAAB3gIBAAAAAeACAAAA4AICAx8AANwGACCEAwAA3QYAIIoDAAABACANCQAAlgUAIAsAAJcFACAMAACYBQAgtwIBAAAAAb8CQAAAAAHAAkAAAAAB4QIBAAAAAeICAQAAAAHjAgEAAAAB5AIBAAAAAeUCAQAAAAHmAgEAAAAB5wIBAAAAAQQfAACGBQAwhAMAAIcFADCGAwAAiQUAIIoDAACKBQAwBB8AAPkEADCEAwAA-gQAMIYDAAD8BAAgigMAAP0EADAEHwAArgQAMIQDAACvBAAwhgMAALEEACCKAwAAsgQAMAQfAACfBAAwhAMAAKAEADCGAwAAogQAIIoDAACjBAAwAAAAAAAAAAAAAAAAAAUfAADXBgAgIAAA2gYAIIQDAADYBgAghQMAANkGACCKAwAAHQAgAx8AANcGACCEAwAA2AYAIIoDAAAdACAAAAAAAAUfAADSBgAgIAAA1QYAIIQDAADTBgAghQMAANQGACCKAwAAHQAgAx8AANIGACCEAwAA0wYAIIoDAAAdACAAAAAFHwAAzQYAICAAANAGACCEAwAAzgYAIIUDAADPBgAgigMAAB0AIAMfAADNBgAghAMAAM4GACCKAwAAHQAgAAAABR8AAMgGACAgAADLBgAghAMAAMkGACCFAwAAygYAIIoDAAAdACADHwAAyAYAIIQDAADJBgAgigMAAB0AIAAAAAAABR8AAMMGACAgAADGBgAghAMAAMQGACCFAwAAxQYAIIoDAAATACADHwAAwwYAIIQDAADEBgAgigMAABMAIAAAAAsfAADFBQAwIAAAyQUAMIQDAADGBQAwhQMAAMcFADCGAwAAyAUAIIcDAACyBAAwiAMAALIEADCJAwAAsgQAMIoDAACyBAAwiwMAAMoFADCMAwAAtQQAMA4KAADABQAgDwAA9QQAIBAAAPYEACARAAD3BAAgEgAA-AQAIJ8CAQAAAAG3AgEAAAABvwJAAAAAAcACQAAAAAHTAgEAAAAB1QICAAAAAdYCEAAAAAHXAiAAAAAB2AIBAAAAAQIAAAAdACAfAADNBQAgAwAAAB0AIB8AAM0FACAgAADMBQAgARgAAMIGADACAAAAHQAgGAAAzAUAIAIAAAC2BAAgGAAAywUAIAmfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh1QICALgEACHWAhAAnAQAIdcCIAC5BAAh2AIBAKkEACEOCgAAvwUAIA8AALwEACAQAAC9BAAgEQAAvgQAIBIAAL8EACCfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh1QICALgEACHWAhAAnAQAIdcCIAC5BAAh2AIBAKkEACEOCgAAwAUAIA8AAPUEACAQAAD2BAAgEQAA9wQAIBIAAPgEACCfAgEAAAABtwIBAAAAAb8CQAAAAAHAAkAAAAAB0wIBAAAAAdUCAgAAAAHWAhAAAAAB1wIgAAAAAdgCAQAAAAEEHwAAxQUAMIQDAADGBQAwhgMAAMgFACCKAwAAsgQAMAAAAAAFHwAAvQYAICAAAMAGACCEAwAAvgYAIIUDAAC_BgAgigMAABMAIAMfAAC9BgAghAMAAL4GACCKAwAAEwAgAAAABR8AALgGACAgAAC7BgAghAMAALkGACCFAwAAugYAIIoDAAATACADHwAAuAYAIIQDAAC5BgAgigMAABMAIAAAAAcfAACzBgAgIAAAtgYAIIQDAAC0BgAghQMAALUGACCIAwAADwAgiQMAAA8AIIoDAACUAwAgAx8AALMGACCEAwAAtAYAIIoDAACUAwAgAAAAAAAABR8AAK4GACAgAACxBgAghAMAAK8GACCFAwAAsAYAIIoDAAABACADHwAArgYAIIQDAACvBgAgigMAAAEAIAAAAAAABYcDCAAAAAGNAwgAAAABjgMIAAAAAY8DCAAAAAGQAwgAAAABBR8AAKkGACAgAACsBgAghAMAAKoGACCFAwAAqwYAIIoDAAABACADHwAAqQYAIIQDAACqBgAgigMAAAEAIAAAAAsfAACKBgAwIAAAjwYAMIQDAACLBgAwhQMAAIwGADCGAwAAjQYAIIcDAACOBgAwiAMAAI4GADCJAwAAjgYAMIoDAACOBgAwiwMAAJAGADCMAwAAkQYAMAsfAAD-BQAwIAAAgwYAMIQDAAD_BQAwhQMAAIAGADCGAwAAgQYAIIcDAACCBgAwiAMAAIIGADCJAwAAggYAMIoDAACCBgAwiwMAAIQGADCMAwAAhQYAMAsfAAD1BQAwIAAA-QUAMIQDAAD2BQAwhQMAAPcFADCGAwAA-AUAIIcDAACKBQAwiAMAAIoFADCJAwAAigUAMIoDAACKBQAwiwMAAPoFADCMAwAAjQUAMAQKAADZBQAgvwJAAAAAAdMCAQAAAAHgAgAAAOACAgIAAAANACAfAAD9BQAgAwAAAA0AIB8AAP0FACAgAAD8BQAgARgAAKgGADACAAAADQAgGAAA_AUAIAIAAACOBQAgGAAA-wUAIAO_AkAAnQQAIdMCAQCbBAAh4AIAAJAF4AIiBAoAANgFACC_AkAAnQQAIdMCAQCbBAAh4AIAAJAF4AIiBAoAANkFACC_AkAAAAAB0wIBAAAAAeACAAAA4AICDLcCAQAAAAG_AkAAAAABwAJAAAAAAesCAQAAAAHsAgEAAAAB7QIBAAAAAe4CAQAAAAHvAgEAAAAB8AJAAAAAAfECQAAAAAHyAgEAAAAB8wIBAAAAAQIAAAAJACAfAACJBgAgAwAAAAkAIB8AAIkGACAgAACIBgAgARgAAKcGADARAwAAkgQAIJsCAACTBAAwnAIAAAcAEJ0CAACTBAAwtwIBAAAAAb8CQAC9AwAhwAJAAL0DACHeAgEAugMAIesCAQC6AwAh7AIBALoDACHtAgEA-AMAIe4CAQD4AwAh7wIBAPgDACHwAkAAzAMAIfECQADMAwAh8gIBAPgDACHzAgEA-AMAIQIAAAAJACAYAACIBgAgAgAAAIYGACAYAACHBgAgEJsCAACFBgAwnAIAAIYGABCdAgAAhQYAMLcCAQC6AwAhvwJAAL0DACHAAkAAvQMAId4CAQC6AwAh6wIBALoDACHsAgEAugMAIe0CAQD4AwAh7gIBAPgDACHvAgEA-AMAIfACQADMAwAh8QJAAMwDACHyAgEA-AMAIfMCAQD4AwAhEJsCAACFBgAwnAIAAIYGABCdAgAAhQYAMLcCAQC6AwAhvwJAAL0DACHAAkAAvQMAId4CAQC6AwAh6wIBALoDACHsAgEAugMAIe0CAQD4AwAh7gIBAPgDACHvAgEA-AMAIfACQADMAwAh8QJAAMwDACHyAgEA-AMAIfMCAQD4AwAhDLcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIesCAQCbBAAh7AIBAJsEACHtAgEAqQQAIe4CAQCpBAAh7wIBAKkEACHwAkAAgwUAIfECQACDBQAh8gIBAKkEACHzAgEAqQQAIQy3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHrAgEAmwQAIewCAQCbBAAh7QIBAKkEACHuAgEAqQQAIe8CAQCpBAAh8AJAAIMFACHxAkAAgwUAIfICAQCpBAAh8wIBAKkEACEMtwIBAAAAAb8CQAAAAAHAAkAAAAAB6wIBAAAAAewCAQAAAAHtAgEAAAAB7gIBAAAAAe8CAQAAAAHwAkAAAAAB8QJAAAAAAfICAQAAAAHzAgEAAAABDLcCAQAAAAG_AkAAAAABwAJAAAAAAdsCQAAAAAHjAgEAAAAB5QIBAAAAAfQCAQAAAAH1AgEAAAAB9gIBAAAAAfcCAQAAAAH4AggAAAAB-QIIAAAAAQIAAAAFACAfAACVBgAgAwAAAAUAIB8AAJUGACAgAACUBgAgARgAAKYGADARAwAAkgQAIJsCAACUBAAwnAIAAAMAEJ0CAACUBAAwtwIBAAAAAb8CQAC9AwAhwAJAAL0DACHbAkAAvQMAId4CAQC6AwAh4wIBAPgDACHlAgEA-AMAIfQCAQAAAAH1AgEA-AMAIfYCAQD4AwAh9wIBAPgDACH4AggAlQQAIfkCCACVBAAhAgAAAAUAIBgAAJQGACACAAAAkgYAIBgAAJMGACAQmwIAAJEGADCcAgAAkgYAEJ0CAACRBgAwtwIBALoDACG_AkAAvQMAIcACQAC9AwAh2wJAAL0DACHeAgEAugMAIeMCAQD4AwAh5QIBAPgDACH0AgEAugMAIfUCAQD4AwAh9gIBAPgDACH3AgEA-AMAIfgCCACVBAAh-QIIAJUEACEQmwIAAJEGADCcAgAAkgYAEJ0CAACRBgAwtwIBALoDACG_AkAAvQMAIcACQAC9AwAh2wJAAL0DACHeAgEAugMAIeMCAQD4AwAh5QIBAPgDACH0AgEAugMAIfUCAQD4AwAh9gIBAPgDACH3AgEA-AMAIfgCCACVBAAh-QIIAJUEACEMtwIBAJsEACG_AkAAnQQAIcACQACdBAAh2wJAAJ0EACHjAgEAqQQAIeUCAQCpBAAh9AIBAJsEACH1AgEAqQQAIfYCAQCpBAAh9wIBAKkEACH4AggA7AUAIfkCCADsBQAhDLcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdsCQACdBAAh4wIBAKkEACHlAgEAqQQAIfQCAQCbBAAh9QIBAKkEACH2AgEAqQQAIfcCAQCpBAAh-AIIAOwFACH5AggA7AUAIQy3AgEAAAABvwJAAAAAAcACQAAAAAHbAkAAAAAB4wIBAAAAAeUCAQAAAAH0AgEAAAAB9QIBAAAAAfYCAQAAAAH3AgEAAAAB-AIIAAAAAfkCCAAAAAEEHwAAigYAMIQDAACLBgAwhgMAAI0GACCKAwAAjgYAMAQfAAD-BQAwhAMAAP8FADCGAwAAgQYAIIoDAACCBgAwBB8AAPUFADCEAwAA9gUAMIYDAAD4BQAgigMAAIoFADAAAAAHCgAAnQYAIA0AAJ4GACAPAACfBgAgEAAAoAYAIBEAAKEGACASAACiBgAg2AIAAJsFACAJCAAAowYAIAkAAJsGACALAACkBgAgDAAAzwUAIOICAACbBQAg4wIAAJsFACDkAgAAmwUAIOUCAACbBQAg6AIAAJsFACABDAAAzwUAIAAAAAABBgAAmgUAIAAHBAAAmQYAIAUAAJoGACAGAACbBgAg-wIAAJsFACD8AgAAmwUAIP4CAACbBQAg_wIAAJsFACAMtwIBAAAAAb8CQAAAAAHAAkAAAAAB2wJAAAAAAeMCAQAAAAHlAgEAAAAB9AIBAAAAAfUCAQAAAAH2AgEAAAAB9wIBAAAAAfgCCAAAAAH5AggAAAABDLcCAQAAAAG_AkAAAAABwAJAAAAAAesCAQAAAAHsAgEAAAAB7QIBAAAAAe4CAQAAAAHvAgEAAAAB8AJAAAAAAfECQAAAAAHyAgEAAAAB8wIBAAAAAQO_AkAAAAAB0wIBAAAAAeACAAAA4AICDgUAAJcGACAGAACYBgAgnwIBAAAAAbcCAQAAAAG4AgEAAAABvwJAAAAAAcACQAAAAAHgAgEAAAAB-gIgAAAAAfsCAQAAAAH8AgEAAAAB_QIgAAAAAf4CQAAAAAH_AgEAAAABAgAAAAEAIB8AAKkGACADAAAAPAAgHwAAqQYAICAAAK0GACAQAAAAPAAgBQAA8wUAIAYAAPQFACAYAACtBgAgnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhDgUAAPMFACAGAAD0BQAgnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhDgQAAJYGACAGAACYBgAgnwIBAAAAAbcCAQAAAAG4AgEAAAABvwJAAAAAAcACQAAAAAHgAgEAAAAB-gIgAAAAAfsCAQAAAAH8AgEAAAAB_QIgAAAAAf4CQAAAAAH_AgEAAAABAgAAAAEAIB8AAK4GACADAAAAPAAgHwAArgYAICAAALIGACAQAAAAPAAgBAAA8gUAIAYAAPQFACAYAACyBgAgnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhDgQAAPIFACAGAAD0BQAgnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhBZ4CAQAAAAGfAgEAAAABoAIQAAAAAaECgAAAAAGiAkAAAAABAgAAAJQDACAfAACzBgAgAwAAAA8AIB8AALMGACAgAAC3BgAgBwAAAA8AIBgAALcGACCeAgEAmwQAIZ8CAQCbBAAhoAIQAJwEACGhAoAAAAABogJAAJ0EACEFngIBAJsEACGfAgEAmwQAIaACEACcBAAhoQKAAAAAAaICQACdBAAhDggAAN4FACALAACXBQAgDAAAmAUAILcCAQAAAAG_AkAAAAABwAJAAAAAAeECAQAAAAHiAgEAAAAB4wIBAAAAAeQCAQAAAAHlAgEAAAAB5gIBAAAAAecCAQAAAAHoAgEAAAABAgAAABMAIB8AALgGACADAAAAEQAgHwAAuAYAICAAALwGACAQAAAAEQAgCAAA3QUAIAsAAKwEACAMAACtBAAgGAAAvAYAILcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeECAQCbBAAh4gIBAKkEACHjAgEAqQQAIeQCAQCpBAAh5QIBAKkEACHmAgEAmwQAIecCAQCbBAAh6AIBAKkEACEOCAAA3QUAIAsAAKwEACAMAACtBAAgtwIBAJsEACG_AkAAnQQAIcACQACdBAAh4QIBAJsEACHiAgEAqQQAIeMCAQCpBAAh5AIBAKkEACHlAgEAqQQAIeYCAQCbBAAh5wIBAJsEACHoAgEAqQQAIQ4IAADeBQAgCQAAlgUAIAwAAJgFACC3AgEAAAABvwJAAAAAAcACQAAAAAHhAgEAAAAB4gIBAAAAAeMCAQAAAAHkAgEAAAAB5QIBAAAAAeYCAQAAAAHnAgEAAAAB6AIBAAAAAQIAAAATACAfAAC9BgAgAwAAABEAIB8AAL0GACAgAADBBgAgEAAAABEAIAgAAN0FACAJAACrBAAgDAAArQQAIBgAAMEGACC3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHhAgEAmwQAIeICAQCpBAAh4wIBAKkEACHkAgEAqQQAIeUCAQCpBAAh5gIBAJsEACHnAgEAmwQAIegCAQCpBAAhDggAAN0FACAJAACrBAAgDAAArQQAILcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeECAQCbBAAh4gIBAKkEACHjAgEAqQQAIeQCAQCpBAAh5QIBAKkEACHmAgEAmwQAIecCAQCbBAAh6AIBAKkEACEJnwIBAAAAAbcCAQAAAAG_AkAAAAABwAJAAAAAAdMCAQAAAAHVAgIAAAAB1gIQAAAAAdcCIAAAAAHYAgEAAAABDggAAN4FACAJAACWBQAgCwAAlwUAILcCAQAAAAG_AkAAAAABwAJAAAAAAeECAQAAAAHiAgEAAAAB4wIBAAAAAeQCAQAAAAHlAgEAAAAB5gIBAAAAAecCAQAAAAHoAgEAAAABAgAAABMAIB8AAMMGACADAAAAEQAgHwAAwwYAICAAAMcGACAQAAAAEQAgCAAA3QUAIAkAAKsEACALAACsBAAgGAAAxwYAILcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeECAQCbBAAh4gIBAKkEACHjAgEAqQQAIeQCAQCpBAAh5QIBAKkEACHmAgEAmwQAIecCAQCbBAAh6AIBAKkEACEOCAAA3QUAIAkAAKsEACALAACsBAAgtwIBAJsEACG_AkAAnQQAIcACQACdBAAh4QIBAJsEACHiAgEAqQQAIeMCAQCpBAAh5AIBAKkEACHlAgEAqQQAIeYCAQCbBAAh5wIBAJsEACHoAgEAqQQAIQ8KAADABQAgDQAA9AQAIA8AAPUEACAQAAD2BAAgEQAA9wQAIJ8CAQAAAAG3AgEAAAABvwJAAAAAAcACQAAAAAHTAgEAAAAB1AIBAAAAAdUCAgAAAAHWAhAAAAAB1wIgAAAAAdgCAQAAAAECAAAAHQAgHwAAyAYAIAMAAAAbACAfAADIBgAgIAAAzAYAIBEAAAAbACAKAAC_BQAgDQAAuwQAIA8AALwEACAQAAC9BAAgEQAAvgQAIBgAAMwGACCfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh1AIBAJsEACHVAgIAuAQAIdYCEACcBAAh1wIgALkEACHYAgEAqQQAIQ8KAAC_BQAgDQAAuwQAIA8AALwEACAQAAC9BAAgEQAAvgQAIJ8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh0wIBAJsEACHUAgEAmwQAIdUCAgC4BAAh1gIQAJwEACHXAiAAuQQAIdgCAQCpBAAhDwoAAMAFACANAAD0BAAgEAAA9gQAIBEAAPcEACASAAD4BAAgnwIBAAAAAbcCAQAAAAG_AkAAAAABwAJAAAAAAdMCAQAAAAHUAgEAAAAB1QICAAAAAdYCEAAAAAHXAiAAAAAB2AIBAAAAAQIAAAAdACAfAADNBgAgAwAAABsAIB8AAM0GACAgAADRBgAgEQAAABsAIAoAAL8FACANAAC7BAAgEAAAvQQAIBEAAL4EACASAAC_BAAgGAAA0QYAIJ8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh0wIBAJsEACHUAgEAmwQAIdUCAgC4BAAh1gIQAJwEACHXAiAAuQQAIdgCAQCpBAAhDwoAAL8FACANAAC7BAAgEAAAvQQAIBEAAL4EACASAAC_BAAgnwIBAJsEACG3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHTAgEAmwQAIdQCAQCbBAAh1QICALgEACHWAhAAnAQAIdcCIAC5BAAh2AIBAKkEACEPCgAAwAUAIA0AAPQEACAPAAD1BAAgEQAA9wQAIBIAAPgEACCfAgEAAAABtwIBAAAAAb8CQAAAAAHAAkAAAAAB0wIBAAAAAdQCAQAAAAHVAgIAAAAB1gIQAAAAAdcCIAAAAAHYAgEAAAABAgAAAB0AIB8AANIGACADAAAAGwAgHwAA0gYAICAAANYGACARAAAAGwAgCgAAvwUAIA0AALsEACAPAAC8BAAgEQAAvgQAIBIAAL8EACAYAADWBgAgnwIBAJsEACG3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHTAgEAmwQAIdQCAQCbBAAh1QICALgEACHWAhAAnAQAIdcCIAC5BAAh2AIBAKkEACEPCgAAvwUAIA0AALsEACAPAAC8BAAgEQAAvgQAIBIAAL8EACCfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh1AIBAJsEACHVAgIAuAQAIdYCEACcBAAh1wIgALkEACHYAgEAqQQAIQ8KAADABQAgDQAA9AQAIA8AAPUEACAQAAD2BAAgEgAA-AQAIJ8CAQAAAAG3AgEAAAABvwJAAAAAAcACQAAAAAHTAgEAAAAB1AIBAAAAAdUCAgAAAAHWAhAAAAAB1wIgAAAAAdgCAQAAAAECAAAAHQAgHwAA1wYAIAMAAAAbACAfAADXBgAgIAAA2wYAIBEAAAAbACAKAAC_BQAgDQAAuwQAIA8AALwEACAQAAC9BAAgEgAAvwQAIBgAANsGACCfAgEAmwQAIbcCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIdMCAQCbBAAh1AIBAJsEACHVAgIAuAQAIdYCEACcBAAh1wIgALkEACHYAgEAqQQAIQ8KAAC_BQAgDQAAuwQAIA8AALwEACAQAAC9BAAgEgAAvwQAIJ8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh0wIBAJsEACHUAgEAmwQAIdUCAgC4BAAh1gIQAJwEACHXAiAAuQQAIdgCAQCpBAAhDgQAAJYGACAFAACXBgAgnwIBAAAAAbcCAQAAAAG4AgEAAAABvwJAAAAAAcACQAAAAAHgAgEAAAAB-gIgAAAAAfsCAQAAAAH8AgEAAAAB_QIgAAAAAf4CQAAAAAH_AgEAAAABAgAAAAEAIB8AANwGACADAAAAPAAgHwAA3AYAICAAAOAGACAQAAAAPAAgBAAA8gUAIAUAAPMFACAYAADgBgAgnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhDgQAAPIFACAFAADzBQAgnwIBAJsEACG3AgEAmwQAIbgCAQCbBAAhvwJAAJ0EACHAAkAAnQQAIeACAQCbBAAh-gIgALkEACH7AgEAqQQAIfwCAQCpBAAh_QIgALkEACH-AkAAgwUAIf8CAQCpBAAhA78CQAAAAAHeAgEAAAAB4AIAAADgAgIItwIBAAAAAbgCAQAAAAG_AkAAAAABwAJAAAAAAdoCAQAAAAHbAkAAAAAB3AJAAAAAAd0CQAAAAAEGnwIBAAAAAbcCAQAAAAG_AkAAAAABwAJAAAAAAdACIAAAAAHZAgEAAAABAgAAANsBACAfAADjBgAgBbcCAQAAAAG_AkAAAAABxAIBAAAAAcUCAQAAAAHPAgAAAM8CAgigAhAAAAABtwIBAAAAAb8CQAAAAAHAAkAAAAABxAIBAAAAAcUCAQAAAAHPAgAAAM8CA9ACIAAAAAELtwIBAAAAAb8CQAAAAAHAAkAAAAABwQIBAAAAAcMCQAAAAAHEAgEAAAABxQIBAAAAAckCAQAAAAHKAgEAAAABywIBAAAAAc0CAAAAxwICB7cCAQAAAAG_AkAAAAABwAJAAAAAAcQCAQAAAAHFAgEAAAAB0QJAAAAAAdICAQAAAAEDAAAA3gEAIB8AAOMGACAgAADrBgAgCAAAAN4BACAYAADrBgAgnwIBAJsEACG3AgEAmwQAIb8CQACdBAAhwAJAAJ0EACHQAiAAuQQAIdkCAQCbBAAhBp8CAQCbBAAhtwIBAJsEACG_AkAAnQQAIcACQACdBAAh0AIgALkEACHZAgEAmwQAIQmfAgEAAAABtwIBAAAAAb8CQAAAAAHAAkAAAAAB1AIBAAAAAdUCAgAAAAHWAhAAAAAB1wIgAAAAAdgCAQAAAAEKtwIBAAAAAb8CQAAAAAHAAkAAAAAB4QIBAAAAAeICAQAAAAHjAgEAAAAB5AIBAAAAAeUCAQAAAAHmAgEAAAAB5wIBAAAAAQQEBgIFCgMGDgQHABIBAwABAQMAAQIDAAEKAAUFBwARCBAGCRYECxoIDB4JAgYUBQcABwEGFQABCgAFBwcAEAoABQ0ACg8kDBAoDREsDhIwDwIHAAsMHwkBDCAAAQ4ACQEOAAkBDgAJAQ4ACQQPMQAQMgARMwASNAADCTUACzYADDcAAwQ4AAU5AAY6AAAAAAMHABclABgmABkAAAADBwAXJQAYJgAZAQMAAQEDAAEFBwAeJQAhJgAiNwAfOAAgAAAAAAAFBwAeJQAhJgAiNwAfOAAgAQMAAQEDAAEDBwAnJQAoJgApAAAAAwcAJyUAKCYAKQAAAAMHAC8lADAmADEAAAADBwAvJQAwJgAxAQihAQYBCKcBBgMHADYlADcmADgAAAADBwA2JQA3JgA4AgMAAQoABQIDAAEKAAUDBwA9JQA-JgA_AAAAAwcAPSUAPiYAPwEKAAUBCgAFAwcARCUARSYARgAAAAMHAEQlAEUmAEYAAAMHAEslAEwmAE0AAAADBwBLJQBMJgBNAgoABQ0ACgIKAAUNAAoFBwBSJQBVJgBWNwBTOABUAAAAAAAFBwBSJQBVJgBWNwBTOABUAQ4ACQEOAAkDBwBbJQBcJgBdAAAAAwcAWyUAXCYAXQEOAAkBDgAJAwcAYiUAYyYAZAAAAAMHAGIlAGMmAGQBDgAJAQ4ACQUHAGklAGwmAG03AGo4AGsAAAAAAAUHAGklAGwmAG03AGo4AGsBDgAJAQ4ACQMHAHIlAHMmAHQAAAADBwByJQBzJgB0AAAAAwcAeiUAeyYAfAAAAAMHAHolAHsmAHwAAAAFBwCCASUAhQEmAIYBNwCDATgAhAEAAAAAAAUHAIIBJQCFASYAhgE3AIMBOACEAQAABQcAiwElAI4BJgCPATcAjAE4AI0BAAAAAAAFBwCLASUAjgEmAI8BNwCMATgAjQETAgEUOwEVPgEWPwEXQAEZQgEaRBMbRRQcRwEdSRMeShUhSwEiTAEjTRMnUBYoURopUgIqUwIrVAIsVQItVgIuWAIvWhMwWxsxXQIyXxMzYBw0YQI1YgI2YxM5Zh06ZyM7aAM8aQM9agM-awM_bANAbgNBcBNCcSRDcwNEdRNFdiVGdwNHeANIeRNJfCZKfSpLfytMgAErTYMBK06EAStPhQErUIcBK1GJARNSigEsU4wBK1SOARNVjwEtVpABK1eRAStYkgETWZUBLlqWATJblwEFXJgBBV2ZAQVemgEFX5sBBWCdAQVhnwETYqABM2OjAQVkpQETZaYBNGaoAQVnqQEFaKoBE2mtATVqrgE5a68BBGywAQRtsQEEbrIBBG-zAQRwtQEEcbcBE3K4ATpzugEEdLwBE3W9ATt2vgEEd78BBHjAARN5wwE8esQBQHvFAQh8xgEIfccBCH7IAQh_yQEIgAHLAQiBAc0BE4IBzgFBgwHQAQiEAdIBE4UB0wFChgHUAQiHAdUBCIgB1gETiQHZAUOKAdoBR4sB3AEKjAHdAQqNAeABCo4B4QEKjwHiAQqQAeQBCpEB5gETkgHnAUiTAekBCpQB6wETlQHsAUmWAe0BCpcB7gEKmAHvAROZAfIBSpoB8wFOmwH0AQmcAfUBCZ0B9gEJngH3AQmfAfgBCaAB-gEJoQH8AROiAf0BT6MB_wEJpAGBAhOlAYICUKYBgwIJpwGEAgmoAYUCE6kBiAJRqgGJAlerAYoCD6wBiwIPrQGMAg-uAY0CD68BjgIPsAGQAg-xAZICE7IBkwJYswGVAg-0AZcCE7UBmAJZtgGZAg-3AZoCD7gBmwITuQGeAlq6AZ8CXrsBoAIMvAGhAgy9AaICDL4BowIMvwGkAgzAAaYCDMEBqAITwgGpAl_DAasCDMQBrQITxQGuAmDGAa8CDMcBsAIMyAGxAhPJAbQCYcoBtQJlywG2Ag3MAbcCDc0BuAINzgG5Ag3PAboCDdABvAIN0QG-AhPSAb8CZtMBwQIN1AHDAhPVAcQCZ9YBxQIN1wHGAg3YAccCE9kBygJo2gHLAm7bAcwCDtwBzQIO3QHOAg7eAc8CDt8B0AIO4AHSAg7hAdQCE-IB1QJv4wHXAg7kAdkCE-UB2gJw5gHbAg7nAdwCDugB3QIT6QHgAnHqAeECdesB4wJ27AHkAnbtAecCdu4B6AJ27wHpAnbwAesCdvEB7QIT8gHuAnfzAfACdvQB8gIT9QHzAnj2AfQCdvcB9QJ2-AH2AhP5AfkCefoB-gJ9-wH8An78Af0Cfv0BgAN-_gGBA37_AYIDfoAChAN-gQKGAxOCAocDf4MCiQN-hAKLAxOFAowDgAGGAo0DfocCjgN-iAKPAxOJApIDgQGKApMDhwGLApUDBowClgMGjQKYAwaOApkDBo8CmgMGkAKcAwaRAp4DE5ICnwOIAZMCoQMGlAKjAxOVAqQDiQGWAqUDBpcCpgMGmAKnAxOZAqoDigGaAqsDkAE" + strings: JSON.parse("[\"where\",\"orderBy\",\"cursor\",\"user\",\"sessions\",\"accounts\",\"complexes\",\"_count\",\"plan\",\"users\",\"complex\",\"invitations\",\"courts\",\"sport\",\"court\",\"availabilities\",\"priceRules\",\"bookings\",\"recurringGroup\",\"maintenances\",\"recurringGroups\",\"User.findUnique\",\"User.findUniqueOrThrow\",\"User.findFirst\",\"User.findFirstOrThrow\",\"User.findMany\",\"data\",\"User.createOne\",\"User.createMany\",\"User.createManyAndReturn\",\"User.updateOne\",\"User.updateMany\",\"User.updateManyAndReturn\",\"create\",\"update\",\"User.upsertOne\",\"User.deleteOne\",\"User.deleteMany\",\"having\",\"_min\",\"_max\",\"User.groupBy\",\"User.aggregate\",\"Session.findUnique\",\"Session.findUniqueOrThrow\",\"Session.findFirst\",\"Session.findFirstOrThrow\",\"Session.findMany\",\"Session.createOne\",\"Session.createMany\",\"Session.createManyAndReturn\",\"Session.updateOne\",\"Session.updateMany\",\"Session.updateManyAndReturn\",\"Session.upsertOne\",\"Session.deleteOne\",\"Session.deleteMany\",\"_avg\",\"_sum\",\"Session.groupBy\",\"Session.aggregate\",\"Account.findUnique\",\"Account.findUniqueOrThrow\",\"Account.findFirst\",\"Account.findFirstOrThrow\",\"Account.findMany\",\"Account.createOne\",\"Account.createMany\",\"Account.createManyAndReturn\",\"Account.updateOne\",\"Account.updateMany\",\"Account.updateManyAndReturn\",\"Account.upsertOne\",\"Account.deleteOne\",\"Account.deleteMany\",\"Account.groupBy\",\"Account.aggregate\",\"Verification.findUnique\",\"Verification.findUniqueOrThrow\",\"Verification.findFirst\",\"Verification.findFirstOrThrow\",\"Verification.findMany\",\"Verification.createOne\",\"Verification.createMany\",\"Verification.createManyAndReturn\",\"Verification.updateOne\",\"Verification.updateMany\",\"Verification.updateManyAndReturn\",\"Verification.upsertOne\",\"Verification.deleteOne\",\"Verification.deleteMany\",\"Verification.groupBy\",\"Verification.aggregate\",\"Complex.findUnique\",\"Complex.findUniqueOrThrow\",\"Complex.findFirst\",\"Complex.findFirstOrThrow\",\"Complex.findMany\",\"Complex.createOne\",\"Complex.createMany\",\"Complex.createManyAndReturn\",\"Complex.updateOne\",\"Complex.updateMany\",\"Complex.updateManyAndReturn\",\"Complex.upsertOne\",\"Complex.deleteOne\",\"Complex.deleteMany\",\"Complex.groupBy\",\"Complex.aggregate\",\"ComplexUser.findUnique\",\"ComplexUser.findUniqueOrThrow\",\"ComplexUser.findFirst\",\"ComplexUser.findFirstOrThrow\",\"ComplexUser.findMany\",\"ComplexUser.createOne\",\"ComplexUser.createMany\",\"ComplexUser.createManyAndReturn\",\"ComplexUser.updateOne\",\"ComplexUser.updateMany\",\"ComplexUser.updateManyAndReturn\",\"ComplexUser.upsertOne\",\"ComplexUser.deleteOne\",\"ComplexUser.deleteMany\",\"ComplexUser.groupBy\",\"ComplexUser.aggregate\",\"ComplexInvitation.findUnique\",\"ComplexInvitation.findUniqueOrThrow\",\"ComplexInvitation.findFirst\",\"ComplexInvitation.findFirstOrThrow\",\"ComplexInvitation.findMany\",\"ComplexInvitation.createOne\",\"ComplexInvitation.createMany\",\"ComplexInvitation.createManyAndReturn\",\"ComplexInvitation.updateOne\",\"ComplexInvitation.updateMany\",\"ComplexInvitation.updateManyAndReturn\",\"ComplexInvitation.upsertOne\",\"ComplexInvitation.deleteOne\",\"ComplexInvitation.deleteMany\",\"ComplexInvitation.groupBy\",\"ComplexInvitation.aggregate\",\"Sport.findUnique\",\"Sport.findUniqueOrThrow\",\"Sport.findFirst\",\"Sport.findFirstOrThrow\",\"Sport.findMany\",\"Sport.createOne\",\"Sport.createMany\",\"Sport.createManyAndReturn\",\"Sport.updateOne\",\"Sport.updateMany\",\"Sport.updateManyAndReturn\",\"Sport.upsertOne\",\"Sport.deleteOne\",\"Sport.deleteMany\",\"Sport.groupBy\",\"Sport.aggregate\",\"Court.findUnique\",\"Court.findUniqueOrThrow\",\"Court.findFirst\",\"Court.findFirstOrThrow\",\"Court.findMany\",\"Court.createOne\",\"Court.createMany\",\"Court.createManyAndReturn\",\"Court.updateOne\",\"Court.updateMany\",\"Court.updateManyAndReturn\",\"Court.upsertOne\",\"Court.deleteOne\",\"Court.deleteMany\",\"Court.groupBy\",\"Court.aggregate\",\"CourtMaintenance.findUnique\",\"CourtMaintenance.findUniqueOrThrow\",\"CourtMaintenance.findFirst\",\"CourtMaintenance.findFirstOrThrow\",\"CourtMaintenance.findMany\",\"CourtMaintenance.createOne\",\"CourtMaintenance.createMany\",\"CourtMaintenance.createManyAndReturn\",\"CourtMaintenance.updateOne\",\"CourtMaintenance.updateMany\",\"CourtMaintenance.updateManyAndReturn\",\"CourtMaintenance.upsertOne\",\"CourtMaintenance.deleteOne\",\"CourtMaintenance.deleteMany\",\"CourtMaintenance.groupBy\",\"CourtMaintenance.aggregate\",\"CourtAvailability.findUnique\",\"CourtAvailability.findUniqueOrThrow\",\"CourtAvailability.findFirst\",\"CourtAvailability.findFirstOrThrow\",\"CourtAvailability.findMany\",\"CourtAvailability.createOne\",\"CourtAvailability.createMany\",\"CourtAvailability.createManyAndReturn\",\"CourtAvailability.updateOne\",\"CourtAvailability.updateMany\",\"CourtAvailability.updateManyAndReturn\",\"CourtAvailability.upsertOne\",\"CourtAvailability.deleteOne\",\"CourtAvailability.deleteMany\",\"CourtAvailability.groupBy\",\"CourtAvailability.aggregate\",\"CourtPriceRule.findUnique\",\"CourtPriceRule.findUniqueOrThrow\",\"CourtPriceRule.findFirst\",\"CourtPriceRule.findFirstOrThrow\",\"CourtPriceRule.findMany\",\"CourtPriceRule.createOne\",\"CourtPriceRule.createMany\",\"CourtPriceRule.createManyAndReturn\",\"CourtPriceRule.updateOne\",\"CourtPriceRule.updateMany\",\"CourtPriceRule.updateManyAndReturn\",\"CourtPriceRule.upsertOne\",\"CourtPriceRule.deleteOne\",\"CourtPriceRule.deleteMany\",\"CourtPriceRule.groupBy\",\"CourtPriceRule.aggregate\",\"CourtBooking.findUnique\",\"CourtBooking.findUniqueOrThrow\",\"CourtBooking.findFirst\",\"CourtBooking.findFirstOrThrow\",\"CourtBooking.findMany\",\"CourtBooking.createOne\",\"CourtBooking.createMany\",\"CourtBooking.createManyAndReturn\",\"CourtBooking.updateOne\",\"CourtBooking.updateMany\",\"CourtBooking.updateManyAndReturn\",\"CourtBooking.upsertOne\",\"CourtBooking.deleteOne\",\"CourtBooking.deleteMany\",\"CourtBooking.groupBy\",\"CourtBooking.aggregate\",\"CourtBookingLog.findUnique\",\"CourtBookingLog.findUniqueOrThrow\",\"CourtBookingLog.findFirst\",\"CourtBookingLog.findFirstOrThrow\",\"CourtBookingLog.findMany\",\"CourtBookingLog.createOne\",\"CourtBookingLog.createMany\",\"CourtBookingLog.createManyAndReturn\",\"CourtBookingLog.updateOne\",\"CourtBookingLog.updateMany\",\"CourtBookingLog.updateManyAndReturn\",\"CourtBookingLog.upsertOne\",\"CourtBookingLog.deleteOne\",\"CourtBookingLog.deleteMany\",\"CourtBookingLog.groupBy\",\"CourtBookingLog.aggregate\",\"RecurringBookingGroup.findUnique\",\"RecurringBookingGroup.findUniqueOrThrow\",\"RecurringBookingGroup.findFirst\",\"RecurringBookingGroup.findFirstOrThrow\",\"RecurringBookingGroup.findMany\",\"RecurringBookingGroup.createOne\",\"RecurringBookingGroup.createMany\",\"RecurringBookingGroup.createManyAndReturn\",\"RecurringBookingGroup.updateOne\",\"RecurringBookingGroup.updateMany\",\"RecurringBookingGroup.updateManyAndReturn\",\"RecurringBookingGroup.upsertOne\",\"RecurringBookingGroup.deleteOne\",\"RecurringBookingGroup.deleteMany\",\"RecurringBookingGroup.groupBy\",\"RecurringBookingGroup.aggregate\",\"PasswordResetRequest.findUnique\",\"PasswordResetRequest.findUniqueOrThrow\",\"PasswordResetRequest.findFirst\",\"PasswordResetRequest.findFirstOrThrow\",\"PasswordResetRequest.findMany\",\"PasswordResetRequest.createOne\",\"PasswordResetRequest.createMany\",\"PasswordResetRequest.createManyAndReturn\",\"PasswordResetRequest.updateOne\",\"PasswordResetRequest.updateMany\",\"PasswordResetRequest.updateManyAndReturn\",\"PasswordResetRequest.upsertOne\",\"PasswordResetRequest.deleteOne\",\"PasswordResetRequest.deleteMany\",\"PasswordResetRequest.groupBy\",\"PasswordResetRequest.aggregate\",\"Plan.findUnique\",\"Plan.findUniqueOrThrow\",\"Plan.findFirst\",\"Plan.findFirstOrThrow\",\"Plan.findMany\",\"Plan.createOne\",\"Plan.createMany\",\"Plan.createManyAndReturn\",\"Plan.updateOne\",\"Plan.updateMany\",\"Plan.updateManyAndReturn\",\"Plan.upsertOne\",\"Plan.deleteOne\",\"Plan.deleteMany\",\"Plan.groupBy\",\"Plan.aggregate\",\"AND\",\"OR\",\"NOT\",\"code\",\"name\",\"price\",\"rules\",\"lastUpdatedAt\",\"equals\",\"in\",\"notIn\",\"lt\",\"lte\",\"gt\",\"gte\",\"not\",\"string_contains\",\"string_starts_with\",\"string_ends_with\",\"array_starts_with\",\"array_ends_with\",\"array_contains\",\"contains\",\"startsWith\",\"endsWith\",\"every\",\"some\",\"none\",\"id\",\"email\",\"otpHash\",\"otpExpiresAt\",\"otpAttempts\",\"otpLastSentAt\",\"otpResendCount\",\"usedAt\",\"createdAt\",\"updatedAt\",\"complexId\",\"courtId\",\"startTime\",\"endTime\",\"DayOfWeek\",\"dayOfWeek\",\"startDate\",\"endDate\",\"RecurringBookingGroupStatus\",\"status\",\"customerName\",\"customerPhone\",\"customerEmail\",\"bookingCode\",\"bookingDate\",\"CourtBookingStatus\",\"previousStatus\",\"newStatus\",\"changedAt\",\"recurringGroupId\",\"isActive\",\"reason\",\"sportId\",\"slotDurationMinutes\",\"basePrice\",\"isUnderMaintenance\",\"maintenanceReason\",\"slug\",\"tokenHash\",\"expiresAt\",\"acceptedAt\",\"revokedAt\",\"userId\",\"ComplexUserRole\",\"role\",\"complexName\",\"physicalAddress\",\"city\",\"state\",\"country\",\"complexSlug\",\"adminEmail\",\"planCode\",\"identifier\",\"value\",\"accountId\",\"providerId\",\"accessToken\",\"refreshToken\",\"idToken\",\"accessTokenExpiresAt\",\"refreshTokenExpiresAt\",\"scope\",\"password\",\"token\",\"ipAddress\",\"userAgent\",\"countryCode\",\"latitude\",\"longitude\",\"emailVerified\",\"image\",\"phone\",\"banned\",\"bannedAt\",\"banReason\",\"courtId_bookingDate_startTime\",\"complexId_userId\",\"is\",\"isNot\",\"connectOrCreate\",\"upsert\",\"createMany\",\"set\",\"disconnect\",\"delete\",\"connect\",\"updateMany\",\"deleteMany\",\"increment\",\"decrement\",\"multiply\",\"divide\"]"), + graph: "3QeZAZACEgQAAKEEACAFAACiBAAgBgAAowQAIK0CAACfBAAwrgIAAEYAEK8CAACfBAAwsQIBANwDACHJAgEAAAABygIBAAAAAdECQADfAwAh0gJAAN8DACH1AgEA3AMAIY8DIACPBAAhkAMBAKAEACGRAwEAoAQAIZIDIACPBAAhkwNAAO4DACGUAwEAoAQAIQEAAAABACARAwAAwAQAIK0CAADCBAAwrgIAAAMAEK8CAADCBAAwyQIBANwDACHRAkAA3wMAIdICQADfAwAh8AJAAN8DACHzAgEA3AMAIfgCAQCgBAAh-gIBAKAEACGJAwEA3AMAIYoDAQCgBAAhiwMBAKAEACGMAwEAoAQAIY0DCADDBAAhjgMIAMMEACEIAwAAgwcAIPgCAAD2BQAg-gIAAPYFACCKAwAA9gUAIIsDAAD2BQAgjAMAAPYFACCNAwAA9gUAII4DAAD2BQAgEQMAAMAEACCtAgAAwgQAMK4CAAADABCvAgAAwgQAMMkCAQAAAAHRAkAA3wMAIdICQADfAwAh8AJAAN8DACHzAgEA3AMAIfgCAQCgBAAh-gIBAKAEACGJAwEAAAABigMBAKAEACGLAwEAoAQAIYwDAQCgBAAhjQMIAMMEACGOAwgAwwQAIQMAAAADACABAAAEADACAAAFACARAwAAwAQAIK0CAADBBAAwrgIAAAcAEK8CAADBBAAwyQIBANwDACHRAkAA3wMAIdICQADfAwAh8wIBANwDACGAAwEA3AMAIYEDAQDcAwAhggMBAKAEACGDAwEAoAQAIYQDAQCgBAAhhQNAAO4DACGGA0AA7gMAIYcDAQCgBAAhiAMBAKAEACEIAwAAgwcAIIIDAAD2BQAggwMAAPYFACCEAwAA9gUAIIUDAAD2BQAghgMAAPYFACCHAwAA9gUAIIgDAAD2BQAgEQMAAMAEACCtAgAAwQQAMK4CAAAHABCvAgAAwQQAMMkCAQAAAAHRAkAA3wMAIdICQADfAwAh8wIBANwDACGAAwEA3AMAIYEDAQDcAwAhggMBAKAEACGDAwEAoAQAIYQDAQCgBAAhhQNAAO4DACGGA0AA7gMAIYcDAQCgBAAhiAMBAKAEACEDAAAABwAgAQAACAAwAgAACQAgCQMAAMAEACAKAACoBAAgrQIAAL4EADCuAgAACwAQrwIAAL4EADDRAkAA3wMAIdMCAQDsAwAh8wIBANwDACH1AgAAvwT1AiICAwAAgwcAIAoAAPkGACAKAwAAwAQAIAoAAKgEACCtAgAAvgQAMK4CAAALABCvAgAAvgQAMNECQADfAwAh0wIBAOwDACHzAgEA3AMAIfUCAAC_BPUCIpYDAAC9BAAgAwAAAAsAIAEAAAwAMAIAAA0AIAkGAADgAwAgrQIAANsDADCuAgAADwAQrwIAANsDADCwAgEA3AMAIbECAQDcAwAhsgIQAN0DACGzAgAA3gMAILQCQADfAwAhAQAAAA8AIBMIAAC7BAAgCQAAowQAIAsAALwEACAMAACQBAAgFAAAuAQAIK0CAAC6BAAwrgIAABEAEK8CAAC6BAAwyQIBAOwDACHRAkAA3wMAIdICQADfAwAh9gIBANwDACH3AgEAoAQAIfgCAQCgBAAh-QIBAKAEACH6AgEAoAQAIfsCAQDcAwAh_AIBANwDACH9AgEAoAQAIQoIAACBBwAgCQAA9wYAIAsAAIIHACAMAACrBgAgFAAAgAcAIPcCAAD2BQAg-AIAAPYFACD5AgAA9gUAIPoCAAD2BQAg_QIAAPYFACATCAAAuwQAIAkAAKMEACALAAC8BAAgDAAAkAQAIBQAALgEACCtAgAAugQAMK4CAAARABCvAgAAugQAMMkCAQAAAAHRAkAA3wMAIdICQADfAwAh9gIBANwDACH3AgEAoAQAIfgCAQCgBAAh-QIBAKAEACH6AgEAoAQAIfsCAQAAAAH8AgEA3AMAIf0CAQCgBAAhAwAAABEAIAEAABIAMAIAABMAIAEAAAARACADAAAACwAgAQAADAAwAgAADQAgDQoAAKgEACCtAgAAuQQAMK4CAAAXABCvAgAAuQQAMMkCAQDsAwAhygIBANwDACHRAkAA3wMAIdICQADfAwAh0wIBAOwDACHvAgEA3AMAIfACQADfAwAh8QJAAO4DACHyAkAA7gMAIQMKAAD5BgAg8QIAAPYFACDyAgAA9gUAIA0KAACoBAAgrQIAALkEADCuAgAAFwAQrwIAALkEADDJAgEAAAABygIBANwDACHRAkAA3wMAIdICQADfAwAh0wIBAOwDACHvAgEAAAAB8AJAAN8DACHxAkAA7gMAIfICQADuAwAhAwAAABcAIAEAABgAMAIAABkAIBQKAACoBAAgDQAAtAQAIA8AALUEACAQAAC2BAAgEQAAqQQAIBMAALcEACAUAAC4BAAgrQIAALMEADCuAgAAGwAQrwIAALMEADCxAgEA3AMAIckCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdMCAQDsAwAh6QIBAOwDACHqAgIA7QMAIesCEADdAwAh7AIgAI8EACHtAgEAoAQAIQgKAAD5BgAgDQAA_AYAIA8AAP0GACAQAAD-BgAgEQAA-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_BgAgggMAAPYFACCDAwAA9gUAIIQDAAD2BQAghQMAAPYFACCGAwAA9gUAIIcDAAD2BQAgiAMAAPYFACAQrQIAAJkEADCuAgAAhQEAEK8CAACZBAAwyQIBAM8DACHRAkAA0gMAIdICQADSAwAh8wIBAM8DACGAAwEAzwMAIYEDAQDPAwAhggMBAIMEACGDAwEAgwQAIYQDAQCDBAAhhQNAAOQDACGGA0AA5AMAIYcDAQCDBAAhiAMBAIMEACEDAAAABwAgAQAAhAEAMCYAAIUBACADAAAABwAgAQAACAAwAgAACQAgCa0CAACYBAAwrgIAAIsBABCvAgAAmAQAMMkCAQAAAAHRAkAA3wMAIdICQADfAwAh8AJAAN8DACH-AgEA3AMAIf8CAQDcAwAhAQAAAIgBACABAAAAiAEAIAmtAgAAmAQAMK4CAACLAQAQrwIAAJgEADDJAgEA3AMAIdECQADfAwAh0gJAAN8DACHwAkAA3wMAIf4CAQDcAwAh_wIBANwDACEAAwAAAIsBACABAACMAQAwAgAAiAEAIAMAAACLAQAgAQAAjAEAMAIAAIgBACADAAAAiwEAIAEAAIwBADACAACIAQAgBskCAQAAAAHRAkAAAAAB0gJAAAAAAfACQAAAAAH-AgEAAAAB_wIBAAAAAQEaAACQAQAgBskCAQAAAAHRAkAAAAAB0gJAAAAAAfACQAAAAAH-AgEAAAAB_wIBAAAAAQEaAACSAQAwARoAAJIBADAGyQIBAMkEACHRAkAAywQAIdICQADLBAAh8AJAAMsEACH-AgEAyQQAIf8CAQDJBAAhAgAAAIgBACAaAACVAQAgBskCAQDJBAAh0QJAAMsEACHSAkAAywQAIfACQADLBAAh_gIBAMkEACH_AgEAyQQAIQIAAACLAQAgGgAAlwEAIAIAAACLAQAgGgAAlwEAIAMAAACIAQAgIQAAkAEAICIAAJUBACABAAAAiAEAIAEAAACLAQAgAwcAALsGACAnAAC9BgAgKAAAvAYAIAmtAgAAlwQAMK4CAACeAQAQrwIAAJcEADDJAgEAzwMAIdECQADSAwAh0gJAANIDACHwAkAA0gMAIf4CAQDPAwAh_wIBAM8DACEDAAAAiwEAIAEAAJ0BADAmAACeAQAgAwAAAIsBACABAACMAQAwAgAAiAEAIAEAAAATACABAAAAEwAgAwAAABEAIAEAABIAMAIAABMAIAMAAAARACABAAASADACAAATACADAAAAEQAgAQAAEgAwAgAAEwAgEAgAALoGACAJAADwBQAgCwAA8QUAIAwAAPIFACAUAADzBQAgyQIBAAAAAdECQAAAAAHSAkAAAAAB9gIBAAAAAfcCAQAAAAH4AgEAAAAB-QIBAAAAAfoCAQAAAAH7AgEAAAAB_AIBAAAAAf0CAQAAAAEBGgAApgEAIAvJAgEAAAAB0QJAAAAAAdICQAAAAAH2AgEAAAAB9wIBAAAAAfgCAQAAAAH5AgEAAAAB-gIBAAAAAfsCAQAAAAH8AgEAAAAB_QIBAAAAAQEaAACoAQAwARoAAKgBADABAAAADwAgEAgAALkGACAJAADZBAAgCwAA2gQAIAwAANsEACAUAADcBAAgyQIBAMkEACHRAkAAywQAIdICQADLBAAh9gIBAMkEACH3AgEA1wQAIfgCAQDXBAAh-QIBANcEACH6AgEA1wQAIfsCAQDJBAAh_AIBAMkEACH9AgEA1wQAIQIAAAATACAaAACsAQAgC8kCAQDJBAAh0QJAAMsEACHSAkAAywQAIfYCAQDJBAAh9wIBANcEACH4AgEA1wQAIfkCAQDXBAAh-gIBANcEACH7AgEAyQQAIfwCAQDJBAAh_QIBANcEACECAAAAEQAgGgAArgEAIAIAAAARACAaAACuAQAgAQAAAA8AIAMAAAATACAhAACmAQAgIgAArAEAIAEAAAATACABAAAAEQAgCAcAALYGACAnAAC4BgAgKAAAtwYAIPcCAAD2BQAg-AIAAPYFACD5AgAA9gUAIPoCAAD2BQAg_QIAAPYFACAOrQIAAJYEADCuAgAAtgEAEK8CAACWBAAwyQIBAOIDACHRAkAA0gMAIdICQADSAwAh9gIBAM8DACH3AgEAgwQAIfgCAQCDBAAh-QIBAIMEACH6AgEAgwQAIfsCAQDPAwAh_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-tAgAA-wMAMK4CAADxAgAQrwIAAPsDADDJAgEAAAAB1AIBAOwDACHVAgEA3AMAIdYCAQDcAwAh3QIBANwDACHeAgEA3AMAId8CAQDcAwAh4AIBANwDACHhAkAA3wMAIeMCAAD8A-MCIuQCAAD8A-MCIuUCQADfAwAhAQAAAO4CACABAAAA7gIAIA-tAgAA-wMAMK4CAADxAgAQrwIAAPsDADDJAgEA7AMAIdQCAQDsAwAh1QIBANwDACHWAgEA3AMAId0CAQDcAwAh3gIBANwDACHfAgEA3AMAIeACAQDcAwAh4QJAAN8DACHjAgAA_APjAiLkAgAA_APjAiLlAkAA3wMAIQADAAAA8QIAIAEAAPICADACAADuAgAgAwAAAPECACABAADyAgAwAgAA7gIAIAMAAADxAgAgAQAA8gIAMAIAAO4CACAMyQIBAAAAAdQCAQAAAAHVAgEAAAAB1gIBAAAAAd0CAQAAAAHeAgEAAAAB3wIBAAAAAeACAQAAAAHhAkAAAAAB4wIAAADjAgLkAgAAAOMCAuUCQAAAAAEBGgAA9gIAIAzJAgEAAAAB1AIBAAAAAdUCAQAAAAHWAgEAAAAB3QIBAAAAAd4CAQAAAAHfAgEAAAAB4AIBAAAAAeECQAAAAAHjAgAAAOMCAuQCAAAA4wIC5QJAAAAAAQEaAAD4AgAwARoAAPgCADAMyQIBAMkEACHUAgEAyQQAIdUCAQDJBAAh1gIBAMkEACHdAgEAyQQAId4CAQDJBAAh3wIBAMkEACHgAgEAyQQAIeECQADLBAAh4wIAAPcE4wIi5AIAAPcE4wIi5QJAAMsEACECAAAA7gIAIBoAAPsCACAMyQIBAMkEACHUAgEAyQQAIdUCAQDJBAAh1gIBAMkEACHdAgEAyQQAId4CAQDJBAAh3wIBAMkEACHgAgEAyQQAIeECQADLBAAh4wIAAPcE4wIi5AIAAPcE4wIi5QJAAMsEACECAAAA8QIAIBoAAP0CACACAAAA8QIAIBoAAP0CACADAAAA7gIAICEAAPYCACAiAAD7AgAgAQAAAO4CACABAAAA8QIAIAMHAAD_BQAgJwAAgQYAICgAAIAGACAPrQIAAPcDADCuAgAAhAMAEK8CAAD3AwAwyQIBAOIDACHUAgEA4gMAIdUCAQDPAwAh1gIBAM8DACHdAgEAzwMAId4CAQDPAwAh3wIBAM8DACHgAgEAzwMAIeECQADSAwAh4wIAAPgD4wIi5AIAAPgD4wIi5QJAANIDACEDAAAA8QIAIAEAAIMDADAmAACEAwAgAwAAAPECACABAADyAgAwAgAA7gIAIAEAAAA2ACABAAAANgAgAwAAAC0AIAEAADUAMAIAADYAIAMAAAAtACABAAA1ADACAAA2ACADAAAALQAgAQAANQAwAgAANgAgEQoAAJwFACAOAAD9BAAgEQAA_gQAIMkCAQAAAAHRAkAAAAAB0gJAAAAAAdMCAQAAAAHUAgEAAAAB1QIBAAAAAdYCAQAAAAHYAgAAANgCAtkCQAAAAAHaAkAAAAAB3AIAAADcAgLdAgEAAAAB3gIBAAAAAd8CAQAAAAEBGgAAjAMAIA7JAgEAAAAB0QJAAAAAAdICQAAAAAHTAgEAAAAB1AIBAAAAAdUCAQAAAAHWAgEAAAAB2AIAAADYAgLZAkAAAAAB2gJAAAAAAdwCAAAA3AIC3QIBAAAAAd4CAQAAAAHfAgEAAAABARoAAI4DADABGgAAjgMAMBEKAACaBQAgDgAA6wQAIBEAAOwEACDJAgEAyQQAIdECQADLBAAh0gJAAMsEACHTAgEAyQQAIdQCAQDJBAAh1QIBAMkEACHWAgEAyQQAIdgCAADnBNgCItkCQADLBAAh2gJAAOgEACHcAgAA6QTcAiLdAgEAyQQAId4CAQDJBAAh3wIBAMkEACECAAAANgAgGgAAkQMAIA7JAgEAyQQAIdECQADLBAAh0gJAAMsEACHTAgEAyQQAIdQCAQDJBAAh1QIBAMkEACHWAgEAyQQAIdgCAADnBNgCItkCQADLBAAh2gJAAOgEACHcAgAA6QTcAiLdAgEAyQQAId4CAQDJBAAh3wIBAMkEACECAAAALQAgGgAAkwMAIAIAAAAtACAaAACTAwAgAwAAADYAICEAAIwDACAiAACRAwAgAQAAADYAIAEAAAAtACAEBwAA_AUAICcAAP4FACAoAAD9BQAg2gIAAPYFACARrQIAAPADADCuAgAAmgMAEK8CAADwAwAwyQIBAOIDACHRAkAA0gMAIdICQADSAwAh0wIBAOIDACHUAgEA4gMAIdUCAQDPAwAh1gIBAM8DACHYAgAA8QPYAiLZAkAA0gMAIdoCQADkAwAh3AIAAPID3AIi3QIBAM8DACHeAgEAzwMAId8CAQDPAwAhAwAAAC0AIAEAAJkDADAmAACaAwAgAwAAAC0AIAEAADUAMAIAADYAIA2tAgAA6wMAMK4CAACgAwAQrwIAAOsDADDJAgEAAAABygIBANwDACHLAgEA3AMAIcwCQADfAwAhzQICAO0DACHOAkAA3wMAIc8CAgDtAwAh0AJAAO4DACHRAkAA3wMAIdICQADfAwAhAQAAAJ0DACABAAAAnQMAIA2tAgAA6wMAMK4CAACgAwAQrwIAAOsDADDJAgEA7AMAIcoCAQDcAwAhywIBANwDACHMAkAA3wMAIc0CAgDtAwAhzgJAAN8DACHPAgIA7QMAIdACQADuAwAh0QJAAN8DACHSAkAA3wMAIQHQAgAA9gUAIAMAAACgAwAgAQAAoQMAMAIAAJ0DACADAAAAoAMAIAEAAKEDADACAACdAwAgAwAAAKADACABAAChAwAwAgAAnQMAIArJAgEAAAABygIBAAAAAcsCAQAAAAHMAkAAAAABzQICAAAAAc4CQAAAAAHPAgIAAAAB0AJAAAAAAdECQAAAAAHSAkAAAAABARoAAKUDACAKyQIBAAAAAcoCAQAAAAHLAgEAAAABzAJAAAAAAc0CAgAAAAHOAkAAAAABzwICAAAAAdACQAAAAAHRAkAAAAAB0gJAAAAAAQEaAACnAwAwARoAAKcDADAKyQIBAMkEACHKAgEAyQQAIcsCAQDJBAAhzAJAAMsEACHNAgIAiQUAIc4CQADLBAAhzwICAIkFACHQAkAA6AQAIdECQADLBAAh0gJAAMsEACECAAAAnQMAIBoAAKoDACAKyQIBAMkEACHKAgEAyQQAIcsCAQDJBAAhzAJAAMsEACHNAgIAiQUAIc4CQADLBAAhzwICAIkFACHQAkAA6AQAIdECQADLBAAh0gJAAMsEACECAAAAoAMAIBoAAKwDACACAAAAoAMAIBoAAKwDACADAAAAnQMAICEAAKUDACAiAACqAwAgAQAAAJ0DACABAAAAoAMAIAYHAAD3BQAgJwAA-gUAICgAAPkFACA5AAD4BQAgOgAA-wUAINACAAD2BQAgDa0CAADhAwAwrgIAALMDABCvAgAA4QMAMMkCAQDiAwAhygIBAM8DACHLAgEAzwMAIcwCQADSAwAhzQICAOMDACHOAkAA0gMAIc8CAgDjAwAh0AJAAOQDACHRAkAA0gMAIdICQADSAwAhAwAAAKADACABAACyAwAwJgAAswMAIAMAAACgAwAgAQAAoQMAMAIAAJ0DACAJBgAA4AMAIK0CAADbAwAwrgIAAA8AEK8CAADbAwAwsAIBAAAAAbECAQDcAwAhsgIQAN0DACGzAgAA3gMAILQCQADfAwAhAQAAALYDACABAAAAtgMAIAEGAAD1BQAgAwAAAA8AIAEAALkDADACAAC2AwAgAwAAAA8AIAEAALkDADACAAC2AwAgAwAAAA8AIAEAALkDADACAAC2AwAgBgYAAPQFACCwAgEAAAABsQIBAAAAAbICEAAAAAGzAoAAAAABtAJAAAAAAQEaAAC9AwAgBbACAQAAAAGxAgEAAAABsgIQAAAAAbMCgAAAAAG0AkAAAAABARoAAL8DADABGgAAvwMAMAYGAADMBAAgsAIBAMkEACGxAgEAyQQAIbICEADKBAAhswKAAAAAAbQCQADLBAAhAgAAALYDACAaAADCAwAgBbACAQDJBAAhsQIBAMkEACGyAhAAygQAIbMCgAAAAAG0AkAAywQAIQIAAAAPACAaAADEAwAgAgAAAA8AIBoAAMQDACADAAAAtgMAICEAAL0DACAiAADCAwAgAQAAALYDACABAAAADwAgBQcAAMQEACAnAADHBAAgKAAAxgQAIDkAAMUEACA6AADIBAAgCK0CAADOAwAwrgIAAMsDABCvAgAAzgMAMLACAQDPAwAhsQIBAM8DACGyAhAA0AMAIbMCAADRAwAgtAJAANIDACEDAAAADwAgAQAAygMAMCYAAMsDACADAAAADwAgAQAAuQMAMAIAALYDACAIrQIAAM4DADCuAgAAywMAEK8CAADOAwAwsAIBAM8DACGxAgEAzwMAIbICEADQAwAhswIAANEDACC0AkAA0gMAIQ4HAADUAwAgJwAA2gMAICgAANoDACC1AgEAAAABtgIBAAAABLcCAQAAAAS4AgEAAAABuQIBAAAAAboCAQAAAAG7AgEAAAABvAIBANkDACHDAgEAAAABxAIBAAAAAcUCAQAAAAENBwAA1AMAICcAANgDACAoAADYAwAgOQAA2AMAIDoAANgDACC1AhAAAAABtgIQAAAABLcCEAAAAAS4AhAAAAABuQIQAAAAAboCEAAAAAG7AhAAAAABvAIQANcDACEPBwAA1AMAICcAANYDACAoAADWAwAgtQKAAAAAAbgCgAAAAAG5AoAAAAABugKAAAAAAbsCgAAAAAG8AoAAAAABvQIBAAAAAb4CAQAAAAG_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-MCIuQCAAD4A-MCIuUCQADSAwAhBwcAANQDACAnAAD6AwAgKAAA-gMAILUCAAAA4wICtgIAAADjAgi3AgAAAOMCCLwCAAD5A-MCIgcHAADUAwAgJwAA-gMAICgAAPoDACC1AgAAAOMCArYCAAAA4wIItwIAAADjAgi8AgAA-QPjAiIEtQIAAADjAgK2AgAAAOMCCLcCAAAA4wIIvAIAAPoD4wIiD60CAAD7AwAwrgIAAPECABCvAgAA-wMAMMkCAQDsAwAh1AIBAOwDACHVAgEA3AMAIdYCAQDcAwAh3QIBANwDACHeAgEA3AMAId8CAQDcAwAh4AIBANwDACHhAkAA3wMAIeMCAAD8A-MCIuQCAAD8A-MCIuUCQADfAwAhBLUCAAAA4wICtgIAAADjAgi3AgAAAOMCCLwCAAD6A-MCIhCtAgAA_QMAMK4CAADrAgAQrwIAAP0DADDJAgEA4gMAIdECQADSAwAh0gJAANIDACHUAgEA4gMAIdUCAQDPAwAh1gIBAM8DACHcAgAA-APjAiLdAgEAzwMAId4CAQDPAwAh3wIBAM8DACHgAgEAzwMAIeECQADSAwAh5gIBAP4DACELBwAA5gMAICcAAIAEACAoAACABAAgtQIBAAAAAbYCAQAAAAW3AgEAAAAFuAIBAAAAAbkCAQAAAAG6AgEAAAABuwIBAAAAAbwCAQD_AwAhCwcAAOYDACAnAACABAAgKAAAgAQAILUCAQAAAAG2AgEAAAAFtwIBAAAABbgCAQAAAAG5AgEAAAABugIBAAAAAbsCAQAAAAG8AgEA_wMAIQu1AgEAAAABtgIBAAAABbcCAQAAAAW4AgEAAAABuQIBAAAAAboCAQAAAAG7AgEAAAABvAIBAIAEACHDAgEAAAABxAIBAAAAAcUCAQAAAAEMrQIAAIEEADCuAgAA0wIAEK8CAACBBAAwsgIQANADACHJAgEA4gMAIdECQADSAwAh0gJAANIDACHUAgEA4gMAIdUCAQCDBAAh1gIBAIMEACHYAgAAggTYAiPnAiAAhAQAIQcHAADmAwAgJwAAiQQAICgAAIkEACC1AgAAANgCA7YCAAAA2AIJtwIAAADYAgm8AgAAiATYAiMOBwAA5gMAICcAAIAEACAoAACABAAgtQIBAAAAAbYCAQAAAAW3AgEAAAAFuAIBAAAAAbkCAQAAAAG6AgEAAAABuwIBAAAAAbwCAQCHBAAhwwIBAAAAAcQCAQAAAAHFAgEAAAABBQcAANQDACAnAACGBAAgKAAAhgQAILUCIAAAAAG8AiAAhQQAIQUHAADUAwAgJwAAhgQAICgAAIYEACC1AiAAAAABvAIgAIUEACECtQIgAAAAAbwCIACGBAAhDgcAAOYDACAnAACABAAgKAAAgAQAILUCAQAAAAG2AgEAAAAFtwIBAAAABbgCAQAAAAG5AgEAAAABugIBAAAAAbsCAQAAAAG8AgEAhwQAIcMCAQAAAAHEAgEAAAABxQIBAAAAAQcHAADmAwAgJwAAiQQAICgAAIkEACC1AgAAANgCA7YCAAAA2AIJtwIAAADYAgm8AgAAiATYAiMEtQIAAADYAgO2AgAAANgCCbcCAAAA2AIJvAIAAIkE2AIjCa0CAACKBAAwrgIAAL0CABCvAgAAigQAMMkCAQDiAwAh0QJAANIDACHUAgEA4gMAIdUCAQDPAwAh1gIBAM8DACHYAgAA8QPYAiILrQIAAIsEADCuAgAApwIAEK8CAACLBAAwyQIBAOIDACHRAkAA0gMAIdICQADSAwAh1AIBAOIDACHVAgEAgwQAIdYCAQCDBAAh2QJAANIDACHoAgEAgwQAIQ2tAgAAjAQAMK4CAACRAgAQrwIAAIwEADCxAgEAzwMAIckCAQDiAwAh0QJAANIDACHSAkAA0gMAIdMCAQDiAwAh6QIBAOIDACHqAgIA4wMAIesCEADQAwAh7AIgAIQEACHtAgEAgwQAIQmtAgAAjQQAMK4CAAD7AQAQrwIAAI0EADCxAgEAzwMAIckCAQDiAwAh0QJAANIDACHSAkAA0gMAIecCIACEBAAh7gIBAM8DACEKDAAAkAQAIK0CAACOBAAwrgIAAOgBABCvAgAAjgQAMLECAQDcAwAhyQIBAOwDACHRAkAA3wMAIdICQADfAwAh5wIgAI8EACHuAgEA3AMAIQK1AiAAAAABvAIgAIYEACEDxgIAABsAIMcCAAAbACDIAgAAGwAgDK0CAACRBAAwrgIAAOIBABCvAgAAkQQAMMkCAQDiAwAhygIBAM8DACHRAkAA0gMAIdICQADSAwAh0wIBAOIDACHvAgEAzwMAIfACQADSAwAh8QJAAOQDACHyAkAA5AMAIQetAgAAkgQAMK4CAADMAQAQrwIAAJIEADDRAkAA0gMAIdMCAQDiAwAh8wIBAM8DACH1AgAAkwT1AiIHBwAA1AMAICcAAJUEACAoAACVBAAgtQIAAAD1AgK2AgAAAPUCCLcCAAAA9QIIvAIAAJQE9QIiBwcAANQDACAnAACVBAAgKAAAlQQAILUCAAAA9QICtgIAAAD1Agi3AgAAAPUCCLwCAACUBPUCIgS1AgAAAPUCArYCAAAA9QIItwIAAAD1Agi8AgAAlQT1AiIOrQIAAJYEADCuAgAAtgEAEK8CAACWBAAwyQIBAOIDACHRAkAA0gMAIdICQADSAwAh9gIBAM8DACH3AgEAgwQAIfgCAQCDBAAh-QIBAIMEACH6AgEAgwQAIfsCAQDPAwAh_AIBAM8DACH9AgEAgwQAIQmtAgAAlwQAMK4CAACeAQAQrwIAAJcEADDJAgEAzwMAIdECQADSAwAh0gJAANIDACHwAkAA0gMAIf4CAQDPAwAh_wIBAM8DACEJrQIAAJgEADCuAgAAiwEAEK8CAACYBAAwyQIBANwDACHRAkAA3wMAIdICQADfAwAh8AJAAN8DACH-AgEA3AMAIf8CAQDcAwAhEK0CAACZBAAwrgIAAIUBABCvAgAAmQQAMMkCAQDPAwAh0QJAANIDACHSAkAA0gMAIfMCAQDPAwAhgAMBAM8DACGBAwEAzwMAIYIDAQCDBAAhgwMBAIMEACGEAwEAgwQAIYUDQADkAwAhhgNAAOQDACGHAwEAgwQAIYgDAQCDBAAhEK0CAACaBAAwrgIAAG8AEK8CAACaBAAwyQIBAM8DACHRAkAA0gMAIdICQADSAwAh8AJAANIDACHzAgEAzwMAIfgCAQCDBAAh-gIBAIMEACGJAwEAzwMAIYoDAQCDBAAhiwMBAIMEACGMAwEAgwQAIY0DCACbBAAhjgMIAJsEACENBwAA5gMAICcAAJ0EACAoAACdBAAgOQAAnQQAIDoAAJ0EACC1AggAAAABtgIIAAAABbcCCAAAAAW4AggAAAABuQIIAAAAAboCCAAAAAG7AggAAAABvAIIAJwEACENBwAA5gMAICcAAJ0EACAoAACdBAAgOQAAnQQAIDoAAJ0EACC1AggAAAABtgIIAAAABbcCCAAAAAW4AggAAAABuQIIAAAAAboCCAAAAAG7AggAAAABvAIIAJwEACEItQIIAAAAAbYCCAAAAAW3AggAAAAFuAIIAAAAAbkCCAAAAAG6AggAAAABuwIIAAAAAbwCCACdBAAhD60CAACeBAAwrgIAAFkAEK8CAACeBAAwsQIBAM8DACHJAgEAzwMAIcoCAQDPAwAh0QJAANIDACHSAkAA0gMAIfUCAQDPAwAhjwMgAIQEACGQAwEAgwQAIZEDAQCDBAAhkgMgAIQEACGTA0AA5AMAIZQDAQCDBAAhEgQAAKEEACAFAACiBAAgBgAAowQAIK0CAACfBAAwrgIAAEYAEK8CAACfBAAwsQIBANwDACHJAgEA3AMAIcoCAQDcAwAh0QJAAN8DACHSAkAA3wMAIfUCAQDcAwAhjwMgAI8EACGQAwEAoAQAIZEDAQCgBAAhkgMgAI8EACGTA0AA7gMAIZQDAQCgBAAhC7UCAQAAAAG2AgEAAAAFtwIBAAAABbgCAQAAAAG5AgEAAAABugIBAAAAAbsCAQAAAAG8AgEAgAQAIcMCAQAAAAHEAgEAAAABxQIBAAAAAQPGAgAAAwAgxwIAAAMAIMgCAAADACADxgIAAAcAIMcCAAAHACDIAgAABwAgA8YCAAALACDHAgAACwAgyAIAAAsAIBQKAACoBAAgDgAApwQAIBEAAKkEACCtAgAApAQAMK4CAAAtABCvAgAApAQAMMkCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdMCAQDsAwAh1AIBAOwDACHVAgEA3AMAIdYCAQDcAwAh2AIAAKUE2AIi2QJAAN8DACHaAkAA7gMAIdwCAACmBNwCIt0CAQDcAwAh3gIBANwDACHfAgEA3AMAIQS1AgAAANgCArYCAAAA2AIItwIAAADYAgi8AgAA9gPYAiIEtQIAAADcAgK2AgAAANwCCLcCAAAA3AIIvAIAAPQD3AIiFgoAAKgEACANAAC0BAAgDwAAtQQAIBAAALYEACARAACpBAAgEwAAtwQAIBQAALgEACCtAgAAswQAMK4CAAAbABCvAgAAswQAMLECAQDcAwAhyQIBAOwDACHRAkAA3wMAIdICQADfAwAh0wIBAOwDACHpAgEA7AMAIeoCAgDtAwAh6wIQAN0DACHsAiAAjwQAIe0CAQCgBAAhlwMAABsAIJgDAAAbACAVCAAAuwQAIAkAAKMEACALAAC8BAAgDAAAkAQAIBQAALgEACCtAgAAugQAMK4CAAARABCvAgAAugQAMMkCAQDsAwAh0QJAAN8DACHSAkAA3wMAIfYCAQDcAwAh9wIBAKAEACH4AgEAoAQAIfkCAQCgBAAh-gIBAKAEACH7AgEA3AMAIfwCAQDcAwAh_QIBAKAEACGXAwAAEQAgmAMAABEAIAPGAgAAKQAgxwIAACkAIMgCAAApACAMDgAApwQAIK0CAACqBAAwrgIAADEAEK8CAACqBAAwyQIBAOwDACHRAkAA3wMAIdICQADfAwAh1AIBAOwDACHVAgEAoAQAIdYCAQCgBAAh2QJAAN8DACHoAgEAoAQAIQPUAgEAAAAB1QIBAAAAAeECQAAAAAESDgAApwQAIBIAAK4EACCtAgAArAQAMK4CAAApABCvAgAArAQAMMkCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdQCAQDsAwAh1QIBANwDACHWAgEA3AMAIdwCAAD8A-MCIt0CAQDcAwAh3gIBANwDACHfAgEA3AMAIeACAQDcAwAh4QJAAN8DACHmAgEArQQAIQi1AgEAAAABtgIBAAAABbcCAQAAAAW4AgEAAAABuQIBAAAAAboCAQAAAAG7AgEAAAABvAIBAK8EACEWCgAAqAQAIA4AAKcEACARAACpBAAgrQIAAKQEADCuAgAALQAQrwIAAKQEADDJAgEA7AMAIdECQADfAwAh0gJAAN8DACHTAgEA7AMAIdQCAQDsAwAh1QIBANwDACHWAgEA3AMAIdgCAAClBNgCItkCQADfAwAh2gJAAO4DACHcAgAApgTcAiLdAgEA3AMAId4CAQDcAwAh3wIBANwDACGXAwAALQAgmAMAAC0AIAi1AgEAAAABtgIBAAAABbcCAQAAAAW4AgEAAAABuQIBAAAAAboCAQAAAAG7AgEAAAABvAIBAK8EACENDgAApwQAIK0CAACwBAAwrgIAACUAEK8CAACwBAAwsgIQAN0DACHJAgEA7AMAIdECQADfAwAh0gJAAN8DACHUAgEA7AMAIdUCAQCgBAAh1gIBAKAEACHYAgAAsQTYAiPnAiAAjwQAIQS1AgAAANgCA7YCAAAA2AIJtwIAAADYAgm8AgAAiQTYAiMKDgAApwQAIK0CAACyBAAwrgIAACEAEK8CAACyBAAwyQIBAOwDACHRAkAA3wMAIdQCAQDsAwAh1QIBANwDACHWAgEA3AMAIdgCAAClBNgCIhQKAACoBAAgDQAAtAQAIA8AALUEACAQAAC2BAAgEQAAqQQAIBMAALcEACAUAAC4BAAgrQIAALMEADCuAgAAGwAQrwIAALMEADCxAgEA3AMAIckCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdMCAQDsAwAh6QIBAOwDACHqAgIA7QMAIesCEADdAwAh7AIgAI8EACHtAgEAoAQAIQwMAACQBAAgrQIAAI4EADCuAgAA6AEAEK8CAACOBAAwsQIBANwDACHJAgEA7AMAIdECQADfAwAh0gJAAN8DACHnAiAAjwQAIe4CAQDcAwAhlwMAAOgBACCYAwAA6AEAIAPGAgAAIQAgxwIAACEAIMgCAAAhACADxgIAACUAIMcCAAAlACDIAgAAJQAgA8YCAAAxACDHAgAAMQAgyAIAADEAIAPGAgAALQAgxwIAAC0AIMgCAAAtACANCgAAqAQAIK0CAAC5BAAwrgIAABcAEK8CAAC5BAAwyQIBAOwDACHKAgEA3AMAIdECQADfAwAh0gJAAN8DACHTAgEA7AMAIe8CAQDcAwAh8AJAAN8DACHxAkAA7gMAIfICQADuAwAhEwgAALsEACAJAACjBAAgCwAAvAQAIAwAAJAEACAUAAC4BAAgrQIAALoEADCuAgAAEQAQrwIAALoEADDJAgEA7AMAIdECQADfAwAh0gJAAN8DACH2AgEA3AMAIfcCAQCgBAAh-AIBAKAEACH5AgEAoAQAIfoCAQCgBAAh-wIBANwDACH8AgEA3AMAIf0CAQCgBAAhCwYAAOADACCtAgAA2wMAMK4CAAAPABCvAgAA2wMAMLACAQDcAwAhsQIBANwDACGyAhAA3QMAIbMCAADeAwAgtAJAAN8DACGXAwAADwAgmAMAAA8AIAPGAgAAFwAgxwIAABcAIMgCAAAXACAC0wIBAAAAAfMCAQAAAAEJAwAAwAQAIAoAAKgEACCtAgAAvgQAMK4CAAALABCvAgAAvgQAMNECQADfAwAh0wIBAOwDACHzAgEA3AMAIfUCAAC_BPUCIgS1AgAAAPUCArYCAAAA9QIItwIAAAD1Agi8AgAAlQT1AiIUBAAAoQQAIAUAAKIEACAGAACjBAAgrQIAAJ8EADCuAgAARgAQrwIAAJ8EADCxAgEA3AMAIckCAQDcAwAhygIBANwDACHRAkAA3wMAIdICQADfAwAh9QIBANwDACGPAyAAjwQAIZADAQCgBAAhkQMBAKAEACGSAyAAjwQAIZMDQADuAwAhlAMBAKAEACGXAwAARgAgmAMAAEYAIBEDAADABAAgrQIAAMEEADCuAgAABwAQrwIAAMEEADDJAgEA3AMAIdECQADfAwAh0gJAAN8DACHzAgEA3AMAIYADAQDcAwAhgQMBANwDACGCAwEAoAQAIYMDAQCgBAAhhAMBAKAEACGFA0AA7gMAIYYDQADuAwAhhwMBAKAEACGIAwEAoAQAIREDAADABAAgrQIAAMIEADCuAgAAAwAQrwIAAMIEADDJAgEA3AMAIdECQADfAwAh0gJAAN8DACHwAkAA3wMAIfMCAQDcAwAh-AIBAKAEACH6AgEAoAQAIYkDAQDcAwAhigMBAKAEACGLAwEAoAQAIYwDAQCgBAAhjQMIAMMEACGOAwgAwwQAIQi1AggAAAABtgIIAAAABbcCCAAAAAW4AggAAAABuQIIAAAAAboCCAAAAAG7AggAAAABvAIIAJ0EACEAAAAAAAGcAwEAAAABBZwDEAAAAAGiAxAAAAABowMQAAAAAaQDEAAAAAGlAxAAAAABAZwDQAAAAAELIQAAzQQAMCIAANIEADCZAwAAzgQAMJoDAADPBAAwmwMAANAEACCcAwAA0QQAMJ0DAADRBAAwngMAANEEADCfAwAA0QQAMKADAADTBAAwoQMAANQEADAOCQAA8AUAIAsAAPEFACAMAADyBQAgFAAA8wUAIMkCAQAAAAHRAkAAAAAB0gJAAAAAAfYCAQAAAAH3AgEAAAAB-AIBAAAAAfkCAQAAAAH6AgEAAAAB-wIBAAAAAfwCAQAAAAECAAAAEwAgIQAA7wUAIAMAAAATACAhAADvBQAgIgAA2AQAIAEaAADdBwAwEwgAALsEACAJAACjBAAgCwAAvAQAIAwAAJAEACAUAAC4BAAgrQIAALoEADCuAgAAEQAQrwIAALoEADDJAgEAAAAB0QJAAN8DACHSAkAA3wMAIfYCAQDcAwAh9wIBAKAEACH4AgEAoAQAIfkCAQCgBAAh-gIBAKAEACH7AgEAAAAB_AIBANwDACH9AgEAoAQAIQIAAAATACAaAADYBAAgAgAAANUEACAaAADWBAAgDq0CAADUBAAwrgIAANUEABCvAgAA1AQAMMkCAQDsAwAh0QJAAN8DACHSAkAA3wMAIfYCAQDcAwAh9wIBAKAEACH4AgEAoAQAIfkCAQCgBAAh-gIBAKAEACH7AgEA3AMAIfwCAQDcAwAh_QIBAKAEACEOrQIAANQEADCuAgAA1QQAEK8CAADUBAAwyQIBAOwDACHRAkAA3wMAIdICQADfAwAh9gIBANwDACH3AgEAoAQAIfgCAQCgBAAh-QIBAKAEACH6AgEAoAQAIfsCAQDcAwAh_AIBANwDACH9AgEAoAQAIQrJAgEAyQQAIdECQADLBAAh0gJAAMsEACH2AgEAyQQAIfcCAQDXBAAh-AIBANcEACH5AgEA1wQAIfoCAQDXBAAh-wIBAMkEACH8AgEAyQQAIQGcAwEAAAABDgkAANkEACALAADaBAAgDAAA2wQAIBQAANwEACDJAgEAyQQAIdECQADLBAAh0gJAAMsEACH2AgEAyQQAIfcCAQDXBAAh-AIBANcEACH5AgEA1wQAIfoCAQDXBAAh-wIBAMkEACH8AgEAyQQAIQshAADgBQAwIgAA5QUAMJkDAADhBQAwmgMAAOIFADCbAwAA4wUAIJwDAADkBQAwnQMAAOQFADCeAwAA5AUAMJ8DAADkBQAwoAMAAOYFADChAwAA5wUAMAshAADUBQAwIgAA2QUAMJkDAADVBQAwmgMAANYFADCbAwAA1wUAIJwDAADYBQAwnQMAANgFADCeAwAA2AUAMJ8DAADYBQAwoAMAANoFADChAwAA2wUAMAshAAD_BAAwIgAAhAUAMJkDAACABQAwmgMAAIEFADCbAwAAggUAIJwDAACDBQAwnQMAAIMFADCeAwAAgwUAMJ8DAACDBQAwoAMAAIUFADChAwAAhgUAMAshAADdBAAwIgAA4gQAMJkDAADeBAAwmgMAAN8EADCbAwAA4AQAIJwDAADhBAAwnQMAAOEEADCeAwAA4QQAMJ8DAADhBAAwoAMAAOMEADChAwAA5AQAMA8OAAD9BAAgEQAA_gQAIMkCAQAAAAHRAkAAAAAB0gJAAAAAAdQCAQAAAAHVAgEAAAAB1gIBAAAAAdgCAAAA2AIC2QJAAAAAAdoCQAAAAAHcAgAAANwCAt0CAQAAAAHeAgEAAAAB3wIBAAAAAQIAAAA2ACAhAAD8BAAgAwAAADYAICEAAPwEACAiAADqBAAgARoAANwHADAUCgAAqAQAIA4AAKcEACARAACpBAAgrQIAAKQEADCuAgAALQAQrwIAAKQEADDJAgEAAAAB0QJAAN8DACHSAkAA3wMAIdMCAQDsAwAh1AIBAOwDACHVAgEA3AMAIdYCAQDcAwAh2AIAAKUE2AIi2QJAAN8DACHaAkAA7gMAIdwCAACmBNwCIt0CAQDcAwAh3gIBANwDACHfAgEA3AMAIQIAAAA2ACAaAADqBAAgAgAAAOUEACAaAADmBAAgEa0CAADkBAAwrgIAAOUEABCvAgAA5AQAMMkCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdMCAQDsAwAh1AIBAOwDACHVAgEA3AMAIdYCAQDcAwAh2AIAAKUE2AIi2QJAAN8DACHaAkAA7gMAIdwCAACmBNwCIt0CAQDcAwAh3gIBANwDACHfAgEA3AMAIRGtAgAA5AQAMK4CAADlBAAQrwIAAOQEADDJAgEA7AMAIdECQADfAwAh0gJAAN8DACHTAgEA7AMAIdQCAQDsAwAh1QIBANwDACHWAgEA3AMAIdgCAAClBNgCItkCQADfAwAh2gJAAO4DACHcAgAApgTcAiLdAgEA3AMAId4CAQDcAwAh3wIBANwDACENyQIBAMkEACHRAkAAywQAIdICQADLBAAh1AIBAMkEACHVAgEAyQQAIdYCAQDJBAAh2AIAAOcE2AIi2QJAAMsEACHaAkAA6AQAIdwCAADpBNwCIt0CAQDJBAAh3gIBAMkEACHfAgEAyQQAIQGcAwAAANgCAgGcA0AAAAABAZwDAAAA3AICDw4AAOsEACARAADsBAAgyQIBAMkEACHRAkAAywQAIdICQADLBAAh1AIBAMkEACHVAgEAyQQAIdYCAQDJBAAh2AIAAOcE2AIi2QJAAMsEACHaAkAA6AQAIdwCAADpBNwCIt0CAQDJBAAh3gIBAMkEACHfAgEAyQQAIQUhAADRBwAgIgAA2gcAIJkDAADSBwAgmgMAANkHACCfAwAAHQAgCyEAAO0EADAiAADyBAAwmQMAAO4EADCaAwAA7wQAMJsDAADwBAAgnAMAAPEEADCdAwAA8QQAMJ4DAADxBAAwnwMAAPEEADCgAwAA8wQAMKEDAAD0BAAwDQ4AAPsEACDJAgEAAAAB0QJAAAAAAdICQAAAAAHUAgEAAAAB1QIBAAAAAdYCAQAAAAHcAgAAAOMCAt0CAQAAAAHeAgEAAAAB3wIBAAAAAeACAQAAAAHhAkAAAAABAgAAACsAICEAAPoEACADAAAAKwAgIQAA-gQAICIAAPgEACABGgAA2AcAMBMOAACnBAAgEgAArgQAIK0CAACsBAAwrgIAACkAEK8CAACsBAAwyQIBAAAAAdECQADfAwAh0gJAAN8DACHUAgEA7AMAIdUCAQDcAwAh1gIBANwDACHcAgAA_APjAiLdAgEA3AMAId4CAQDcAwAh3wIBANwDACHgAgEAAAAB4QJAAN8DACHmAgEArQQAIZUDAACrBAAgAgAAACsAIBoAAPgEACACAAAA9QQAIBoAAPYEACAQrQIAAPQEADCuAgAA9QQAEK8CAAD0BAAwyQIBAOwDACHRAkAA3wMAIdICQADfAwAh1AIBAOwDACHVAgEA3AMAIdYCAQDcAwAh3AIAAPwD4wIi3QIBANwDACHeAgEA3AMAId8CAQDcAwAh4AIBANwDACHhAkAA3wMAIeYCAQCtBAAhEK0CAAD0BAAwrgIAAPUEABCvAgAA9AQAMMkCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdQCAQDsAwAh1QIBANwDACHWAgEA3AMAIdwCAAD8A-MCIt0CAQDcAwAh3gIBANwDACHfAgEA3AMAIeACAQDcAwAh4QJAAN8DACHmAgEArQQAIQzJAgEAyQQAIdECQADLBAAh0gJAAMsEACHUAgEAyQQAIdUCAQDJBAAh1gIBAMkEACHcAgAA9wTjAiLdAgEAyQQAId4CAQDJBAAh3wIBAMkEACHgAgEAyQQAIeECQADLBAAhAZwDAAAA4wICDQ4AAPkEACDJAgEAyQQAIdECQADLBAAh0gJAAMsEACHUAgEAyQQAIdUCAQDJBAAh1gIBAMkEACHcAgAA9wTjAiLdAgEAyQQAId4CAQDJBAAh3wIBAMkEACHgAgEAyQQAIeECQADLBAAhBSEAANMHACAiAADWBwAgmQMAANQHACCaAwAA1QcAIJ8DAAAdACANDgAA-wQAIMkCAQAAAAHRAkAAAAAB0gJAAAAAAdQCAQAAAAHVAgEAAAAB1gIBAAAAAdwCAAAA4wIC3QIBAAAAAd4CAQAAAAHfAgEAAAAB4AIBAAAAAeECQAAAAAEDIQAA0wcAIJkDAADUBwAgnwMAAB0AIA8OAAD9BAAgEQAA_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_BQAgARoAAL8HADANDgAApwQAIK0CAACwBAAwrgIAACUAEK8CAACwBAAwsgIQAN0DACHJAgEAAAAB0QJAAN8DACHSAkAA3wMAIdQCAQDsAwAh1QIBAKAEACHWAgEAoAQAIdgCAACxBNgCI-cCIACPBAAhAgAAACcAIBoAAL8FACACAAAAvAUAIBoAAL0FACAMrQIAALsFADCuAgAAvAUAEK8CAAC7BQAwsgIQAN0DACHJAgEA7AMAIdECQADfAwAh0gJAAN8DACHUAgEA7AMAIdUCAQCgBAAh1gIBAKAEACHYAgAAsQTYAiPnAiAAjwQAIQytAgAAuwUAMK4CAAC8BQAQrwIAALsFADCyAhAA3QMAIckCAQDsAwAh0QJAAN8DACHSAkAA3wMAIdQCAQDsAwAh1QIBAKAEACHWAgEAoAQAIdgCAACxBNgCI-cCIACPBAAhCLICEADKBAAhyQIBAMkEACHRAkAAywQAIdICQADLBAAh1QIBANcEACHWAgEA1wQAIdgCAAC-BdgCI-cCIACKBQAhAZwDAAAA2AIDCLICEADKBAAhyQIBAMkEACHRAkAAywQAIdICQADLBAAh1QIBANcEACHWAgEA1wQAIdgCAAC-BdgCI-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-BAAwrgIAAAsAEK8CAAC-BAAw0QJAAN8DACHTAgEA7AMAIfMCAQDcAwAh9QIAAL8E9QIilgMAAL0EACACAAAADQAgGgAA6wUAIAIAAADoBQAgGgAA6QUAIAetAgAA5wUAMK4CAADoBQAQrwIAAOcFADDRAkAA3wMAIdMCAQDsAwAh8wIBANwDACH1AgAAvwT1AiIHrQIAAOcFADCuAgAA6AUAEK8CAADnBQAw0QJAAN8DACHTAgEA7AMAIfMCAQDcAwAh9QIAAL8E9QIiA9ECQADLBAAh8wIBAMkEACH1AgAA6gX1AiIBnAMAAAD1AgIEAwAA7AUAINECQADLBAAh8wIBAMkEACH1AgAA6gX1AiIFIQAAtQcAICIAALgHACCZAwAAtgcAIJoDAAC3BwAgnwMAAAEAIAQDAADuBQAg0QJAAAAAAfMCAQAAAAH1AgAAAPUCAgMhAAC1BwAgmQMAALYHACCfAwAAAQAgDgkAAPAFACALAADxBQAgDAAA8gUAIBQAAPMFACDJAgEAAAAB0QJAAAAAAdICQAAAAAH2AgEAAAAB9wIBAAAAAfgCAQAAAAH5AgEAAAAB-gIBAAAAAfsCAQAAAAH8AgEAAAABBCEAAOAFADCZAwAA4QUAMJsDAADjBQAgnwMAAOQFADAEIQAA1AUAMJkDAADVBQAwmwMAANcFACCfAwAA2AUAMAQhAAD_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-QYAIA0AAPwGACAPAAD9BgAgEAAA_gYAIBEAAPoGACATAAD_BgAgFAAAgAcAIO0CAAD2BQAgCggAAIEHACAJAAD3BgAgCwAAggcAIAwAAKsGACAUAACABwAg9wIAAPYFACD4AgAA9gUAIPkCAAD2BQAg-gIAAPYFACD9AgAA9gUAIAAECgAA-QYAIA4AAPgGACARAAD6BgAg2gIAAPYFACABDAAAqwYAIAAAAAABBgAA9QUAIAAHBAAA9QYAIAUAAPYGACAGAAD3BgAgkAMAAPYFACCRAwAA9gUAIJMDAAD2BQAglAMAAPYFACAMyQIBAAAAAdECQAAAAAHSAkAAAAAB8AJAAAAAAfgCAQAAAAH6AgEAAAABiQMBAAAAAYoDAQAAAAGLAwEAAAABjAMBAAAAAY0DCAAAAAGOAwgAAAABDMkCAQAAAAHRAkAAAAAB0gJAAAAAAYADAQAAAAGBAwEAAAABggMBAAAAAYMDAQAAAAGEAwEAAAABhQNAAAAAAYYDQAAAAAGHAwEAAAABiAMBAAAAAQPRAkAAAAAB0wIBAAAAAfUCAAAA9QICDgUAAPMGACAGAAD0BgAgsQIBAAAAAckCAQAAAAHKAgEAAAAB0QJAAAAAAdICQAAAAAH1AgEAAAABjwMgAAAAAZADAQAAAAGRAwEAAAABkgMgAAAAAZMDQAAAAAGUAwEAAAABAgAAAAEAICEAAIcHACADAAAARgAgIQAAhwcAICIAAIsHACAQAAAARgAgBQAAzwYAIAYAANAGACAaAACLBwAgsQIBAMkEACHJAgEAyQQAIcoCAQDJBAAh0QJAAMsEACHSAkAAywQAIfUCAQDJBAAhjwMgAIoFACGQAwEA1wQAIZEDAQDXBAAhkgMgAIoFACGTA0AA6AQAIZQDAQDXBAAhDgUAAM8GACAGAADQBgAgsQIBAMkEACHJAgEAyQQAIcoCAQDJBAAh0QJAAMsEACHSAkAAywQAIfUCAQDJBAAhjwMgAIoFACGQAwEA1wQAIZEDAQDXBAAhkgMgAIoFACGTA0AA6AQAIZQDAQDXBAAhDgQAAPIGACAGAAD0BgAgsQIBAAAAAckCAQAAAAHKAgEAAAAB0QJAAAAAAdICQAAAAAH1AgEAAAABjwMgAAAAAZADAQAAAAGRAwEAAAABkgMgAAAAAZMDQAAAAAGUAwEAAAABAgAAAAEAICEAAIwHACADAAAARgAgIQAAjAcAICIAAJAHACAQAAAARgAgBAAAzgYAIAYAANAGACAaAACQBwAgsQIBAMkEACHJAgEAyQQAIcoCAQDJBAAh0QJAAMsEACHSAkAAywQAIfUCAQDJBAAhjwMgAIoFACGQAwEA1wQAIZEDAQDXBAAhkgMgAIoFACGTA0AA6AQAIZQDAQDXBAAhDgQAAM4GACAGAADQBgAgsQIBAMkEACHJAgEAyQQAIcoCAQDJBAAh0QJAAMsEACHSAkAAywQAIfUCAQDJBAAhjwMgAIoFACGQAwEA1wQAIZEDAQDXBAAhkgMgAIoFACGTA0AA6AQAIZQDAQDXBAAhBbACAQAAAAGxAgEAAAABsgIQAAAAAbMCgAAAAAG0AkAAAAABAgAAALYDACAhAACRBwAgAwAAAA8AICEAAJEHACAiAACVBwAgBwAAAA8AIBoAAJUHACCwAgEAyQQAIbECAQDJBAAhsgIQAMoEACGzAoAAAAABtAJAAMsEACEFsAIBAMkEACGxAgEAyQQAIbICEADKBAAhswKAAAAAAbQCQADLBAAhDwgAALoGACALAADxBQAgDAAA8gUAIBQAAPMFACDJAgEAAAAB0QJAAAAAAdICQAAAAAH2AgEAAAAB9wIBAAAAAfgCAQAAAAH5AgEAAAAB-gIBAAAAAfsCAQAAAAH8AgEAAAAB_QIBAAAAAQIAAAATACAhAACWBwAgAwAAABEAICEAAJYHACAiAACaBwAgEQAAABEAIAgAALkGACALAADaBAAgDAAA2wQAIBQAANwEACAaAACaBwAgyQIBAMkEACHRAkAAywQAIdICQADLBAAh9gIBAMkEACH3AgEA1wQAIfgCAQDXBAAh-QIBANcEACH6AgEA1wQAIfsCAQDJBAAh_AIBAMkEACH9AgEA1wQAIQ8IAAC5BgAgCwAA2gQAIAwAANsEACAUAADcBAAgyQIBAMkEACHRAkAAywQAIdICQADLBAAh9gIBAMkEACH3AgEA1wQAIfgCAQDXBAAh-QIBANcEACH6AgEA1wQAIfsCAQDJBAAh_AIBAMkEACH9AgEA1wQAIQ8IAAC6BgAgCQAA8AUAIAwAAPIFACAUAADzBQAgyQIBAAAAAdECQAAAAAHSAkAAAAAB9gIBAAAAAfcCAQAAAAH4AgEAAAAB-QIBAAAAAfoCAQAAAAH7AgEAAAAB_AIBAAAAAf0CAQAAAAECAAAAEwAgIQAAmwcAIAMAAAARACAhAACbBwAgIgAAnwcAIBEAAAARACAIAAC5BgAgCQAA2QQAIAwAANsEACAUAADcBAAgGgAAnwcAIMkCAQDJBAAh0QJAAMsEACHSAkAAywQAIfYCAQDJBAAh9wIBANcEACH4AgEA1wQAIfkCAQDXBAAh-gIBANcEACH7AgEAyQQAIfwCAQDJBAAh_QIBANcEACEPCAAAuQYAIAkAANkEACAMAADbBAAgFAAA3AQAIMkCAQDJBAAh0QJAAMsEACHSAkAAywQAIfYCAQDJBAAh9wIBANcEACH4AgEA1wQAIfkCAQDXBAAh-gIBANcEACH7AgEAyQQAIfwCAQDJBAAh_QIBANcEACEJsQIBAAAAAckCAQAAAAHRAkAAAAAB0gJAAAAAAdMCAQAAAAHqAgIAAAAB6wIQAAAAAewCIAAAAAHtAgEAAAABDwgAALoGACAJAADwBQAgCwAA8QUAIBQAAPMFACDJAgEAAAAB0QJAAAAAAdICQAAAAAH2AgEAAAAB9wIBAAAAAfgCAQAAAAH5AgEAAAAB-gIBAAAAAfsCAQAAAAH8AgEAAAAB_QIBAAAAAQIAAAATACAhAAChBwAgAwAAABEAICEAAKEHACAiAAClBwAgEQAAABEAIAgAALkGACAJAADZBAAgCwAA2gQAIBQAANwEACAaAAClBwAgyQIBAMkEACHRAkAAywQAIdICQADLBAAh9gIBAMkEACH3AgEA1wQAIfgCAQDXBAAh-QIBANcEACH6AgEA1wQAIfsCAQDJBAAh_AIBAMkEACH9AgEA1wQAIQ8IAAC5BgAgCQAA2QQAIAsAANoEACAUAADcBAAgyQIBAMkEACHRAkAAywQAIdICQADLBAAh9gIBAMkEACH3AgEA1wQAIfgCAQDXBAAh-QIBANcEACH6AgEA1wQAIfsCAQDJBAAh_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-AIBAAAAAfkCAQAAAAH6AgEAAAAB-wIBAAAAAfwCAQAAAAH9AgEAAAABAgAAABMAICEAAMcHACADAAAAEQAgIQAAxwcAICIAAMsHACARAAAAEQAgCAAAuQYAIAkAANkEACALAADaBAAgDAAA2wQAIBoAAMsHACDJAgEAyQQAIdECQADLBAAh0gJAAMsEACH2AgEAyQQAIfcCAQDXBAAh-AIBANcEACH5AgEA1wQAIfoCAQDXBAAh-wIBAMkEACH8AgEAyQQAIf0CAQDXBAAhDwgAALkGACAJAADZBAAgCwAA2gQAIAwAANsEACDJAgEAyQQAIdECQADLBAAh0gJAAMsEACH2AgEAyQQAIfcCAQDXBAAh-AIBANcEACH5AgEA1wQAIfoCAQDXBAAh-wIBAMkEACH8AgEAyQQAIf0CAQDXBAAhDckCAQAAAAHRAkAAAAAB0gJAAAAAAdMCAQAAAAHVAgEAAAAB1gIBAAAAAdgCAAAA2AIC2QJAAAAAAdoCQAAAAAHcAgAAANwCAt0CAQAAAAHeAgEAAAAB3wIBAAAAAQMAAADoAQAgIQAAvAcAICIAAM8HACAIAAAA6AEAIBoAAM8HACCxAgEAyQQAIckCAQDJBAAh0QJAAMsEACHSAkAAywQAIecCIACKBQAh7gIBAMkEACEGsQIBAMkEACHJAgEAyQQAIdECQADLBAAh0gJAAMsEACHnAiAAigUAIe4CAQDJBAAhCbECAQAAAAHJAgEAAAAB0QJAAAAAAdICQAAAAAHpAgEAAAAB6gICAAAAAesCEAAAAAHsAiAAAAAB7QIBAAAAARAKAACcBgAgDQAAzgUAIA8AAM8FACAQAADQBQAgEQAA0QUAIBMAANIFACCxAgEAAAAByQIBAAAAAdECQAAAAAHSAkAAAAAB0wIBAAAAAekCAQAAAAHqAgIAAAAB6wIQAAAAAewCIAAAAAHtAgEAAAABAgAAAB0AICEAANEHACAQCgAAnAYAIA0AAM4FACAPAADPBQAgEAAA0AUAIBMAANIFACAUAADTBQAgsQIBAAAAAckCAQAAAAHRAkAAAAAB0gJAAAAAAdMCAQAAAAHpAgEAAAAB6gICAAAAAesCEAAAAAHsAiAAAAAB7QIBAAAAAQIAAAAdACAhAADTBwAgAwAAABsAICEAANMHACAiAADXBwAgEgAAABsAIAoAAJsGACANAACMBQAgDwAAjQUAIBAAAI4FACATAACQBQAgFAAAkQUAIBoAANcHACCxAgEAyQQAIckCAQDJBAAh0QJAAMsEACHSAkAAywQAIdMCAQDJBAAh6QIBAMkEACHqAgIAiQUAIesCEADKBAAh7AIgAIoFACHtAgEA1wQAIRAKAACbBgAgDQAAjAUAIA8AAI0FACAQAACOBQAgEwAAkAUAIBQAAJEFACCxAgEAyQQAIckCAQDJBAAh0QJAAMsEACHSAkAAywQAIdMCAQDJBAAh6QIBAMkEACHqAgIAiQUAIesCEADKBAAh7AIgAIoFACHtAgEA1wQAIQzJAgEAAAAB0QJAAAAAAdICQAAAAAHUAgEAAAAB1QIBAAAAAdYCAQAAAAHcAgAAAOMCAt0CAQAAAAHeAgEAAAAB3wIBAAAAAeACAQAAAAHhAkAAAAABAwAAABsAICEAANEHACAiAADbBwAgEgAAABsAIAoAAJsGACANAACMBQAgDwAAjQUAIBAAAI4FACARAACPBQAgEwAAkAUAIBoAANsHACCxAgEAyQQAIckCAQDJBAAh0QJAAMsEACHSAkAAywQAIdMCAQDJBAAh6QIBAMkEACHqAgIAiQUAIesCEADKBAAh7AIgAIoFACHtAgEA1wQAIRAKAACbBgAgDQAAjAUAIA8AAI0FACAQAACOBQAgEQAAjwUAIBMAAJAFACCxAgEAyQQAIckCAQDJBAAh0QJAAMsEACHSAkAAywQAIdMCAQDJBAAh6QIBAMkEACHqAgIAiQUAIesCEADKBAAh7AIgAIoFACHtAgEA1wQAIQ3JAgEAAAAB0QJAAAAAAdICQAAAAAHUAgEAAAAB1QIBAAAAAdYCAQAAAAHYAgAAANgCAtkCQAAAAAHaAkAAAAAB3AIAAADcAgLdAgEAAAAB3gIBAAAAAd8CAQAAAAEKyQIBAAAAAdECQAAAAAHSAkAAAAAB9gIBAAAAAfcCAQAAAAH4AgEAAAAB-QIBAAAAAfoCAQAAAAH7AgEAAAAB_AIBAAAAAQQEBgIFCgMGDgQHABQBAwABAQMAAQIDAAEKAAUGBwATCBAGCRYECxoIDB4JFD0PAgYUBQcABwEGFQABCgAFCAcAEgoABQ0ACg8kDBAoDREsDhM0ERQ3DwIHAAsMHwkBDCAAAQ4ACQEOAAkCDgAJEi4PBAcAEAoABQ4ACREvDgERMAABDgAJBQ84ABA5ABE6ABM7ABQ8AAQJPgALPwAMQAAUQQADBEIABUMABkQAAAAAAwcAGScAGigAGwAAAAMHABknABooABsBAwABAQMAAQUHACAnACMoACQ5ACE6ACIAAAAAAAUHACAnACMoACQ5ACE6ACIBAwABAQMAAQMHACknACooACsAAAADBwApJwAqKAArAAAAAwcAMScAMigAMwAAAAMHADEnADIoADMBCKsBBgEIsQEGAwcAOCcAOSgAOgAAAAMHADgnADkoADoCAwABCgAFAgMAAQoABQMHAD8nAEAoAEEAAAADBwA_JwBAKABBAQoABQEKAAUDBwBGJwBHKABIAAAAAwcARicARygASAAAAwcATScATigATwAAAAMHAE0nAE4oAE8CCgAFDQAKAgoABQ0ACgUHAFQnAFcoAFg5AFU6AFYAAAAAAAUHAFQnAFcoAFg5AFU6AFYBDgAJAQ4ACQMHAF0nAF4oAF8AAAADBwBdJwBeKABfAQ4ACQEOAAkDBwBkJwBlKABmAAAAAwcAZCcAZSgAZgEOAAkBDgAJBQcAaycAbigAbzkAbDoAbQAAAAAABQcAaycAbigAbzkAbDoAbQIOAAkS4AIPAg4ACRLmAg8DBwB0JwB1KAB2AAAAAwcAdCcAdSgAdgAAAAMHAHwnAH0oAH4AAAADBwB8JwB9KAB-AgoABQ4ACQIKAAUOAAkDBwCDAScAhAEoAIUBAAAAAwcAgwEnAIQBKACFAQAAAAUHAIsBJwCOASgAjwE5AIwBOgCNAQAAAAAABQcAiwEnAI4BKACPATkAjAE6AI0BAAAFBwCUAScAlwEoAJgBOQCVAToAlgEAAAAAAAUHAJQBJwCXASgAmAE5AJUBOgCWARUCARZFARdIARhJARlKARtMARxOFR1PFh5RAR9TFSBUFyNVASRWASVXFSlaGCpbHCtcAixdAi1eAi5fAi9gAjBiAjFkFTJlHTNnAjRpFTVqHjZrAjdsAjhtFTtwHzxxJT1yAz5zAz90A0B1A0F2A0J4A0N6FUR7JkV9A0Z_FUeAASdIgQEDSYIBA0qDARVLhgEoTIcBLE2JAS1OigEtT40BLVCOAS1RjwEtUpEBLVOTARVUlAEuVZYBLVaYARVXmQEvWJoBLVmbAS1anAEVW58BMFygATRdoQEFXqIBBV-jAQVgpAEFYaUBBWKnAQVjqQEVZKoBNWWtAQVmrwEVZ7ABNmiyAQVpswEFarQBFWu3ATdsuAE7bbkBBG66AQRvuwEEcLwBBHG9AQRyvwEEc8EBFXTCATx1xAEEdsYBFXfHAT14yAEEeckBBHrKARV7zQE-fM4BQn3PAQh-0AEIf9EBCIAB0gEIgQHTAQiCAdUBCIMB1wEVhAHYAUOFAdoBCIYB3AEVhwHdAUSIAd4BCIkB3wEIigHgARWLAeMBRYwB5AFJjQHmAQqOAecBCo8B6gEKkAHrAQqRAewBCpIB7gEKkwHwARWUAfEBSpUB8wEKlgH1ARWXAfYBS5gB9wEKmQH4AQqaAfkBFZsB_AFMnAH9AVCdAf4BCZ4B_wEJnwGAAgmgAYECCaEBggIJogGEAgmjAYYCFaQBhwJRpQGJAgmmAYsCFacBjAJSqAGNAgmpAY4CCaoBjwIVqwGSAlOsAZMCWa0BlAIRrgGVAhGvAZYCEbABlwIRsQGYAhGyAZoCEbMBnAIVtAGdAlq1AZ8CEbYBoQIVtwGiAlu4AaMCEbkBpAIRugGlAhW7AagCXLwBqQJgvQGqAgy-AasCDL8BrAIMwAGtAgzBAa4CDMIBsAIMwwGyAhXEAbMCYcUBtQIMxgG3AhXHAbgCYsgBuQIMyQG6AgzKAbsCFcsBvgJjzAG_AmfNAcACDc4BwQINzwHCAg3QAcMCDdEBxAIN0gHGAg3TAcgCFdQByQJo1QHLAg3WAc0CFdcBzgJp2AHPAg3ZAdACDdoB0QIV2wHUAmrcAdUCcN0B1gIO3gHXAg7fAdgCDuAB2QIO4QHaAg7iAdwCDuMB3gIV5AHfAnHlAeICDuYB5AIV5wHlAnLoAecCDukB6AIO6gHpAhXrAewCc-wB7QJ37QHvAnjuAfACeO8B8wJ48AH0AnjxAfUCePIB9wJ48wH5AhX0AfoCefUB_AJ49gH-AhX3Af8CevgBgAN4-QGBA3j6AYIDFfsBhQN7_AGGA3_9AYcDD_4BiAMP_wGJAw-AAooDD4ECiwMPggKNAw-DAo8DFYQCkAOAAYUCkgMPhgKUAxWHApUDgQGIApYDD4kClwMPigKYAxWLApsDggGMApwDhgGNAp4DhwGOAp8DhwGPAqIDhwGQAqMDhwGRAqQDhwGSAqYDhwGTAqgDFZQCqQOIAZUCqwOHAZYCrQMVlwKuA4kBmAKvA4cBmQKwA4cBmgKxAxWbArQDigGcArUDkAGdArcDBp4CuAMGnwK6AwagArsDBqECvAMGogK-AwajAsADFaQCwQORAaUCwwMGpgLFAxWnAsYDkgGoAscDBqkCyAMGqgLJAxWrAswDkwGsAs0DmQE" } async function decodeBase64AsWasm(wasmBase64: string): Promise { @@ -328,6 +328,16 @@ export interface PrismaClient< */ get courtBookingLog(): Prisma.CourtBookingLogDelegate; + /** + * `prisma.recurringBookingGroup`: Exposes CRUD operations for the **RecurringBookingGroup** model. + * Example usage: + * ```ts + * // Fetch zero or more RecurringBookingGroups + * const recurringBookingGroups = await prisma.recurringBookingGroup.findMany() + * ``` + */ + get recurringBookingGroup(): Prisma.RecurringBookingGroupDelegate; + /** * `prisma.passwordResetRequest`: Exposes CRUD operations for the **PasswordResetRequest** model. * Example usage: diff --git a/apps/backend/src/generated/prisma/internal/prismaNamespace.ts b/apps/backend/src/generated/prisma/internal/prismaNamespace.ts index 86ae405..78f3a17 100644 --- a/apps/backend/src/generated/prisma/internal/prismaNamespace.ts +++ b/apps/backend/src/generated/prisma/internal/prismaNamespace.ts @@ -398,6 +398,7 @@ export const ModelName = { CourtPriceRule: 'CourtPriceRule', CourtBooking: 'CourtBooking', CourtBookingLog: 'CourtBookingLog', + RecurringBookingGroup: 'RecurringBookingGroup', PasswordResetRequest: 'PasswordResetRequest', Plan: 'Plan' } as const @@ -415,7 +416,7 @@ export type TypeMap + fields: Prisma.RecurringBookingGroupFieldRefs + operations: { + findUnique: { + args: Prisma.RecurringBookingGroupFindUniqueArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findUniqueOrThrow: { + args: Prisma.RecurringBookingGroupFindUniqueOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findFirst: { + args: Prisma.RecurringBookingGroupFindFirstArgs + result: runtime.Types.Utils.PayloadToResult | null + } + findFirstOrThrow: { + args: Prisma.RecurringBookingGroupFindFirstOrThrowArgs + result: runtime.Types.Utils.PayloadToResult + } + findMany: { + args: Prisma.RecurringBookingGroupFindManyArgs + result: runtime.Types.Utils.PayloadToResult[] + } + create: { + args: Prisma.RecurringBookingGroupCreateArgs + result: runtime.Types.Utils.PayloadToResult + } + createMany: { + args: Prisma.RecurringBookingGroupCreateManyArgs + result: BatchPayload + } + createManyAndReturn: { + args: Prisma.RecurringBookingGroupCreateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + delete: { + args: Prisma.RecurringBookingGroupDeleteArgs + result: runtime.Types.Utils.PayloadToResult + } + update: { + args: Prisma.RecurringBookingGroupUpdateArgs + result: runtime.Types.Utils.PayloadToResult + } + deleteMany: { + args: Prisma.RecurringBookingGroupDeleteManyArgs + result: BatchPayload + } + updateMany: { + args: Prisma.RecurringBookingGroupUpdateManyArgs + result: BatchPayload + } + updateManyAndReturn: { + args: Prisma.RecurringBookingGroupUpdateManyAndReturnArgs + result: runtime.Types.Utils.PayloadToResult[] + } + upsert: { + args: Prisma.RecurringBookingGroupUpsertArgs + result: runtime.Types.Utils.PayloadToResult + } + aggregate: { + args: Prisma.RecurringBookingGroupAggregateArgs + result: runtime.Types.Utils.Optional + } + groupBy: { + args: Prisma.RecurringBookingGroupGroupByArgs + result: runtime.Types.Utils.Optional[] + } + count: { + args: Prisma.RecurringBookingGroupCountArgs + result: runtime.Types.Utils.Optional | number + } + } + } PasswordResetRequest: { payload: Prisma.$PasswordResetRequestPayload fields: Prisma.PasswordResetRequestFieldRefs @@ -1832,6 +1907,7 @@ export const CourtBookingScalarFieldEnum = { customerPhone: 'customerPhone', customerEmail: 'customerEmail', status: 'status', + recurringGroupId: 'recurringGroupId', createdAt: 'createdAt', updatedAt: 'updatedAt' } as const @@ -1857,6 +1933,26 @@ export const CourtBookingLogScalarFieldEnum = { export type CourtBookingLogScalarFieldEnum = (typeof CourtBookingLogScalarFieldEnum)[keyof typeof CourtBookingLogScalarFieldEnum] +export const RecurringBookingGroupScalarFieldEnum = { + id: 'id', + complexId: 'complexId', + courtId: 'courtId', + startTime: 'startTime', + endTime: 'endTime', + dayOfWeek: 'dayOfWeek', + startDate: 'startDate', + endDate: 'endDate', + status: 'status', + customerName: 'customerName', + customerPhone: 'customerPhone', + customerEmail: 'customerEmail', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type RecurringBookingGroupScalarFieldEnum = (typeof RecurringBookingGroupScalarFieldEnum)[keyof typeof RecurringBookingGroupScalarFieldEnum] + + export const PasswordResetRequestScalarFieldEnum = { id: 'id', email: 'email', @@ -2049,6 +2145,20 @@ export type ListEnumCourtBookingStatusFieldRefInput<$PrismaModel> = FieldRefInpu +/** + * Reference to a field of type 'RecurringBookingGroupStatus' + */ +export type EnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'RecurringBookingGroupStatus'> + + + +/** + * Reference to a field of type 'RecurringBookingGroupStatus[]' + */ +export type ListEnumRecurringBookingGroupStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'RecurringBookingGroupStatus[]'> + + + /** * Reference to a field of type 'Json' */ @@ -2171,6 +2281,7 @@ export type GlobalOmitConfig = { courtPriceRule?: Prisma.CourtPriceRuleOmit courtBooking?: Prisma.CourtBookingOmit courtBookingLog?: Prisma.CourtBookingLogOmit + recurringBookingGroup?: Prisma.RecurringBookingGroupOmit passwordResetRequest?: Prisma.PasswordResetRequestOmit plan?: Prisma.PlanOmit } diff --git a/apps/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts b/apps/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts index e2e7a79..d4e8439 100644 --- a/apps/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts +++ b/apps/backend/src/generated/prisma/internal/prismaNamespaceBrowser.ts @@ -65,6 +65,7 @@ export const ModelName = { CourtPriceRule: 'CourtPriceRule', CourtBooking: 'CourtBooking', CourtBookingLog: 'CourtBookingLog', + RecurringBookingGroup: 'RecurringBookingGroup', PasswordResetRequest: 'PasswordResetRequest', Plan: 'Plan' } as const @@ -275,6 +276,7 @@ export const CourtBookingScalarFieldEnum = { customerPhone: 'customerPhone', customerEmail: 'customerEmail', status: 'status', + recurringGroupId: 'recurringGroupId', createdAt: 'createdAt', updatedAt: 'updatedAt' } as const @@ -300,6 +302,26 @@ export const CourtBookingLogScalarFieldEnum = { export type CourtBookingLogScalarFieldEnum = (typeof CourtBookingLogScalarFieldEnum)[keyof typeof CourtBookingLogScalarFieldEnum] +export const RecurringBookingGroupScalarFieldEnum = { + id: 'id', + complexId: 'complexId', + courtId: 'courtId', + startTime: 'startTime', + endTime: 'endTime', + dayOfWeek: 'dayOfWeek', + startDate: 'startDate', + endDate: 'endDate', + status: 'status', + customerName: 'customerName', + customerPhone: 'customerPhone', + customerEmail: 'customerEmail', + createdAt: 'createdAt', + updatedAt: 'updatedAt' +} as const + +export type RecurringBookingGroupScalarFieldEnum = (typeof RecurringBookingGroupScalarFieldEnum)[keyof typeof RecurringBookingGroupScalarFieldEnum] + + export const PasswordResetRequestScalarFieldEnum = { id: 'id', email: 'email', diff --git a/apps/backend/src/generated/prisma/models.ts b/apps/backend/src/generated/prisma/models.ts index 72a2f70..f499e73 100644 --- a/apps/backend/src/generated/prisma/models.ts +++ b/apps/backend/src/generated/prisma/models.ts @@ -22,6 +22,7 @@ export type * from './models/CourtAvailability' export type * from './models/CourtPriceRule' export type * from './models/CourtBooking' export type * from './models/CourtBookingLog' +export type * from './models/RecurringBookingGroup' export type * from './models/PasswordResetRequest' export type * from './models/Plan' export type * from './commonInputTypes' \ No newline at end of file diff --git a/apps/backend/src/generated/prisma/models/Complex.ts b/apps/backend/src/generated/prisma/models/Complex.ts index fb3237a..2aa0058 100644 --- a/apps/backend/src/generated/prisma/models/Complex.ts +++ b/apps/backend/src/generated/prisma/models/Complex.ts @@ -234,6 +234,7 @@ export type ComplexWhereInput = { users?: Prisma.ComplexUserListRelationFilter invitations?: Prisma.ComplexInvitationListRelationFilter courts?: Prisma.CourtListRelationFilter + recurringGroups?: Prisma.RecurringBookingGroupListRelationFilter } export type ComplexOrderByWithRelationInput = { @@ -252,6 +253,7 @@ export type ComplexOrderByWithRelationInput = { users?: Prisma.ComplexUserOrderByRelationAggregateInput invitations?: Prisma.ComplexInvitationOrderByRelationAggregateInput courts?: Prisma.CourtOrderByRelationAggregateInput + recurringGroups?: Prisma.RecurringBookingGroupOrderByRelationAggregateInput } export type ComplexWhereUniqueInput = Prisma.AtLeast<{ @@ -273,6 +275,7 @@ export type ComplexWhereUniqueInput = Prisma.AtLeast<{ users?: Prisma.ComplexUserListRelationFilter invitations?: Prisma.ComplexInvitationListRelationFilter courts?: Prisma.CourtListRelationFilter + recurringGroups?: Prisma.RecurringBookingGroupListRelationFilter }, "id" | "complexSlug"> export type ComplexOrderByWithAggregationInput = { @@ -324,6 +327,7 @@ export type ComplexCreateInput = { users?: Prisma.ComplexUserCreateNestedManyWithoutComplexInput invitations?: Prisma.ComplexInvitationCreateNestedManyWithoutComplexInput courts?: Prisma.CourtCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutComplexInput } export type ComplexUncheckedCreateInput = { @@ -341,6 +345,7 @@ export type ComplexUncheckedCreateInput = { users?: Prisma.ComplexUserUncheckedCreateNestedManyWithoutComplexInput invitations?: Prisma.ComplexInvitationUncheckedCreateNestedManyWithoutComplexInput courts?: Prisma.CourtUncheckedCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutComplexInput } export type ComplexUpdateInput = { @@ -358,6 +363,7 @@ export type ComplexUpdateInput = { users?: Prisma.ComplexUserUpdateManyWithoutComplexNestedInput invitations?: Prisma.ComplexInvitationUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutComplexNestedInput } export type ComplexUncheckedUpdateInput = { @@ -375,6 +381,7 @@ export type ComplexUncheckedUpdateInput = { users?: Prisma.ComplexUserUncheckedUpdateManyWithoutComplexNestedInput invitations?: Prisma.ComplexInvitationUncheckedUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUncheckedUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutComplexNestedInput } export type ComplexCreateManyInput = { @@ -517,6 +524,20 @@ export type ComplexUpdateOneRequiredWithoutCourtsNestedInput = { update?: Prisma.XOR, Prisma.ComplexUncheckedUpdateWithoutCourtsInput> } +export type ComplexCreateNestedOneWithoutRecurringGroupsInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.ComplexCreateOrConnectWithoutRecurringGroupsInput + connect?: Prisma.ComplexWhereUniqueInput +} + +export type ComplexUpdateOneRequiredWithoutRecurringGroupsNestedInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.ComplexCreateOrConnectWithoutRecurringGroupsInput + upsert?: Prisma.ComplexUpsertWithoutRecurringGroupsInput + connect?: Prisma.ComplexWhereUniqueInput + update?: Prisma.XOR, Prisma.ComplexUncheckedUpdateWithoutRecurringGroupsInput> +} + export type ComplexCreateNestedManyWithoutPlanInput = { create?: Prisma.XOR | Prisma.ComplexCreateWithoutPlanInput[] | Prisma.ComplexUncheckedCreateWithoutPlanInput[] connectOrCreate?: Prisma.ComplexCreateOrConnectWithoutPlanInput | Prisma.ComplexCreateOrConnectWithoutPlanInput[] @@ -573,6 +594,7 @@ export type ComplexCreateWithoutUsersInput = { plan?: Prisma.PlanCreateNestedOneWithoutComplexesInput invitations?: Prisma.ComplexInvitationCreateNestedManyWithoutComplexInput courts?: Prisma.CourtCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutComplexInput } export type ComplexUncheckedCreateWithoutUsersInput = { @@ -589,6 +611,7 @@ export type ComplexUncheckedCreateWithoutUsersInput = { updatedAt?: Date | string invitations?: Prisma.ComplexInvitationUncheckedCreateNestedManyWithoutComplexInput courts?: Prisma.CourtUncheckedCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutComplexInput } export type ComplexCreateOrConnectWithoutUsersInput = { @@ -621,6 +644,7 @@ export type ComplexUpdateWithoutUsersInput = { plan?: Prisma.PlanUpdateOneWithoutComplexesNestedInput invitations?: Prisma.ComplexInvitationUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutComplexNestedInput } export type ComplexUncheckedUpdateWithoutUsersInput = { @@ -637,6 +661,7 @@ export type ComplexUncheckedUpdateWithoutUsersInput = { updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string invitations?: Prisma.ComplexInvitationUncheckedUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUncheckedUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutComplexNestedInput } export type ComplexCreateWithoutInvitationsInput = { @@ -653,6 +678,7 @@ export type ComplexCreateWithoutInvitationsInput = { plan?: Prisma.PlanCreateNestedOneWithoutComplexesInput users?: Prisma.ComplexUserCreateNestedManyWithoutComplexInput courts?: Prisma.CourtCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutComplexInput } export type ComplexUncheckedCreateWithoutInvitationsInput = { @@ -669,6 +695,7 @@ export type ComplexUncheckedCreateWithoutInvitationsInput = { updatedAt?: Date | string users?: Prisma.ComplexUserUncheckedCreateNestedManyWithoutComplexInput courts?: Prisma.CourtUncheckedCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutComplexInput } export type ComplexCreateOrConnectWithoutInvitationsInput = { @@ -701,6 +728,7 @@ export type ComplexUpdateWithoutInvitationsInput = { plan?: Prisma.PlanUpdateOneWithoutComplexesNestedInput users?: Prisma.ComplexUserUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutComplexNestedInput } export type ComplexUncheckedUpdateWithoutInvitationsInput = { @@ -717,6 +745,7 @@ export type ComplexUncheckedUpdateWithoutInvitationsInput = { updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string users?: Prisma.ComplexUserUncheckedUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUncheckedUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutComplexNestedInput } export type ComplexCreateWithoutCourtsInput = { @@ -733,6 +762,7 @@ export type ComplexCreateWithoutCourtsInput = { plan?: Prisma.PlanCreateNestedOneWithoutComplexesInput users?: Prisma.ComplexUserCreateNestedManyWithoutComplexInput invitations?: Prisma.ComplexInvitationCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutComplexInput } export type ComplexUncheckedCreateWithoutCourtsInput = { @@ -749,6 +779,7 @@ export type ComplexUncheckedCreateWithoutCourtsInput = { updatedAt?: Date | string users?: Prisma.ComplexUserUncheckedCreateNestedManyWithoutComplexInput invitations?: Prisma.ComplexInvitationUncheckedCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutComplexInput } export type ComplexCreateOrConnectWithoutCourtsInput = { @@ -781,6 +812,7 @@ export type ComplexUpdateWithoutCourtsInput = { plan?: Prisma.PlanUpdateOneWithoutComplexesNestedInput users?: Prisma.ComplexUserUpdateManyWithoutComplexNestedInput invitations?: Prisma.ComplexInvitationUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutComplexNestedInput } export type ComplexUncheckedUpdateWithoutCourtsInput = { @@ -797,6 +829,91 @@ export type ComplexUncheckedUpdateWithoutCourtsInput = { updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string users?: Prisma.ComplexUserUncheckedUpdateManyWithoutComplexNestedInput invitations?: Prisma.ComplexInvitationUncheckedUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutComplexNestedInput +} + +export type ComplexCreateWithoutRecurringGroupsInput = { + id: string + complexName: string + physicalAddress?: string | null + city?: string | null + state?: string | null + country?: string | null + complexSlug: string + adminEmail: string + createdAt?: Date | string + updatedAt?: Date | string + plan?: Prisma.PlanCreateNestedOneWithoutComplexesInput + users?: Prisma.ComplexUserCreateNestedManyWithoutComplexInput + invitations?: Prisma.ComplexInvitationCreateNestedManyWithoutComplexInput + courts?: Prisma.CourtCreateNestedManyWithoutComplexInput +} + +export type ComplexUncheckedCreateWithoutRecurringGroupsInput = { + id: string + complexName: string + physicalAddress?: string | null + city?: string | null + state?: string | null + country?: string | null + complexSlug: string + adminEmail: string + planCode?: string | null + createdAt?: Date | string + updatedAt?: Date | string + users?: Prisma.ComplexUserUncheckedCreateNestedManyWithoutComplexInput + invitations?: Prisma.ComplexInvitationUncheckedCreateNestedManyWithoutComplexInput + courts?: Prisma.CourtUncheckedCreateNestedManyWithoutComplexInput +} + +export type ComplexCreateOrConnectWithoutRecurringGroupsInput = { + where: Prisma.ComplexWhereUniqueInput + create: Prisma.XOR +} + +export type ComplexUpsertWithoutRecurringGroupsInput = { + update: Prisma.XOR + create: Prisma.XOR + where?: Prisma.ComplexWhereInput +} + +export type ComplexUpdateToOneWithWhereWithoutRecurringGroupsInput = { + where?: Prisma.ComplexWhereInput + data: Prisma.XOR +} + +export type ComplexUpdateWithoutRecurringGroupsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + complexName?: Prisma.StringFieldUpdateOperationsInput | string + physicalAddress?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + city?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + state?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + country?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + complexSlug?: Prisma.StringFieldUpdateOperationsInput | string + adminEmail?: Prisma.StringFieldUpdateOperationsInput | string + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + plan?: Prisma.PlanUpdateOneWithoutComplexesNestedInput + users?: Prisma.ComplexUserUpdateManyWithoutComplexNestedInput + invitations?: Prisma.ComplexInvitationUpdateManyWithoutComplexNestedInput + courts?: Prisma.CourtUpdateManyWithoutComplexNestedInput +} + +export type ComplexUncheckedUpdateWithoutRecurringGroupsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + complexName?: Prisma.StringFieldUpdateOperationsInput | string + physicalAddress?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + city?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + state?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + country?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + complexSlug?: Prisma.StringFieldUpdateOperationsInput | string + adminEmail?: Prisma.StringFieldUpdateOperationsInput | string + planCode?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + users?: Prisma.ComplexUserUncheckedUpdateManyWithoutComplexNestedInput + invitations?: Prisma.ComplexInvitationUncheckedUpdateManyWithoutComplexNestedInput + courts?: Prisma.CourtUncheckedUpdateManyWithoutComplexNestedInput } export type ComplexCreateWithoutPlanInput = { @@ -813,6 +930,7 @@ export type ComplexCreateWithoutPlanInput = { users?: Prisma.ComplexUserCreateNestedManyWithoutComplexInput invitations?: Prisma.ComplexInvitationCreateNestedManyWithoutComplexInput courts?: Prisma.CourtCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutComplexInput } export type ComplexUncheckedCreateWithoutPlanInput = { @@ -829,6 +947,7 @@ export type ComplexUncheckedCreateWithoutPlanInput = { users?: Prisma.ComplexUserUncheckedCreateNestedManyWithoutComplexInput invitations?: Prisma.ComplexInvitationUncheckedCreateNestedManyWithoutComplexInput courts?: Prisma.CourtUncheckedCreateNestedManyWithoutComplexInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutComplexInput } export type ComplexCreateOrConnectWithoutPlanInput = { @@ -901,6 +1020,7 @@ export type ComplexUpdateWithoutPlanInput = { users?: Prisma.ComplexUserUpdateManyWithoutComplexNestedInput invitations?: Prisma.ComplexInvitationUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutComplexNestedInput } export type ComplexUncheckedUpdateWithoutPlanInput = { @@ -917,6 +1037,7 @@ export type ComplexUncheckedUpdateWithoutPlanInput = { users?: Prisma.ComplexUserUncheckedUpdateManyWithoutComplexNestedInput invitations?: Prisma.ComplexInvitationUncheckedUpdateManyWithoutComplexNestedInput courts?: Prisma.CourtUncheckedUpdateManyWithoutComplexNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutComplexNestedInput } export type ComplexUncheckedUpdateManyWithoutPlanInput = { @@ -941,12 +1062,14 @@ export type ComplexCountOutputType = { users: number invitations: number courts: number + recurringGroups: number } export type ComplexCountOutputTypeSelect = { users?: boolean | ComplexCountOutputTypeCountUsersArgs invitations?: boolean | ComplexCountOutputTypeCountInvitationsArgs courts?: boolean | ComplexCountOutputTypeCountCourtsArgs + recurringGroups?: boolean | ComplexCountOutputTypeCountRecurringGroupsArgs } /** @@ -980,6 +1103,13 @@ export type ComplexCountOutputTypeCountCourtsArgs = { + where?: Prisma.RecurringBookingGroupWhereInput +} + export type ComplexSelect = runtime.Types.Extensions.GetSelect<{ id?: boolean @@ -997,6 +1127,7 @@ export type ComplexSelect invitations?: boolean | Prisma.Complex$invitationsArgs courts?: boolean | Prisma.Complex$courtsArgs + recurringGroups?: boolean | Prisma.Complex$recurringGroupsArgs _count?: boolean | Prisma.ComplexCountOutputTypeDefaultArgs }, ExtArgs["result"]["complex"]> @@ -1050,6 +1181,7 @@ export type ComplexInclude invitations?: boolean | Prisma.Complex$invitationsArgs courts?: boolean | Prisma.Complex$courtsArgs + recurringGroups?: boolean | Prisma.Complex$recurringGroupsArgs _count?: boolean | Prisma.ComplexCountOutputTypeDefaultArgs } export type ComplexIncludeCreateManyAndReturn = { @@ -1066,6 +1198,7 @@ export type $ComplexPayload[] invitations: Prisma.$ComplexInvitationPayload[] courts: Prisma.$CourtPayload[] + recurringGroups: Prisma.$RecurringBookingGroupPayload[] } scalars: runtime.Types.Extensions.GetPayloadResult<{ id: string @@ -1477,6 +1610,7 @@ export interface Prisma__ComplexClient = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> invitations = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> courts = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + recurringGroups = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -2008,6 +2142,30 @@ export type Complex$courtsArgs = { + /** + * Select specific fields to fetch from the RecurringBookingGroup + */ + select?: Prisma.RecurringBookingGroupSelect | null + /** + * Omit specific fields from the RecurringBookingGroup + */ + omit?: Prisma.RecurringBookingGroupOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.RecurringBookingGroupInclude | null + where?: Prisma.RecurringBookingGroupWhereInput + orderBy?: Prisma.RecurringBookingGroupOrderByWithRelationInput | Prisma.RecurringBookingGroupOrderByWithRelationInput[] + cursor?: Prisma.RecurringBookingGroupWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.RecurringBookingGroupScalarFieldEnum | Prisma.RecurringBookingGroupScalarFieldEnum[] +} + /** * Complex without action */ diff --git a/apps/backend/src/generated/prisma/models/Court.ts b/apps/backend/src/generated/prisma/models/Court.ts index 7607fef..da6c905 100644 --- a/apps/backend/src/generated/prisma/models/Court.ts +++ b/apps/backend/src/generated/prisma/models/Court.ts @@ -266,6 +266,7 @@ export type CourtWhereInput = { priceRules?: Prisma.CourtPriceRuleListRelationFilter bookings?: Prisma.CourtBookingListRelationFilter maintenances?: Prisma.CourtMaintenanceListRelationFilter + recurringGroups?: Prisma.RecurringBookingGroupListRelationFilter } export type CourtOrderByWithRelationInput = { @@ -285,6 +286,7 @@ export type CourtOrderByWithRelationInput = { priceRules?: Prisma.CourtPriceRuleOrderByRelationAggregateInput bookings?: Prisma.CourtBookingOrderByRelationAggregateInput maintenances?: Prisma.CourtMaintenanceOrderByRelationAggregateInput + recurringGroups?: Prisma.RecurringBookingGroupOrderByRelationAggregateInput } export type CourtWhereUniqueInput = Prisma.AtLeast<{ @@ -307,6 +309,7 @@ export type CourtWhereUniqueInput = Prisma.AtLeast<{ priceRules?: Prisma.CourtPriceRuleListRelationFilter bookings?: Prisma.CourtBookingListRelationFilter maintenances?: Prisma.CourtMaintenanceListRelationFilter + recurringGroups?: Prisma.RecurringBookingGroupListRelationFilter }, "id"> export type CourtOrderByWithAggregationInput = { @@ -358,6 +361,7 @@ export type CourtCreateInput = { priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateInput = { @@ -375,6 +379,7 @@ export type CourtUncheckedCreateInput = { priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtUpdateInput = { @@ -392,6 +397,7 @@ export type CourtUpdateInput = { priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateInput = { @@ -409,6 +415,7 @@ export type CourtUncheckedUpdateInput = { priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput } export type CourtCreateManyInput = { @@ -668,6 +675,20 @@ export type CourtUpdateOneRequiredWithoutBookingsNestedInput = { update?: Prisma.XOR, Prisma.CourtUncheckedUpdateWithoutBookingsInput> } +export type CourtCreateNestedOneWithoutRecurringGroupsInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.CourtCreateOrConnectWithoutRecurringGroupsInput + connect?: Prisma.CourtWhereUniqueInput +} + +export type CourtUpdateOneRequiredWithoutRecurringGroupsNestedInput = { + create?: Prisma.XOR + connectOrCreate?: Prisma.CourtCreateOrConnectWithoutRecurringGroupsInput + upsert?: Prisma.CourtUpsertWithoutRecurringGroupsInput + connect?: Prisma.CourtWhereUniqueInput + update?: Prisma.XOR, Prisma.CourtUncheckedUpdateWithoutRecurringGroupsInput> +} + export type CourtCreateWithoutComplexInput = { id: string name: string @@ -682,6 +703,7 @@ export type CourtCreateWithoutComplexInput = { priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateWithoutComplexInput = { @@ -698,6 +720,7 @@ export type CourtUncheckedCreateWithoutComplexInput = { priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtCreateOrConnectWithoutComplexInput = { @@ -756,6 +779,7 @@ export type CourtCreateWithoutSportInput = { priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateWithoutSportInput = { @@ -772,6 +796,7 @@ export type CourtUncheckedCreateWithoutSportInput = { priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtCreateOrConnectWithoutSportInput = { @@ -814,6 +839,7 @@ export type CourtCreateWithoutMaintenancesInput = { availabilities?: Prisma.CourtAvailabilityCreateNestedManyWithoutCourtInput priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateWithoutMaintenancesInput = { @@ -830,6 +856,7 @@ export type CourtUncheckedCreateWithoutMaintenancesInput = { availabilities?: Prisma.CourtAvailabilityUncheckedCreateNestedManyWithoutCourtInput priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtCreateOrConnectWithoutMaintenancesInput = { @@ -862,6 +889,7 @@ export type CourtUpdateWithoutMaintenancesInput = { availabilities?: Prisma.CourtAvailabilityUpdateManyWithoutCourtNestedInput priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateWithoutMaintenancesInput = { @@ -878,6 +906,7 @@ export type CourtUncheckedUpdateWithoutMaintenancesInput = { availabilities?: Prisma.CourtAvailabilityUncheckedUpdateManyWithoutCourtNestedInput priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput } export type CourtCreateWithoutAvailabilitiesInput = { @@ -894,6 +923,7 @@ export type CourtCreateWithoutAvailabilitiesInput = { priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateWithoutAvailabilitiesInput = { @@ -910,6 +940,7 @@ export type CourtUncheckedCreateWithoutAvailabilitiesInput = { priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtCreateOrConnectWithoutAvailabilitiesInput = { @@ -942,6 +973,7 @@ export type CourtUpdateWithoutAvailabilitiesInput = { priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateWithoutAvailabilitiesInput = { @@ -958,6 +990,7 @@ export type CourtUncheckedUpdateWithoutAvailabilitiesInput = { priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput } export type CourtCreateWithoutPriceRulesInput = { @@ -974,6 +1007,7 @@ export type CourtCreateWithoutPriceRulesInput = { availabilities?: Prisma.CourtAvailabilityCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateWithoutPriceRulesInput = { @@ -990,6 +1024,7 @@ export type CourtUncheckedCreateWithoutPriceRulesInput = { availabilities?: Prisma.CourtAvailabilityUncheckedCreateNestedManyWithoutCourtInput bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtCreateOrConnectWithoutPriceRulesInput = { @@ -1022,6 +1057,7 @@ export type CourtUpdateWithoutPriceRulesInput = { availabilities?: Prisma.CourtAvailabilityUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateWithoutPriceRulesInput = { @@ -1038,6 +1074,7 @@ export type CourtUncheckedUpdateWithoutPriceRulesInput = { availabilities?: Prisma.CourtAvailabilityUncheckedUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput } export type CourtCreateWithoutBookingsInput = { @@ -1054,6 +1091,7 @@ export type CourtCreateWithoutBookingsInput = { availabilities?: Prisma.CourtAvailabilityCreateNestedManyWithoutCourtInput priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupCreateNestedManyWithoutCourtInput } export type CourtUncheckedCreateWithoutBookingsInput = { @@ -1070,6 +1108,7 @@ export type CourtUncheckedCreateWithoutBookingsInput = { availabilities?: Prisma.CourtAvailabilityUncheckedCreateNestedManyWithoutCourtInput priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedCreateNestedManyWithoutCourtInput } export type CourtCreateOrConnectWithoutBookingsInput = { @@ -1102,6 +1141,7 @@ export type CourtUpdateWithoutBookingsInput = { availabilities?: Prisma.CourtAvailabilityUpdateManyWithoutCourtNestedInput priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateWithoutBookingsInput = { @@ -1118,6 +1158,91 @@ export type CourtUncheckedUpdateWithoutBookingsInput = { availabilities?: Prisma.CourtAvailabilityUncheckedUpdateManyWithoutCourtNestedInput priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput +} + +export type CourtCreateWithoutRecurringGroupsInput = { + id: string + name: string + slotDurationMinutes: number + basePrice: runtime.Decimal | runtime.DecimalJsLike | number | string + isUnderMaintenance?: boolean + maintenanceReason?: string | null + createdAt?: Date | string + updatedAt?: Date | string + complex: Prisma.ComplexCreateNestedOneWithoutCourtsInput + sport: Prisma.SportCreateNestedOneWithoutCourtsInput + availabilities?: Prisma.CourtAvailabilityCreateNestedManyWithoutCourtInput + priceRules?: Prisma.CourtPriceRuleCreateNestedManyWithoutCourtInput + bookings?: Prisma.CourtBookingCreateNestedManyWithoutCourtInput + maintenances?: Prisma.CourtMaintenanceCreateNestedManyWithoutCourtInput +} + +export type CourtUncheckedCreateWithoutRecurringGroupsInput = { + id: string + complexId: string + sportId: string + name: string + slotDurationMinutes: number + basePrice: runtime.Decimal | runtime.DecimalJsLike | number | string + isUnderMaintenance?: boolean + maintenanceReason?: string | null + createdAt?: Date | string + updatedAt?: Date | string + availabilities?: Prisma.CourtAvailabilityUncheckedCreateNestedManyWithoutCourtInput + priceRules?: Prisma.CourtPriceRuleUncheckedCreateNestedManyWithoutCourtInput + bookings?: Prisma.CourtBookingUncheckedCreateNestedManyWithoutCourtInput + maintenances?: Prisma.CourtMaintenanceUncheckedCreateNestedManyWithoutCourtInput +} + +export type CourtCreateOrConnectWithoutRecurringGroupsInput = { + where: Prisma.CourtWhereUniqueInput + create: Prisma.XOR +} + +export type CourtUpsertWithoutRecurringGroupsInput = { + update: Prisma.XOR + create: Prisma.XOR + where?: Prisma.CourtWhereInput +} + +export type CourtUpdateToOneWithWhereWithoutRecurringGroupsInput = { + where?: Prisma.CourtWhereInput + data: Prisma.XOR +} + +export type CourtUpdateWithoutRecurringGroupsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + slotDurationMinutes?: Prisma.IntFieldUpdateOperationsInput | number + basePrice?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string + isUnderMaintenance?: Prisma.BoolFieldUpdateOperationsInput | boolean + maintenanceReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + complex?: Prisma.ComplexUpdateOneRequiredWithoutCourtsNestedInput + sport?: Prisma.SportUpdateOneRequiredWithoutCourtsNestedInput + availabilities?: Prisma.CourtAvailabilityUpdateManyWithoutCourtNestedInput + priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput + bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput + maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput +} + +export type CourtUncheckedUpdateWithoutRecurringGroupsInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + complexId?: Prisma.StringFieldUpdateOperationsInput | string + sportId?: Prisma.StringFieldUpdateOperationsInput | string + name?: Prisma.StringFieldUpdateOperationsInput | string + slotDurationMinutes?: Prisma.IntFieldUpdateOperationsInput | number + basePrice?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string + isUnderMaintenance?: Prisma.BoolFieldUpdateOperationsInput | boolean + maintenanceReason?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + availabilities?: Prisma.CourtAvailabilityUncheckedUpdateManyWithoutCourtNestedInput + priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput + bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput + maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput } export type CourtCreateManyComplexInput = { @@ -1146,6 +1271,7 @@ export type CourtUpdateWithoutComplexInput = { priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateWithoutComplexInput = { @@ -1162,6 +1288,7 @@ export type CourtUncheckedUpdateWithoutComplexInput = { priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateManyWithoutComplexInput = { @@ -1202,6 +1329,7 @@ export type CourtUpdateWithoutSportInput = { priceRules?: Prisma.CourtPriceRuleUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateWithoutSportInput = { @@ -1218,6 +1346,7 @@ export type CourtUncheckedUpdateWithoutSportInput = { priceRules?: Prisma.CourtPriceRuleUncheckedUpdateManyWithoutCourtNestedInput bookings?: Prisma.CourtBookingUncheckedUpdateManyWithoutCourtNestedInput maintenances?: Prisma.CourtMaintenanceUncheckedUpdateManyWithoutCourtNestedInput + recurringGroups?: Prisma.RecurringBookingGroupUncheckedUpdateManyWithoutCourtNestedInput } export type CourtUncheckedUpdateManyWithoutSportInput = { @@ -1242,6 +1371,7 @@ export type CourtCountOutputType = { priceRules: number bookings: number maintenances: number + recurringGroups: number } export type CourtCountOutputTypeSelect = { @@ -1249,6 +1379,7 @@ export type CourtCountOutputTypeSelect = { + where?: Prisma.RecurringBookingGroupWhereInput +} + export type CourtSelect = runtime.Types.Extensions.GetSelect<{ id?: boolean @@ -1307,6 +1445,7 @@ export type CourtSelect bookings?: boolean | Prisma.Court$bookingsArgs maintenances?: boolean | Prisma.Court$maintenancesArgs + recurringGroups?: boolean | Prisma.Court$recurringGroupsArgs _count?: boolean | Prisma.CourtCountOutputTypeDefaultArgs }, ExtArgs["result"]["court"]> @@ -1361,6 +1500,7 @@ export type CourtInclude bookings?: boolean | Prisma.Court$bookingsArgs maintenances?: boolean | Prisma.Court$maintenancesArgs + recurringGroups?: boolean | Prisma.Court$recurringGroupsArgs _count?: boolean | Prisma.CourtCountOutputTypeDefaultArgs } export type CourtIncludeCreateManyAndReturn = { @@ -1381,6 +1521,7 @@ export type $CourtPayload[] bookings: Prisma.$CourtBookingPayload[] maintenances: Prisma.$CourtMaintenancePayload[] + recurringGroups: Prisma.$RecurringBookingGroupPayload[] } scalars: runtime.Types.Extensions.GetPayloadResult<{ id: string @@ -1793,6 +1934,7 @@ export interface Prisma__CourtClient = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> bookings = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> maintenances = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> + recurringGroups = {}>(args?: Prisma.Subset>): Prisma.PrismaPromise, T, "findMany", GlobalOmitOptions> | Null> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -2328,6 +2470,30 @@ export type Court$maintenancesArgs = { + /** + * Select specific fields to fetch from the RecurringBookingGroup + */ + select?: Prisma.RecurringBookingGroupSelect | null + /** + * Omit specific fields from the RecurringBookingGroup + */ + omit?: Prisma.RecurringBookingGroupOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.RecurringBookingGroupInclude | null + where?: Prisma.RecurringBookingGroupWhereInput + orderBy?: Prisma.RecurringBookingGroupOrderByWithRelationInput | Prisma.RecurringBookingGroupOrderByWithRelationInput[] + cursor?: Prisma.RecurringBookingGroupWhereUniqueInput + take?: number + skip?: number + distinct?: Prisma.RecurringBookingGroupScalarFieldEnum | Prisma.RecurringBookingGroupScalarFieldEnum[] +} + /** * Court without action */ diff --git a/apps/backend/src/generated/prisma/models/CourtBooking.ts b/apps/backend/src/generated/prisma/models/CourtBooking.ts index 3b7863c..cc9cc3f 100644 --- a/apps/backend/src/generated/prisma/models/CourtBooking.ts +++ b/apps/backend/src/generated/prisma/models/CourtBooking.ts @@ -35,6 +35,7 @@ export type CourtBookingMinAggregateOutputType = { customerPhone: string | null customerEmail: string | null status: $Enums.CourtBookingStatus | null + recurringGroupId: string | null createdAt: Date | null updatedAt: Date | null } @@ -50,6 +51,7 @@ export type CourtBookingMaxAggregateOutputType = { customerPhone: string | null customerEmail: string | null status: $Enums.CourtBookingStatus | null + recurringGroupId: string | null createdAt: Date | null updatedAt: Date | null } @@ -65,6 +67,7 @@ export type CourtBookingCountAggregateOutputType = { customerPhone: number customerEmail: number status: number + recurringGroupId: number createdAt: number updatedAt: number _all: number @@ -82,6 +85,7 @@ export type CourtBookingMinAggregateInputType = { customerPhone?: true customerEmail?: true status?: true + recurringGroupId?: true createdAt?: true updatedAt?: true } @@ -97,6 +101,7 @@ export type CourtBookingMaxAggregateInputType = { customerPhone?: true customerEmail?: true status?: true + recurringGroupId?: true createdAt?: true updatedAt?: true } @@ -112,6 +117,7 @@ export type CourtBookingCountAggregateInputType = { customerPhone?: true customerEmail?: true status?: true + recurringGroupId?: true createdAt?: true updatedAt?: true _all?: true @@ -200,6 +206,7 @@ export type CourtBookingGroupByOutputType = { customerPhone: string customerEmail: string status: $Enums.CourtBookingStatus + recurringGroupId: string | null createdAt: Date updatedAt: Date _count: CourtBookingCountAggregateOutputType | null @@ -236,9 +243,11 @@ export type CourtBookingWhereInput = { customerPhone?: Prisma.StringFilter<"CourtBooking"> | string customerEmail?: Prisma.StringFilter<"CourtBooking"> | string status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.UuidNullableFilter<"CourtBooking"> | string | null createdAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string updatedAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string court?: Prisma.XOR + recurringGroup?: Prisma.XOR | null } export type CourtBookingOrderByWithRelationInput = { @@ -252,9 +261,11 @@ export type CourtBookingOrderByWithRelationInput = { customerPhone?: Prisma.SortOrder customerEmail?: Prisma.SortOrder status?: Prisma.SortOrder + recurringGroupId?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder court?: Prisma.CourtOrderByWithRelationInput + recurringGroup?: Prisma.RecurringBookingGroupOrderByWithRelationInput } export type CourtBookingWhereUniqueInput = Prisma.AtLeast<{ @@ -272,9 +283,11 @@ export type CourtBookingWhereUniqueInput = Prisma.AtLeast<{ customerPhone?: Prisma.StringFilter<"CourtBooking"> | string customerEmail?: Prisma.StringFilter<"CourtBooking"> | string status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.UuidNullableFilter<"CourtBooking"> | string | null createdAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string updatedAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string court?: Prisma.XOR + recurringGroup?: Prisma.XOR | null }, "id" | "bookingCode" | "courtId_bookingDate_startTime"> export type CourtBookingOrderByWithAggregationInput = { @@ -288,6 +301,7 @@ export type CourtBookingOrderByWithAggregationInput = { customerPhone?: Prisma.SortOrder customerEmail?: Prisma.SortOrder status?: Prisma.SortOrder + recurringGroupId?: Prisma.SortOrderInput | Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder _count?: Prisma.CourtBookingCountOrderByAggregateInput @@ -309,6 +323,7 @@ export type CourtBookingScalarWhereWithAggregatesInput = { customerPhone?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string customerEmail?: Prisma.StringWithAggregatesFilter<"CourtBooking"> | string status?: Prisma.EnumCourtBookingStatusWithAggregatesFilter<"CourtBooking"> | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.UuidNullableWithAggregatesFilter<"CourtBooking"> | string | null createdAt?: Prisma.DateTimeWithAggregatesFilter<"CourtBooking"> | Date | string updatedAt?: Prisma.DateTimeWithAggregatesFilter<"CourtBooking"> | Date | string } @@ -326,6 +341,7 @@ export type CourtBookingCreateInput = { createdAt?: Date | string updatedAt?: Date | string court: Prisma.CourtCreateNestedOneWithoutBookingsInput + recurringGroup?: Prisma.RecurringBookingGroupCreateNestedOneWithoutBookingsInput } export type CourtBookingUncheckedCreateInput = { @@ -339,6 +355,7 @@ export type CourtBookingUncheckedCreateInput = { customerPhone: string customerEmail: string status?: $Enums.CourtBookingStatus + recurringGroupId?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -356,6 +373,7 @@ export type CourtBookingUpdateInput = { createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string court?: Prisma.CourtUpdateOneRequiredWithoutBookingsNestedInput + recurringGroup?: Prisma.RecurringBookingGroupUpdateOneWithoutBookingsNestedInput } export type CourtBookingUncheckedUpdateInput = { @@ -369,6 +387,7 @@ export type CourtBookingUncheckedUpdateInput = { customerPhone?: Prisma.StringFieldUpdateOperationsInput | string customerEmail?: Prisma.StringFieldUpdateOperationsInput | string status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -384,6 +403,7 @@ export type CourtBookingCreateManyInput = { customerPhone: string customerEmail: string status?: $Enums.CourtBookingStatus + recurringGroupId?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -413,6 +433,7 @@ export type CourtBookingUncheckedUpdateManyInput = { customerPhone?: Prisma.StringFieldUpdateOperationsInput | string customerEmail?: Prisma.StringFieldUpdateOperationsInput | string status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -444,6 +465,7 @@ export type CourtBookingCountOrderByAggregateInput = { customerPhone?: Prisma.SortOrder customerEmail?: Prisma.SortOrder status?: Prisma.SortOrder + recurringGroupId?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder } @@ -459,6 +481,7 @@ export type CourtBookingMaxOrderByAggregateInput = { customerPhone?: Prisma.SortOrder customerEmail?: Prisma.SortOrder status?: Prisma.SortOrder + recurringGroupId?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder } @@ -474,6 +497,7 @@ export type CourtBookingMinOrderByAggregateInput = { customerPhone?: Prisma.SortOrder customerEmail?: Prisma.SortOrder status?: Prisma.SortOrder + recurringGroupId?: Prisma.SortOrder createdAt?: Prisma.SortOrder updatedAt?: Prisma.SortOrder } @@ -524,6 +548,48 @@ export type EnumCourtBookingStatusFieldUpdateOperationsInput = { set?: $Enums.CourtBookingStatus } +export type CourtBookingCreateNestedManyWithoutRecurringGroupInput = { + create?: Prisma.XOR | Prisma.CourtBookingCreateWithoutRecurringGroupInput[] | Prisma.CourtBookingUncheckedCreateWithoutRecurringGroupInput[] + connectOrCreate?: Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput | Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput[] + createMany?: Prisma.CourtBookingCreateManyRecurringGroupInputEnvelope + connect?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] +} + +export type CourtBookingUncheckedCreateNestedManyWithoutRecurringGroupInput = { + create?: Prisma.XOR | Prisma.CourtBookingCreateWithoutRecurringGroupInput[] | Prisma.CourtBookingUncheckedCreateWithoutRecurringGroupInput[] + connectOrCreate?: Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput | Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput[] + createMany?: Prisma.CourtBookingCreateManyRecurringGroupInputEnvelope + connect?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] +} + +export type CourtBookingUpdateManyWithoutRecurringGroupNestedInput = { + create?: Prisma.XOR | Prisma.CourtBookingCreateWithoutRecurringGroupInput[] | Prisma.CourtBookingUncheckedCreateWithoutRecurringGroupInput[] + connectOrCreate?: Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput | Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput[] + upsert?: Prisma.CourtBookingUpsertWithWhereUniqueWithoutRecurringGroupInput | Prisma.CourtBookingUpsertWithWhereUniqueWithoutRecurringGroupInput[] + createMany?: Prisma.CourtBookingCreateManyRecurringGroupInputEnvelope + set?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + disconnect?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + delete?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + connect?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + update?: Prisma.CourtBookingUpdateWithWhereUniqueWithoutRecurringGroupInput | Prisma.CourtBookingUpdateWithWhereUniqueWithoutRecurringGroupInput[] + updateMany?: Prisma.CourtBookingUpdateManyWithWhereWithoutRecurringGroupInput | Prisma.CourtBookingUpdateManyWithWhereWithoutRecurringGroupInput[] + deleteMany?: Prisma.CourtBookingScalarWhereInput | Prisma.CourtBookingScalarWhereInput[] +} + +export type CourtBookingUncheckedUpdateManyWithoutRecurringGroupNestedInput = { + create?: Prisma.XOR | Prisma.CourtBookingCreateWithoutRecurringGroupInput[] | Prisma.CourtBookingUncheckedCreateWithoutRecurringGroupInput[] + connectOrCreate?: Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput | Prisma.CourtBookingCreateOrConnectWithoutRecurringGroupInput[] + upsert?: Prisma.CourtBookingUpsertWithWhereUniqueWithoutRecurringGroupInput | Prisma.CourtBookingUpsertWithWhereUniqueWithoutRecurringGroupInput[] + createMany?: Prisma.CourtBookingCreateManyRecurringGroupInputEnvelope + set?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + disconnect?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + delete?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + connect?: Prisma.CourtBookingWhereUniqueInput | Prisma.CourtBookingWhereUniqueInput[] + update?: Prisma.CourtBookingUpdateWithWhereUniqueWithoutRecurringGroupInput | Prisma.CourtBookingUpdateWithWhereUniqueWithoutRecurringGroupInput[] + updateMany?: Prisma.CourtBookingUpdateManyWithWhereWithoutRecurringGroupInput | Prisma.CourtBookingUpdateManyWithWhereWithoutRecurringGroupInput[] + deleteMany?: Prisma.CourtBookingScalarWhereInput | Prisma.CourtBookingScalarWhereInput[] +} + export type CourtBookingCreateWithoutCourtInput = { id: string bookingCode: string @@ -536,6 +602,7 @@ export type CourtBookingCreateWithoutCourtInput = { status?: $Enums.CourtBookingStatus createdAt?: Date | string updatedAt?: Date | string + recurringGroup?: Prisma.RecurringBookingGroupCreateNestedOneWithoutBookingsInput } export type CourtBookingUncheckedCreateWithoutCourtInput = { @@ -548,6 +615,7 @@ export type CourtBookingUncheckedCreateWithoutCourtInput = { customerPhone: string customerEmail: string status?: $Enums.CourtBookingStatus + recurringGroupId?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -592,10 +660,67 @@ export type CourtBookingScalarWhereInput = { customerPhone?: Prisma.StringFilter<"CourtBooking"> | string customerEmail?: Prisma.StringFilter<"CourtBooking"> | string status?: Prisma.EnumCourtBookingStatusFilter<"CourtBooking"> | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.UuidNullableFilter<"CourtBooking"> | string | null createdAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string updatedAt?: Prisma.DateTimeFilter<"CourtBooking"> | Date | string } +export type CourtBookingCreateWithoutRecurringGroupInput = { + id: string + bookingCode: string + bookingDate: Date | string + startTime: string + endTime: string + customerName: string + customerPhone: string + customerEmail: string + status?: $Enums.CourtBookingStatus + createdAt?: Date | string + updatedAt?: Date | string + court: Prisma.CourtCreateNestedOneWithoutBookingsInput +} + +export type CourtBookingUncheckedCreateWithoutRecurringGroupInput = { + id: string + bookingCode: string + courtId: string + bookingDate: Date | string + startTime: string + endTime: string + customerName: string + customerPhone: string + customerEmail: string + status?: $Enums.CourtBookingStatus + createdAt?: Date | string + updatedAt?: Date | string +} + +export type CourtBookingCreateOrConnectWithoutRecurringGroupInput = { + where: Prisma.CourtBookingWhereUniqueInput + create: Prisma.XOR +} + +export type CourtBookingCreateManyRecurringGroupInputEnvelope = { + data: Prisma.CourtBookingCreateManyRecurringGroupInput | Prisma.CourtBookingCreateManyRecurringGroupInput[] + skipDuplicates?: boolean +} + +export type CourtBookingUpsertWithWhereUniqueWithoutRecurringGroupInput = { + where: Prisma.CourtBookingWhereUniqueInput + update: Prisma.XOR + create: Prisma.XOR +} + +export type CourtBookingUpdateWithWhereUniqueWithoutRecurringGroupInput = { + where: Prisma.CourtBookingWhereUniqueInput + data: Prisma.XOR +} + +export type CourtBookingUpdateManyWithWhereWithoutRecurringGroupInput = { + where: Prisma.CourtBookingScalarWhereInput + data: Prisma.XOR +} + export type CourtBookingCreateManyCourtInput = { id: string bookingCode: string @@ -606,6 +731,7 @@ export type CourtBookingCreateManyCourtInput = { customerPhone: string customerEmail: string status?: $Enums.CourtBookingStatus + recurringGroupId?: string | null createdAt?: Date | string updatedAt?: Date | string } @@ -622,6 +748,7 @@ export type CourtBookingUpdateWithoutCourtInput = { status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + recurringGroup?: Prisma.RecurringBookingGroupUpdateOneWithoutBookingsNestedInput } export type CourtBookingUncheckedUpdateWithoutCourtInput = { @@ -634,6 +761,7 @@ export type CourtBookingUncheckedUpdateWithoutCourtInput = { customerPhone?: Prisma.StringFieldUpdateOperationsInput | string customerEmail?: Prisma.StringFieldUpdateOperationsInput | string status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -648,6 +776,67 @@ export type CourtBookingUncheckedUpdateManyWithoutCourtInput = { customerPhone?: Prisma.StringFieldUpdateOperationsInput | string customerEmail?: Prisma.StringFieldUpdateOperationsInput | string status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus + recurringGroupId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CourtBookingCreateManyRecurringGroupInput = { + id: string + bookingCode: string + courtId: string + bookingDate: Date | string + startTime: string + endTime: string + customerName: string + customerPhone: string + customerEmail: string + status?: $Enums.CourtBookingStatus + createdAt?: Date | string + updatedAt?: Date | string +} + +export type CourtBookingUpdateWithoutRecurringGroupInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + bookingCode?: Prisma.StringFieldUpdateOperationsInput | string + bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + startTime?: Prisma.StringFieldUpdateOperationsInput | string + endTime?: Prisma.StringFieldUpdateOperationsInput | string + customerName?: Prisma.StringFieldUpdateOperationsInput | string + customerPhone?: Prisma.StringFieldUpdateOperationsInput | string + customerEmail?: Prisma.StringFieldUpdateOperationsInput | string + status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + court?: Prisma.CourtUpdateOneRequiredWithoutBookingsNestedInput +} + +export type CourtBookingUncheckedUpdateWithoutRecurringGroupInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + bookingCode?: Prisma.StringFieldUpdateOperationsInput | string + courtId?: Prisma.StringFieldUpdateOperationsInput | string + bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + startTime?: Prisma.StringFieldUpdateOperationsInput | string + endTime?: Prisma.StringFieldUpdateOperationsInput | string + customerName?: Prisma.StringFieldUpdateOperationsInput | string + customerPhone?: Prisma.StringFieldUpdateOperationsInput | string + customerEmail?: Prisma.StringFieldUpdateOperationsInput | string + status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus + createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string +} + +export type CourtBookingUncheckedUpdateManyWithoutRecurringGroupInput = { + id?: Prisma.StringFieldUpdateOperationsInput | string + bookingCode?: Prisma.StringFieldUpdateOperationsInput | string + courtId?: Prisma.StringFieldUpdateOperationsInput | string + bookingDate?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string + startTime?: Prisma.StringFieldUpdateOperationsInput | string + endTime?: Prisma.StringFieldUpdateOperationsInput | string + customerName?: Prisma.StringFieldUpdateOperationsInput | string + customerPhone?: Prisma.StringFieldUpdateOperationsInput | string + customerEmail?: Prisma.StringFieldUpdateOperationsInput | string + status?: Prisma.EnumCourtBookingStatusFieldUpdateOperationsInput | $Enums.CourtBookingStatus createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string } @@ -665,9 +854,11 @@ export type CourtBookingSelect + recurringGroup?: boolean | Prisma.CourtBooking$recurringGroupArgs }, ExtArgs["result"]["courtBooking"]> export type CourtBookingSelectCreateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -681,9 +872,11 @@ export type CourtBookingSelectCreateManyAndReturn + recurringGroup?: boolean | Prisma.CourtBooking$recurringGroupArgs }, ExtArgs["result"]["courtBooking"]> export type CourtBookingSelectUpdateManyAndReturn = runtime.Types.Extensions.GetSelect<{ @@ -697,9 +890,11 @@ export type CourtBookingSelectUpdateManyAndReturn + recurringGroup?: boolean | Prisma.CourtBooking$recurringGroupArgs }, ExtArgs["result"]["courtBooking"]> export type CourtBookingSelectScalar = { @@ -713,25 +908,30 @@ export type CourtBookingSelectScalar = { customerPhone?: boolean customerEmail?: boolean status?: boolean + recurringGroupId?: boolean createdAt?: boolean updatedAt?: boolean } -export type CourtBookingOmit = runtime.Types.Extensions.GetOmit<"id" | "bookingCode" | "courtId" | "bookingDate" | "startTime" | "endTime" | "customerName" | "customerPhone" | "customerEmail" | "status" | "createdAt" | "updatedAt", ExtArgs["result"]["courtBooking"]> +export type CourtBookingOmit = runtime.Types.Extensions.GetOmit<"id" | "bookingCode" | "courtId" | "bookingDate" | "startTime" | "endTime" | "customerName" | "customerPhone" | "customerEmail" | "status" | "recurringGroupId" | "createdAt" | "updatedAt", ExtArgs["result"]["courtBooking"]> export type CourtBookingInclude = { court?: boolean | Prisma.CourtDefaultArgs + recurringGroup?: boolean | Prisma.CourtBooking$recurringGroupArgs } export type CourtBookingIncludeCreateManyAndReturn = { court?: boolean | Prisma.CourtDefaultArgs + recurringGroup?: boolean | Prisma.CourtBooking$recurringGroupArgs } export type CourtBookingIncludeUpdateManyAndReturn = { court?: boolean | Prisma.CourtDefaultArgs + recurringGroup?: boolean | Prisma.CourtBooking$recurringGroupArgs } export type $CourtBookingPayload = { name: "CourtBooking" objects: { court: Prisma.$CourtPayload + recurringGroup: Prisma.$RecurringBookingGroupPayload | null } scalars: runtime.Types.Extensions.GetPayloadResult<{ id: string @@ -744,6 +944,7 @@ export type $CourtBookingPayload @@ -1141,6 +1342,7 @@ readonly fields: CourtBookingFieldRefs; export interface Prisma__CourtBookingClient extends Prisma.PrismaPromise { readonly [Symbol.toStringTag]: "PrismaPromise" court = {}>(args?: Prisma.Subset>): Prisma.Prisma__CourtClient, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions> + recurringGroup = {}>(args?: Prisma.Subset>): Prisma.Prisma__RecurringBookingGroupClient, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions> /** * Attaches callbacks for the resolution and/or rejection of the Promise. * @param onfulfilled The callback to execute when the Promise is resolved. @@ -1180,6 +1382,7 @@ export interface CourtBookingFieldRefs { readonly customerPhone: Prisma.FieldRef<"CourtBooking", 'String'> readonly customerEmail: Prisma.FieldRef<"CourtBooking", 'String'> readonly status: Prisma.FieldRef<"CourtBooking", 'CourtBookingStatus'> + readonly recurringGroupId: Prisma.FieldRef<"CourtBooking", 'String'> readonly createdAt: Prisma.FieldRef<"CourtBooking", 'DateTime'> readonly updatedAt: Prisma.FieldRef<"CourtBooking", 'DateTime'> } @@ -1582,6 +1785,25 @@ export type CourtBookingDeleteManyArgs = { + /** + * Select specific fields to fetch from the RecurringBookingGroup + */ + select?: Prisma.RecurringBookingGroupSelect | null + /** + * Omit specific fields from the RecurringBookingGroup + */ + omit?: Prisma.RecurringBookingGroupOmit | null + /** + * Choose, which related nodes to fetch as well + */ + include?: Prisma.RecurringBookingGroupInclude | null + where?: Prisma.RecurringBookingGroupWhereInput +} + /** * CourtBooking without action */ diff --git a/apps/backend/src/modules/admin-booking/admin-booking.routes.ts b/apps/backend/src/modules/admin-booking/admin-booking.routes.ts index a3e3a08..f6aa181 100644 --- a/apps/backend/src/modules/admin-booking/admin-booking.routes.ts +++ b/apps/backend/src/modules/admin-booking/admin-booking.routes.ts @@ -1,13 +1,19 @@ import { requireAuth } from '@/middlewares/require-auth.middleware'; +import { cancelRecurringGroupHandler } from '@/modules/admin-booking/handlers/cancel-recurring-group.handler'; import { createAdminBookingHandler } from '@/modules/admin-booking/handlers/create-admin-booking.handler'; +import { createAdminRecurringBookingHandler } from '@/modules/admin-booking/handlers/create-admin-recurring-booking.handler'; import { listAdminBookingsHandler } from '@/modules/admin-booking/handlers/list-admin-bookings.handler'; +import { listRecurringGroupsHandler } from '@/modules/admin-booking/handlers/list-recurring-groups.handler'; import { updateAdminBookingStatusHandler } from '@/modules/admin-booking/handlers/update-admin-booking-status.handler'; +import { updateRecurringGroupHandler } from '@/modules/admin-booking/handlers/update-recurring-group.handler'; import type { AppEnv } from '@/types/hono'; import { zValidator } from '@hono/zod-validator'; import { createAdminBookingSchema, + createRecurringBookingSchema, listAdminBookingsQuerySchema, updateAdminBookingStatusSchema, + updateRecurringGroupSchema, } from '@repo/api-contract'; import { Hono } from 'hono'; import { z } from 'zod'; @@ -15,6 +21,7 @@ import { z } from 'zod'; export const adminBookingRoutes = new Hono(); const complexIdParamsSchema = z.object({ complexId: z.uuid() }); const bookingIdParamsSchema = z.object({ id: z.uuid() }); +const groupIdParamsSchema = z.object({ groupId: z.uuid() }); adminBookingRoutes.use('*', requireAuth); @@ -32,6 +39,32 @@ adminBookingRoutes.post( createAdminBookingHandler ); +adminBookingRoutes.post( + '/complex/:complexId/recurring', + zValidator('param', complexIdParamsSchema), + zValidator('json', createRecurringBookingSchema), + createAdminRecurringBookingHandler +); + +adminBookingRoutes.post( + '/recurring/:groupId/cancel', + zValidator('param', groupIdParamsSchema), + cancelRecurringGroupHandler +); + +adminBookingRoutes.get( + '/complex/:complexId/recurring', + zValidator('param', complexIdParamsSchema), + listRecurringGroupsHandler +); + +adminBookingRoutes.patch( + '/recurring/:groupId', + zValidator('param', groupIdParamsSchema), + zValidator('json', updateRecurringGroupSchema), + updateRecurringGroupHandler +); + adminBookingRoutes.patch( '/:id/status', zValidator('param', bookingIdParamsSchema), diff --git a/apps/backend/src/modules/admin-booking/handlers/cancel-recurring-group.handler.ts b/apps/backend/src/modules/admin-booking/handlers/cancel-recurring-group.handler.ts new file mode 100644 index 0000000..0d1c698 --- /dev/null +++ b/apps/backend/src/modules/admin-booking/handlers/cancel-recurring-group.handler.ts @@ -0,0 +1,20 @@ +import { AdminBookingServiceError } from '@/modules/admin-booking/services/admin-booking.service'; +import { cancelRecurringGroup } from '@/modules/admin-booking/services/admin-recurring-booking.service'; +import type { AppContext } from '@/types/hono'; + +type GroupIdParams = { groupId: string }; + +export async function cancelRecurringGroupHandler(c: AppContext) { + const { groupId } = c.req.valid('param' as never) as GroupIdParams; + const user = c.get('user'); + + try { + const result = await cancelRecurringGroup(user.id, groupId); + return c.json(result); + } catch (error) { + if (error instanceof AdminBookingServiceError) { + return c.json({ message: error.message }, error.status); + } + throw error; + } +} diff --git a/apps/backend/src/modules/admin-booking/handlers/create-admin-recurring-booking.handler.ts b/apps/backend/src/modules/admin-booking/handlers/create-admin-recurring-booking.handler.ts new file mode 100644 index 0000000..08bea79 --- /dev/null +++ b/apps/backend/src/modules/admin-booking/handlers/create-admin-recurring-booking.handler.ts @@ -0,0 +1,40 @@ +import { AdminBookingServiceError } from '@/modules/admin-booking/services/admin-booking.service'; +import { createAdminRecurringBooking } from '@/modules/admin-booking/services/admin-recurring-booking.service'; +import { sendBookingConfirmation } from '@/services/booking-email.service'; +import type { AppContext } from '@/types/hono'; +import type { CreateRecurringBookingInput } from '@repo/api-contract'; + +type ComplexIdParams = { complexId: string }; + +export async function createAdminRecurringBookingHandler(c: AppContext) { + const { complexId } = c.req.valid('param' as never) as ComplexIdParams; + const payload = c.req.valid('json' as never) as CreateRecurringBookingInput; + const user = c.get('user'); + + try { + const group = await createAdminRecurringBooking(user.id, complexId, payload); + + const firstBooking = group.bookings[0]; + if (firstBooking?.customerEmail) { + void sendBookingConfirmation({ + bookingCode: firstBooking.bookingCode, + complexName: firstBooking.complexName, + date: firstBooking.date, + startTime: firstBooking.startTime, + endTime: firstBooking.endTime, + courtName: firstBooking.courtName, + sportName: firstBooking.sport.name, + customerName: firstBooking.customerName, + customerEmail: firstBooking.customerEmail, + price: firstBooking.price, + }); + } + + return c.json(group, 201); + } catch (error) { + if (error instanceof AdminBookingServiceError) { + return c.json({ message: error.message }, error.status); + } + throw error; + } +} diff --git a/apps/backend/src/modules/admin-booking/handlers/list-recurring-groups.handler.ts b/apps/backend/src/modules/admin-booking/handlers/list-recurring-groups.handler.ts new file mode 100644 index 0000000..6f79004 --- /dev/null +++ b/apps/backend/src/modules/admin-booking/handlers/list-recurring-groups.handler.ts @@ -0,0 +1,19 @@ +import { AdminBookingServiceError } from '@/modules/admin-booking/services/admin-booking.service'; +import { listRecurringGroups } from '@/modules/admin-booking/services/admin-recurring-booking.service'; +import type { AppContext } from '@/types/hono'; + +type ComplexIdParams = { complexId: string }; + +export async function listRecurringGroupsHandler(c: AppContext) { + const { complexId } = c.req.valid('param' as never) as ComplexIdParams; + + try { + const groups = await listRecurringGroups(complexId); + return c.json({ groups }); + } catch (error) { + if (error instanceof AdminBookingServiceError) { + return c.json({ message: error.message }, error.status); + } + throw error; + } +} diff --git a/apps/backend/src/modules/admin-booking/handlers/update-recurring-group.handler.ts b/apps/backend/src/modules/admin-booking/handlers/update-recurring-group.handler.ts new file mode 100644 index 0000000..7df3c30 --- /dev/null +++ b/apps/backend/src/modules/admin-booking/handlers/update-recurring-group.handler.ts @@ -0,0 +1,22 @@ +import { AdminBookingServiceError } from '@/modules/admin-booking/services/admin-booking.service'; +import { updateRecurringGroup } from '@/modules/admin-booking/services/admin-recurring-booking.service'; +import type { AppContext } from '@/types/hono'; +import type { UpdateRecurringGroupInput } from '@repo/api-contract'; + +type GroupIdParams = { groupId: string }; + +export async function updateRecurringGroupHandler(c: AppContext) { + const { groupId } = c.req.valid('param' as never) as GroupIdParams; + const payload = c.req.valid('json' as never) as UpdateRecurringGroupInput; + const user = c.get('user'); + + try { + const group = await updateRecurringGroup(user.id, groupId, payload); + return c.json(group); + } catch (error) { + if (error instanceof AdminBookingServiceError) { + return c.json({ message: error.message }, error.status); + } + throw error; + } +} diff --git a/apps/backend/src/modules/admin-booking/services/admin-booking.service.ts b/apps/backend/src/modules/admin-booking/services/admin-booking.service.ts index 6cec611..51bd209 100644 --- a/apps/backend/src/modules/admin-booking/services/admin-booking.service.ts +++ b/apps/backend/src/modules/admin-booking/services/admin-booking.service.ts @@ -202,6 +202,7 @@ function mapBookingResponse(booking: { customerPhone: string; customerEmail: string; status: 'CONFIRMED' | 'CANCELLED' | 'COMPLETED' | 'NOSHOW'; + recurringGroupId: string | null; createdAt: Date; updatedAt: Date; court: { @@ -239,6 +240,7 @@ function mapBookingResponse(booking: { customerEmail: booking.customerEmail, price: booking.price ?? 0, status: booking.status, + recurringGroupId: booking.recurringGroupId, createdAt: booking.createdAt.toISOString(), updatedAt: booking.updatedAt.toISOString(), }; @@ -431,6 +433,7 @@ export async function createAdminBooking( customerPhone: input.customerPhone.trim(), customerEmail: input.customerEmail?.trim() ?? '', status: 'CONFIRMED', + recurringGroupId: null, }, include: { court: { diff --git a/apps/backend/src/modules/admin-booking/services/admin-recurring-booking.service.ts b/apps/backend/src/modules/admin-booking/services/admin-recurring-booking.service.ts new file mode 100644 index 0000000..5793a84 --- /dev/null +++ b/apps/backend/src/modules/admin-booking/services/admin-recurring-booking.service.ts @@ -0,0 +1,893 @@ +import { randomInt } from 'node:crypto'; +import { DayOfWeek as DayOfWeekEnum } from '@/generated/prisma/enums'; +import { db } from '@/lib/prisma'; +import { isSlotInPast } from '@/lib/slot-validator'; +import { + evaluatePlanUsage, + isFeatureEnabled, + parsePlanRules, +} from '@/modules/plan/services/plan-rules.service'; +import type { + CreateRecurringBookingInput, + RecurringBookingGroup, + UpdateRecurringGroupInput, +} from '@repo/api-contract'; +import { v7 as uuidv7 } from 'uuid'; +import { AdminBookingServiceError } from './admin-booking.service'; + +const BOOKING_CODE_ALPHABET = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; +const BOOKING_CODE_LENGTH = 6; +const MAX_RECURRING_WEEKS = 52; + +const DAY_INDEX_BY_VALUE: Record = { + SUNDAY: 0, + MONDAY: 1, + TUESDAY: 2, + WEDNESDAY: 3, + THURSDAY: 4, + FRIDAY: 5, + SATURDAY: 6, +}; + +const DAY_OF_WEEK_BY_INDEX = [ + DayOfWeekEnum.SUNDAY, + DayOfWeekEnum.MONDAY, + DayOfWeekEnum.TUESDAY, + DayOfWeekEnum.WEDNESDAY, + DayOfWeekEnum.THURSDAY, + DayOfWeekEnum.FRIDAY, + DayOfWeekEnum.SATURDAY, +] as const; + +type DayOfWeek = (typeof DAY_OF_WEEK_BY_INDEX)[number]; + +function toMinutes(value: string): number { + const [hours, minutes] = value.split(':').map((part) => Number(part)); + return hours * 60 + minutes; +} + +function minutesToTime(minutes: number): string { + const safeMinutes = Math.max(0, minutes); + const hours = Math.floor(safeMinutes / 60); + const mins = safeMinutes % 60; + return `${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}`; +} + +function parseIsoDate(date: string): Date { + const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(date); + + if (!match) { + throw new AdminBookingServiceError('La fecha debe tener formato YYYY-MM-DD.', 400); + } + + const year = Number(match[1]); + const month = Number(match[2]); + const day = Number(match[3]); + + const parsed = new Date(Date.UTC(year, month - 1, day)); + + if ( + Number.isNaN(parsed.getTime()) || + parsed.getUTCFullYear() !== year || + parsed.getUTCMonth() + 1 !== month || + parsed.getUTCDate() !== day + ) { + throw new AdminBookingServiceError('La fecha enviada no es valida.', 400); + } + + return parsed; +} + +function formatIsoDate(date: Date): string { + return date.toISOString().slice(0, 10); +} + +function getDayOfWeekValue(date: Date): DayOfWeek { + const dayOfWeek = DAY_OF_WEEK_BY_INDEX[date.getUTCDay()]; + + if (!dayOfWeek) { + throw new AdminBookingServiceError('No se pudo resolver el dia de la semana.', 400); + } + + return dayOfWeek; +} + +function generateBookingCode(): string { + let code = ''; + + for (let index = 0; index < BOOKING_CODE_LENGTH; index += 1) { + code += BOOKING_CODE_ALPHABET[randomInt(0, BOOKING_CODE_ALPHABET.length)]; + } + + return code; +} + +function buildSlots( + availability: Array<{ + startTime: string; + endTime: string; + }>, + slotDurationMinutes: number +) { + const slots: Array<{ startTime: string; endTime: string }> = []; + + for (const range of availability) { + const start = toMinutes(range.startTime); + const end = toMinutes(range.endTime); + + for ( + let current = start; + current + slotDurationMinutes <= end; + current += slotDurationMinutes + ) { + slots.push({ + startTime: minutesToTime(current), + endTime: minutesToTime(current + slotDurationMinutes), + }); + } + } + + return slots; +} + +async function ensureComplexAccess(complexId: string, userId: string) { + const complexUser = await db.complexUser.findUnique({ + where: { + complexId_userId: { + complexId, + userId, + }, + }, + include: { + complex: { + select: { + id: true, + complexName: true, + plan: { + select: { + rules: true, + }, + }, + }, + }, + }, + }); + + if (!complexUser) { + throw new AdminBookingServiceError('No tienes permisos para administrar este complejo.', 403); + } + + return complexUser.complex; +} + +function* generateRecurringDates( + startDate: Date, + endDate: Date | null, + dayOfWeek: number +): Generator { + const current = new Date(startDate); + current.setUTCDate(current.getUTCDate() + ((dayOfWeek - current.getUTCDay() + 7) % 7)); + + if (current < startDate) { + current.setUTCDate(current.getUTCDate() + 7); + } + + const maxDate = endDate ?? new Date(startDate); + if (!endDate) { + maxDate.setUTCDate(maxDate.getUTCDate() + MAX_RECURRING_WEEKS * 7); + } + + while (current <= maxDate) { + yield new Date(current); + current.setUTCDate(current.getUTCDate() + 7); + } +} + +function mapBookingResponse(booking: { + id: string; + bookingCode: string; + bookingDate: Date; + startTime: string; + endTime: string; + customerName: string; + customerPhone: string; + customerEmail: string; + status: 'CONFIRMED' | 'CANCELLED' | 'COMPLETED' | 'NOSHOW'; + recurringGroupId: string | null; + createdAt: Date; + updatedAt: Date; + court: { + id: string; + name: string; + complex: { + id: string; + complexName: string; + }; + sport: { + id: string; + name: string; + slug: string; + }; + }; + price?: number; +}) { + return { + id: booking.id, + bookingCode: booking.bookingCode, + complexId: booking.court.complex.id, + complexName: booking.court.complex.complexName, + courtId: booking.court.id, + courtName: booking.court.name, + sport: { + id: booking.court.sport.id, + name: booking.court.sport.name, + slug: booking.court.sport.slug, + }, + date: formatIsoDate(booking.bookingDate), + startTime: booking.startTime, + endTime: booking.endTime, + customerName: booking.customerName, + customerPhone: booking.customerPhone, + customerEmail: booking.customerEmail, + price: booking.price ?? 0, + status: booking.status, + recurringGroupId: booking.recurringGroupId, + createdAt: booking.createdAt.toISOString(), + updatedAt: booking.updatedAt.toISOString(), + }; +} + +export async function createAdminRecurringBooking( + userId: string, + complexId: string, + input: CreateRecurringBookingInput +): Promise { + const complex = await ensureComplexAccess(complexId, userId); + + const adminUser = await db.user.findUnique({ + where: { id: userId }, + select: { emailVerified: true }, + }); + + if (!adminUser?.emailVerified) { + throw new AdminBookingServiceError('Debés verificar tu email para poder crear reservas.', 403); + } + + if (!complex.plan) { + throw new AdminBookingServiceError('El complejo no tiene un plan asignado.', 403); + } + + const rules = parsePlanRules(complex.plan.rules); + + if (!isFeatureEnabled(rules, 'fixedSlots')) { + throw new AdminBookingServiceError( + 'Tu plan no permite la creación de turnos fijos. Comunicate con el administrador.', + 403 + ); + } + + const startDate = parseIsoDate(input.date); + const dayOfWeek = getDayOfWeekValue(startDate); + const endDate = input.recurringEndDate ? parseIsoDate(input.recurringEndDate) : null; + + if (endDate && endDate <= startDate) { + throw new AdminBookingServiceError( + 'La fecha de fin debe ser posterior a la fecha de inicio.', + 400 + ); + } + + const court = await db.court.findFirst({ + where: { + id: input.courtId, + complexId, + }, + include: { + availabilities: { + where: { + dayOfWeek, + }, + orderBy: { + startTime: 'asc', + }, + }, + sport: { + select: { + id: true, + name: true, + slug: true, + }, + }, + priceRules: { + where: { isActive: true }, + orderBy: [{ dayOfWeek: 'asc' }, { startTime: 'asc' }], + }, + }, + }); + + if (!court) { + throw new AdminBookingServiceError('La cancha seleccionada no existe en el complejo.', 404); + } + + const validSlots = buildSlots(court.availabilities, court.slotDurationMinutes); + const selectedEndMinutes = toMinutes(input.startTime) + court.slotDurationMinutes; + const selectedSlot = { + startTime: input.startTime, + endTime: minutesToTime(selectedEndMinutes), + }; + + const slotExists = validSlots.some( + (slot) => slot.startTime === selectedSlot.startTime && slot.endTime === selectedSlot.endTime + ); + + if (!slotExists) { + throw new AdminBookingServiceError( + 'El horario seleccionado no esta disponible para esa cancha.', + 409 + ); + } + + if (isSlotInPast(startDate, input.startTime, court.slotDurationMinutes)) { + throw new AdminBookingServiceError('La fecha de inicio no puede estar en el pasado.', 400); + } + + const recurringDates = Array.from( + generateRecurringDates(startDate, endDate, startDate.getUTCDay()) + ); + + if (recurringDates.length === 0) { + throw new AdminBookingServiceError( + 'No se generaron fechas para la reserva periódica. Verifica las fechas ingresadas.', + 400 + ); + } + + for (let attempt = 0; attempt < 5; attempt += 1) { + try { + const result = await db.$transaction(async (tx) => { + const groupId = uuidv7(); + + const bookingsForDate = await tx.courtBooking.count({ + where: { + startTime: selectedSlot.startTime, + bookingDate: startDate, + status: 'CONFIRMED', + court: { + complexId, + }, + }, + }); + + const courtsCount = await tx.court.count({ + where: { complexId }, + }); + + const violations = evaluatePlanUsage(rules, { + courtsCount, + bookingsToday: bookingsForDate, + }); + + const maxBookingsViolation = violations.find( + (v) => v.code === 'MAX_BOOKINGS_PER_DAY_REACHED' + ); + + if (maxBookingsViolation) { + throw new AdminBookingServiceError(maxBookingsViolation.message, 409); + } + + const group = await tx.recurringBookingGroup.create({ + data: { + id: groupId, + complexId, + courtId: court.id, + startTime: selectedSlot.startTime, + endTime: selectedSlot.endTime, + dayOfWeek, + startDate, + endDate, + status: 'ACTIVE', + customerName: input.customerName.trim(), + customerPhone: input.customerPhone.trim(), + customerEmail: input.customerEmail?.trim() ?? '', + }, + }); + + const createdBookings = []; + + for (const date of recurringDates) { + if (isSlotInPast(date, input.startTime, court.slotDurationMinutes)) { + continue; + } + + const overlappingBooking = await tx.courtBooking.findFirst({ + where: { + courtId: court.id, + bookingDate: date, + status: 'CONFIRMED', + startTime: { + lt: selectedSlot.endTime, + }, + endTime: { + gt: selectedSlot.startTime, + }, + }, + }); + + if (overlappingBooking) { + throw new AdminBookingServiceError( + `El horario seleccionado ya fue reservado para el dia ${formatIsoDate(date)}.`, + 409 + ); + } + + const booking = await tx.courtBooking.create({ + data: { + id: uuidv7(), + bookingCode: generateBookingCode(), + courtId: court.id, + bookingDate: date, + startTime: selectedSlot.startTime, + endTime: selectedSlot.endTime, + customerName: input.customerName.trim(), + customerPhone: input.customerPhone.trim(), + customerEmail: input.customerEmail?.trim() ?? '', + status: 'CONFIRMED', + recurringGroupId: groupId, + }, + include: { + court: { + select: { + id: true, + name: true, + sport: { + select: { + id: true, + name: true, + slug: true, + }, + }, + complex: { + select: { + id: true, + complexName: true, + }, + }, + }, + }, + }, + }); + + createdBookings.push(booking); + } + + return { group, bookings: createdBookings }; + }); + + return { + id: result.group.id, + complexId, + courtId: court.id, + startTime: result.group.startTime, + endTime: result.group.endTime, + dayOfWeek: result.group.dayOfWeek, + startDate: formatIsoDate(result.group.startDate), + endDate: result.group.endDate ? formatIsoDate(result.group.endDate) : null, + status: 'ACTIVE' as const, + customerName: result.group.customerName, + customerPhone: result.group.customerPhone, + customerEmail: result.group.customerEmail, + bookings: result.bookings.map((b) => mapBookingResponse(b)), + createdAt: result.group.createdAt.toISOString(), + updatedAt: result.group.updatedAt.toISOString(), + }; + } catch (error) { + if (error instanceof AdminBookingServiceError) { + throw error; + } + + const prismaError = error as { + code?: string; + meta?: { + target?: string[] | string; + }; + }; + + if (prismaError.code === 'P2002') { + const targets = Array.isArray(prismaError.meta?.target) + ? prismaError.meta?.target + : [prismaError.meta?.target]; + const isBookingCodeCollision = targets.some((target) => + String(target).includes('booking_code') + ); + + if (isBookingCodeCollision) { + continue; + } + + throw new AdminBookingServiceError('El horario seleccionado ya fue reservado.', 409); + } + + throw error; + } + } + + throw new AdminBookingServiceError( + 'No se pudo generar un codigo de reserva unico. Intenta nuevamente.', + 409 + ); +} + +export async function cancelRecurringGroup(userId: string, groupId: string) { + const group = await db.recurringBookingGroup.findUnique({ + where: { id: groupId }, + include: { + complex: { + select: { + id: true, + users: { + where: { userId }, + select: { userId: true }, + }, + }, + }, + }, + }); + + if (!group) { + throw new AdminBookingServiceError('Grupo de reservas no encontrado.', 404); + } + + if (group.complex.users.length === 0) { + throw new AdminBookingServiceError('No tienes permisos para administrar este complejo.', 403); + } + + if (group.status === 'CANCELLED') { + throw new AdminBookingServiceError('El grupo ya fue cancelado anteriormente.', 409); + } + + const now = new Date(); + const todayStart = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())); + + await db.$transaction(async (tx) => { + await tx.recurringBookingGroup.update({ + where: { id: groupId }, + data: { status: 'CANCELLED' }, + }); + + const futureBookings = await tx.courtBooking.findMany({ + where: { + recurringGroupId: groupId, + bookingDate: { gte: todayStart }, + status: 'CONFIRMED', + }, + }); + + for (const booking of futureBookings) { + await tx.courtBookingLog.create({ + data: { + id: uuidv7(), + bookingCode: booking.bookingCode, + courtId: booking.courtId, + bookingDate: booking.bookingDate, + startTime: booking.startTime, + endTime: booking.endTime, + customerName: booking.customerName, + customerPhone: booking.customerPhone, + customerEmail: booking.customerEmail, + previousStatus: booking.status, + newStatus: 'CANCELLED', + changedAt: new Date(), + }, + }); + + await tx.courtBooking.delete({ + where: { id: booking.id }, + }); + } + }); + + return { ok: true }; +} + +export async function listRecurringGroups(complexId: string): Promise { + const groups = await db.recurringBookingGroup.findMany({ + where: { complexId, status: 'ACTIVE' }, + include: { + court: { + select: { + id: true, + name: true, + sport: { + select: { id: true, name: true, slug: true }, + }, + complex: { + select: { id: true, complexName: true }, + }, + }, + }, + bookings: { + orderBy: { bookingDate: 'asc' }, + include: { + court: { + select: { + id: true, + name: true, + sport: { + select: { id: true, name: true, slug: true }, + }, + complex: { + select: { id: true, complexName: true }, + }, + }, + }, + }, + }, + }, + orderBy: { createdAt: 'desc' }, + }); + + return groups.map((group) => ({ + id: group.id, + complexId: group.complexId, + courtId: group.courtId, + startTime: group.startTime, + endTime: group.endTime, + dayOfWeek: group.dayOfWeek, + startDate: formatIsoDate(group.startDate), + endDate: group.endDate ? formatIsoDate(group.endDate) : null, + status: group.status, + customerName: group.customerName, + customerPhone: group.customerPhone, + customerEmail: group.customerEmail, + bookings: group.bookings.map(mapBookingResponse), + createdAt: group.createdAt.toISOString(), + updatedAt: group.updatedAt.toISOString(), + })); +} + +export async function updateRecurringGroup( + userId: string, + groupId: string, + input: UpdateRecurringGroupInput +): Promise { + const group = await db.recurringBookingGroup.findUnique({ + where: { id: groupId }, + include: { + complex: { + select: { + id: true, + users: { + where: { userId }, + select: { userId: true }, + }, + }, + }, + }, + }); + + if (!group) { + throw new AdminBookingServiceError('Grupo de turnos fijos no encontrado.', 404); + } + + if (group.complex.users.length === 0) { + throw new AdminBookingServiceError('No tienes permisos para administrar este complejo.', 403); + } + + if (group.status === 'CANCELLED') { + throw new AdminBookingServiceError('No se puede editar un grupo cancelado.', 409); + } + + const courtId = input.courtId ?? group.courtId; + const dayOfWeek = input.dayOfWeek ?? group.dayOfWeek; + const startTime = input.startTime ?? group.startTime; + + const scheduleChanged = + input.courtId !== undefined || input.dayOfWeek !== undefined || input.startTime !== undefined; + + if (scheduleChanged) { + const court = await db.court.findFirst({ + where: { id: courtId, complexId: group.complexId }, + include: { + availabilities: { + where: { dayOfWeek: dayOfWeek as DayOfWeek }, + orderBy: { startTime: 'asc' }, + }, + }, + }); + + if (!court) { + throw new AdminBookingServiceError('La cancha seleccionada no existe en el complejo.', 404); + } + + const validSlots = buildSlots(court.availabilities, court.slotDurationMinutes); + const selectedEndMinutes = toMinutes(startTime) + court.slotDurationMinutes; + const endTime = minutesToTime(selectedEndMinutes); + + const slotExists = validSlots.some( + (slot) => slot.startTime === startTime && slot.endTime === endTime + ); + + if (!slotExists) { + throw new AdminBookingServiceError( + 'El horario seleccionado no esta disponible para esa cancha.', + 409 + ); + } + + const now = new Date(); + const todayStart = new Date( + Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()) + ); + + await db.$transaction(async (tx) => { + await tx.recurringBookingGroup.update({ + where: { id: groupId }, + data: { + courtId, + dayOfWeek: dayOfWeek as DayOfWeek, + startTime, + endTime, + customerName: input.customerName?.trim() ?? group.customerName, + customerPhone: input.customerPhone?.trim() ?? group.customerPhone, + customerEmail: input.customerEmail?.trim() ?? group.customerEmail, + }, + }); + + const futureBookings = await tx.courtBooking.findMany({ + where: { + recurringGroupId: groupId, + bookingDate: { gte: todayStart }, + status: 'CONFIRMED', + }, + }); + + for (const booking of futureBookings) { + await tx.courtBookingLog.create({ + data: { + id: uuidv7(), + bookingCode: booking.bookingCode, + courtId: booking.courtId, + bookingDate: booking.bookingDate, + startTime: booking.startTime, + endTime: booking.endTime, + customerName: booking.customerName, + customerPhone: booking.customerPhone, + customerEmail: booking.customerEmail, + previousStatus: booking.status, + newStatus: 'CANCELLED', + changedAt: new Date(), + }, + }); + + await tx.courtBooking.delete({ + where: { id: booking.id }, + }); + } + + const dayIndex = DAY_INDEX_BY_VALUE[dayOfWeek] ?? 0; + const recurringDates = Array.from( + generateRecurringDates(todayStart, group.endDate, dayIndex) + ); + + for (const date of recurringDates) { + const overlappingBooking = await tx.courtBooking.findFirst({ + where: { + courtId, + bookingDate: date, + status: 'CONFIRMED', + startTime: { lt: endTime }, + endTime: { gt: startTime }, + }, + }); + + if (overlappingBooking) { + throw new AdminBookingServiceError( + `El horario seleccionado ya fue reservado para el dia ${formatIsoDate(date)}.`, + 409 + ); + } + + await tx.courtBooking.create({ + data: { + id: uuidv7(), + bookingCode: generateBookingCode(), + courtId, + bookingDate: date, + startTime, + endTime, + customerName: input.customerName?.trim() ?? group.customerName, + customerPhone: input.customerPhone?.trim() ?? group.customerPhone, + customerEmail: input.customerEmail?.trim() ?? group.customerEmail, + status: 'CONFIRMED', + recurringGroupId: groupId, + }, + include: { + court: { + select: { + id: true, + name: true, + sport: { select: { id: true, name: true, slug: true } }, + complex: { select: { id: true, complexName: true } }, + }, + }, + }, + }); + } + }); + } else { + await db.recurringBookingGroup.update({ + where: { id: groupId }, + data: { + ...(input.customerName !== undefined && { customerName: input.customerName.trim() }), + ...(input.customerPhone !== undefined && { customerPhone: input.customerPhone.trim() }), + ...(input.customerEmail !== undefined && { customerEmail: input.customerEmail.trim() }), + }, + }); + + const now = new Date(); + const todayStart = new Date( + Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()) + ); + + const updateData: Record = {}; + if (input.customerName !== undefined) updateData.customerName = input.customerName.trim(); + if (input.customerPhone !== undefined) updateData.customerPhone = input.customerPhone.trim(); + if (input.customerEmail !== undefined) updateData.customerEmail = input.customerEmail.trim(); + + if (Object.keys(updateData).length > 0) { + await db.courtBooking.updateMany({ + where: { recurringGroupId: groupId, bookingDate: { gte: todayStart } }, + data: updateData, + }); + } + } + + const updated = await db.recurringBookingGroup.findUnique({ + where: { id: groupId }, + include: { + court: { + select: { + id: true, + name: true, + sport: { select: { id: true, name: true, slug: true } }, + complex: { select: { id: true, complexName: true } }, + }, + }, + bookings: { + orderBy: { bookingDate: 'asc' }, + include: { + court: { + select: { + id: true, + name: true, + sport: { select: { id: true, name: true, slug: true } }, + complex: { select: { id: true, complexName: true } }, + }, + }, + }, + }, + }, + }); + + if (!updated) { + throw new AdminBookingServiceError('Error al actualizar el grupo.', 409); + } + + return { + id: updated.id, + complexId: updated.complexId, + courtId: updated.courtId, + startTime: updated.startTime, + endTime: updated.endTime, + dayOfWeek: updated.dayOfWeek, + startDate: formatIsoDate(updated.startDate), + endDate: updated.endDate ? formatIsoDate(updated.endDate) : null, + status: updated.status, + customerName: updated.customerName, + customerPhone: updated.customerPhone, + customerEmail: updated.customerEmail, + bookings: updated.bookings.map(mapBookingResponse), + createdAt: updated.createdAt.toISOString(), + updatedAt: updated.updatedAt.toISOString(), + }; +} diff --git a/apps/backend/src/modules/complex/services/complex.service.ts b/apps/backend/src/modules/complex/services/complex.service.ts index 167b8ba..57aa4c5 100644 --- a/apps/backend/src/modules/complex/services/complex.service.ts +++ b/apps/backend/src/modules/complex/services/complex.service.ts @@ -1,5 +1,6 @@ import { Prisma } from '@/generated/prisma/client'; import { db } from '@/lib/prisma'; +import { parsePlanRules } from '@/modules/plan/services/plan-rules.service'; import { v7 as uuidv7 } from 'uuid'; export type CreateComplexInput = { @@ -185,7 +186,11 @@ export async function listMyComplexes(userId: string) { const complexUsers = await db.complexUser.findMany({ where: { userId }, include: { - complex: true, + complex: { + include: { + plan: true, + }, + }, }, orderBy: { createdAt: 'asc', @@ -195,6 +200,9 @@ export async function listMyComplexes(userId: string) { return complexUsers.map((complexUser) => ({ ...complexUser.complex, role: complexUser.role, + planFeatures: complexUser.complex.plan + ? parsePlanRules(complexUser.complex.plan.rules).features + : null, })); } @@ -207,7 +215,11 @@ export async function getCurrentComplex(userId: string, complexId: string) { }, }, include: { - complex: true, + complex: { + include: { + plan: true, + }, + }, }, }); @@ -216,6 +228,9 @@ export async function getCurrentComplex(userId: string, complexId: string) { return { ...complexUser.complex, role: complexUser.role, + planFeatures: complexUser.complex.plan + ? parsePlanRules(complexUser.complex.plan.rules).features + : null, }; } @@ -228,7 +243,11 @@ export async function selectComplex(userId: string, complexId: string) { }, }, include: { - complex: true, + complex: { + include: { + plan: true, + }, + }, }, }); @@ -237,6 +256,9 @@ export async function selectComplex(userId: string, complexId: string) { return { ...complexUser.complex, role: complexUser.role, + planFeatures: complexUser.complex.plan + ? parsePlanRules(complexUser.complex.plan.rules).features + : null, }; } diff --git a/apps/backend/test/plan/plan-pricing.service.test.ts b/apps/backend/test/plan/plan-pricing.service.test.ts index 8f44fb6..eb349ff 100644 --- a/apps/backend/test/plan/plan-pricing.service.test.ts +++ b/apps/backend/test/plan/plan-pricing.service.test.ts @@ -14,6 +14,7 @@ function makeV1Rules(): PlanRules { publicBookingPage: false, advancedReports: false, whatsappReminders: false, + fixedSlots: false, }, }; } @@ -28,6 +29,7 @@ function makeV2Rules(overrides?: Record (
diff --git a/apps/frontend/src/features/booking/booking-provider.tsx b/apps/frontend/src/features/booking/booking-provider.tsx index c2422e3..4515ba8 100644 --- a/apps/frontend/src/features/booking/booking-provider.tsx +++ b/apps/frontend/src/features/booking/booking-provider.tsx @@ -1,5 +1,11 @@ import { ApiClientError, apiClient } from '@/lib/api-client'; -import type { AdminBooking, ComplexWithRole, Court } from '@repo/api-contract'; +import type { + AdminBooking, + ComplexWithRole, + Court, + PlanFeatureFlags, + RecurringBookingGroup, +} from '@repo/api-contract'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { type ReactNode, @@ -44,6 +50,16 @@ interface CreateManualBookingPayload { customerEmail: string; } +interface CreateRecurringBookingPayload { + courtId: string; + date: string; + startTime: string; + customerName: string; + customerPhone: string; + customerEmail: string; + recurringEndDate?: string; +} + interface BookingContextValue { complex: ComplexWithRole; courts: Court[]; @@ -66,6 +82,8 @@ interface BookingContextValue { createBookingError: string | null; isCreatingBooking: boolean; bookingToolsOpen: boolean; + planFeatures: PlanFeatureFlags | null; + isRecurringEnabled: boolean; setSelectedDate: (date: string) => void; moveSelectedDate: (amount: number) => void; setSelectedSportId: (sportId: string) => void; @@ -73,8 +91,14 @@ interface BookingContextValue { setViewMode: (mode: BookingViewMode) => void; setVisibleTimeRange: (range: BookingTimeRange) => void; openCreateBooking: (draft?: Partial) => void; + recurringGroups: RecurringBookingGroup[]; + isRecurringGroupsLoading: boolean; + cancelRecurringGroup: (groupId: string) => void; + isCancellingRecurringGroup: boolean; + refreshRecurringGroups: () => void; closeCreateBooking: () => void; createBooking: (payload: CreateManualBookingPayload) => Promise; + createRecurringBooking: (payload: CreateRecurringBookingPayload) => Promise; updateBookingStatus: (bookingId: string, status: 'CANCELLED' | 'COMPLETED' | 'NOSHOW') => void; exportDayReport: () => void; openBookingTools: (segment?: BookingTimelineSegment) => void; @@ -245,6 +269,20 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { queryFn: () => apiClient.courts.listByComplex(complex.id), }); + const recurringGroupsQuery = useQuery({ + queryKey: ['recurring-groups', complex.id], + queryFn: () => apiClient.adminBookings.listRecurringGroups(complex.id), + enabled: viewMode === 'recurring', + }); + + const cancelRecurringGroupMutation = useMutation({ + mutationFn: (groupId: string) => apiClient.adminBookings.cancelRecurringGroup(groupId), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ['recurring-groups', complex.id] }); + await queryClient.invalidateQueries({ queryKey: ['admin-bookings', complex.id] }); + }, + }); + const bookingsQuery = useQuery({ queryKey: ['admin-bookings', complex.id, selectedDate], queryFn: () => @@ -325,6 +363,26 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { }, }); + const createRecurringBookingMutation = useMutation({ + mutationFn: (payload: CreateRecurringBookingPayload) => + apiClient.adminBookings.createRecurring(complex.id, { + date: payload.date, + courtId: payload.courtId, + startTime: payload.startTime, + customerName: payload.customerName, + customerPhone: payload.customerPhone, + customerEmail: payload.customerEmail, + isRecurring: true, + recurringEndDate: payload.recurringEndDate, + }), + onSuccess: async () => { + await queryClient.invalidateQueries({ queryKey: ['admin-bookings', complex.id] }); + await queryClient.invalidateQueries({ queryKey: ['manual-booking-availability'] }); + setIsCreateBookingOpen(false); + setSelectedSlot(null); + }, + }); + const updateStatusMutation = useMutation({ mutationFn: (payload: { bookingId: string; status: 'CANCELLED' | 'COMPLETED' | 'NOSHOW' }) => apiClient.adminBookings.updateStatus(payload.bookingId, { status: payload.status }), @@ -413,6 +471,16 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { URL.revokeObjectURL(url); }, [bookings, complex.complexSlug, selectedDate]); + const planFeatures = complex.planFeatures ?? null; + const isRecurringEnabled = planFeatures?.fixedSlots ?? false; + + const createRecurringBooking = useCallback( + async (payload: CreateRecurringBookingPayload) => { + await createRecurringBookingMutation.mutateAsync(payload); + }, + [createRecurringBookingMutation] + ); + const value = useMemo( () => ({ complex, @@ -437,11 +505,24 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { 'No pudimos cargar el panel de reservas.' ) : null, + recurringGroups: recurringGroupsQuery.data?.groups ?? [], + isRecurringGroupsLoading: recurringGroupsQuery.isLoading, + cancelRecurringGroup: (groupId: string) => cancelRecurringGroupMutation.mutate(groupId), + isCancellingRecurringGroup: cancelRecurringGroupMutation.isPending, + refreshRecurringGroups: () => + queryClient.invalidateQueries({ queryKey: ['recurring-groups', complex.id] }), isCreateBookingOpen, - createBookingError: createBookingMutation.isError - ? extractMessage(createBookingMutation.error, 'No pudimos crear la reserva.') - : null, - isCreatingBooking: createBookingMutation.isPending, + createBookingError: + createBookingMutation.isError || createRecurringBookingMutation.isError + ? extractMessage( + createBookingMutation.error ?? createRecurringBookingMutation.error, + 'No pudimos crear la reserva.' + ) + : null, + isCreatingBooking: + createBookingMutation.isPending || createRecurringBookingMutation.isPending, + planFeatures, + isRecurringEnabled, setSelectedDate, moveSelectedDate: (amount) => setSelectedDate((date) => addDaysIso(date, amount)), setSelectedSportId, @@ -451,6 +532,7 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { openCreateBooking, closeCreateBooking, createBooking, + createRecurringBooking, updateBookingStatus, exportDayReport, bookingToolsOpen, @@ -473,10 +555,16 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { createBookingMutation.error, createBookingMutation.isError, createBookingMutation.isPending, + createRecurringBooking, + createRecurringBookingMutation.error, + createRecurringBookingMutation.isError, + createRecurringBookingMutation.isPending, currentTime, exportDayReport, isCreateBookingOpen, openCreateBooking, + planFeatures, + isRecurringEnabled, schedules, selectedDate, selectedSlot, @@ -488,6 +576,9 @@ export function BookingProvider({ children, complex }: BookingProviderProps) { viewMode, visibleTimeRange, bookingToolsOpen, + recurringGroupsQuery.data?.groups, + recurringGroupsQuery.isLoading, + cancelRecurringGroupMutation.isPending, ] ); diff --git a/apps/frontend/src/features/booking/booking.tsx b/apps/frontend/src/features/booking/booking.tsx index 301dfc6..8011293 100644 --- a/apps/frontend/src/features/booking/booking.tsx +++ b/apps/frontend/src/features/booking/booking.tsx @@ -12,6 +12,7 @@ import { BookingMobile } from './components/booking-mobile'; import { BookingTimeline } from './components/booking-timeline'; import { BookingToolbar } from './components/booking-toolbar'; import { BookingToolsDialog } from './components/booking-tools-dialog'; +import { RecurringBookingListView } from './components/recurring-booking-list'; interface BookingProps { complex: ComplexWithRole; @@ -71,6 +72,10 @@ function BookingInner() { return ; } + if (viewMode === 'recurring') { + return ; + } + if (isMobile) { return ; } diff --git a/apps/frontend/src/features/booking/booking.types.ts b/apps/frontend/src/features/booking/booking.types.ts index 775dca3..e7c7218 100644 --- a/apps/frontend/src/features/booking/booking.types.ts +++ b/apps/frontend/src/features/booking/booking.types.ts @@ -1,6 +1,6 @@ import type { AdminBooking, Court } from '@repo/api-contract'; -export type BookingViewMode = 'panel' | 'status' | 'list'; +export type BookingViewMode = 'panel' | 'status' | 'list' | 'recurring'; export type BookingStatusFilter = 'all' | 'free' | 'reserved'; export type BookingSegmentStatus = 'free' | 'reserved'; diff --git a/apps/frontend/src/features/booking/components/booking-create-dialog.tsx b/apps/frontend/src/features/booking/components/booking-create-dialog.tsx index 32280d9..aa72570 100644 --- a/apps/frontend/src/features/booking/components/booking-create-dialog.tsx +++ b/apps/frontend/src/features/booking/components/booking-create-dialog.tsx @@ -18,6 +18,7 @@ import { SelectTrigger, SelectValue, } from '@/components/ui/select'; +import { Separator } from '@/components/ui/separator'; import { zodResolver } from '@hookform/resolvers/zod'; import { useEffect, useMemo, useState } from 'react'; import { useForm } from 'react-hook-form'; @@ -60,12 +61,16 @@ export function BookingCreateDialog() { isCreatingBooking, closeCreateBooking, createBooking, + createRecurringBooking, + isRecurringEnabled, } = useBooking(); const [date, setDate] = useState(selectedSlot?.date ?? selectedDate); const [sportId, setSportId] = useState(selectedSlot?.sportId ?? 'all'); const [courtId, setCourtId] = useState(selectedSlot?.courtId ?? ''); const [startTime, setStartTime] = useState(selectedSlot?.startTime ?? ''); + const [isRecurring, setIsRecurring] = useState(false); + const [recurringEndDate, setRecurringEndDate] = useState(undefined); const { register, @@ -90,6 +95,8 @@ export function BookingCreateDialog() { setSportId(selectedSlot?.sportId ?? 'all'); setCourtId(selectedSlot?.courtId ?? ''); setStartTime(selectedSlot?.startTime ?? ''); + setIsRecurring(false); + setRecurringEndDate(undefined); reset(); if (selectedSlot?.courtId && selectedSlot?.startTime) { @@ -155,14 +162,26 @@ export function BookingCreateDialog() { }, [availableStartTimes, startTime]); const onSubmit = async (values: BookingForm) => { - await createBooking({ - courtId, - date, - startTime, - customerName: values.customerName, - customerPhone: values.customerPhone, - customerEmail: values.customerEmail, - }); + if (isRecurring) { + await createRecurringBooking({ + courtId, + date, + startTime, + customerName: values.customerName, + customerPhone: values.customerPhone, + customerEmail: values.customerEmail, + recurringEndDate, + }); + } else { + await createBooking({ + courtId, + date, + startTime, + customerName: values.customerName, + customerPhone: values.customerPhone, + customerEmail: values.customerEmail, + }); + } }; return ( @@ -260,6 +279,52 @@ export function BookingCreateDialog() {
+ {isRecurringEnabled && ( + <> + + +
+
+

Repetir todas las semanas

+

+ {isRecurring + ? `Se creará una reserva todos los ${getDayOfWeekLabel(date)} a las ${startTime || '...'}` + : 'Crea turnos fijos en el mismo horario'} +

+
+ +
+ + {isRecurring && ( + + + Repetir hasta{' '} + (opcional) + + { + setRecurringEndDate(nextDate ? toIsoDateLocal(nextDate) : undefined); + }} + /> +

+ Si no se selecciona una fecha, se repetirá por tiempo indefinido. +

+
+ )} + + )} + + + Nombre - {isCreatingBooking ? 'Guardando...' : 'Crear reserva'} + {isCreatingBooking + ? isRecurring + ? 'Creando turnos...' + : 'Guardando...' + : isRecurring + ? 'Crear turno fijo' + : 'Crear reserva'} ); } + +function getDayOfWeekLabel(dateIso: string): string { + const labels: Record = { + MONDAY: 'lunes', + TUESDAY: 'martes', + WEDNESDAY: 'miércoles', + THURSDAY: 'jueves', + FRIDAY: 'viernes', + SATURDAY: 'sábado', + SUNDAY: 'domingo', + }; + return labels[getDayOfWeek(dateIso)] ?? ''; +} diff --git a/apps/frontend/src/features/booking/components/booking-day-summary.tsx b/apps/frontend/src/features/booking/components/booking-day-summary.tsx index 31a07c6..316bb8b 100644 --- a/apps/frontend/src/features/booking/components/booking-day-summary.tsx +++ b/apps/frontend/src/features/booking/components/booking-day-summary.tsx @@ -1,4 +1,4 @@ -import { CalendarDays, Download, ShieldCheck, UsersRound } from 'lucide-react'; +import { CalendarDays, Download, Repeat, ShieldCheck, UsersRound } from 'lucide-react'; import { useBooking } from '../booking-provider'; import { formatBookingDate, toIsoDateLocal } from '../lib/booking-time'; @@ -66,7 +66,7 @@ function SummaryCard({ label, value, detail, icon: Icon, className }: SummaryCar } export function BookingQuickActions() { - const { setSelectedDate, setViewMode, exportDayReport } = useBooking(); + const { setSelectedDate, setViewMode, exportDayReport, isRecurringEnabled } = useBooking(); const todayIso = toIsoDateLocal(new Date()); return ( @@ -92,6 +92,16 @@ export function BookingQuickActions() { Exportar reporte + {isRecurringEnabled && ( + + )} ); diff --git a/apps/frontend/src/features/booking/components/recurring-booking-edit-dialog.tsx b/apps/frontend/src/features/booking/components/recurring-booking-edit-dialog.tsx new file mode 100644 index 0000000..b0877de --- /dev/null +++ b/apps/frontend/src/features/booking/components/recurring-booking-edit-dialog.tsx @@ -0,0 +1,210 @@ +import { Button } from '@/components/ui/button'; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; +import { apiClient } from '@/lib/api-client'; +import type { RecurringBookingGroup } from '@repo/api-contract'; +import { useEffect, useState } from 'react'; +import { useBooking } from '../booking-provider'; +import { minutesToTime, timeToMinutes } from '../lib/booking-time'; + +const DAY_OPTIONS = [ + { value: 'MONDAY', label: 'Lunes' }, + { value: 'TUESDAY', label: 'Martes' }, + { value: 'WEDNESDAY', label: 'Miércoles' }, + { value: 'THURSDAY', label: 'Jueves' }, + { value: 'FRIDAY', label: 'Viernes' }, + { value: 'SATURDAY', label: 'Sábado' }, + { value: 'SUNDAY', label: 'Domingo' }, +]; + +interface RecurringBookingEditDialogProps { + group: RecurringBookingGroup; + open: boolean; + onClose: () => void; +} + +export function RecurringBookingEditDialog({ + group, + open, + onClose, +}: RecurringBookingEditDialogProps) { + const { courts, refreshRecurringGroups } = useBooking(); + + const [courtId, setCourtId] = useState(group.courtId); + const [dayOfWeek, setDayOfWeek] = useState(group.dayOfWeek); + const [startTime, setStartTime] = useState(group.startTime); + const [customerName, setCustomerName] = useState(group.customerName); + const [customerPhone, setCustomerPhone] = useState(group.customerPhone); + const [customerEmail, setCustomerEmail] = useState(group.customerEmail); + const [error, setError] = useState(''); + const [saving, setSaving] = useState(false); + + useEffect(() => { + setCourtId(group.courtId); + setDayOfWeek(group.dayOfWeek); + setStartTime(group.startTime); + setCustomerName(group.customerName); + setCustomerPhone(group.customerPhone); + setCustomerEmail(group.customerEmail); + }, [group]); + + const selectedCourt = courts.find((c) => c.id === courtId); + const slotDuration = selectedCourt?.slotDurationMinutes ?? 60; + + const availableSlots: string[] = []; + if (selectedCourt) { + const availabilities = selectedCourt.availability.filter((a) => a.dayOfWeek === dayOfWeek); + for (const avail of availabilities) { + const startMins = timeToMinutes(avail.startTime); + const endMins = timeToMinutes(avail.endTime); + for (let m = startMins; m + slotDuration <= endMins; m += slotDuration) { + availableSlots.push(minutesToTime(m)); + } + } + } + + const handleSave = async () => { + if (!customerName || customerName.trim().length < 2) { + setError('El nombre debe tener al menos 2 caracteres.'); + return; + } + + setError(''); + setSaving(true); + + try { + await apiClient.adminBookings.updateRecurringGroup(group.id, { + ...(courtId !== group.courtId && { courtId }), + ...(dayOfWeek !== group.dayOfWeek && { + dayOfWeek: dayOfWeek as + | 'MONDAY' + | 'TUESDAY' + | 'WEDNESDAY' + | 'THURSDAY' + | 'FRIDAY' + | 'SATURDAY' + | 'SUNDAY', + }), + ...(startTime !== group.startTime && { startTime }), + ...(customerName !== group.customerName && { customerName }), + ...(customerPhone !== group.customerPhone && { customerPhone }), + ...(customerEmail !== group.customerEmail && { customerEmail }), + }); + + await refreshRecurringGroups(); + onClose(); + } catch (e) { + setError(e instanceof Error ? e.message : 'Error al guardar los cambios.'); + } finally { + setSaving(false); + } + }; + + return ( + !open && onClose()}> + + + Editar turno fijo + + +
+
+ + setCustomerName(e.target.value)} + placeholder="Nombre del cliente" + /> +
+ +
+ + setCustomerPhone(e.target.value)} + placeholder="Teléfono" + /> +
+ +
+ + setCustomerEmail(e.target.value)} + placeholder="Email" + /> +
+ +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ + {error &&

{error}

} + +
+ + +
+
+
+
+ ); +} diff --git a/apps/frontend/src/features/booking/components/recurring-booking-list.tsx b/apps/frontend/src/features/booking/components/recurring-booking-list.tsx new file mode 100644 index 0000000..668e334 --- /dev/null +++ b/apps/frontend/src/features/booking/components/recurring-booking-list.tsx @@ -0,0 +1,246 @@ +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import type { RecurringBookingGroup } from '@repo/api-contract'; +import { ArrowLeft, Clock, MapPin, Pencil, Repeat, Trash2, User } from 'lucide-react'; +import { useState } from 'react'; +import { useBooking } from '../booking-provider'; +import { RecurringBookingEditDialog } from './recurring-booking-edit-dialog'; + +const DAY_LABELS: Record = { + MONDAY: 'Lunes', + TUESDAY: 'Martes', + WEDNESDAY: 'Miércoles', + THURSDAY: 'Jueves', + FRIDAY: 'Viernes', + SATURDAY: 'Sábado', + SUNDAY: 'Domingo', +}; + +function getNextBookingDate(group: RecurringBookingGroup): string { + const today = new Date().toISOString().slice(0, 10); + const future = group.bookings + .filter((b) => b.date >= today && b.status === 'CONFIRMED') + .sort((a, b) => a.date.localeCompare(b.date)); + return future[0]?.date ?? '-'; +} + +function formatDate(dateStr: string): string { + if (dateStr === '-') return '-'; + const [y, m, d] = dateStr.split('-'); + return `${d}/${m}/${y}`; +} + +export function RecurringBookingListView() { + const { + setViewMode, + recurringGroups, + isRecurringGroupsLoading, + cancelRecurringGroup, + isCancellingRecurringGroup, + } = useBooking(); + + const [editingGroup, setEditingGroup] = useState(null); + const [cancellingGroupId, setCancellingGroupId] = useState(null); + + return ( + <> +
+
+
+ +
+

Turnos fijos

+

+ {recurringGroups.length}{' '} + {recurringGroups.length === 1 ? 'turno fijo' : 'turnos fijos'} +

+
+
+
+ + {isRecurringGroupsLoading && ( +
Cargando turnos fijos...
+ )} + + {!isRecurringGroupsLoading && recurringGroups.length === 0 && ( +
+ +

No hay turnos fijos creados.

+
+ )} + + {!isRecurringGroupsLoading && recurringGroups.length > 0 && ( +
+ + + + + + + + + + + + + {recurringGroups.map((group) => { + const nextDate = getNextBookingDate(group); + return ( + + + + + + + + + ); + })} + +
ClienteCanchaDíaHorarioPróxima fechaAcciones
+
+ + {group.customerName || '-'} +
+
+
+ + + {group.bookings[0]?.courtName ?? '-'} + +
+
+ {DAY_LABELS[group.dayOfWeek] ?? group.dayOfWeek} + +
+ + + {group.startTime} - {group.endTime} + +
+
{formatDate(nextDate)} +
+ + +
+
+ +
+ {recurringGroups.map((group) => { + const nextDate = getNextBookingDate(group); + return ( +
+
+
+ + {group.customerName || '-'} +
+ + {DAY_LABELS[group.dayOfWeek]} + +
+

+ {group.bookings[0]?.courtName} · {group.startTime} - {group.endTime} +

+

+ Próxima: {formatDate(nextDate)} +

+
+ + +
+
+ ); + })} +
+
+ )} +
+ + !open && setCancellingGroupId(null)} + > + + + Cancelar turno fijo + + ¿Estás seguro de cancelar este turno fijo? Se eliminarán todas las reservas futuras. + Las reservas pasadas no se verán afectadas. + + + + + + + + + + {editingGroup && ( + setEditingGroup(null)} + /> + )} + + ); +} diff --git a/apps/frontend/src/features/onboard/components/steps/plan-select-step.tsx b/apps/frontend/src/features/onboard/components/steps/plan-select-step.tsx index 8947d69..a842c09 100644 --- a/apps/frontend/src/features/onboard/components/steps/plan-select-step.tsx +++ b/apps/frontend/src/features/onboard/components/steps/plan-select-step.tsx @@ -13,6 +13,7 @@ const FEATURE_LABELS: Record = { onlinePayments: 'Pagos online', advancedReports: 'Reportes avanzados', whatsappReminders: 'Recordatorios WhatsApp', + fixedSlots: 'Turnos fijos', }; export function PlanSelectStep({ form, plans }: PlanSelectStepProps) { @@ -24,6 +25,7 @@ export function PlanSelectStep({ form, plans }: PlanSelectStepProps) { 'onlinePayments', 'advancedReports', 'whatsappReminders', + 'fixedSlots', ] as const; return ( diff --git a/apps/frontend/src/lib/api-client.ts b/apps/frontend/src/lib/api-client.ts index 7e6f455..4e084c3 100644 --- a/apps/frontend/src/lib/api-client.ts +++ b/apps/frontend/src/lib/api-client.ts @@ -74,6 +74,10 @@ export const apiClient = { adminBookings: { listByComplex: api.listByComplex, create: api.createAdmin, + createRecurring: api.createRecurring, + cancelRecurringGroup: api.cancelRecurringGroup, + listRecurringGroups: api.listRecurringGroups, + updateRecurringGroup: api.updateRecurringGroup, updateStatus: api.updateStatus, }, }; diff --git a/apps/frontend/src/lib/api/index.ts b/apps/frontend/src/lib/api/index.ts index c175d7f..ddcb67f 100644 --- a/apps/frontend/src/lib/api/index.ts +++ b/apps/frontend/src/lib/api/index.ts @@ -15,5 +15,9 @@ export { getConfirmation, listByComplex, createAdmin, + createRecurring, + cancelRecurringGroup, + listRecurringGroups, + updateRecurringGroup, updateStatus, } from './resources/bookings'; diff --git a/apps/frontend/src/lib/api/resources/bookings.ts b/apps/frontend/src/lib/api/resources/bookings.ts index 764f626..735d11c 100644 --- a/apps/frontend/src/lib/api/resources/bookings.ts +++ b/apps/frontend/src/lib/api/resources/bookings.ts @@ -3,11 +3,15 @@ import type { CancelPublicBookingInput, CreateAdminBookingInput, CreatePublicBookingInput, + ListRecurringGroupsResponse, PublicAvailabilityResponse, PublicBooking, PublicBookingConfirmation, + RecurringBookingGroup, UpdateAdminBookingStatusInput, + UpdateRecurringGroupInput, } from '@repo/api-contract'; +import type { CreateRecurringBookingInput } from '@repo/api-contract'; import { http } from '../http'; export async function getAvailability( @@ -52,6 +56,36 @@ export async function createAdmin(complexId: string, payload: CreateAdminBooking return response.data; } +export async function createRecurring(complexId: string, payload: CreateRecurringBookingInput) { + const response = await http.post( + `/api/admin-bookings/complex/${complexId}/recurring`, + payload + ); + return response.data; +} + +export async function cancelRecurringGroup(groupId: string) { + const response = await http.post<{ ok: boolean }>( + `/api/admin-bookings/recurring/${groupId}/cancel` + ); + return response.data; +} + +export async function listRecurringGroups(complexId: string) { + const response = await http.get( + `/api/admin-bookings/complex/${complexId}/recurring` + ); + return response.data; +} + +export async function updateRecurringGroup(groupId: string, payload: UpdateRecurringGroupInput) { + const response = await http.patch( + `/api/admin-bookings/recurring/${groupId}`, + payload + ); + return response.data; +} + export async function cancelPublic(complexSlug: string, payload: CancelPublicBookingInput) { const response = await http.post( `/api/public-bookings/complex/${complexSlug}/cancel`, diff --git a/packages/api-contract/src/admin-booking.ts b/packages/api-contract/src/admin-booking.ts index d291e79..a88f91b 100644 --- a/packages/api-contract/src/admin-booking.ts +++ b/packages/api-contract/src/admin-booking.ts @@ -1,16 +1,18 @@ -import { z } from 'zod' +import { z } from 'zod'; -const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/ -const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/ -const BOOKING_CODE_REGEX = /^[A-Z0-9]{6,8}$/ +const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/; +const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/; +const BOOKING_CODE_REGEX = /^[A-Z0-9]{6,8}$/; -export const bookingStatusSchema = z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED', 'NOSHOW']) +export const bookingStatusSchema = z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED', 'NOSHOW']); + +export const recurringGroupStatusSchema = z.enum(['ACTIVE', 'CANCELLED']); export const adminBookingSportSchema = z.object({ id: z.uuid(), name: z.string(), slug: z.string(), -}) +}); export const adminBookingSchema = z.object({ id: z.uuid(), @@ -28,17 +30,18 @@ export const adminBookingSchema = z.object({ customerEmail: z.string(), price: z.number().nonnegative(), status: bookingStatusSchema, + recurringGroupId: z.string().uuid().nullable().optional(), createdAt: z.string().datetime(), updatedAt: z.string().datetime(), -}) +}); export const listAdminBookingsQuerySchema = z.object({ fromDate: z.string().regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.'), -}) +}); export const listAdminBookingsResponseSchema = z.object({ bookings: z.array(adminBookingSchema), -}) +}); export const createAdminBookingSchema = z.object({ date: z.string().regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.'), @@ -54,20 +57,73 @@ export const createAdminBookingSchema = z.object({ .trim() .min(6, 'El telefono debe tener al menos 6 caracteres.') .max(30, 'El telefono no puede superar los 30 caracteres.'), - customerEmail: z - .string() - .email('El email ingresado no es valido.') - .or(z.literal('')), -}) + customerEmail: z.string().email('El email ingresado no es valido.').or(z.literal('')), +}); export const updateAdminBookingStatusSchema = z.object({ status: z.enum(['CANCELLED', 'COMPLETED', 'NOSHOW']), -}) +}); -export type BookingStatus = z.infer -export type AdminBookingSport = z.infer -export type AdminBooking = z.infer -export type ListAdminBookingsQuery = z.infer -export type ListAdminBookingsResponse = z.infer -export type CreateAdminBookingInput = z.infer -export type UpdateAdminBookingStatusInput = z.infer +export const createRecurringBookingSchema = createAdminBookingSchema.extend({ + isRecurring: z.literal(true), + recurringEndDate: z + .string() + .regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.') + .optional(), +}); + +export const recurringBookingGroupSchema = z.object({ + id: z.uuid(), + complexId: z.uuid(), + courtId: z.uuid(), + startTime: z.string().regex(TIME_REGEX), + endTime: z.string().regex(TIME_REGEX), + dayOfWeek: z.enum(['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']), + startDate: z.string().regex(ISO_DATE_REGEX), + endDate: z.string().regex(ISO_DATE_REGEX).nullable(), + status: recurringGroupStatusSchema, + customerName: z.string(), + customerPhone: z.string(), + customerEmail: z.string(), + bookings: z.array(adminBookingSchema), + createdAt: z.string().datetime(), + updatedAt: z.string().datetime(), +}); + +export const updateRecurringGroupSchema = z.object({ + courtId: z.uuid('El courtId debe ser un UUID valido.').optional(), + dayOfWeek: z + .enum(['MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY']) + .optional(), + startTime: z.string().regex(TIME_REGEX, 'La hora debe tener formato HH:mm.').optional(), + customerName: z + .string() + .trim() + .min(2, 'El nombre debe tener al menos 2 caracteres.') + .max(120, 'El nombre no puede superar los 120 caracteres.') + .optional(), + customerPhone: z + .string() + .trim() + .min(6, 'El telefono debe tener al menos 6 caracteres.') + .max(30, 'El telefono no puede superar los 30 caracteres.') + .optional(), + customerEmail: z.string().email('El email ingresado no es valido.').or(z.literal('')).optional(), +}); + +export const listRecurringGroupsResponseSchema = z.object({ + groups: z.array(recurringBookingGroupSchema), +}); + +export type BookingStatus = z.infer; +export type RecurringGroupStatus = z.infer; +export type AdminBookingSport = z.infer; +export type AdminBooking = z.infer; +export type ListAdminBookingsQuery = z.infer; +export type ListAdminBookingsResponse = z.infer; +export type CreateAdminBookingInput = z.infer; +export type CreateRecurringBookingInput = z.infer; +export type RecurringBookingGroup = z.infer; +export type UpdateAdminBookingStatusInput = z.infer; +export type UpdateRecurringGroupInput = z.infer; +export type ListRecurringGroupsResponse = z.infer; diff --git a/packages/api-contract/src/admin.ts b/packages/api-contract/src/admin.ts index 73969cd..0f15966 100644 --- a/packages/api-contract/src/admin.ts +++ b/packages/api-contract/src/admin.ts @@ -1,6 +1,6 @@ -import { z } from 'zod' +import { z } from 'zod'; -export const adminPaymentStatusSchema = z.enum(['active', 'no_plan', 'expired']) +export const adminPaymentStatusSchema = z.enum(['active', 'no_plan', 'expired']); export const adminComplexListItemSchema = z.object({ id: z.string(), @@ -13,7 +13,7 @@ export const adminComplexListItemSchema = z.object({ courtCount: z.number().int().nonnegative(), avgBookingsPerDay: z.number().nonnegative(), paymentStatus: adminPaymentStatusSchema, -}) +}); export const adminComplexStatsSchema = z.object({ id: z.string(), @@ -34,20 +34,20 @@ export const adminComplexStatsSchema = z.object({ noshow: z.number().int().nonnegative(), }), paymentStatus: adminPaymentStatusSchema, -}) +}); export const adminCreatePlanSchema = z.object({ code: z.string().trim().min(1).max(10), name: z.string().trim().min(1).max(30), price: z.number().nonnegative(), rules: z.any(), -}) +}); export const adminUpdatePlanSchema = z.object({ name: z.string().trim().min(1).max(30).optional(), price: z.number().nonnegative().optional(), rules: z.any().optional(), -}) +}); export const adminUserSchema = z.object({ id: z.string(), @@ -60,18 +60,18 @@ export const adminUserSchema = z.object({ createdAt: z.string().datetime(), complexCount: z.number().int().nonnegative(), activeSessions: z.number().int().nonnegative(), -}) +}); export const adminBlockUserSchema = z.object({ banReason: z.string().max(500).optional(), -}) +}); export const adminGlobalStatsSchema = z.object({ totalComplexes: z.number().int().nonnegative(), totalUsers: z.number().int().nonnegative(), totalCourts: z.number().int().nonnegative(), totalBookings: z.number().int().nonnegative(), -}) +}); export const adminUserSessionSchema = z.object({ id: z.string(), @@ -82,35 +82,35 @@ export const adminUserSessionSchema = z.object({ city: z.string().nullable(), country: z.string().nullable(), countryCode: z.string().nullable(), -}) +}); -export type AdminComplexListItem = z.infer -export type AdminComplexStats = z.infer -export type AdminCreatePlanInput = z.infer -export type AdminUpdatePlanInput = z.infer -export type AdminUser = z.infer -export type AdminBlockUserInput = z.infer -export type AdminGlobalStats = z.infer -export type AdminPaymentStatus = z.infer -export type AdminUserSession = z.infer +export type AdminComplexListItem = z.infer; +export type AdminComplexStats = z.infer; +export type AdminCreatePlanInput = z.infer; +export type AdminUpdatePlanInput = z.infer; +export type AdminUser = z.infer; +export type AdminBlockUserInput = z.infer; +export type AdminGlobalStats = z.infer; +export type AdminPaymentStatus = z.infer; +export type AdminUserSession = z.infer; export const adminGeoCitySchema = z.object({ city: z.string(), userCount: z.number().int().nonnegative(), -}) +}); export const adminGeoCountrySchema = z.object({ country: z.string(), countryCode: z.string(), totalUsers: z.number().int().nonnegative(), cities: z.array(adminGeoCitySchema), -}) +}); export const adminGeoStatsSchema = z.object({ countries: z.array(adminGeoCountrySchema), totalUniqueCountries: z.number().int().nonnegative(), -}) +}); -export type AdminGeoCity = z.infer -export type AdminGeoCountry = z.infer -export type AdminGeoStats = z.infer +export type AdminGeoCity = z.infer; +export type AdminGeoCountry = z.infer; +export type AdminGeoStats = z.infer; diff --git a/packages/api-contract/src/complex.ts b/packages/api-contract/src/complex.ts index 15c8bf9..185c850 100644 --- a/packages/api-contract/src/complex.ts +++ b/packages/api-contract/src/complex.ts @@ -1,4 +1,5 @@ -import { z } from 'zod' +import { z } from 'zod'; +import { planFeatureFlagsSchema } from './plan'; const dayOfWeekEnum = z.enum([ 'MONDAY', @@ -8,7 +9,7 @@ const dayOfWeekEnum = z.enum([ 'FRIDAY', 'SATURDAY', 'SUNDAY', -]) +]); export const complexSchema = z.object({ id: z.uuid(), @@ -22,7 +23,7 @@ export const complexSchema = z.object({ planCode: z.string().max(10).nullable(), createdAt: z.string().datetime(), updatedAt: z.string().datetime(), -}) +}); export const createComplexSchema = z .object({ @@ -36,21 +37,13 @@ export const createComplexSchema = z .trim() .min(5, 'La direccion debe tener al menos 5 caracteres.') .max(200, 'La direccion no puede superar los 200 caracteres.'), - city: z - .string() - .trim() - .max(100, 'La ciudad no puede superar los 100 caracteres.') - .optional(), + city: z.string().trim().max(100, 'La ciudad no puede superar los 100 caracteres.').optional(), state: z .string() .trim() .max(100, 'La provincia/estado no puede superar los 100 caracteres.') .optional(), - country: z - .string() - .trim() - .max(100, 'El país no puede superar los 100 caracteres.') - .optional(), + country: z.string().trim().max(100, 'El país no puede superar los 100 caracteres.').optional(), planCode: z .string() .trim() @@ -70,31 +63,31 @@ export const createComplexSchema = z code: z.ZodIssueCode.custom, path: ['courtSportId'], message: 'Debes seleccionar un deporte.', - }) + }); } if (!data.courtStartTime || !/^\d{2}:\d{2}$/.test(data.courtStartTime)) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['courtStartTime'], message: 'La hora de inicio debe tener formato HH:mm.', - }) + }); } if (!data.courtEndTime || !/^\d{2}:\d{2}$/.test(data.courtEndTime)) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['courtEndTime'], message: 'La hora de fin debe tener formato HH:mm.', - }) + }); } if (!data.courtDaysOfWeek || data.courtDaysOfWeek.length === 0) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['courtDaysOfWeek'], message: 'Debes seleccionar al menos un día.', - }) + }); } } - }) + }); export const updateComplexSchema = z .object({ @@ -154,16 +147,16 @@ export const updateComplexSchema = z payload.country !== undefined || payload.complexSlug || payload.adminEmail || - payload.planCode !== undefined, + payload.planCode !== undefined ), { message: 'Debes enviar al menos un campo para actualizar.', - }, - ) + } + ); -export const complexUserRoleSchema = z.enum(['ADMIN', 'EMPLOYEE']) +export const complexUserRoleSchema = z.enum(['ADMIN', 'EMPLOYEE']); -export type ComplexUserRole = z.infer +export type ComplexUserRole = z.infer; export const complexMemberSchema = z.object({ userId: z.string(), @@ -172,13 +165,13 @@ export const complexMemberSchema = z.object({ avatarUrl: z.url(), role: complexUserRoleSchema, createdAt: z.string().datetime(), -}) +}); -export type ComplexMember = z.infer +export type ComplexMember = z.infer; -export const complexInvitationStatusSchema = z.enum(['PENDING', 'ACCEPTED', 'REVOKED', 'EXPIRED']) +export const complexInvitationStatusSchema = z.enum(['PENDING', 'ACCEPTED', 'REVOKED', 'EXPIRED']); -export type ComplexInvitationStatus = z.infer +export type ComplexInvitationStatus = z.infer; export const complexInvitationSchema = z.object({ id: z.uuid(), @@ -189,62 +182,63 @@ export const complexInvitationSchema = z.object({ expiresAt: z.string().datetime(), acceptedAt: z.string().datetime().nullable(), revokedAt: z.string().datetime().nullable(), -}) +}); -export type ComplexInvitation = z.infer +export type ComplexInvitation = z.infer; export const complexUsersOverviewSchema = z.object({ members: z.array(complexMemberSchema), invitations: z.array(complexInvitationSchema), -}) +}); -export type ComplexUsersOverview = z.infer +export type ComplexUsersOverview = z.infer; export const inviteComplexUserSchema = z.object({ email: z.email('El email debe ser válido.'), -}) +}); -export type InviteComplexUserInput = z.infer +export type InviteComplexUserInput = z.infer; export const acceptComplexInvitationsSchema = z.object({ inviteToken: z.string().min(1, 'El token de invitación no puede estar vacío.').optional(), -}) +}); -export type AcceptComplexInvitationsInput = z.infer +export type AcceptComplexInvitationsInput = z.infer; export const revokeComplexUserSchema = z.object({ userId: z.string().min(1, 'El userId no puede estar vacío.'), -}) +}); -export type RevokeComplexUserInput = z.infer +export type RevokeComplexUserInput = z.infer; export const selectComplexSchema = z.object({ complexId: z.string().uuid(), -}) +}); -export type SelectComplexInput = z.infer +export type SelectComplexInput = z.infer; export const complexWithRoleSchema = complexSchema.merge( z.object({ role: complexUserRoleSchema, + planFeatures: planFeatureFlagsSchema.nullable(), }) -) +); -export type ComplexWithRole = z.infer +export type ComplexWithRole = z.infer; -export type Complex = z.infer -export type CreateComplexInput = z.infer -export type UpdateComplexInput = z.infer -export type CreateComplexPayload = CreateComplexInput -export type CreateComplexResponse = Complex -export type UpdateComplexPayload = UpdateComplexInput -export type UpdateComplexResponse = Complex +export type Complex = z.infer; +export type CreateComplexInput = z.infer; +export type UpdateComplexInput = z.infer; +export type CreateComplexPayload = CreateComplexInput; +export type CreateComplexResponse = Complex; +export type UpdateComplexPayload = UpdateComplexInput; +export type UpdateComplexResponse = Complex; export type InviteComplexUserResponse = { - invitation: ComplexInvitation -} + invitation: ComplexInvitation; +}; export type AcceptComplexInvitationsResponse = { - acceptedCount: number -} + acceptedCount: number; +}; export type CancelComplexInvitationResponse = { - ok: boolean -} + ok: boolean; +}; diff --git a/packages/api-contract/src/court.ts b/packages/api-contract/src/court.ts index b11ddd7..aee2374 100644 --- a/packages/api-contract/src/court.ts +++ b/packages/api-contract/src/court.ts @@ -1,65 +1,65 @@ -import { z } from 'zod' +import { z } from 'zod'; -const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/ +const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/; function toMinutes(value: string): number { - const [hours, minutes] = value.split(':').map((part) => Number(part)) - return hours * 60 + minutes + const [hours, minutes] = value.split(':').map((part) => Number(part)); + return hours * 60 + minutes; } function hasOverlaps( availability: Array<{ - dayOfWeek: DayOfWeek - startTime: string - endTime: string - }>, + dayOfWeek: DayOfWeek; + startTime: string; + endTime: string; + }> ): boolean { const grouped = new Map< DayOfWeek, Array<{ - start: number - end: number + start: number; + end: number; }> - >() + >(); for (const range of availability) { - const start = toMinutes(range.startTime) - const end = toMinutes(range.endTime) - const current = grouped.get(range.dayOfWeek) ?? [] - current.push({ start, end }) - grouped.set(range.dayOfWeek, current) + const start = toMinutes(range.startTime); + const end = toMinutes(range.endTime); + const current = grouped.get(range.dayOfWeek) ?? []; + current.push({ start, end }); + grouped.set(range.dayOfWeek, current); } for (const ranges of grouped.values()) { - ranges.sort((a, b) => a.start - b.start) + ranges.sort((a, b) => a.start - b.start); for (let index = 1; index < ranges.length; index += 1) { - const previous = ranges[index - 1] - const current = ranges[index] + const previous = ranges[index - 1]; + const current = ranges[index]; if (previous.end > current.start) { - return true + return true; } } } - return false + return false; } function refineAvailability( availability: Array<{ - dayOfWeek: DayOfWeek - startTime: string - endTime: string + dayOfWeek: DayOfWeek; + startTime: string; + endTime: string; }>, - context: z.RefinementCtx, + context: z.RefinementCtx ) { for (const range of availability) { if (toMinutes(range.startTime) >= toMinutes(range.endTime)) { context.addIssue({ code: z.ZodIssueCode.custom, message: `El rango ${range.startTime}-${range.endTime} es invalido. La hora de inicio debe ser menor a la de fin.`, - }) + }); } } @@ -67,7 +67,7 @@ function refineAvailability( context.addIssue({ code: z.ZodIssueCode.custom, message: 'Hay rangos horarios superpuestos para el mismo dia.', - }) + }); } } @@ -79,22 +79,22 @@ export const dayOfWeekSchema = z.enum([ 'FRIDAY', 'SATURDAY', 'SUNDAY', -]) +]); -export type DayOfWeek = z.infer +export type DayOfWeek = z.infer; export const courtAvailabilitySchema = z.object({ id: z.uuid(), dayOfWeek: dayOfWeekSchema, startTime: z.string().regex(TIME_REGEX, 'La hora debe tener formato HH:mm.'), endTime: z.string().regex(TIME_REGEX, 'La hora debe tener formato HH:mm.'), -}) +}); export const courtAvailabilityInputSchema = z.object({ dayOfWeek: dayOfWeekSchema, startTime: z.string().regex(TIME_REGEX, 'La hora debe tener formato HH:mm.'), endTime: z.string().regex(TIME_REGEX, 'La hora debe tener formato HH:mm.'), -}) +}); export const courtPriceRuleSchema = z.object({ id: z.uuid(), @@ -103,13 +103,13 @@ export const courtPriceRuleSchema = z.object({ endTime: z.string().nullable(), price: z.number().nonnegative(), isActive: z.boolean(), -}) +}); export const courtSportSchema = z.object({ id: z.uuid(), name: z.string(), slug: z.string(), -}) +}); export const courtSchema = z.object({ id: z.uuid(), @@ -124,7 +124,7 @@ export const courtSchema = z.object({ hasCustomPricing: z.boolean(), createdAt: z.string().datetime(), updatedAt: z.string().datetime(), -}) +}); export const createCourtSchema = z .object({ @@ -139,9 +139,11 @@ export const createCourtSchema = z .min(15, 'La duracion minima por turno es 15 minutos.') .max(480, 'La duracion maxima por turno es 480 minutos.'), basePrice: z.number().nonnegative('El precio base no puede ser negativo.'), - availability: z.array(courtAvailabilityInputSchema).min(1, 'Debes definir al menos un rango horario.'), + availability: z + .array(courtAvailabilityInputSchema) + .min(1, 'Debes definir al menos un rango horario.'), }) - .superRefine((payload, context) => refineAvailability(payload.availability, context)) + .superRefine((payload, context) => refineAvailability(payload.availability, context)); export const updateCourtSchema = z .object({ @@ -158,7 +160,10 @@ export const updateCourtSchema = z .max(480, 'La duracion maxima por turno es 480 minutos.') .optional(), basePrice: z.number().nonnegative('El precio base no puede ser negativo.').optional(), - availability: z.array(courtAvailabilityInputSchema).min(1, 'Debes definir al menos un rango horario.').optional(), + availability: z + .array(courtAvailabilityInputSchema) + .min(1, 'Debes definir al menos un rango horario.') + .optional(), }) .superRefine((payload, context) => { if ( @@ -171,17 +176,17 @@ export const updateCourtSchema = z context.addIssue({ code: z.ZodIssueCode.custom, message: 'Debes enviar al menos un campo para actualizar.', - }) + }); } if (payload.availability) { - refineAvailability(payload.availability, context) + refineAvailability(payload.availability, context); } - }) + }); -export type Court = z.infer -export type CourtAvailability = z.infer -export type CourtAvailabilityInput = z.infer -export type CourtPriceRule = z.infer -export type CreateCourtInput = z.infer -export type UpdateCourtInput = z.infer +export type Court = z.infer; +export type CourtAvailability = z.infer; +export type CourtAvailabilityInput = z.infer; +export type CourtPriceRule = z.infer; +export type CreateCourtInput = z.infer; +export type UpdateCourtInput = z.infer; diff --git a/packages/api-contract/src/index.ts b/packages/api-contract/src/index.ts index 06b7698..34af853 100644 --- a/packages/api-contract/src/index.ts +++ b/packages/api-contract/src/index.ts @@ -6,7 +6,7 @@ export { planSummarySchema, planWithFeaturesSchema, planLimitsSchema, -} from './plan' +} from './plan'; export type { Plan, PlanFeatureFlags, @@ -15,7 +15,7 @@ export type { PlanSummary, PlanWithFeatures, PlanLimits, -} from './plan' +} from './plan'; export { acceptComplexInvitationsSchema, complexInvitationSchema, @@ -30,7 +30,7 @@ export { revokeComplexUserSchema, selectComplexSchema, updateComplexSchema, -} from './complex' +} from './complex'; export type { AcceptComplexInvitationsInput, AcceptComplexInvitationsResponse, @@ -52,7 +52,7 @@ export type { UpdateComplexPayload, UpdateComplexResponse, RevokeComplexUserInput, -} from './complex' +} from './complex'; export { dayOfWeekSchema, courtAvailabilityInputSchema, @@ -61,7 +61,7 @@ export { courtSchema, createCourtSchema, updateCourtSchema, -} from './court' +} from './court'; export type { DayOfWeek, Court, @@ -70,25 +70,35 @@ export type { CourtPriceRule, CreateCourtInput, UpdateCourtInput, -} from './court' +} from './court'; export { adminBookingSchema, adminBookingSportSchema, bookingStatusSchema, createAdminBookingSchema, + createRecurringBookingSchema, listAdminBookingsQuerySchema, listAdminBookingsResponseSchema, + listRecurringGroupsResponseSchema, + recurringBookingGroupSchema, + recurringGroupStatusSchema, updateAdminBookingStatusSchema, -} from './admin-booking' + updateRecurringGroupSchema, +} from './admin-booking'; export type { AdminBooking, AdminBookingSport, BookingStatus, CreateAdminBookingInput, + CreateRecurringBookingInput, ListAdminBookingsQuery, ListAdminBookingsResponse, + ListRecurringGroupsResponse, + RecurringBookingGroup, + RecurringGroupStatus, UpdateAdminBookingStatusInput, -} from './admin-booking' + UpdateRecurringGroupInput, +} from './admin-booking'; export { createPublicBookingSchema, publicAvailabilityCourtSchema, @@ -99,7 +109,7 @@ export { publicBookingSlotSchema, publicBookingSportSchema, cancelPublicBookingSchema, -} from './public-booking' +} from './public-booking'; export type { CreatePublicBookingInput, CancelPublicBookingInput, @@ -110,15 +120,15 @@ export type { PublicBookingConfirmation, PublicBookingSlot, PublicBookingSport, -} from './public-booking' -export { sportSchema, createSportSchema, updateSportSchema } from './sport' -export type { Sport, CreateSportInput, UpdateSportInput } from './sport' +} from './public-booking'; +export { sportSchema, createSportSchema, updateSportSchema } from './sport'; +export type { Sport, CreateSportInput, UpdateSportInput } from './sport'; export { userProfileSchema, passwordResetStartSchema, passwordResetVerifySchema, passwordResetResendSchema, -} from './user' +} from './user'; export type { UserProfile, UserProfileResponse, @@ -128,7 +138,7 @@ export type { PasswordResetStartResponse, PasswordResetVerifyResponse, PasswordResetResendResponse, -} from './user' +} from './user'; export { adminComplexListItemSchema, adminComplexStatsSchema, @@ -142,7 +152,7 @@ export { adminGeoCitySchema, adminGeoCountrySchema, adminGeoStatsSchema, -} from './admin' +} from './admin'; export type { AdminComplexListItem, AdminComplexStats, @@ -156,4 +166,4 @@ export type { AdminGeoCity, AdminGeoCountry, AdminGeoStats, -} from './admin' +} from './admin'; diff --git a/packages/api-contract/src/plan.ts b/packages/api-contract/src/plan.ts index 496de9e..49e1a3c 100644 --- a/packages/api-contract/src/plan.ts +++ b/packages/api-contract/src/plan.ts @@ -1,14 +1,15 @@ -import { z } from 'zod' +import { z } from 'zod'; -const nonNegativeInt = z.int().nonnegative() -const positiveInt = z.int().positive() +const nonNegativeInt = z.int().nonnegative(); +const positiveInt = z.int().positive(); export const planFeatureFlagsSchema = z.object({ onlinePayments: z.boolean().default(false), publicBookingPage: z.boolean().default(false), advancedReports: z.boolean().default(false), whatsappReminders: z.boolean().default(false), -}) + fixedSlots: z.boolean().default(false), +}); export const planRulesV1Schema = z.object({ version: z.literal('v1'), @@ -31,13 +32,14 @@ export const planRulesV1Schema = z.object({ publicBookingPage: false, advancedReports: false, whatsappReminders: false, + fixedSlots: false, }), -}) +}); export const planPriceOverrideSchema = z.object({ amount: z.number().nonnegative(), currency: z.string().length(3), -}) +}); export const planRulesV2Schema = planRulesV1Schema.extend({ version: z.literal('v2'), @@ -46,12 +48,12 @@ export const planRulesV2Schema = planRulesV1Schema.extend({ overrides: z.record(z.string(), planPriceOverrideSchema), }) .optional(), -}) +}); export const planRulesSchema = z.discriminatedUnion('version', [ planRulesV1Schema, planRulesV2Schema, -]) +]); export const planSchema = z.object({ code: z.string().trim().min(1).max(10), @@ -59,13 +61,13 @@ export const planSchema = z.object({ price: z.number().nonnegative(), lastUpdatedAt: z.string().datetime(), rules: planRulesSchema, -}) +}); export const planSummarySchema = z.object({ code: z.string().trim().min(1).max(10), name: z.string().trim().min(1).max(30), price: z.number().nonnegative(), -}) +}); export const planLimitsSchema = z.object({ maxCourts: positiveInt, @@ -73,7 +75,7 @@ export const planLimitsSchema = z.object({ maxActiveUsers: positiveInt.optional(), maxConcurrentBookingsPerSlot: positiveInt.optional(), maxSports: positiveInt.optional(), -}) +}); export const planWithFeaturesSchema = z.object({ code: z.string().trim().min(1).max(10), @@ -82,13 +84,13 @@ export const planWithFeaturesSchema = z.object({ currency: z.string().length(3), features: planFeatureFlagsSchema, limits: planLimitsSchema, -}) +}); -export type PlanFeatureFlags = z.infer -export type PlanRulesV1 = z.infer -export type PlanRulesV2 = z.infer -export type PlanRules = z.infer -export type Plan = z.infer -export type PlanSummary = z.infer -export type PlanWithFeatures = z.infer -export type PlanLimits = z.infer +export type PlanFeatureFlags = z.infer; +export type PlanRulesV1 = z.infer; +export type PlanRulesV2 = z.infer; +export type PlanRules = z.infer; +export type Plan = z.infer; +export type PlanSummary = z.infer; +export type PlanWithFeatures = z.infer; +export type PlanLimits = z.infer; diff --git a/packages/api-contract/src/public-booking.ts b/packages/api-contract/src/public-booking.ts index a602d71..fbed205 100644 --- a/packages/api-contract/src/public-booking.ts +++ b/packages/api-contract/src/public-booking.ts @@ -1,26 +1,26 @@ -import { z } from 'zod' -import { dayOfWeekSchema } from './court' +import { z } from 'zod'; +import { dayOfWeekSchema } from './court'; -const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/ -const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/ -const BOOKING_CODE_REGEX = /^[A-Z0-9]{6,8}$/ +const TIME_REGEX = /^([01]\d|2[0-3]):([0-5]\d)$/; +const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/; +const BOOKING_CODE_REGEX = /^[A-Z0-9]{6,8}$/; export const publicAvailabilityQuerySchema = z.object({ date: z.string().regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.'), sportId: z.uuid('El sportId debe ser un UUID valido.').optional(), -}) +}); export const publicBookingSportSchema = z.object({ id: z.uuid(), name: z.string(), slug: z.string(), -}) +}); export const publicBookingSlotSchema = z.object({ startTime: z.string().regex(TIME_REGEX), endTime: z.string().regex(TIME_REGEX), price: z.number().nonnegative(), -}) +}); export const publicAvailabilityCourtSchema = z.object({ courtId: z.uuid(), @@ -29,7 +29,7 @@ export const publicAvailabilityCourtSchema = z.object({ slotDurationMinutes: z.int().positive(), availabilityDay: dayOfWeekSchema, availableSlots: z.array(publicBookingSlotSchema), -}) +}); export const publicAvailabilityResponseSchema = z.object({ complexId: z.uuid(), @@ -40,7 +40,7 @@ export const publicAvailabilityResponseSchema = z.object({ sportSelectionRequired: z.boolean(), sports: z.array(publicBookingSportSchema), courts: z.array(publicAvailabilityCourtSchema), -}) +}); export const createPublicBookingSchema = z.object({ date: z.string().regex(ISO_DATE_REGEX, 'La fecha debe tener formato YYYY-MM-DD.'), @@ -57,10 +57,8 @@ export const createPublicBookingSchema = z.object({ .trim() .min(6, 'El telefono debe tener al menos 6 caracteres.') .max(30, 'El telefono no puede superar los 30 caracteres.'), - customerEmail: z - .string() - .email('El email ingresado no es valido.'), -}) + customerEmail: z.string().email('El email ingresado no es valido.'), +}); export const cancelPublicBookingSchema = z.object({ bookingCode: z.string().regex(BOOKING_CODE_REGEX, 'El codigo de reserva no es valido.'), @@ -69,7 +67,7 @@ export const cancelPublicBookingSchema = z.object({ .trim() .min(6, 'El telefono debe tener al menos 6 caracteres.') .max(30, 'El telefono no puede superar los 30 caracteres.'), -}) +}); export const publicBookingSchema = z.object({ id: z.uuid(), @@ -89,7 +87,7 @@ export const publicBookingSchema = z.object({ status: z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED']), price: z.number().nonnegative(), createdAt: z.string().datetime(), -}) +}); export const publicBookingConfirmationSchema = z.object({ bookingCode: z.string().regex(BOOKING_CODE_REGEX), @@ -105,14 +103,14 @@ export const publicBookingConfirmationSchema = z.object({ status: z.enum(['CONFIRMED', 'CANCELLED', 'COMPLETED']), customerEmail: z.string(), createdAt: z.string().datetime(), -}) +}); -export type PublicAvailabilityQuery = z.infer -export type PublicBookingSport = z.infer -export type PublicBookingSlot = z.infer -export type PublicAvailabilityCourt = z.infer -export type PublicAvailabilityResponse = z.infer -export type CreatePublicBookingInput = z.infer -export type CancelPublicBookingInput = z.infer -export type PublicBooking = z.infer -export type PublicBookingConfirmation = z.infer +export type PublicAvailabilityQuery = z.infer; +export type PublicBookingSport = z.infer; +export type PublicBookingSlot = z.infer; +export type PublicAvailabilityCourt = z.infer; +export type PublicAvailabilityResponse = z.infer; +export type CreatePublicBookingInput = z.infer; +export type CancelPublicBookingInput = z.infer; +export type PublicBooking = z.infer; +export type PublicBookingConfirmation = z.infer; diff --git a/packages/api-contract/src/sport.ts b/packages/api-contract/src/sport.ts index dae961d..7badda3 100644 --- a/packages/api-contract/src/sport.ts +++ b/packages/api-contract/src/sport.ts @@ -1,4 +1,4 @@ -import { z } from 'zod' +import { z } from 'zod'; export const sportSchema = z.object({ id: z.uuid(), @@ -7,7 +7,7 @@ export const sportSchema = z.object({ isActive: z.boolean(), createdAt: z.string().datetime(), updatedAt: z.string().datetime(), -}) +}); export const createSportSchema = z.object({ name: z @@ -15,7 +15,7 @@ export const createSportSchema = z.object({ .trim() .min(2, 'El deporte debe tener al menos 2 caracteres.') .max(80, 'El deporte no puede superar los 80 caracteres.'), -}) +}); export const updateSportSchema = z .object({ @@ -29,8 +29,8 @@ export const updateSportSchema = z }) .refine((payload) => payload.name !== undefined || payload.isActive !== undefined, { message: 'Debes enviar al menos un campo para actualizar.', - }) + }); -export type Sport = z.infer -export type CreateSportInput = z.infer -export type UpdateSportInput = z.infer +export type Sport = z.infer; +export type CreateSportInput = z.infer; +export type UpdateSportInput = z.infer; diff --git a/packages/api-contract/src/user.ts b/packages/api-contract/src/user.ts index 02b0767..bb41e99 100644 --- a/packages/api-contract/src/user.ts +++ b/packages/api-contract/src/user.ts @@ -1,4 +1,4 @@ -import { z } from 'zod' +import { z } from 'zod'; export const userProfileSchema = z.object({ id: z.string(), @@ -7,30 +7,30 @@ export const userProfileSchema = z.object({ role: z.string(), avatarUrl: z.url().nullable(), createdAt: z.string(), -}) +}); -export type UserProfile = z.infer -export type UserProfileResponse = UserProfile +export type UserProfile = z.infer; +export type UserProfileResponse = UserProfile; export const passwordResetStartSchema = z.object({ email: z.string().email('Ingresá un email válido.'), -}) +}); -export type PasswordResetStartInput = z.infer +export type PasswordResetStartInput = z.infer; export const passwordResetVerifySchema = z.object({ requestId: z.string().uuid('Request ID inválido.'), otp: z.string().length(6, 'El código debe tener 6 dígitos.'), newPassword: z.string().min(6, 'La contraseña debe tener al menos 6 caracteres.'), -}) +}); -export type PasswordResetVerifyInput = z.infer +export type PasswordResetVerifyInput = z.infer; export const passwordResetResendSchema = z.object({ requestId: z.string().uuid('Request ID inválido.'), -}) +}); -export type PasswordResetResendInput = z.infer +export type PasswordResetResendInput = z.infer; export type PasswordResetStartResponse = { message: string; @@ -38,11 +38,11 @@ export type PasswordResetStartResponse = { email: string; expiresAt: string; cooldownSeconds: number; -} +}; export type PasswordResetVerifyResponse = { message: string; -} +}; export type PasswordResetResendResponse = { message: string; @@ -50,4 +50,4 @@ export type PasswordResetResendResponse = { email: string; expiresAt: string; cooldownSeconds: number; -} +};