// 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" binaryTargets = ["native", "debian-openssl-3.0.x"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique name String? password String? image String? emailVerified DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Stripe subscription fields stripeCustomerId String? @unique stripeSubscriptionId String? @unique stripePriceId String? stripeCurrentPeriodEnd DateTime? plan Plan @default(FREE) // Password reset fields resetPasswordToken String? @unique resetPasswordExpires DateTime? // Retention email tracking activationNudgeSentAt DateTime? upgradeNudgeSentAt DateTime? thirtyDayNudgeSentAt DateTime? // RevOps attribution signupSource String? signupSourceSelfReported String? signupMedium String? signupCampaign String? signupContent String? signupTerm String? signupReferrer String? signupLandingPath String? signupFirstSeenAt DateTime? emailDomain String? // Onboarding and qualification primaryUseCase String? primaryGoal String? jobRole String? companyName String? companyWebsite String? teamSizeBucket String? onboardingStartedAt DateTime? sourceConfirmedAt DateTime? useCaseSelectedAt DateTime? goalSelectedAt DateTime? profileCompletedAt DateTime? firstQrCreatedAt DateTime? firstDynamicQrAt DateTime? firstStaticQrAt DateTime? firstScanAt DateTime? activationAt DateTime? onboardingCompletedAt DateTime? // RevOps scoring fitScore Int @default(0) intentScore Int @default(0) leadScore Int @default(0) lifecycleStage String @default("cold") lastQualifiedAt DateTime? lastScoredAt DateTime? qrCodes QRCode[] integrations Integration[] accounts Account[] sessions Session[] lifecycleLogs UserLifecycleLog[] } enum Plan { FREE PRO BUSINESS } model Account { id String @id @default(cuid()) userId String type String provider String providerAccountId String refresh_token String? @db.Text access_token String? @db.Text expires_at Int? token_type String? scope String? id_token String? @db.Text session_state String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([provider, providerAccountId]) } model Session { id String @id @default(cuid()) sessionToken String @unique userId String expires DateTime user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model VerificationToken { identifier String token String @unique expires DateTime @@unique([identifier, token]) } model QRCode { id String @id @default(cuid()) userId String title String type QRType @default(DYNAMIC) contentType ContentType @default(URL) content Json tags String[] status QRStatus @default(ACTIVE) style Json slug String @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) scans QRScan[] @@index([userId, createdAt]) } enum QRType { STATIC DYNAMIC } enum ContentType { URL VCARD GEO PHONE SMS TEXT WHATSAPP PDF APP COUPON FEEDBACK BARCODE } enum QRStatus { ACTIVE PAUSED } model QRScan { id String @id @default(cuid()) qrId String ts DateTime @default(now()) ipHash String userAgent String? device String? os String? country String? referrer String? utmSource String? utmMedium String? utmCampaign String? isUnique Boolean @default(false) qr QRCode @relation(fields: [qrId], references: [id], onDelete: Cascade) @@index([qrId, ts]) } model Integration { id String @id @default(cuid()) userId String provider String status String @default("inactive") config Json createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model UserLifecycleLog { id String @id @default(cuid()) userId String fromStage String? toStage String fitScore Int @default(0) intentScore Int @default(0) leadScore Int @default(0) reason String? createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) } model NewsletterSubscription { id String @id @default(cuid()) email String @unique source String @default("ai-coming-soon") status String @default("subscribed") createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([email]) @@index([createdAt]) } model Lead { id String @id @default(cuid()) email String source String @default("reprint-calculator") reprintCost Float? updatesPerYear Float? annualSavings Float? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }