JB/web/scripts/import-postgres-data.js

168 lines
4.5 KiB
JavaScript

/**
* 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());