/** * LocalGreenChain Database Seed Script * Populates the database with development data * * Run with: bun run db:seed */ import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); async function main() { console.log('Starting database seed...'); // Clean existing data (in reverse dependency order) console.log('Cleaning existing data...'); await prisma.auditLog.deleteMany(); await prisma.blockchainBlock.deleteMany(); await prisma.marketMatch.deleteMany(); await prisma.plantingRecommendation.deleteMany(); await prisma.demandForecast.deleteMany(); await prisma.seasonalPlan.deleteMany(); await prisma.supplyCommitment.deleteMany(); await prisma.demandSignal.deleteMany(); await prisma.consumerPreference.deleteMany(); await prisma.farmAnalytics.deleteMany(); await prisma.resourceUsage.deleteMany(); await prisma.harvestBatch.deleteMany(); await prisma.cropBatch.deleteMany(); await prisma.growingRecipe.deleteMany(); await prisma.growingZone.deleteMany(); await prisma.verticalFarm.deleteMany(); await prisma.transportEvent.deleteMany(); await prisma.seedBatch.deleteMany(); await prisma.plant.deleteMany(); await prisma.user.deleteMany(); // Create users console.log('Creating users...'); const users = await Promise.all([ prisma.user.create({ data: { email: 'alice@localgreenchain.io', name: 'Alice Green', userType: 'GROWER', latitude: 37.7749, longitude: -122.4194, city: 'San Francisco', country: 'USA', bio: 'Urban farmer specializing in leafy greens and microgreens', walletAddress: '0x1234567890abcdef1234567890abcdef12345678', }, }), prisma.user.create({ data: { email: 'bob@localgreenchain.io', name: 'Bob Farmer', userType: 'GROWER', latitude: 37.8044, longitude: -122.2712, city: 'Oakland', country: 'USA', bio: 'Vertical farm operator with 5 years experience', walletAddress: '0xabcdef1234567890abcdef1234567890abcdef12', }, }), prisma.user.create({ data: { email: 'carol@localgreenchain.io', name: 'Carol Consumer', userType: 'CONSUMER', latitude: 37.7849, longitude: -122.4094, city: 'San Francisco', country: 'USA', bio: 'Health-conscious consumer supporting local farms', }, }), prisma.user.create({ data: { email: 'david@localgreenchain.io', name: 'David Distributor', userType: 'DISTRIBUTOR', latitude: 37.7649, longitude: -122.3994, city: 'San Francisco', country: 'USA', bio: 'Local food distributor serving Bay Area restaurants', }, }), prisma.user.create({ data: { email: 'eve@localgreenchain.io', name: 'Eve Admin', userType: 'ADMIN', latitude: 37.7949, longitude: -122.4294, city: 'San Francisco', country: 'USA', bio: 'LocalGreenChain platform administrator', }, }), ]); console.log(`Created ${users.length} users`); // Create plants console.log('Creating plants...'); const plants = await Promise.all([ // Original tomato plant prisma.plant.create({ data: { commonName: 'Cherry Tomato', scientificName: 'Solanum lycopersicum var. cerasiforme', species: 'lycopersicum', genus: 'Solanum', family: 'Solanaceae', propagationType: 'ORIGINAL', generation: 0, plantedDate: new Date('2024-03-15'), status: 'MATURE', latitude: 37.7749, longitude: -122.4194, city: 'San Francisco', country: 'USA', ownerId: users[0].id, notes: 'Heirloom variety from local seed library', images: ['tomato-seedling.jpg', 'tomato-mature.jpg'], }, }), // Basil plant prisma.plant.create({ data: { commonName: 'Sweet Basil', scientificName: 'Ocimum basilicum', species: 'basilicum', genus: 'Ocimum', family: 'Lamiaceae', propagationType: 'SEED', generation: 1, plantedDate: new Date('2024-04-01'), status: 'GROWING', latitude: 37.7749, longitude: -122.4194, city: 'San Francisco', country: 'USA', ownerId: users[0].id, notes: 'Italian large leaf variety', }, }), // Lettuce prisma.plant.create({ data: { commonName: 'Butterhead Lettuce', scientificName: 'Lactuca sativa var. capitata', species: 'sativa', genus: 'Lactuca', family: 'Asteraceae', propagationType: 'SEED', generation: 0, plantedDate: new Date('2024-05-01'), status: 'GROWING', latitude: 37.8044, longitude: -122.2712, city: 'Oakland', country: 'USA', ownerId: users[1].id, notes: 'Vertical farm grown with LED lighting', }, }), // Kale prisma.plant.create({ data: { commonName: 'Curly Kale', scientificName: 'Brassica oleracea var. sabellica', species: 'oleracea', genus: 'Brassica', family: 'Brassicaceae', propagationType: 'SEED', generation: 0, plantedDate: new Date('2024-04-15'), status: 'MATURE', latitude: 37.8044, longitude: -122.2712, city: 'Oakland', country: 'USA', ownerId: users[1].id, notes: 'Organic certified', }, }), // Microgreens prisma.plant.create({ data: { commonName: 'Sunflower Microgreens', scientificName: 'Helianthus annuus', species: 'annuus', genus: 'Helianthus', family: 'Asteraceae', propagationType: 'SEED', generation: 0, plantedDate: new Date('2024-05-20'), status: 'SPROUTED', latitude: 37.7749, longitude: -122.4194, city: 'San Francisco', country: 'USA', ownerId: users[0].id, notes: 'Fast-growing microgreen variety', }, }), ]); console.log(`Created ${plants.length} plants`); // Create tomato clone (child plant) const tomatoClone = await prisma.plant.create({ data: { commonName: 'Cherry Tomato Clone', scientificName: 'Solanum lycopersicum var. cerasiforme', species: 'lycopersicum', genus: 'Solanum', family: 'Solanaceae', parentPlantId: plants[0].id, propagationType: 'CLONE', generation: 1, plantedDate: new Date('2024-04-20'), status: 'GROWING', latitude: 37.8044, longitude: -122.2712, city: 'Oakland', country: 'USA', ownerId: users[1].id, notes: 'Cloned from Alice\'s heirloom tomato', }, }); console.log('Created tomato clone'); // Create seed batches console.log('Creating seed batches...'); const seedBatches = await Promise.all([ prisma.seedBatch.create({ data: { species: 'Solanum lycopersicum', variety: 'Cherry Heirloom', quantity: 100, quantityUnit: 'seeds', generation: 0, germinationRate: 0.92, purityPercentage: 0.99, harvestDate: new Date('2023-10-15'), expirationDate: new Date('2026-10-15'), certifications: ['organic', 'heirloom'], status: 'AVAILABLE', }, }), prisma.seedBatch.create({ data: { species: 'Lactuca sativa', variety: 'Butterhead', quantity: 500, quantityUnit: 'seeds', generation: 0, germinationRate: 0.88, harvestDate: new Date('2024-01-20'), expirationDate: new Date('2027-01-20'), certifications: ['organic', 'non_gmo'], status: 'AVAILABLE', }, }), ]); console.log(`Created ${seedBatches.length} seed batches`); // Create vertical farm console.log('Creating vertical farms...'); const farm = await prisma.verticalFarm.create({ data: { name: 'Oakland Urban Greens', ownerId: users[1].id, latitude: 37.8044, longitude: -122.2712, address: '123 Industrial Blvd', city: 'Oakland', country: 'USA', timezone: 'America/Los_Angeles', specs: { totalAreaSqm: 500, growingAreaSqm: 400, numberOfLevels: 5, ceilingHeightM: 4, totalGrowingPositions: 2000, currentActivePlants: 1500, powerCapacityKw: 100, waterStorageL: 5000, backupPowerHours: 8, certifications: ['gap', 'haccp'], buildingType: 'warehouse', insulation: 'high_efficiency', }, environmentalControl: { hvacUnits: [ { id: 'hvac1', type: 'heat_pump', capacityKw: 20, status: 'running' }, { id: 'hvac2', type: 'cooling', capacityKw: 15, status: 'running' }, ], co2Injection: { type: 'tank', capacityKg: 50, currentLevelKg: 35 }, }, lightingSystem: { type: 'LED', totalWattage: 50000, efficacyUmolJ: 2.8, }, automationLevel: 'SEMI_AUTOMATED', status: 'OPERATIONAL', operationalSince: new Date('2023-06-01'), capacityUtilization: 0.75, yieldEfficiency: 0.85, energyEfficiencyScore: 0.78, }, }); console.log('Created vertical farm'); // Create growing zones console.log('Creating growing zones...'); const zones = await Promise.all([ prisma.growingZone.create({ data: { name: 'Zone A - Leafy Greens', farmId: farm.id, level: 1, areaSqm: 80, lengthM: 10, widthM: 8, growingMethod: 'NFT', plantPositions: 400, currentCrop: 'Butterhead Lettuce', plantingDate: new Date('2024-05-01'), expectedHarvestDate: new Date('2024-05-28'), environmentTargets: { temperatureC: { min: 18, max: 24, target: 21 }, humidityPercent: { min: 60, max: 80, target: 70 }, co2Ppm: { min: 800, max: 1200, target: 1000 }, lightPpfd: { min: 200, max: 400, target: 300 }, lightHours: 16, }, currentEnvironment: { timestamp: new Date().toISOString(), temperatureC: 21.5, humidityPercent: 68, co2Ppm: 950, ppfd: 310, waterTempC: 20, ec: 1.4, ph: 6.2, }, status: 'GROWING', }, }), prisma.growingZone.create({ data: { name: 'Zone B - Herbs', farmId: farm.id, level: 2, areaSqm: 60, lengthM: 10, widthM: 6, growingMethod: 'DWC', plantPositions: 300, currentCrop: 'Sweet Basil', plantingDate: new Date('2024-05-10'), expectedHarvestDate: new Date('2024-06-10'), status: 'GROWING', }, }), prisma.growingZone.create({ data: { name: 'Zone C - Microgreens', farmId: farm.id, level: 3, areaSqm: 40, growingMethod: 'RACK_SYSTEM', plantPositions: 500, status: 'EMPTY', }, }), ]); console.log(`Created ${zones.length} growing zones`); // Create growing recipe console.log('Creating growing recipes...'); const recipe = await prisma.growingRecipe.create({ data: { name: 'Butterhead Lettuce - Fast Cycle', cropType: 'Lettuce', variety: 'Butterhead', version: '2.0', stages: [ { name: 'Germination', daysStart: 0, daysEnd: 3, temperature: { day: 20, night: 18 }, humidity: { day: 80, night: 85 }, lightHours: 18, lightPpfd: 150, }, { name: 'Seedling', daysStart: 4, daysEnd: 10, temperature: { day: 21, night: 18 }, humidity: { day: 70, night: 75 }, lightHours: 16, lightPpfd: 250, }, { name: 'Vegetative', daysStart: 11, daysEnd: 24, temperature: { day: 22, night: 18 }, humidity: { day: 65, night: 70 }, lightHours: 16, lightPpfd: 350, }, { name: 'Harvest', daysStart: 25, daysEnd: 28, temperature: { day: 18, night: 16 }, humidity: { day: 60, night: 65 }, lightHours: 12, lightPpfd: 300, }, ], expectedDays: 28, expectedYieldGrams: 150, expectedYieldPerSqm: 3.5, requirements: { positions: 1, zoneType: 'NFT', minimumPpfd: 200, idealTemperatureC: 20, }, source: 'INTERNAL', author: 'Bob Farmer', rating: 4.5, timesUsed: 15, }, }); console.log('Created growing recipe'); // Create crop batch console.log('Creating crop batches...'); const cropBatch = await prisma.cropBatch.create({ data: { farmId: farm.id, zoneId: zones[0].id, cropType: 'Butterhead Lettuce', variety: 'Bibb', recipeId: recipe.id, seedBatchId: seedBatches[1].id, plantCount: 400, plantingDate: new Date('2024-05-01'), expectedHarvestDate: new Date('2024-05-28'), expectedYieldKg: 60, currentStage: 'vegetative', currentDay: 18, healthScore: 92, status: 'GROWING', environmentLog: [ { timestamp: new Date('2024-05-15').toISOString(), readings: { temperatureC: 21, humidityPercent: 68, ppfd: 320 }, }, { timestamp: new Date('2024-05-18').toISOString(), readings: { temperatureC: 21.5, humidityPercent: 67, ppfd: 325 }, }, ], }, }); console.log('Created crop batch'); // Create transport events console.log('Creating transport events...'); const transportEvents = await Promise.all([ prisma.transportEvent.create({ data: { eventType: 'SEED_ACQUISITION', fromLatitude: 37.7849, fromLongitude: -122.4094, fromLocationType: 'SEED_BANK', fromFacilityName: 'Bay Area Seed Library', toLatitude: 37.7749, toLongitude: -122.4194, toLocationType: 'FARM', toFacilityName: 'Alice\'s Urban Farm', distanceKm: 1.2, durationMinutes: 15, transportMethod: 'BICYCLE', carbonFootprintKg: 0, senderId: users[2].id, receiverId: users[0].id, status: 'VERIFIED', notes: 'Picked up heirloom tomato seeds', eventData: { seedBatchId: seedBatches[0].id, quantity: 50, sourceType: 'seed_library', }, }, }), prisma.transportEvent.create({ data: { eventType: 'DISTRIBUTION', fromLatitude: 37.8044, fromLongitude: -122.2712, fromLocationType: 'VERTICAL_FARM', fromFacilityName: 'Oakland Urban Greens', toLatitude: 37.7849, toLongitude: -122.4094, toLocationType: 'MARKET', toFacilityName: 'Ferry Building Farmers Market', distanceKm: 8.5, durationMinutes: 25, transportMethod: 'ELECTRIC_TRUCK', carbonFootprintKg: 0.51, senderId: users[1].id, receiverId: users[3].id, status: 'DELIVERED', notes: 'Weekly lettuce delivery', eventData: { batchIds: [cropBatch.id], quantityKg: 45, destinationType: 'market', }, }, }), ]); console.log(`Created ${transportEvents.length} transport events`); // Create consumer preference console.log('Creating consumer preferences...'); await prisma.consumerPreference.create({ data: { consumerId: users[2].id, latitude: 37.7849, longitude: -122.4094, maxDeliveryRadiusKm: 15, city: 'San Francisco', region: 'Bay Area', dietaryType: ['vegetarian', 'flexitarian'], allergies: [], dislikes: ['cilantro'], preferredCategories: ['leafy_greens', 'herbs', 'microgreens'], preferredItems: [ { produceType: 'Lettuce', category: 'leafy_greens', priority: 'must_have' }, { produceType: 'Basil', category: 'herbs', priority: 'preferred' }, { produceType: 'Kale', category: 'leafy_greens', priority: 'nice_to_have' }, ], certificationPreferences: ['organic', 'local'], freshnessImportance: 5, priceImportance: 3, sustainabilityImportance: 5, deliveryPreferences: { method: ['farmers_market', 'home_delivery'], frequency: 'weekly', preferredDays: ['saturday', 'sunday'], }, householdSize: 2, weeklyBudget: 75, currency: 'USD', }, }); console.log('Created consumer preference'); // Create demand signal console.log('Creating demand signals...'); const demandSignal = await prisma.demandSignal.create({ data: { centerLat: 37.7849, centerLon: -122.4094, radiusKm: 20, regionName: 'San Francisco Bay Area', periodStart: new Date('2024-05-01'), periodEnd: new Date('2024-05-31'), seasonalPeriod: 'spring', demandItems: [ { produceType: 'Butterhead Lettuce', category: 'leafy_greens', weeklyDemandKg: 150, monthlyDemandKg: 600, consumerCount: 45, aggregatePriority: 8, urgency: 'this_week', inSeason: true, }, { produceType: 'Sweet Basil', category: 'herbs', weeklyDemandKg: 30, monthlyDemandKg: 120, consumerCount: 32, aggregatePriority: 7, urgency: 'this_week', inSeason: true, }, ], totalConsumers: 78, totalWeeklyDemandKg: 180, confidenceLevel: 85, currentSupplyKg: 120, supplyGapKg: 60, supplyStatus: 'SHORTAGE', }, }); console.log('Created demand signal'); // Create supply commitment console.log('Creating supply commitments...'); const supplyCommitment = await prisma.supplyCommitment.create({ data: { growerId: users[1].id, produceType: 'Butterhead Lettuce', variety: 'Bibb', committedQuantityKg: 60, availableFrom: new Date('2024-05-28'), availableUntil: new Date('2024-06-15'), pricePerKg: 8.5, currency: 'USD', minimumOrderKg: 2, bulkDiscountThreshold: 20, bulkDiscountPercent: 10, certifications: ['gap', 'local'], freshnessGuaranteeHours: 24, deliveryRadiusKm: 25, deliveryMethods: ['grower_delivery', 'customer_pickup'], status: 'AVAILABLE', remainingKg: 60, }, }); console.log('Created supply commitment'); // Create market match console.log('Creating market matches...'); await prisma.marketMatch.create({ data: { consumerId: users[2].id, growerId: users[1].id, demandSignalId: demandSignal.id, supplyCommitmentId: supplyCommitment.id, produceType: 'Butterhead Lettuce', matchedQuantityKg: 4, agreedPricePerKg: 8.5, totalPrice: 34, currency: 'USD', deliveryDate: new Date('2024-05-30'), deliveryMethod: 'farmers_market', deliveryLatitude: 37.7955, deliveryLongitude: -122.3937, deliveryAddress: 'Ferry Building, San Francisco', status: 'CONFIRMED', }, }); console.log('Created market match'); // Create seasonal plan console.log('Creating seasonal plans...'); await prisma.seasonalPlan.create({ data: { growerId: users[1].id, year: 2024, season: 'summer', location: { latitude: 37.8044, longitude: -122.2712, hardinessZone: '10a', }, growingCapacity: { verticalFarmSqMeters: 400, hydroponicUnits: 5, }, plannedCrops: [ { produceType: 'Butterhead Lettuce', plantingDate: '2024-06-01', quantity: 500, expectedYieldKg: 75, status: 'planned', }, { produceType: 'Sweet Basil', plantingDate: '2024-06-15', quantity: 300, expectedYieldKg: 15, status: 'planned', }, ], expectedTotalYieldKg: 90, expectedRevenue: 765, status: 'DRAFT', }, }); console.log('Created seasonal plan'); // Create audit logs console.log('Creating audit logs...'); await Promise.all([ prisma.auditLog.create({ data: { userId: users[0].id, action: 'CREATE', entityType: 'Plant', entityId: plants[0].id, newValue: { commonName: 'Cherry Tomato', status: 'SPROUTED' }, metadata: { source: 'web_app' }, }, }), prisma.auditLog.create({ data: { userId: users[1].id, action: 'CREATE', entityType: 'VerticalFarm', entityId: farm.id, newValue: { name: 'Oakland Urban Greens' }, metadata: { source: 'web_app' }, }, }), prisma.auditLog.create({ data: { userId: users[1].id, action: 'UPDATE', entityType: 'CropBatch', entityId: cropBatch.id, previousValue: { status: 'GERMINATING' }, newValue: { status: 'GROWING' }, metadata: { source: 'automated_agent' }, }, }), ]); console.log('Created audit logs'); // Create blockchain blocks console.log('Creating blockchain blocks...'); await Promise.all([ prisma.blockchainBlock.create({ data: { index: 0, timestamp: new Date('2024-01-01'), previousHash: '0', hash: '0000000000000000000000000000000000000000000000000000000000000000', nonce: 0, blockType: 'genesis', content: { message: 'LocalGreenChain Genesis Block' }, }, }), prisma.blockchainBlock.create({ data: { index: 1, timestamp: new Date('2024-03-15'), previousHash: '0000000000000000000000000000000000000000000000000000000000000000', hash: '1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890', nonce: 42, blockType: 'plant', plantId: plants[0].id, content: { plantId: plants[0].id, commonName: 'Cherry Tomato', action: 'REGISTERED', }, }, }), ]); console.log('Created blockchain blocks'); // Create resource usage records console.log('Creating resource usage records...'); await prisma.resourceUsage.create({ data: { farmId: farm.id, periodStart: new Date('2024-05-01'), periodEnd: new Date('2024-05-15'), electricityKwh: 1500, electricityCostUsd: 225, renewablePercent: 60, peakDemandKw: 45, waterUsageL: 3000, waterCostUsd: 15, waterRecycledPercent: 85, co2UsedKg: 20, co2CostUsd: 40, nutrientsUsedL: 50, nutrientCostUsd: 75, kwhPerKgProduce: 25, litersPerKgProduce: 50, costPerKgProduce: 5.92, }, }); console.log('Created resource usage records'); // Summary console.log('\n=== Seed Complete ==='); console.log(`Users: ${users.length}`); console.log(`Plants: ${plants.length + 1}`); console.log(`Seed Batches: ${seedBatches.length}`); console.log(`Vertical Farms: 1`); console.log(`Growing Zones: ${zones.length}`); console.log(`Growing Recipes: 1`); console.log(`Crop Batches: 1`); console.log(`Transport Events: ${transportEvents.length}`); console.log('\nDatabase seeded successfully!'); } main() .catch((e) => { console.error('Seed error:', e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });