Agent 2 - Database Integration (P0 Critical): - Add Prisma ORM with PostgreSQL for persistent data storage - Create comprehensive database schema with 20+ models: - User & authentication models - Plant & lineage tracking - Transport events & supply chain - Vertical farming (farms, zones, batches, recipes) - Demand & market matching - Audit logging & blockchain storage - Implement complete database service layer (lib/db/): - users.ts: User CRUD with search and stats - plants.ts: Plant operations with lineage tracking - transport.ts: Transport events and carbon tracking - farms.ts: Vertical farm and crop batch management - demand.ts: Consumer preferences and market matching - audit.ts: Audit logging and blockchain integrity - Add PlantChainDB for database-backed blockchain - Create development seed script with sample data - Add database documentation (docs/DATABASE.md) - Update package.json with Prisma dependencies and scripts This provides the foundation for all other agents to build upon with persistent, scalable data storage.
835 lines
23 KiB
TypeScript
835 lines
23 KiB
TypeScript
/**
|
|
* 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();
|
|
});
|