/** * Migration Runner: Restores sqlite-export.json into target PostgreSQL instance * Usage: DATABASE_URL="postgresql://user:password@host:5432/jobsboard" node scripts/import-postgres-data.js */ const { PrismaClient } = require("@prisma/client"); const fs = require("fs"); const path = require("path"); const prisma = new PrismaClient(); async function importData() { const exportFile = path.join(__dirname, "sqlite-export.json"); if (!fs.existsSync(exportFile)) { console.error("Export file not found: sqlite-export.json. Run export-sqlite-data.js first."); process.exit(1); } const data = JSON.parse(fs.readFileSync(exportFile, "utf-8")); console.log("Starting import into target database..."); // 1. Companies console.log(`Importing ${data.companies.length} companies...`); for (const c of data.companies) { await prisma.company.upsert({ where: { id: c.id }, update: {}, create: { id: c.id, name: c.name, logoUrl: c.logoUrl, website: c.website, cultureInfo: c.cultureInfo, location: c.location, description: c.description, createdAt: new Date(c.createdAt), updatedAt: new Date(c.updatedAt), }, }); } // 2. Users console.log(`Importing ${data.users.length} users...`); for (const u of data.users) { await prisma.user.upsert({ where: { id: u.id }, update: {}, create: { id: u.id, email: u.email, passwordHash: u.passwordHash, name: u.name, role: u.role, companyId: u.companyId, failedLoginAttempts: u.failedLoginAttempts || 0, lockedUntil: u.lockedUntil ? new Date(u.lockedUntil) : null, createdAt: new Date(u.createdAt), updatedAt: new Date(u.updatedAt), }, }); } // 3. User Profiles & Children console.log(`Importing profiles and skills...`); for (const p of data.userProfiles) { await prisma.userProfile.upsert({ where: { id: p.id }, update: {}, create: { id: p.id, userId: p.userId, headline: p.headline, bio: p.bio, phone: p.phone, location: p.location, isPublic: p.isPublic, searchableToEmployers: p.searchableToEmployers, createdAt: new Date(p.createdAt), updatedAt: new Date(p.updatedAt), }, }); } for (const s of data.candidateSkills) { await prisma.candidateSkill.upsert({ where: { id: s.id }, update: {}, create: { id: s.id, profileId: s.profileId, name: s.name, level: s.level, }, }); } // 4. Resumes console.log(`Importing ${data.resumes.length} resumes...`); for (const r of data.resumes) { await prisma.resume.upsert({ where: { id: r.id }, update: {}, create: { id: r.id, userId: r.userId, title: r.title, data: r.data, isActiveForMatching: r.isActiveForMatching, createdAt: new Date(r.createdAt), updatedAt: new Date(r.updatedAt), }, }); } // 5. Jobs console.log(`Importing ${data.jobs.length} jobs...`); for (const j of data.jobs) { await prisma.job.upsert({ where: { id: j.id }, update: {}, create: { id: j.id, jobUrlHash: j.jobUrlHash, title: j.title, company: j.company, location: j.location, isRemote: j.isRemote, department: j.department, experienceLevel: j.experienceLevel, description: j.description, salaryMin: j.salaryMin, salaryMax: j.salaryMax, jobUrl: j.jobUrl, source: j.source, datePosted: j.datePosted ? new Date(j.datePosted) : null, companyId: j.companyId, postedById: j.postedById, createdAt: new Date(j.createdAt), updatedAt: new Date(j.updatedAt), }, }); } // 6. Applications console.log(`Importing ${data.applications.length} applications...`); for (const a of data.applications) { await prisma.application.upsert({ where: { id: a.id }, update: {}, create: { id: a.id, jobId: a.jobId, applicantId: a.applicantId, status: a.status, coverLetter: a.coverLetter, snapshotJson: a.snapshotJson, employerNotes: a.employerNotes, createdAt: new Date(a.createdAt), updatedAt: new Date(a.updatedAt), }, }); } console.log("Migration complete!"); } importData() .catch(console.error) .finally(() => prisma.$disconnect());