// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } // Note that some adapters may set a maximum length for the String type by default, please ensure your strings are long // enough when changing adapters. // See https://www.prisma.io/docs/orm/reference/prisma-schema-reference#string for more information datasource db { provider = "postgresql" url = env("DATABASE_URL") } model Session { id String @id shop String state String isOnline Boolean @default(false) scope String? expires DateTime? accessToken String userId BigInt? firstName String? lastName String? email String? accountOwner Boolean @default(false) locale String? collaborator Boolean? @default(false) emailVerified Boolean? @default(false) refreshToken String? refreshTokenExpires DateTime? } // --- Scheduling domain (IMPLEMENTATION_PLAN.md ยง4) ------------------------- // Every model below is scoped by shopDomain (multi-tenant, per CLAUDE.md). // Built incrementally per phase; see the plan for models not yet added // (CapacityResource, Zone, ProductRule, Rate, SlotHold, Booking, ...). enum Method { SHIPPING LOCAL_DELIVERY PICKUP } model Shop { id String @id @default(cuid()) shopDomain String @unique plan String @default("basic") // basic|shopify|advanced|plus tier String @default("free") // free|starter|growth|pro timezone String @default("UTC") settings Json @default("{}") // widget copy, i18n, feature flags createdAt DateTime @default(now()) } model Location { id String @id @default(cuid()) shopDomain String name String address String lat Float? lng Float? timezone String active Boolean @default(true) slotTemplates SlotTemplate[] overrides SlotOverride[] blackouts BlackoutDate[] createdAt DateTime @default(now()) @@index([shopDomain]) } model SlotTemplate { id String @id @default(cuid()) shopDomain String locationId String location Location @relation(fields: [locationId], references: [id], onDelete: Cascade) method Method weekday Int // 0-6 (0 = Sunday), location-local startMin Int // minutes from midnight, local endMin Int capacity Int // default order capacity if no resources cutoffMin Int? // cutoff before slot (minutes) leadTimeMin Int @default(0) createdAt DateTime @default(now()) @@index([shopDomain, locationId, method, weekday]) } model SlotOverride { id String @id @default(cuid()) shopDomain String locationId String location Location @relation(fields: [locationId], references: [id], onDelete: Cascade) date DateTime // date-only, location-local method Method closed Boolean @default(false) startMin Int? endMin Int? capacity Int? createdAt DateTime @default(now()) @@index([shopDomain, locationId, date]) } model BlackoutDate { id String @id @default(cuid()) shopDomain String locationId String? // null = all locations location Location? @relation(fields: [locationId], references: [id], onDelete: Cascade) method Method? // null = all methods date DateTime reason String? source String @default("manual") // manual|holiday-import createdAt DateTime @default(now()) @@index([shopDomain, date]) }