import { PrismaClient, Plan, BatchStatus, ImageStatus, PaymentStatus } from '@prisma/client'; import * as crypto from 'crypto'; const prisma = new PrismaClient(); async function main() { console.log('🌱 Starting database seed...'); // Create test users const users = await Promise.all([ prisma.user.create({ data: { googleUid: 'google_test_user_1', email: 'john.doe@example.com', emailHash: crypto.createHash('sha256').update('john.doe@example.com').digest('hex'), plan: Plan.BASIC, quotaRemaining: 50, quotaResetDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now }, }), prisma.user.create({ data: { googleUid: 'google_test_user_2', email: 'jane.smith@example.com', emailHash: crypto.createHash('sha256').update('jane.smith@example.com').digest('hex'), plan: Plan.PRO, quotaRemaining: 450, quotaResetDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), }, }), prisma.user.create({ data: { googleUid: 'google_test_user_3', email: 'bob.wilson@example.com', emailHash: crypto.createHash('sha256').update('bob.wilson@example.com').digest('hex'), plan: Plan.MAX, quotaRemaining: 900, quotaResetDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), }, }), ]); console.log(`āœ… Created ${users.length} test users`); // Create test batches const batches = []; // Completed batch for first user const completedBatch = await prisma.batch.create({ data: { userId: users[0].id, status: BatchStatus.DONE, totalImages: 5, processedImages: 4, failedImages: 1, completedAt: new Date(), metadata: { processingOptions: { includeColors: true, includeTags: true, aiModel: 'gpt-4-vision', }, }, }, }); batches.push(completedBatch); // Processing batch for second user const processingBatch = await prisma.batch.create({ data: { userId: users[1].id, status: BatchStatus.PROCESSING, totalImages: 10, processedImages: 6, failedImages: 1, metadata: { processingOptions: { includeColors: true, includeTags: true, includeScene: true, aiModel: 'gpt-4-vision', }, }, }, }); batches.push(processingBatch); // Error batch for third user const errorBatch = await prisma.batch.create({ data: { userId: users[2].id, status: BatchStatus.ERROR, totalImages: 3, processedImages: 0, failedImages: 3, completedAt: new Date(), metadata: { error: 'Invalid image format detected', }, }, }); batches.push(errorBatch); console.log(`āœ… Created ${batches.length} test batches`); // Create test images for completed batch const completedBatchImages = await Promise.all([ prisma.image.create({ data: { batchId: completedBatch.id, originalName: 'IMG_20240101_123456.jpg', proposedName: 'modern-kitchen-with-stainless-steel-appliances.jpg', finalName: 'kitchen-renovation-final.jpg', status: ImageStatus.COMPLETED, fileSize: 2048576, mimeType: 'image/jpeg', dimensions: { width: 1920, height: 1080, aspectRatio: '16:9' }, visionTags: { objects: ['kitchen', 'refrigerator', 'countertop', 'cabinets'], colors: ['white', 'stainless steel', 'black'], scene: 'modern kitchen interior', description: 'A modern kitchen with stainless steel appliances and white cabinets', confidence: 0.95, aiModel: 'gpt-4-vision', processingTime: 2.5, }, s3Key: 'uploads/user1/batch1/IMG_20240101_123456.jpg', processedAt: new Date(), }, }), prisma.image.create({ data: { batchId: completedBatch.id, originalName: 'DSC_0001.jpg', proposedName: 'cozy-living-room-with-fireplace.jpg', finalName: 'living-room-cozy-fireplace.jpg', status: ImageStatus.COMPLETED, fileSize: 3145728, mimeType: 'image/jpeg', dimensions: { width: 2560, height: 1440, aspectRatio: '16:9' }, visionTags: { objects: ['fireplace', 'sofa', 'coffee table', 'lamp'], colors: ['brown', 'cream', 'orange'], scene: 'cozy living room', description: 'A cozy living room with a warm fireplace and comfortable seating', confidence: 0.92, aiModel: 'gpt-4-vision', processingTime: 3.1, }, s3Key: 'uploads/user1/batch1/DSC_0001.jpg', processedAt: new Date(), }, }), prisma.image.create({ data: { batchId: completedBatch.id, originalName: 'photo_2024_01_01.png', proposedName: 'elegant-bedroom-with-natural-light.jpg', status: ImageStatus.COMPLETED, fileSize: 1572864, mimeType: 'image/png', dimensions: { width: 1600, height: 900, aspectRatio: '16:9' }, visionTags: { objects: ['bed', 'window', 'curtains', 'nightstand'], colors: ['white', 'beige', 'natural'], scene: 'elegant bedroom', description: 'An elegant bedroom with natural light streaming through large windows', confidence: 0.88, aiModel: 'gpt-4-vision', processingTime: 2.8, }, s3Key: 'uploads/user1/batch1/photo_2024_01_01.png', processedAt: new Date(), }, }), prisma.image.create({ data: { batchId: completedBatch.id, originalName: 'bathroom_pic.jpg', proposedName: 'luxury-bathroom-with-marble-tiles.jpg', status: ImageStatus.COMPLETED, fileSize: 2621440, mimeType: 'image/jpeg', dimensions: { width: 1920, height: 1080, aspectRatio: '16:9' }, visionTags: { objects: ['bathroom', 'bathtub', 'marble', 'mirror'], colors: ['white', 'marble', 'chrome'], scene: 'luxury bathroom', description: 'A luxury bathroom featuring marble tiles and modern fixtures', confidence: 0.94, aiModel: 'gpt-4-vision', processingTime: 3.3, }, s3Key: 'uploads/user1/batch1/bathroom_pic.jpg', processedAt: new Date(), }, }), prisma.image.create({ data: { batchId: completedBatch.id, originalName: 'corrupt_image.jpg', status: ImageStatus.FAILED, fileSize: 0, mimeType: 'image/jpeg', processingError: 'Image file is corrupted and cannot be processed', processedAt: new Date(), }, }), ]); // Create test images for processing batch const processingBatchImages = await Promise.all([ prisma.image.create({ data: { batchId: processingBatch.id, originalName: 'garden_view.jpg', proposedName: 'beautiful-garden-with-colorful-flowers.jpg', status: ImageStatus.COMPLETED, fileSize: 4194304, mimeType: 'image/jpeg', dimensions: { width: 3840, height: 2160, aspectRatio: '16:9' }, visionTags: { objects: ['garden', 'flowers', 'grass', 'trees'], colors: ['green', 'red', 'yellow', 'purple'], scene: 'beautiful garden', description: 'A beautiful garden with colorful flowers and lush greenery', confidence: 0.97, aiModel: 'gpt-4-vision', processingTime: 4.2, }, s3Key: 'uploads/user2/batch2/garden_view.jpg', processedAt: new Date(), }, }), prisma.image.create({ data: { batchId: processingBatch.id, originalName: 'office_space.png', proposedName: 'modern-office-workspace-with-computer.jpg', status: ImageStatus.COMPLETED, fileSize: 2097152, mimeType: 'image/png', dimensions: { width: 2560, height: 1600, aspectRatio: '8:5' }, visionTags: { objects: ['desk', 'computer', 'chair', 'monitor'], colors: ['white', 'black', 'blue'], scene: 'modern office', description: 'A modern office workspace with computer and ergonomic furniture', confidence: 0.91, aiModel: 'gpt-4-vision', processingTime: 3.7, }, s3Key: 'uploads/user2/batch2/office_space.png', processedAt: new Date(), }, }), prisma.image.create({ data: { batchId: processingBatch.id, originalName: 'current_processing.jpg', status: ImageStatus.PROCESSING, fileSize: 1835008, mimeType: 'image/jpeg', s3Key: 'uploads/user2/batch2/current_processing.jpg', }, }), prisma.image.create({ data: { batchId: processingBatch.id, originalName: 'pending_image_1.jpg', status: ImageStatus.PENDING, fileSize: 2359296, mimeType: 'image/jpeg', s3Key: 'uploads/user2/batch2/pending_image_1.jpg', }, }), prisma.image.create({ data: { batchId: processingBatch.id, originalName: 'pending_image_2.png', status: ImageStatus.PENDING, fileSize: 1048576, mimeType: 'image/png', s3Key: 'uploads/user2/batch2/pending_image_2.png', }, }), ]); console.log(`āœ… Created ${completedBatchImages.length + processingBatchImages.length} test images`); // Create test payments const payments = await Promise.all([ prisma.payment.create({ data: { userId: users[1].id, // Jane Smith upgrading to PRO stripeSessionId: 'cs_test_stripe_session_123', stripePaymentId: 'pi_test_stripe_payment_123', plan: Plan.PRO, amount: 2999, // $29.99 currency: 'usd', status: PaymentStatus.COMPLETED, paidAt: new Date(), metadata: { stripeCustomerId: 'cus_test_customer_123', previousPlan: Plan.BASIC, upgradeReason: 'Need more quota for business use', }, }, }), prisma.payment.create({ data: { userId: users[2].id, // Bob Wilson upgrading to MAX stripeSessionId: 'cs_test_stripe_session_456', stripePaymentId: 'pi_test_stripe_payment_456', plan: Plan.MAX, amount: 4999, // $49.99 currency: 'usd', status: PaymentStatus.COMPLETED, paidAt: new Date(), metadata: { stripeCustomerId: 'cus_test_customer_456', previousPlan: Plan.PRO, upgradeReason: 'Agency needs maximum quota', }, }, }), prisma.payment.create({ data: { userId: users[0].id, // John Doe failed payment stripeSessionId: 'cs_test_stripe_session_789', plan: Plan.PRO, amount: 2999, currency: 'usd', status: PaymentStatus.FAILED, metadata: { error: 'Insufficient funds', }, }, }), ]); console.log(`āœ… Created ${payments.length} test payments`); // Create test API keys const apiKeys = await Promise.all([ prisma.apiKey.create({ data: { userId: users[1].id, keyHash: crypto.createHash('sha256').update('test_api_key_pro_user').digest('hex'), name: 'Production API Key', isActive: true, lastUsed: new Date(), }, }), prisma.apiKey.create({ data: { userId: users[2].id, keyHash: crypto.createHash('sha256').update('test_api_key_max_user').digest('hex'), name: 'Development API Key', isActive: true, expiresAt: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1 year from now }, }), ]); console.log(`āœ… Created ${apiKeys.length} test API keys`); console.log('šŸŽ‰ Database seed completed successfully!'); // Print summary console.log('\nšŸ“Š Seed Summary:'); console.log(` Users: ${users.length}`); console.log(` Batches: ${batches.length}`); console.log(` Images: ${completedBatchImages.length + processingBatchImages.length}`); console.log(` Payments: ${payments.length}`); console.log(` API Keys: ${apiKeys.length}`); console.log('\nšŸ‘„ Test Users:'); users.forEach(user => { console.log(` ${user.email} (${user.plan}) - Quota: ${user.quotaRemaining}`); }); } main() .catch((e) => { console.error('āŒ Seed failed:', e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });