SEO_iamge_renamer_starting_.../packages/api/prisma/seed.ts

391 lines
12 KiB
TypeScript
Raw Normal View History

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.COMPLETED,
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.FAILED,
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();
});