feat(seeder): 🏢 30 companies because startup dreams are free

This commit is contained in:
Tiago Yamamoto 2025-12-15 08:54:32 -03:00
parent 430e0f534d
commit 20e03fef81

View file

@ -1,137 +1,100 @@
import { pool } from '../db.js';
import crypto from 'crypto';
// 30 realistic tech company names
const companyData = [
{ name: 'TechCorp', desc: 'Enterprise software solutions' },
{ name: 'DesignHub', desc: 'UI/UX and branding agency' },
{ name: 'DataFlow', desc: 'Big data and analytics' },
{ name: 'InnovateLab', desc: 'Innovation and product development' },
{ name: 'AppMakers', desc: 'Mobile app development' },
{ name: 'CloudTech', desc: 'Cloud infrastructure and DevOps' },
{ name: 'CyberShield', desc: 'Cybersecurity solutions' },
{ name: 'PixelPerfect', desc: 'Digital design studio' },
{ name: 'CodeNinja', desc: 'Custom software development' },
{ name: 'AIVentures', desc: 'Artificial intelligence research' },
{ name: 'FinTechPro', desc: 'Financial technology solutions' },
{ name: 'HealthTech', desc: 'Healthcare technology' },
{ name: 'EduSmart', desc: 'Educational technology platform' },
{ name: 'GreenCode', desc: 'Sustainable tech solutions' },
{ name: 'RoboLogic', desc: 'Robotics and automation' },
{ name: 'BlockChainX', desc: 'Blockchain development' },
{ name: 'GameForge', desc: 'Game development studio' },
{ name: 'StreamLive', desc: 'Streaming technology' },
{ name: 'E-CommerceHub', desc: 'E-commerce solutions' },
{ name: 'LogiTech', desc: 'Logistics technology' },
{ name: 'SpaceTech', desc: 'Aerospace software' },
{ name: 'BioInformatics', desc: 'Bioinformatics and research' },
{ name: 'VRWorld', desc: 'Virtual reality experiences' },
{ name: 'IoTConnect', desc: 'Internet of Things solutions' },
{ name: 'QuantumBits', desc: 'Quantum computing research' },
{ name: 'AgriTech', desc: 'Agricultural technology' },
{ name: 'MediaForge', desc: 'Digital media production' },
{ name: 'TravelTech', desc: 'Travel technology platform' },
{ name: 'PropTech', desc: 'Real estate technology' },
{ name: 'SocialHub', desc: 'Social media technology' }
];
const cities = [
'São Paulo - SP', 'Rio de Janeiro - RJ', 'Belo Horizonte - MG',
'Curitiba - PR', 'Porto Alegre - RS', 'Brasília - DF',
'Salvador - BA', 'Recife - PE', 'Fortaleza - CE', 'Campinas - SP'
];
function generateSlug(name) {
return name.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-');
}
function generateCNPJ(index) {
const base = String(index + 10).padStart(2, '0');
return `${base}.${base}${base}.${base}${base}/0001-${base}`;
}
export async function seedCompanies() {
console.log('🏢 Seeding companies...');
console.log('🏢 Seeding 30 companies...');
// Get region IDs
const regions = await pool.query('SELECT id, code FROM regions');
const regMap = {};
regions.rows.forEach(r => regMap[r.code] = r.id);
// Fallback ID (Tokyo or first available)
const defaultRegionId = regMap['13'] || (regions.rows.length > 0 ? regions.rows[0].id : null);
const companies = [
{
name: 'TechCorp',
slug: 'techcorp',
type: 'company',
document: '12.345.678/0001-90',
address: 'Av. Paulista, 1000, São Paulo - SP',
regionId: regMap['SP'] || defaultRegionId,
phone: '+55-11-3000-0000',
email: 'contact@techcorp.com.br',
website: 'https://techcorp.com.br',
description: JSON.stringify('Leading software development company specializing in enterprise solutions.'),
verified: true
},
{
name: 'DesignHub',
slug: 'designhub',
type: 'company',
document: '98.765.432/0001-12',
address: 'Rua Augusta, 500, São Paulo - SP',
regionId: regMap['SP'] || defaultRegionId,
phone: '+55-11-3000-1111',
email: 'hello@designhub.studio',
website: 'https://designhub.studio',
description: JSON.stringify('Creative agency focused on UI/UX and branding.'),
verified: true
},
{
name: 'DataFlow',
slug: 'dataflow',
type: 'company',
document: '11.223.344/0001-56',
address: 'Av. Atlântica, 200, Rio de Janeiro - RJ',
regionId: regMap['RJ'] || defaultRegionId,
phone: '+55-21-2000-2222',
email: 'jobs@dataflow.io',
website: 'https://dataflow.io',
description: JSON.stringify('Big Data and Analytics solutions for modern businesses.'),
verified: true
},
{
name: 'InnovateLab',
slug: 'innovatelab',
type: 'company',
document: '55.667.788/0001-99',
address: 'Praça da Liberdade, 50, Belo Horizonte - MG',
regionId: regMap['MG'] || defaultRegionId,
phone: '+55-31-3000-3333',
email: 'careers@innovatelab.mg',
website: 'https://innovatelab.mg',
description: JSON.stringify('Innovation hub for product development and startups.'),
verified: true
},
{
name: 'AppMakers',
slug: 'appmakers',
type: 'company',
document: '33.445.566/0001-77',
address: 'Vila Madalena, São Paulo - SP',
regionId: regMap['SP'] || defaultRegionId,
phone: '+55-11-3000-4444',
email: 'dev@appmakers.mobile',
website: 'https://appmakers.mobile',
description: JSON.stringify('Mobile app development specialists.'),
verified: true
},
{
name: 'CloudTech',
slug: 'cloudtech',
type: 'company',
document: '77.889.900/0001-22',
address: 'Berrini, São Paulo - SP',
regionId: regMap['SP'] || defaultRegionId,
phone: '+55-11-3000-5555',
email: 'ops@cloudtech.infra',
website: 'https://cloudtech.infra',
description: JSON.stringify('Cloud infrastructure and DevOps consultancy.'),
verified: true
}
];
try {
for (const company of companies) {
for (let i = 0; i < companyData.length; i++) {
const company = companyData[i];
const city = cities[i % cities.length];
const slug = generateSlug(company.name);
await pool.query(`
INSERT INTO companies (name, slug, type, document, address, region_id, phone, email, website, description, verified, active)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
ON CONFLICT (slug) DO UPDATE SET
name = EXCLUDED.name,
type = EXCLUDED.type,
document = EXCLUDED.document,
address = EXCLUDED.address,
region_id = EXCLUDED.region_id,
phone = EXCLUDED.phone,
email = EXCLUDED.email,
website = EXCLUDED.website,
description = EXCLUDED.description,
verified = EXCLUDED.verified,
active = EXCLUDED.active
`, [
INSERT INTO companies (name, slug, type, document, address, region_id, phone, email, website, description, verified, active)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
ON CONFLICT (slug) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
verified = EXCLUDED.verified,
active = EXCLUDED.active
`, [
company.name,
company.slug,
company.type,
company.document,
company.address,
company.regionId,
company.phone,
company.email,
company.website,
company.description,
company.verified,
slug,
'company',
generateCNPJ(i),
city,
defaultRegionId,
`+55-11-${3000 + i}-${String(i).padStart(4, '0')}`,
`careers@${slug}.com`,
`https://${slug}.com`,
JSON.stringify(company.desc),
true,
true
]);
// Seed Core Company (One-to-one mapping for now)
// Seed Core Company (One-to-one mapping)
const coreId = crypto.randomUUID();
await pool.query(`
INSERT INTO core_companies (id, name, document, status)
VALUES ($1, $2, $3, 'ACTIVE')
ON CONFLICT (id) DO NOTHING -- UUID collision unlikely, but good practice
`, [coreId, company.name, company.document]);
ON CONFLICT (id) DO NOTHING
`, [coreId, company.name, generateCNPJ(i)]);
}
// Seed System Tenant for SuperAdmin
@ -141,9 +104,11 @@ export async function seedCompanies() {
ON CONFLICT (id) DO NOTHING
`);
console.log(`${companies.length} companies seeded (Legacy & Core)`);
console.log(`${companyData.length} companies seeded (Legacy & Core)`);
} catch (error) {
console.error(' ❌ Error seeding companies:', error.message);
throw error;
}
}
export { companyData };