diff --git a/seeder-api/src/index.js b/seeder-api/src/index.js index 4b137a0..700d4cb 100644 --- a/seeder-api/src/index.js +++ b/seeder-api/src/index.js @@ -9,6 +9,7 @@ import { seedFictionalCompanies } from './seeders/fictional-companies.js'; import { seedEpicCompanies } from './seeders/epic-companies.js'; import { seedNotifications } from './seeders/notifications.js'; import { seedTags } from './seeders/tags.js'; +import { seedTickets } from './seeders/tickets.js'; async function resetDatabase() { console.log('🗑️ Resetting database...'); @@ -88,6 +89,7 @@ async function seedDatabase() { await seedEpicCompanies(); // 🌟 BNL, Cyberdyne, Wonka, Wayne, Oceanic, InGen, Bubba Gump, Umbrella, Sprawl-Mart await seedApplications(); // 📝 Applications from candidates await seedNotifications(); // 🔔 Notifications for dashboard + await seedTickets(); // 🎫 Support tickets await seedTags(); // 🏷️ Job tags (area, level, stack) console.log('\n✅ Database seeding completed successfully!'); @@ -145,6 +147,7 @@ async function seedDatabaseLite() { await seedEpicCompanies(); await seedApplications(); await seedNotifications(); + await seedTickets(); await seedTags(); console.log('\n✅ Database seeding (LITE) completed successfully!'); diff --git a/seeder-api/src/seeders/acme.js b/seeder-api/src/seeders/acme.js index be56e48..cf59d59 100644 --- a/seeder-api/src/seeders/acme.js +++ b/seeder-api/src/seeders/acme.js @@ -1,5 +1,7 @@ import { pool } from '../db.js'; import crypto from 'crypto'; +import { seedTickets } from './tickets.js'; +import { seedApplications } from './applications.js'; /** * 🎯 ACME Corporation - Fornecedora Oficial do Coiote desde 1949 diff --git a/seeder-api/src/seeders/companies.js b/seeder-api/src/seeders/companies.js index d69cdda..a9844b7 100644 --- a/seeder-api/src/seeders/companies.js +++ b/seeder-api/src/seeders/companies.js @@ -58,18 +58,25 @@ export async function seedCompanies() { const countryResult = await pool.query("SELECT id FROM countries WHERE iso2 = 'BR'"); const brazilId = countryResult.rows[0]?.id || null; + const employeeCounts = ['1-10', '11-50', '51-200', '201-500', '501-1000', '1001+']; + try { for (let i = 0; i < companyData.length; i++) { const company = companyData[i]; const city = cities[i % cities.length]; const slug = generateSlug(company.name); + const employeeCount = employeeCounts[i % employeeCounts.length]; + const foundedYear = 1990 + (i % 34); // Random year between 1990 and 2024 await pool.query(` - INSERT INTO companies (name, slug, type, document, address, country_id, phone, email, website, description, verified, active) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + INSERT INTO companies (name, slug, type, document, address, country_id, phone, email, website, description, employee_count, founded_year, verified, active) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) ON CONFLICT (slug) DO UPDATE SET name = EXCLUDED.name, description = EXCLUDED.description, + employee_count = EXCLUDED.employee_count, + founded_year = EXCLUDED.founded_year, + website = EXCLUDED.website, verified = EXCLUDED.verified, active = EXCLUDED.active `, [ @@ -79,10 +86,12 @@ export async function seedCompanies() { generateCNPJ(i), city, brazilId, - `+55-11-${3000 + i}-${String(i).padStart(4, '0')}`, + `+55${11 + (i % 20)}9${String(i).padStart(4, '0')}1234`, // Randomized phone `careers@${slug}.com`, - `https://${slug}.com`, - JSON.stringify(company.desc), + `https://www.${slug}.com`, + JSON.stringify(company.desc), // Keeping as is, but maybe wrap in HTML p tag? No, existing code used this. + employeeCount, + foundedYear, true, true ]); diff --git a/seeder-api/src/seeders/tickets.js b/seeder-api/src/seeders/tickets.js new file mode 100644 index 0000000..271e377 --- /dev/null +++ b/seeder-api/src/seeders/tickets.js @@ -0,0 +1,102 @@ +import { pool } from '../db.js'; + +const ticketSubjects = [ + "Problema com o cadastro de vagas", + "Não consigo visualizar candidatos", + "Erro ao salvar perfil da empresa", + "Dúvida sobre planos de assinatura", + "Bug no upload de logo", + "Solicitação de reembolso", + "Denúncia de vaga falsa", + "Como alterar email da conta?", + "Integração com ATS não funciona", + "Sugestão de melhoria para o dashboard" +]; + +const messages = [ + "Olá, estou com dificuldades para realizar X ação.", + "Poderiam me ajudar? O sistema apresenta erro 500.", + "Gostaria de saber mais informações sobre isso.", + "Aguardo retorno urgente, obrigado.", + "A funcionalidade parou de funcionar de repente." +]; + +const adminReplies = [ + "Olá, já estamos verificando o seu caso.", + "Poderia fornecer mais detalhes?", + "O problema foi resolvido, por favor tente novamente.", + "Encaminhei para o time técnico.", + "Agradecemos o feedback." +]; + +export async function seedTickets() { + console.log('🎫 Seeding support tickets...'); + + try { + // Get all users + const usersRes = await pool.query('SELECT id FROM users'); + const users = usersRes.rows; + + if (users.length === 0) { + console.log(' ⚠️ No users found. Skipping tickets seeding.'); + return; + } + + // Get system admin user for replies + const adminRes = await pool.query("SELECT id FROM users WHERE role = 'admin' OR role = 'super_admin' LIMIT 1"); + const adminId = adminRes.rows[0]?.id || users[0].id; + + let ticketCount = 0; + + // Create 20 random tickets + for (let i = 0; i < 20; i++) { + const userId = users[Math.floor(Math.random() * users.length)].id; + const subject = ticketSubjects[Math.floor(Math.random() * ticketSubjects.length)]; + const status = ['open', 'in_progress', 'closed'][Math.floor(Math.random() * 3)]; + const priority = ['low', 'medium', 'high'][Math.floor(Math.random() * 3)]; + + // Create Ticket + const ticketRes = await pool.query(` + INSERT INTO tickets (user_id, subject, status, priority, created_at) + VALUES ($1, $2, $3, $4, NOW() - (random() * interval '30 days')) + RETURNING id, created_at + `, [userId, subject, status, priority]); + + const ticketId = ticketRes.rows[0].id; + const ticketCreatedAt = new Date(ticketRes.rows[0].created_at); + + // Create initial message from user + await pool.query(` + INSERT INTO ticket_messages (ticket_id, user_id, message, created_at) + VALUES ($1, $2, $3, $4) + `, [ + ticketId, + userId, + messages[Math.floor(Math.random() * messages.length)], + ticketCreatedAt + ]); + + // If not open, maybe add some replies + if (status !== 'open') { + // Admin reply + await pool.query(` + INSERT INTO ticket_messages (ticket_id, user_id, message, created_at) + VALUES ($1, $2, $3, $4) + `, [ + ticketId, + adminId, + adminReplies[Math.floor(Math.random() * adminReplies.length)], + new Date(ticketCreatedAt.getTime() + 3600000) // +1 hour + ]); + } + + ticketCount++; + } + + console.log(` ✓ ${ticketCount} tickets seeded`); + + } catch (error) { + console.error(' ❌ Error seeding tickets:', error.message); + throw error; + } +}