gohorsejobs/seeder-api/src/seeders/users.js
2025-12-22 19:18:15 -03:00

227 lines
9.7 KiB
JavaScript

import bcrypt from 'bcrypt';
import crypto from 'crypto';
import { pool } from '../db.js';
export async function seedUsers() {
console.log('👤 Seeding users (Core Architecture)...');
try {
// Fetch core companies to map users
const companiesResult = await pool.query('SELECT id, name FROM core_companies');
const companyMap = {}; // name -> id
companiesResult.rows.forEach(c => companyMap[c.name] = c.id);
const systemTenantId = '00000000-0000-0000-0000-000000000000';
// 1. Create SuperAdmin (Requested: superadmin / Admin@2025!)
const superAdminPassword = await bcrypt.hash('Admin@2025!', 10);
const superAdminId = crypto.randomUUID();
// User requested identifier 'superadmin'
const superAdminIdentifier = 'superadmin';
const result = await pool.query(`
INSERT INTO core_users (id, tenant_id, name, email, password_hash, status)
VALUES ($1, $2, $3, $4, $5, 'ACTIVE')
ON CONFLICT (tenant_id, email) DO UPDATE SET password_hash = EXCLUDED.password_hash
RETURNING id
`, [superAdminId, systemTenantId, 'System Administrator', superAdminIdentifier, superAdminPassword]);
const actualSuperAdminId = result.rows[0].id;
// Role
await pool.query(`
INSERT INTO core_user_roles (user_id, role)
VALUES ($1, 'superadmin')
ON CONFLICT (user_id, role) DO NOTHING
`, [actualSuperAdminId]);
console.log(' ✓ SuperAdmin created (superadmin)');
// 2. Create Company Admins
const companyAdmins = [
// Requested: takeshi_yamamoto / Takeshi@2025 (Company Admin)
{ identifier: 'takeshi_yamamoto', fullName: 'Takeshi Yamamoto', company: 'TechCorp', email: 'takeshi_yamamoto', pass: 'Takeshi@2025', roles: ['admin', 'company'] },
{ identifier: 'kenji', fullName: 'Kenji Tanaka', company: 'AppMakers', email: 'kenji@appmakers.mobile', pass: 'Takeshi@2025', roles: ['admin', 'company'] },
// Requested: maria_santos / User@2025 (Recruiter) - Placing in DesignHub
{ identifier: 'maria_santos', fullName: 'Maria Santos', company: 'DesignHub', email: 'maria_santos', pass: 'User@2025', roles: ['recruiter', 'company'] }
];
for (const admin of companyAdmins) {
const hash = await bcrypt.hash(admin.pass, 10);
const userId = crypto.randomUUID();
const tenantId = companyMap[admin.company];
if (!tenantId) {
console.warn(`Original company ${admin.company} not found for user ${admin.fullName}, skipping.`);
continue;
}
const result = await pool.query(`
INSERT INTO core_users (id, tenant_id, name, email, password_hash, status)
VALUES ($1, $2, $3, $4, $5, 'ACTIVE')
ON CONFLICT (tenant_id, email) DO UPDATE SET password_hash = EXCLUDED.password_hash
RETURNING id
`, [userId, tenantId, admin.fullName, admin.email, hash]);
const actualUserId = result.rows[0].id;
for (const role of admin.roles) {
await pool.query(`
INSERT INTO core_user_roles (user_id, role)
VALUES ($1, $2)
ON CONFLICT (user_id, role) DO NOTHING
`, [actualUserId, role]);
}
console.log(` ✓ User created: ${admin.email}`);
}
// 3. Create Candidates (Job Seekers)
// Requested: paulo_santos / User@2025
const candidates = [
{ fullName: 'Paulo Santos', email: 'paulo_santos', pass: 'User@2025' },
{ fullName: 'Maria Reyes', email: 'maria@email.com', pass: 'User@2025' }
];
for (const cand of candidates) {
const hash = await bcrypt.hash(cand.pass, 10);
const userId = crypto.randomUUID();
const result = await pool.query(`
INSERT INTO core_users (id, tenant_id, name, email, password_hash, status)
VALUES ($1, $2, $3, $4, $5, 'ACTIVE')
ON CONFLICT (tenant_id, email) DO UPDATE SET password_hash = EXCLUDED.password_hash
RETURNING id
`, [userId, systemTenantId, cand.fullName, cand.email, hash]);
const actualUserId = result.rows[0].id;
await pool.query(`
INSERT INTO core_user_roles (user_id, role)
VALUES ($1, 'candidate')
ON CONFLICT (user_id, role) DO NOTHING
`, [actualUserId]);
console.log(` ✓ Candidate created: ${cand.email}`);
}
console.log('👤 Seeding legacy candidates...');
const legacyCandidates = [
{
identifier: 'ana_silva',
fullName: 'Ana Silva',
email: 'ana.silva@example.com',
phone: '+55 11 98765-4321',
city: 'São Paulo',
state: 'SP',
title: 'Full Stack Developer',
experience: '5 years of experience',
skills: ['React', 'Node.js', 'TypeScript', 'AWS', 'Docker'],
bio: 'Developer passionate about building innovative solutions. Experience in React, Node.js, and cloud computing.',
objective: 'Grow as a full stack developer building scalable products.'
},
{
identifier: 'carlos_santos',
fullName: 'Carlos Santos',
email: 'carlos.santos@example.com',
phone: '+55 11 91234-5678',
city: 'Rio de Janeiro',
state: 'RJ',
title: 'UX/UI Designer',
experience: '3 years of experience',
skills: ['Figma', 'Adobe XD', 'UI Design', 'Prototyping', 'Design Systems'],
bio: 'Designer focused on creating memorable experiences. Specialist in design systems and prototyping.',
objective: 'Design intuitive experiences for web and mobile products.'
},
{
identifier: 'maria_oliveira',
fullName: 'Maria Oliveira',
email: 'maria.oliveira@example.com',
phone: '+55 21 99876-5432',
city: 'Belo Horizonte',
state: 'MG',
title: 'Data Engineer',
experience: '7 years of experience',
skills: ['Python', 'SQL', 'Spark', 'Machine Learning', 'Data Visualization'],
bio: 'Data engineer with a strong background in machine learning and big data. Passionate about turning data into insights.',
objective: 'Build robust data pipelines and analytics products.'
},
{
identifier: 'pedro_costa',
fullName: 'Pedro Costa',
email: 'pedro.costa@example.com',
phone: '+55 31 98765-1234',
city: 'Curitiba',
state: 'PR',
title: 'Product Manager',
experience: '6 years of experience',
skills: ['Product Management', 'Agile', 'Scrum', 'Data Analysis', 'User Research'],
bio: 'Product Manager with experience in digital products and agile methodologies. Focused on delivering user value.',
objective: 'Lead cross-functional teams to deliver customer-centric products.'
},
{
identifier: 'juliana_ferreira',
fullName: 'Juliana Ferreira',
email: 'juliana.ferreira@example.com',
phone: '+55 41 91234-8765',
city: 'Porto Alegre',
state: 'RS',
title: 'DevOps Engineer',
experience: '4 years of experience',
skills: ['Docker', 'Kubernetes', 'AWS', 'Terraform', 'CI/CD'],
bio: 'DevOps engineer specialized in automation and cloud infrastructure. Experience with Kubernetes and CI/CD.',
objective: 'Improve delivery pipelines and cloud reliability.'
}
];
for (const cand of legacyCandidates) {
const hash = await bcrypt.hash('User@2025', 10);
await pool.query(`
INSERT INTO users (
identifier,
password_hash,
role,
full_name,
email,
phone,
city,
state,
title,
experience,
skills,
objective,
bio
) VALUES ($1, $2, 'jobSeeker', $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
ON CONFLICT (identifier) DO UPDATE SET
full_name = EXCLUDED.full_name,
email = EXCLUDED.email,
phone = EXCLUDED.phone,
city = EXCLUDED.city,
state = EXCLUDED.state,
title = EXCLUDED.title,
experience = EXCLUDED.experience,
skills = EXCLUDED.skills,
objective = EXCLUDED.objective,
bio = EXCLUDED.bio
`, [
cand.identifier,
hash,
cand.fullName,
cand.email,
cand.phone,
cand.city,
cand.state,
cand.title,
cand.experience,
cand.skills,
cand.objective,
cand.bio
]);
console.log(` ✓ Legacy candidate created: ${cand.email}`);
}
} catch (error) {
console.error(' ❌ Error seeding users:', error.message);
throw error;
}
}