import { PrismaClient } from '@prisma/client'; import bcrypt from 'bcryptjs'; const prisma = new PrismaClient(); async function main() { console.log('🦉 Seeding Owl Stream database...'); // Admin user const adminHash = await bcrypt.hash('admin1234', 12); const admin = await prisma.user.upsert({ where: { email: 'admin@owlwatch.org' }, update: {}, create: { email: 'admin@owlwatch.org', name: 'Admin User', role: 'admin', password_hash: adminHash }, }); // Volunteer user const volHash = await bcrypt.hash('volunteer1234', 12); const volunteer = await prisma.user.upsert({ where: { email: 'vol@owlwatch.org' }, update: {}, create: { email: 'vol@owlwatch.org', name: 'Jane Volunteer', role: 'volunteer', password_hash: volHash }, }); // Donor user const donorHash = await bcrypt.hash('donor1234', 12); await prisma.user.upsert({ where: { email: 'donor@example.com' }, update: {}, create: { email: 'donor@example.com', name: 'Bob Donor', role: 'donor', password_hash: donorHash }, }); // 10 Burrows (Cape Coral GPS coordinates) const burrowData = [ { gps_lat: 26.5629, gps_lng: -81.9495, location_description: 'Burnt Store Rd median' }, { gps_lat: 26.5814, gps_lng: -81.9631, location_description: 'Rotary Park entrance' }, { gps_lat: 26.5677, gps_lng: -81.9712, location_description: 'Veterans Pkwy near Agualinda' }, { gps_lat: 26.5532, gps_lng: -81.9589, location_description: 'Cape Coral Pkwy & Del Prado' }, { gps_lat: 26.5901, gps_lng: -81.9444, location_description: 'Four Mile Cove Ecological Preserve' }, { gps_lat: 26.5743, gps_lng: -81.9822, location_description: 'Yellow Fever Creek Greenway' }, { gps_lat: 26.5465, gps_lng: -81.9367, location_description: 'Cape Harbour Marina' }, { gps_lat: 26.6012, gps_lng: -81.9555, location_description: 'Matlacha Pass Aquatic Preserve edge' }, { gps_lat: 26.5788, gps_lng: -82.0011, location_description: 'Camelot Island access' }, { gps_lat: 26.5620, gps_lng: -81.9198, location_description: 'SE 46th Ln vacant lot' }, ]; for (const b of burrowData) { await prisma.burrow.create({ data: { ...b, status: 'active', assigned_volunteer_id: volunteer.id }, }); } // 3 Livestream Sources await prisma.livestreamSource.createMany({ data: [ { name: 'Rotary Park Cam A', stream_url: 'https://stream.owlwatch.org/live/rotary-a', camera_location: 'Rotary Park, Cape Coral FL', status: 'live', thumbnail_url: 'https://stream.owlwatch.org/thumbs/rotary-a.jpg', }, { name: 'Burnt Store Rd Nest', stream_url: 'https://stream.owlwatch.org/live/burnt-store', camera_location: 'Burnt Store Rd, Cape Coral FL', status: 'live', thumbnail_url: 'https://stream.owlwatch.org/thumbs/burnt-store.jpg', }, { name: 'Veterans Pkwy Cam', stream_url: 'https://stream.owlwatch.org/live/veterans', camera_location: 'Veterans Pkwy, Cape Coral FL', status: 'offline', thumbnail_url: 'https://stream.owlwatch.org/thumbs/veterans.jpg', }, ], skipDuplicates: true, }); // 5 Events const events = [ { title: 'Morning Burrow Count — Spring Survey', description: 'Volunteer survey of all known burrow sites. Meet at Rotary Park 7am.', date: new Date('2026-03-15T07:00:00'), location: 'Rotary Park, Cape Coral', max_attendees: 30, type: 'cleanup' as const, }, { title: 'Burrowing Owl Awareness Day', description: 'Educational fair at Cape Coral City Hall. Bring the family!', date: new Date('2026-03-22T10:00:00'), location: 'Cape Coral City Hall', max_attendees: 200, type: 'educational' as const, }, { title: 'Night Camera Installation', description: 'Volunteers needed to help install night vision cameras at high-activity burrow sites.', date: new Date('2026-04-05T17:30:00'), location: 'Veterans Pkwy Site, Cape Coral', max_attendees: 10, type: 'cleanup' as const, }, { title: 'Owl Fest Fundraiser Dinner', description: 'Annual fundraiser dinner. Tickets include 3-course dinner and owl cam raffle.', date: new Date('2026-04-19T18:00:00'), location: 'Cape Coral Yacht Club', max_attendees: 150, type: 'fundraiser' as const, }, { title: 'Habitat Restoration — Camelot Island', description: 'Remove invasive species around burrow zones. Gloves and tools provided.', date: new Date('2026-05-03T08:00:00'), location: 'Camelot Island, Cape Coral', max_attendees: 40, type: 'cleanup' as const, }, ]; for (const e of events) { await prisma.event.create({ data: e }); } // Sample wildlife sightings const sightings = [ { species: 'Burrowing Owl (Athene cunicularia)', gps_lat: 26.5629, gps_lng: -81.9495, description: 'Pair spotted at entrance burrow, chick visible', verified: true }, { species: 'Florida Sandhill Crane', gps_lat: 26.5814, gps_lng: -81.9631, description: 'Family of 3 near Rotary Park pond', verified: false }, { species: 'Osprey', gps_lat: 26.5901, gps_lng: -81.9444, description: 'Nesting on channel marker', verified: true }, { species: 'Burrowing Owl (Athene cunicularia)', gps_lat: 26.5788, gps_lng: -82.0011, description: 'Single owl standing guard at burrow', verified: true }, { species: 'Gopher Tortoise', gps_lat: 26.5532, gps_lng: -81.9589, description: 'Near burrow site 4, likely co-habiting', verified: false }, ]; for (const s of sightings) { await prisma.wildlifeSighting.create({ data: { ...s, reporter_id: volunteer.id }, }); } // Volunteer hours await prisma.volunteerHour.createMany({ data: [ { volunteer_id: volunteer.id, date: new Date('2026-02-10'), hours: 4, task_description: 'Morning burrow survey, Burnt Store Rd section', verified_by: admin.id }, { volunteer_id: volunteer.id, date: new Date('2026-02-15'), hours: 2.5, task_description: 'Camera check and data upload', verified_by: admin.id }, { volunteer_id: volunteer.id, date: new Date('2026-02-18'), hours: 6, task_description: 'Educational booth at Cape Coral Farmers Market' }, ], }); // Equipment items await prisma.equipmentItem.createMany({ data: [ { name: 'Nikon P950 Spotting Camera', description: '83x optical zoom for burrow photography', status: 'available' }, { name: 'Trail Camera x4 Pack', description: 'Browning night vision trail cams', status: 'checked_out', checked_out_by: volunteer.id, checked_out_at: new Date() }, { name: 'GPS Unit — Garmin eTrex 32x', description: 'For precise burrow coordinate logging', status: 'available' }, { name: 'Binoculars — Vortex Viper 10x42', description: 'Shared pair for volunteer surveys', status: 'available' }, { name: 'First Aid Kit (Field)', description: 'Standard field kit, check quarterly', status: 'available' }, ], }); // Sample donation await prisma.donation.create({ data: { amount: 250, campaign: 'land_preservation', stripe_payment_id: 'pi_seed_001' }, }); console.log('✅ Seeding complete!'); console.log(' Admin: admin@owlwatch.org / admin1234'); console.log(' Volunteer: vol@owlwatch.org / volunteer1234'); console.log(' Donor: donor@example.com / donor1234'); } main() .catch(console.error) .finally(() => prisma.$disconnect());