135 lines
4.2 KiB
JavaScript
135 lines
4.2 KiB
JavaScript
import { pool } from '../db.js';
|
|
import { uuidv7 } from '../utils/uuid.js';
|
|
|
|
/**
|
|
* 🔔 Notifications Seeder
|
|
*
|
|
* Creates realistic notifications like:
|
|
* - New application received
|
|
* - Candidate accepted interview
|
|
* - High-demand role alerts
|
|
* - Job views milestones
|
|
*/
|
|
|
|
const notificationTemplates = [
|
|
{
|
|
title: 'New application received',
|
|
message: 'Ana Silva applied for the Senior Full Stack Developer role',
|
|
type: 'application',
|
|
is_read: false,
|
|
},
|
|
{
|
|
title: 'Candidate accepted interview',
|
|
message: 'Carlos Santos confirmed attendance for tomorrow at 2 PM',
|
|
type: 'interview',
|
|
is_read: false,
|
|
},
|
|
{
|
|
title: 'High-demand role',
|
|
message: 'The UX/UI Designer role received 15 new applications today',
|
|
type: 'alert',
|
|
is_read: false,
|
|
},
|
|
{
|
|
title: 'Job views milestone',
|
|
message: 'Your Senior Developer posting reached 500 views!',
|
|
type: 'milestone',
|
|
is_read: true,
|
|
},
|
|
{
|
|
title: 'New application received',
|
|
message: 'Maria Oliveira applied for the Product Manager role',
|
|
type: 'application',
|
|
is_read: false,
|
|
},
|
|
{
|
|
title: 'Candidate message',
|
|
message: 'Pedro Costa sent a message about the Backend Developer position',
|
|
type: 'message',
|
|
is_read: true,
|
|
},
|
|
{
|
|
title: 'Interview reminder',
|
|
message: 'You have an interview with Juliana Ferreira in 1 hour',
|
|
type: 'reminder',
|
|
is_read: false,
|
|
},
|
|
{
|
|
title: 'Application deadline',
|
|
message: 'Your DevOps Engineer posting closes in 3 days. 45 applications received.',
|
|
type: 'deadline',
|
|
is_read: true,
|
|
},
|
|
{
|
|
title: 'Candidate withdrew',
|
|
message: 'A candidate withdrew their application for Full Stack Developer',
|
|
type: 'withdrawal',
|
|
is_read: true,
|
|
},
|
|
{
|
|
title: 'Weekly report ready',
|
|
message: 'Your job performance report for this week is ready to view',
|
|
type: 'report',
|
|
is_read: false,
|
|
},
|
|
];
|
|
|
|
export async function seedNotifications() {
|
|
console.log('🔔 Seeding notifications...');
|
|
|
|
try {
|
|
// Get users from users
|
|
const usersRes = await pool.query('SELECT id FROM users LIMIT 5');
|
|
const users = usersRes.rows;
|
|
|
|
if (users.length === 0) {
|
|
console.log(' ⚠️ No users found, skipping notifications');
|
|
return;
|
|
}
|
|
|
|
let totalNotifs = 0;
|
|
|
|
// Create notifications for each user
|
|
for (let u = 0; u < Math.min(3, users.length); u++) {
|
|
const userId = users[u].id;
|
|
|
|
// Give each user 5-10 notifications
|
|
const numNotifs = 5 + (u * 2);
|
|
|
|
for (let i = 0; i < numNotifs && i < notificationTemplates.length; i++) {
|
|
const template = notificationTemplates[i % notificationTemplates.length];
|
|
const notifId = uuidv7();
|
|
|
|
// Random time in the past 30 days
|
|
const daysAgo = Math.floor(Math.random() * 30);
|
|
const hoursAgo = Math.floor(Math.random() * 24);
|
|
const createdAt = new Date();
|
|
createdAt.setDate(createdAt.getDate() - daysAgo);
|
|
createdAt.setHours(createdAt.getHours() - hoursAgo);
|
|
|
|
await pool.query(`
|
|
INSERT INTO notifications (id, user_id, title, message, type, read_at, created_at, updated_at)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
ON CONFLICT (id) DO NOTHING
|
|
`, [
|
|
notifId,
|
|
userId,
|
|
template.title,
|
|
template.message,
|
|
template.type,
|
|
template.is_read ? new Date() : null,
|
|
createdAt,
|
|
createdAt
|
|
]);
|
|
|
|
totalNotifs++;
|
|
}
|
|
}
|
|
|
|
console.log(` ✓ ${totalNotifs} notifications criadas`);
|
|
console.log(` 📬 Tipos: application, interview, alert, milestone, message, reminder`);
|
|
} catch (error) {
|
|
console.error(' ❌ Error seeding notifications:', error.message);
|
|
throw error;
|
|
}
|
|
}
|