// 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" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // Enum for user subscription plans enum Plan { BASIC // 50 images per month PRO // 500 images per month MAX // 1000 images per month } // Enum for batch processing status enum BatchStatus { PROCESSING DONE ERROR } // Enum for individual image processing status enum ImageStatus { PENDING PROCESSING COMPLETED FAILED } // Enum for payment status enum PaymentStatus { PENDING COMPLETED FAILED CANCELLED REFUNDED } // Users table - OAuth ready with Google integration model User { id String @id @default(uuid()) googleUid String? @unique @map("google_uid") // Google OAuth UID emailHash String @unique @map("email_hash") // Hashed email for privacy email String @unique // Actual email for communication plan Plan @default(BASIC) quotaRemaining Int @default(50) @map("quota_remaining") // Monthly quota quotaResetDate DateTime @default(now()) @map("quota_reset_date") // When quota resets isActive Boolean @default(true) @map("is_active") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") // Relations batches Batch[] payments Payment[] apiKeys ApiKey[] @@map("users") @@index([emailHash]) @@index([googleUid]) @@index([plan]) } // Batches table - Groups of images processed together model Batch { id String @id @default(uuid()) userId String @map("user_id") status BatchStatus @default(PROCESSING) totalImages Int @default(0) @map("total_images") processedImages Int @default(0) @map("processed_images") failedImages Int @default(0) @map("failed_images") metadata Json? // Additional batch metadata (e.g., processing settings) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") completedAt DateTime? @map("completed_at") // Relations user User @relation(fields: [userId], references: [id], onDelete: Cascade) images Image[] @@map("batches") @@index([userId]) @@index([status]) @@index([createdAt]) } // Images table - Individual images within batches model Image { id String @id @default(uuid()) batchId String @map("batch_id") originalName String @map("original_name") proposedName String? @map("proposed_name") // AI-generated name finalName String? @map("final_name") // User-approved final name visionTags Json? @map("vision_tags") // AI vision analysis results status ImageStatus @default(PENDING) fileSize Int? @map("file_size") // File size in bytes dimensions Json? // Width/height as JSON object mimeType String? @map("mime_type") s3Key String? @map("s3_key") // S3 object key for storage processingError String? @map("processing_error") // Error message if processing failed createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") processedAt DateTime? @map("processed_at") // Relations batch Batch @relation(fields: [batchId], references: [id], onDelete: Cascade) @@map("images") @@index([batchId]) @@index([status]) @@index([originalName]) @@index([createdAt]) } // Payments table - Stripe integration for subscription management model Payment { id String @id @default(uuid()) userId String @map("user_id") stripeSessionId String? @unique @map("stripe_session_id") // Stripe Checkout Session ID stripePaymentId String? @unique @map("stripe_payment_id") // Stripe Payment Intent ID plan Plan // The plan being purchased amount Int // Amount in cents currency String @default("usd") status PaymentStatus @default(PENDING) metadata Json? // Additional payment metadata createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") paidAt DateTime? @map("paid_at") // Relations user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("payments") @@index([userId]) @@index([status]) @@index([stripeSessionId]) @@index([createdAt]) } // API Keys table - For potential API access model ApiKey { id String @id @default(uuid()) userId String @map("user_id") keyHash String @unique @map("key_hash") // Hashed API key name String // User-friendly name for the key isActive Boolean @default(true) @map("is_active") lastUsed DateTime? @map("last_used") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") expiresAt DateTime? @map("expires_at") // Relations user User @relation(fields: [userId], references: [id], onDelete: Cascade) usage ApiKeyUsage[] @@map("api_keys") @@index([userId]) @@index([keyHash]) @@index([isActive]) } // API Key Usage tracking model ApiKeyUsage { id String @id @default(uuid()) apiKeyId String @map("api_key_id") endpoint String // Which API endpoint was called createdAt DateTime @default(now()) @map("created_at") // Relations apiKey ApiKey @relation(fields: [apiKeyId], references: [id], onDelete: Cascade) @@map("api_key_usage") @@index([apiKeyId]) @@index([createdAt]) }