Add NotificationLog schema extensions (nullable userId, email, roundId, projectId, batchId fields), batch notification sender service, and bulk notification dialog UI. Include utility scripts for debugging and seeding. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
79 lines
1.9 KiB
TypeScript
79 lines
1.9 KiB
TypeScript
/**
|
|
* Backfill TeamMember records for all projects that have a submittedByUserId
|
|
* but no corresponding TeamMember link.
|
|
*
|
|
* Usage: npx tsx scripts/backfill-team-leads.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')
|
|
|
|
async function main() {
|
|
console.log(dryRun ? '🔍 DRY RUN — no changes will be made\n' : '🚀 Backfilling team leads...\n')
|
|
|
|
// Find all projects with a submitter but no TeamMember link for that user
|
|
const projects = await prisma.project.findMany({
|
|
where: {
|
|
submittedByUserId: { not: null },
|
|
},
|
|
select: {
|
|
id: true,
|
|
title: true,
|
|
submittedByUserId: true,
|
|
teamMembers: {
|
|
select: { userId: true },
|
|
},
|
|
},
|
|
})
|
|
|
|
let created = 0
|
|
let alreadyLinked = 0
|
|
let noSubmitter = 0
|
|
|
|
for (const project of projects) {
|
|
if (!project.submittedByUserId) {
|
|
noSubmitter++
|
|
continue
|
|
}
|
|
|
|
const alreadyHasLink = project.teamMembers.some(
|
|
(tm) => tm.userId === project.submittedByUserId
|
|
)
|
|
|
|
if (alreadyHasLink) {
|
|
alreadyLinked++
|
|
continue
|
|
}
|
|
|
|
console.log(` + Linking "${project.title}" → user ${project.submittedByUserId}`)
|
|
|
|
if (!dryRun) {
|
|
await prisma.teamMember.create({
|
|
data: {
|
|
projectId: project.id,
|
|
userId: project.submittedByUserId,
|
|
role: 'LEAD',
|
|
},
|
|
})
|
|
}
|
|
|
|
created++
|
|
}
|
|
|
|
console.log(`\n✅ Done!`)
|
|
console.log(` ${created} TeamMember records ${dryRun ? 'would be' : ''} created`)
|
|
console.log(` ${alreadyLinked} projects already had the submitter linked`)
|
|
console.log(` ${noSubmitter} projects had no submitter`)
|
|
console.log(` ${projects.length} total projects checked`)
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error('❌ Error:', e)
|
|
process.exit(1)
|
|
})
|
|
.finally(() => prisma.$disconnect())
|