180 lines
4.9 KiB
TypeScript
180 lines
4.9 KiB
TypeScript
import { PrismaClient } from '@prisma/client'
|
|
import bcrypt from 'bcryptjs'
|
|
|
|
const prisma = new PrismaClient()
|
|
|
|
async function main() {
|
|
console.log('Setting up demo jury member...\n')
|
|
|
|
// Hash a password for the demo jury account
|
|
const password = 'JuryDemo2026!'
|
|
const passwordHash = await bcrypt.hash(password, 12)
|
|
|
|
// Create or update jury member
|
|
const juryUser = await prisma.user.upsert({
|
|
where: { email: 'jury.demo@monaco-opc.com' },
|
|
update: {
|
|
passwordHash,
|
|
mustSetPassword: false,
|
|
status: 'ACTIVE',
|
|
onboardingCompletedAt: new Date(),
|
|
},
|
|
create: {
|
|
email: 'jury.demo@monaco-opc.com',
|
|
name: 'Dr. Marie Laurent',
|
|
role: 'JURY_MEMBER',
|
|
status: 'ACTIVE',
|
|
passwordHash,
|
|
mustSetPassword: false,
|
|
passwordSetAt: new Date(),
|
|
onboardingCompletedAt: new Date(),
|
|
expertiseTags: ['Marine Biology', 'Ocean Conservation', 'Sustainable Innovation'],
|
|
notificationPreference: 'EMAIL',
|
|
},
|
|
})
|
|
|
|
console.log(`Jury user: ${juryUser.email} (${juryUser.id})`)
|
|
console.log(`Password: ${password}\n`)
|
|
|
|
// Find the round
|
|
const round = await prisma.round.findFirst({
|
|
where: { slug: 'mopc-2026-round-1' },
|
|
})
|
|
|
|
if (!round) {
|
|
console.error('Round not found! Run seed-candidatures first.')
|
|
process.exit(1)
|
|
}
|
|
|
|
console.log(`Round: ${round.name} (${round.id})`)
|
|
|
|
// Ensure voting window is open
|
|
const now = new Date()
|
|
const votingStart = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000) // 7 days ago
|
|
const votingEnd = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000) // 30 days from now
|
|
|
|
await prisma.round.update({
|
|
where: { id: round.id },
|
|
data: {
|
|
status: 'ACTIVE',
|
|
votingStartAt: votingStart,
|
|
votingEndAt: votingEnd,
|
|
},
|
|
})
|
|
|
|
console.log(`Voting window: ${votingStart.toISOString()} → ${votingEnd.toISOString()}\n`)
|
|
|
|
// Get some projects to assign
|
|
const projects = await prisma.project.findMany({
|
|
where: { roundId: round.id },
|
|
take: 8,
|
|
orderBy: { createdAt: 'desc' },
|
|
select: { id: true, title: true },
|
|
})
|
|
|
|
if (projects.length === 0) {
|
|
console.error('No projects found! Run seed-candidatures first.')
|
|
process.exit(1)
|
|
}
|
|
|
|
console.log(`Found ${projects.length} projects to assign\n`)
|
|
|
|
// Create assignments
|
|
let created = 0
|
|
let skipped = 0
|
|
|
|
for (const project of projects) {
|
|
try {
|
|
await prisma.assignment.upsert({
|
|
where: {
|
|
userId_projectId_roundId: {
|
|
userId: juryUser.id,
|
|
projectId: project.id,
|
|
roundId: round.id,
|
|
},
|
|
},
|
|
update: {},
|
|
create: {
|
|
userId: juryUser.id,
|
|
projectId: project.id,
|
|
roundId: round.id,
|
|
method: 'MANUAL',
|
|
isRequired: true,
|
|
},
|
|
})
|
|
console.log(` Assigned: ${project.title}`)
|
|
created++
|
|
} catch {
|
|
skipped++
|
|
}
|
|
}
|
|
|
|
// Ensure evaluation criteria exist for this round
|
|
const existingForm = await prisma.evaluationForm.findFirst({
|
|
where: { roundId: round.id },
|
|
})
|
|
|
|
if (!existingForm) {
|
|
await prisma.evaluationForm.create({
|
|
data: {
|
|
roundId: round.id,
|
|
isActive: true,
|
|
criteriaJson: [
|
|
{
|
|
id: 'innovation',
|
|
label: 'Innovation & Originality',
|
|
description: 'How innovative is the proposed solution? Does it bring a new approach to ocean conservation?',
|
|
scale: 10,
|
|
weight: 25,
|
|
required: true,
|
|
},
|
|
{
|
|
id: 'feasibility',
|
|
label: 'Technical Feasibility',
|
|
description: 'Is the solution technically viable? Can it be realistically implemented?',
|
|
scale: 10,
|
|
weight: 25,
|
|
required: true,
|
|
},
|
|
{
|
|
id: 'impact',
|
|
label: 'Environmental Impact',
|
|
description: 'What is the potential positive impact on ocean health and marine ecosystems?',
|
|
scale: 10,
|
|
weight: 30,
|
|
required: true,
|
|
},
|
|
{
|
|
id: 'team',
|
|
label: 'Team Capability',
|
|
description: 'Does the team have the skills, experience, and commitment to execute?',
|
|
scale: 10,
|
|
weight: 20,
|
|
required: true,
|
|
},
|
|
],
|
|
},
|
|
})
|
|
console.log('\nCreated evaluation form with 4 criteria')
|
|
} else {
|
|
console.log('\nEvaluation form already exists')
|
|
}
|
|
|
|
console.log('\n========================================')
|
|
console.log('Demo jury member setup complete!')
|
|
console.log(` Email: jury.demo@monaco-opc.com`)
|
|
console.log(` Password: ${password}`)
|
|
console.log(` Assignments: ${created} created, ${skipped} skipped`)
|
|
console.log(` Voting: OPEN (${round.name})`)
|
|
console.log('========================================\n')
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e)
|
|
process.exit(1)
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect()
|
|
})
|