import { PrismaClient, UserRole } from '@prisma/client'; import bcrypt from 'bcryptjs'; const prisma = new PrismaClient(); async function main() { console.log('Seeding database...'); // Create default super admin const hashedPassword = await bcrypt.hash('changeme', 10); const admin = await prisma.user.upsert({ where: { email: 'admin@cmlite.org' }, update: {}, create: { email: 'admin@cmlite.org', password: hashedPassword, name: 'Admin', role: UserRole.SUPER_ADMIN, emailVerified: true, }, }); console.log(`Created admin user: ${admin.email}`); // Create default map settings await prisma.mapSettings.upsert({ where: { id: 'default' }, update: {}, create: { id: 'default', latitude: 53.5461, longitude: -113.4938, zoom: 11, walkSheetTitle: 'Walk Sheet', walkSheetSubtitle: '', walkSheetFooter: '', }, }); console.log('Created default map settings'); // Phase 3: v1 data migration will go here // - Export NocoDB data via API // - Import influence_users + login tables → unified users // - Deduplicate by email // - Hash plaintext passwords // - Import campaigns, locations, shifts, cuts, etc. // Create default page blocks for landing page builder const defaultBlocks = [ { id: 'default-hero', type: 'hero', label: 'Hero Section', category: 'Headers', sortOrder: 1, schema: { title: { type: 'string', label: 'Title' }, subtitle: { type: 'string', label: 'Subtitle' }, backgroundImage: { type: 'string', label: 'Background Image URL' }, ctaText: { type: 'string', label: 'Button Text' }, ctaUrl: { type: 'string', label: 'Button URL' }, }, defaults: { title: 'Welcome to Our Campaign', subtitle: 'Join us in making a difference in your community.', backgroundImage: '', ctaText: 'Get Involved', ctaUrl: '#', }, }, { id: 'default-text', type: 'text', label: 'Text Block', category: 'Content', sortOrder: 2, schema: { heading: { type: 'string', label: 'Heading' }, body: { type: 'text', label: 'Body Text' }, }, defaults: { heading: 'About Us', body: 'Tell your story here. Explain your mission, values, and what drives your campaign forward.', }, }, { id: 'default-features', type: 'features', label: 'Features Grid', category: 'Content', sortOrder: 3, schema: { features: { type: 'array', label: 'Features', items: { title: 'string', description: 'string', icon: 'string' } }, }, defaults: { features: [ { title: 'Community Action', description: 'Organize local events and initiatives.', icon: '' }, { title: 'Advocacy', description: 'Email your representatives directly.', icon: '' }, { title: 'Volunteer', description: 'Sign up for shifts and make a difference.', icon: '' }, ], }, }, { id: 'default-cta', type: 'cta', label: 'Call to Action', category: 'Actions', sortOrder: 4, schema: { heading: { type: 'string', label: 'Heading' }, description: { type: 'string', label: 'Description' }, buttonText: { type: 'string', label: 'Button Text' }, buttonUrl: { type: 'string', label: 'Button URL' }, }, defaults: { heading: 'Ready to Take Action?', description: 'Join thousands of community members making their voices heard.', buttonText: 'Join Now', buttonUrl: '#', }, }, { id: 'default-testimonials', type: 'testimonials', label: 'Testimonials', category: 'Content', sortOrder: 5, schema: { quotes: { type: 'array', label: 'Quotes', items: { text: 'string', author: 'string', role: 'string' } }, }, defaults: { quotes: [ { text: 'This platform made it so easy to contact my representatives.', author: 'Jane D.', role: 'Community Member' }, { text: 'I signed up for a volunteer shift and it changed my perspective.', author: 'Mark S.', role: 'Volunteer' }, ], }, }, { id: 'default-contact-form', type: 'contact-form', label: 'Contact Form', category: 'Actions', sortOrder: 6, schema: { heading: { type: 'string', label: 'Heading' }, fields: { type: 'array', label: 'Fields', items: { name: 'string', type: 'string', required: 'boolean' } }, }, defaults: { heading: 'Get in Touch', fields: [ { name: 'Name', type: 'text', required: true }, { name: 'Email', type: 'email', required: true }, { name: 'Message', type: 'textarea', required: true }, ], }, }, ]; for (const block of defaultBlocks) { await prisma.pageBlock.upsert({ where: { id: block.id }, update: {}, create: block, }); } console.log(`Created ${defaultBlocks.length} default page blocks`); console.log('Seed complete.'); } main() .catch((e) => { console.error('Seed error:', e); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });