Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
- Add mail/transfer/reshuffle/redistribute icons to each juror row in Members card - New redistributeJurorAssignments procedure: reassign all pending projects without dropping juror from group - New DROPOUT_REASSIGNED email template with project names, deadline, and dropped juror context - Update reassignDroppedJuror to send per-juror DROPOUT_REASSIGNED emails instead of generic BATCH_ASSIGNED - Transfer dialog now shows all candidates with "Already assigned" / "At cap" labels instead of hiding them - SQL script for prod DB insertion of new notification setting without seeding Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
275 lines
6.9 KiB
TypeScript
275 lines
6.9 KiB
TypeScript
/**
|
|
* Seed script for notification email settings
|
|
*
|
|
* Run with: npx tsx prisma/seed-notification-settings.ts
|
|
*/
|
|
|
|
import { PrismaClient } from '@prisma/client'
|
|
|
|
const prisma = new PrismaClient()
|
|
|
|
// Default notification email settings by category
|
|
const NOTIFICATION_EMAIL_SETTINGS = [
|
|
// Team / Applicant notifications
|
|
{
|
|
notificationType: 'APPLICATION_SUBMITTED',
|
|
category: 'team',
|
|
label: 'Application Submitted',
|
|
description: 'When a team submits their application',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'TEAM_INVITE_RECEIVED',
|
|
category: 'team',
|
|
label: 'Team Invitation Received',
|
|
description: 'When someone is invited to join a team',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'TEAM_MEMBER_JOINED',
|
|
category: 'team',
|
|
label: 'Team Member Joined',
|
|
description: 'When a new member joins the team',
|
|
sendEmail: false,
|
|
},
|
|
{
|
|
notificationType: 'ADVANCED_SEMIFINAL',
|
|
category: 'team',
|
|
label: 'Advanced to Semi-Finals',
|
|
description: 'When a project advances to semi-finals',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'ADVANCED_FINAL',
|
|
category: 'team',
|
|
label: 'Selected as Finalist',
|
|
description: 'When a project is selected as a finalist',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'MENTOR_ASSIGNED',
|
|
category: 'team',
|
|
label: 'Mentor Assigned',
|
|
description: 'When a mentor is assigned to the team',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'NOT_SELECTED',
|
|
category: 'team',
|
|
label: 'Not Selected',
|
|
description: 'When a project is not selected for the next round',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'FEEDBACK_AVAILABLE',
|
|
category: 'team',
|
|
label: 'Feedback Available',
|
|
description: 'When jury feedback becomes available',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'WINNER_ANNOUNCEMENT',
|
|
category: 'team',
|
|
label: 'Winner Announcement',
|
|
description: 'When a project wins an award',
|
|
sendEmail: true,
|
|
},
|
|
|
|
// Jury notifications
|
|
{
|
|
notificationType: 'ASSIGNED_TO_PROJECT',
|
|
category: 'jury',
|
|
label: 'Assigned to Project',
|
|
description: 'When a jury member is assigned to a project',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'BATCH_ASSIGNED',
|
|
category: 'jury',
|
|
label: 'Batch Assignment',
|
|
description: 'When multiple projects are assigned at once',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'COI_REASSIGNED',
|
|
category: 'jury',
|
|
label: 'COI Reassignment',
|
|
description: 'When a project is reassigned to you due to another juror\'s conflict of interest',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'MANUAL_REASSIGNED',
|
|
category: 'jury',
|
|
label: 'Manual Reassignment',
|
|
description: 'When an admin manually reassigns a project to you',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'DROPOUT_REASSIGNED',
|
|
category: 'jury',
|
|
label: 'Juror Dropout Reassignment',
|
|
description: 'When projects are reassigned to you because a juror dropped out or became unavailable',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'ROUND_NOW_OPEN',
|
|
category: 'jury',
|
|
label: 'Round Now Open',
|
|
description: 'When a round opens for evaluation',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'REMINDER_24H',
|
|
category: 'jury',
|
|
label: 'Reminder (24h)',
|
|
description: 'Reminder 24 hours before deadline',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'REMINDER_1H',
|
|
category: 'jury',
|
|
label: 'Reminder (1h)',
|
|
description: 'Urgent reminder 1 hour before deadline',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'ROUND_CLOSED',
|
|
category: 'jury',
|
|
label: 'Round Closed',
|
|
description: 'When a round closes',
|
|
sendEmail: false,
|
|
},
|
|
{
|
|
notificationType: 'AWARD_VOTING_OPEN',
|
|
category: 'jury',
|
|
label: 'Award Voting Open',
|
|
description: 'When special award voting opens',
|
|
sendEmail: true,
|
|
},
|
|
|
|
// Mentor notifications
|
|
{
|
|
notificationType: 'MENTEE_ASSIGNED',
|
|
category: 'mentor',
|
|
label: 'Mentee Assigned',
|
|
description: 'When assigned as mentor to a project',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'MENTEE_UPLOADED_DOCS',
|
|
category: 'mentor',
|
|
label: 'Mentee Documents Updated',
|
|
description: 'When a mentee uploads new documents',
|
|
sendEmail: false,
|
|
},
|
|
{
|
|
notificationType: 'MENTEE_ADVANCED',
|
|
category: 'mentor',
|
|
label: 'Mentee Advanced',
|
|
description: 'When a mentee advances to the next round',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'MENTEE_FINALIST',
|
|
category: 'mentor',
|
|
label: 'Mentee is Finalist',
|
|
description: 'When a mentee is selected as finalist',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'MENTEE_WON',
|
|
category: 'mentor',
|
|
label: 'Mentee Won',
|
|
description: 'When a mentee wins an award',
|
|
sendEmail: true,
|
|
},
|
|
|
|
// Observer notifications
|
|
{
|
|
notificationType: 'ROUND_STARTED',
|
|
category: 'observer',
|
|
label: 'Round Started',
|
|
description: 'When a new round begins',
|
|
sendEmail: false,
|
|
},
|
|
{
|
|
notificationType: 'ROUND_COMPLETED',
|
|
category: 'observer',
|
|
label: 'Round Completed',
|
|
description: 'When a round is completed',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'FINALISTS_ANNOUNCED',
|
|
category: 'observer',
|
|
label: 'Finalists Announced',
|
|
description: 'When finalists are announced',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'WINNERS_ANNOUNCED',
|
|
category: 'observer',
|
|
label: 'Winners Announced',
|
|
description: 'When winners are announced',
|
|
sendEmail: true,
|
|
},
|
|
|
|
// Admin notifications (in-app only by default)
|
|
{
|
|
notificationType: 'FILTERING_COMPLETE',
|
|
category: 'admin',
|
|
label: 'AI Filtering Complete',
|
|
description: 'When AI filtering job completes',
|
|
sendEmail: false,
|
|
},
|
|
{
|
|
notificationType: 'FILTERING_FAILED',
|
|
category: 'admin',
|
|
label: 'AI Filtering Failed',
|
|
description: 'When AI filtering job fails',
|
|
sendEmail: true,
|
|
},
|
|
{
|
|
notificationType: 'NEW_APPLICATION',
|
|
category: 'admin',
|
|
label: 'New Application',
|
|
description: 'When a new application is received',
|
|
sendEmail: false,
|
|
},
|
|
{
|
|
notificationType: 'SYSTEM_ERROR',
|
|
category: 'admin',
|
|
label: 'System Error',
|
|
description: 'When a system error occurs',
|
|
sendEmail: true,
|
|
},
|
|
]
|
|
|
|
async function main() {
|
|
console.log('Seeding notification email settings...')
|
|
|
|
for (const setting of NOTIFICATION_EMAIL_SETTINGS) {
|
|
await prisma.notificationEmailSetting.upsert({
|
|
where: { notificationType: setting.notificationType },
|
|
update: {
|
|
category: setting.category,
|
|
label: setting.label,
|
|
description: setting.description,
|
|
},
|
|
create: setting,
|
|
})
|
|
console.log(` - ${setting.label} (${setting.notificationType})`)
|
|
}
|
|
|
|
console.log(`\nSeeded ${NOTIFICATION_EMAIL_SETTINGS.length} notification email settings.`)
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e)
|
|
process.exit(1)
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect()
|
|
})
|