/** * Seed NotificationLog with confirmed SMTP delivery data. * * Sources: * 1. 33 emails confirmed delivered in Poste.io SMTP logs (2026-03-04) * 2. Users with status ACTIVE who are LEADs on PASSED projects * (they clearly received and used their invite link) * * Usage: npx tsx scripts/seed-notification-log.ts * Add --dry-run to preview without making changes. */ import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() const dryRun = process.argv.includes('--dry-run') // Emails confirmed delivered via SMTP logs on 2026-03-04 const CONFIRMED_SMTP_EMAILS = new Set([ 'fbayong@balazstudio.com', 'gnoel@kilimora.africa', 'amal.chebbi@pigmentoco.com', 'nairita@yarsi.net', 'martin.itamalo@greenbrinetechnologies.com', 'petervegan1223@gmail.com', 'dmarinov@redget.io', 'adrien@seavium.com', 'l.buob@whisper-ef.com', 'silvia@omnivorus.com', 'marzettisebastian@gmail.com', 'fiona.mcomish@algae-scope.com', 'karimeguillen@rearvora.com', 'info@skywatt.tech', 'julia@nereia-coatings.com', 'info@janmaisenbacher.com', 'xbm_0201@qq.com', 'irinakharitonova0201@gmail.com', 'seablocksrecif@gmail.com', 'oscar@seafuser.com', 'charles.maher@blueshadow.dk', 'sabirabokhari@gmail.com', 'munayimbabura@gmail.com', 'amritha.ramadevu@edu.escp.eu', 'nele.jordan@myhsba.de', 'karl.mihhels@aalto.fi', 'christine.a.kurz@gmail.com', 'aki@corall.eco', 'topias.kilpinen@hotmail.fi', 'nina.riutta.camilla@gmail.com', 'sofie.boggiosella@my.jcu.edu.au', 'giambattistafigari@gmail.com', 'mussinig0@gmail.com', ]) const SENT_AT = new Date('2026-03-04T01:00:00Z') async function main() { console.log(dryRun ? '--- DRY RUN ---\n' : 'Seeding NotificationLog...\n') // Find LEAD team members on PASSED projects const passedLeads = await prisma.teamMember.findMany({ where: { role: 'LEAD', project: { projectRoundStates: { some: { state: 'PASSED' }, }, }, }, select: { userId: true, projectId: true, project: { select: { projectRoundStates: { where: { state: 'PASSED' }, select: { roundId: true }, take: 1, }, }, }, user: { select: { id: true, email: true, status: true, inviteToken: true, }, }, }, }) console.log(`Found ${passedLeads.length} LEAD team members on PASSED projects\n`) let created = 0 let skipped = 0 for (const lead of passedLeads) { const email = lead.user.email?.toLowerCase() if (!email) { skipped++ continue } // Check if a NotificationLog already exists for this project+email const existing = await prisma.notificationLog.findFirst({ where: { email, projectId: lead.projectId, type: 'ADVANCEMENT_NOTIFICATION', status: 'SENT', }, }) if (existing) { skipped++ continue } // Determine confidence of delivery const isConfirmedSMTP = CONFIRMED_SMTP_EMAILS.has(email) const isActive = lead.user.status === 'ACTIVE' const isInvited = lead.user.status === 'INVITED' && !!lead.user.inviteToken // Only seed for confirmed deliveries or active users if (!isConfirmedSMTP && !isActive && !isInvited) { console.log(` SKIP ${email} (status=${lead.user.status}, not in SMTP logs)`) skipped++ continue } const roundId = lead.project.projectRoundStates[0]?.roundId ?? null const label = isConfirmedSMTP ? 'SMTP-confirmed' : isActive ? 'user-active' : 'invite-sent' console.log(` ${dryRun ? 'WOULD CREATE' : 'CREATE'} ${email} [${label}] project=${lead.projectId}`) if (!dryRun) { await prisma.notificationLog.create({ data: { userId: lead.user.id, channel: 'EMAIL', type: 'ADVANCEMENT_NOTIFICATION', status: 'SENT', email, projectId: lead.projectId, roundId, batchId: 'seed-2026-03-04', createdAt: SENT_AT, }, }) created++ } else { created++ } } console.log(`\nDone. Created: ${created}, Skipped: ${skipped}`) } main() .catch((err) => { console.error('Error:', err) process.exit(1) }) .finally(() => prisma.$disconnect())