Files
fosterflow/scripts/seed.ts
T
justinandClaude Sonnet 4.6 c6b7d4d4eb feat: add seed scripts and AI worker
Adds scripts/seed.ts for fresh self-hosted installs, scripts/seed-tenant.ts for cloud provisioner use, and scripts/ai-worker.ts adapted from AHCR with improved theme prompts, name filtering, and WORKER_API_KEY guard. Installs tsx as a dev dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 12:49:37 -05:00

64 lines
3.1 KiB
TypeScript

import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
import { hash } from '@node-rs/argon2';
import * as schema from '../src/lib/server/schema';
async function seed() {
const pool = mysql.createPool({ uri: process.env.DATABASE_URL });
const db = drizzle(pool, { schema, mode: 'default' });
console.log('Seeding FosterFlow database...');
// 1. Create admin user
const passwordHash = await hash('changeme');
await db.insert(schema.users).values({
email: 'admin@example.com',
passwordHash,
name: 'Admin',
role: 'sysadmin',
active: true,
mustChangePassword: true
});
console.log('Created admin user (admin@example.com / changeme)');
// 2. Default org config
const orgConfigDefaults = [
{ key: 'branding', value: { primaryColor: '#0d9488', primaryColorLight: '#14b8a6', primaryColorDark: '#0f766e', accentColor: '#f59e0b', accentColorLight: '#fbbf24', accentColorDark: '#d97706', logoUrl: '' } },
{ key: 'org_info', value: { name: 'My Rescue', tagline: '', city: '', state: '', phone: '', email: '', facebookUrl: '', instagramUrl: '' } },
{ key: 'locale', value: { language: 'en', currency: 'USD', dateFormat: 'MM/DD/YYYY' } },
{ key: 'applications', value: { adoptionEnabled: true, fosterEnabled: true, volunteerEnabled: true, surrenderEnabled: true, adoptionFee: 250 } },
{ key: 'setup_complete', value: false }
];
for (const row of orgConfigDefaults) {
await db.insert(schema.orgConfig).values({ key: row.key, value: row.value });
}
console.log('Created default org config');
// 3. Default intake sources
const intakeSources = ['Owner Surrender', 'Stray', 'Transfer', 'Born in Care', 'Other'];
for (const name of intakeSources) {
await db.insert(schema.intakeSources).values({ name });
}
console.log('Created default intake sources');
// 4. Default content blocks (placeholder)
const contentDefaults = [
{ page: 'home', sectionKey: 'hero', content: { title: 'Find Your Forever Friend', subtitle: 'We rescue, rehabilitate, and rehome animals in need.' } },
{ page: 'about', sectionKey: 'intro', content: { text: 'Welcome to our rescue! We are dedicated to saving animals in need.' } },
{ page: 'adoption-process', sectionKey: 'intro', content: { text: 'Our adoption process is designed to find the best match for both you and our animals.' } },
{ page: 'become-a-foster', sectionKey: 'intro', content: { text: 'Fostering saves lives! Learn how you can help by opening your home to an animal in need.' } },
{ page: 'how-to-help', sectionKey: 'intro', content: { text: 'There are many ways you can help our rescue mission.' } },
{ page: 'volunteer', sectionKey: 'intro', content: { text: 'Volunteers are the backbone of our organization.' } },
{ page: 'why-adopt', sectionKey: 'intro', content: { text: 'Adopting a pet changes two lives — yours and theirs.' } }
];
for (const block of contentDefaults) {
await db.insert(schema.contentBlocks).values(block);
}
console.log('Created default content blocks');
console.log('\nDone! Log in at /login with admin@example.com / changeme');
await pool.end();
}
seed().catch(console.error);