Add multiple admin improvements and bug fixes

- Email settings: Add separate sender display name field
- Rounds page: Drag-and-drop reordering with visible order numbers
- Round creation: Auto-assign projects to filtering rounds, auto-activate if voting started
- Round detail: Fix incorrect "voting period ended" message for draft rounds
- Projects page: Add delete option with confirmation dialog
- AI filtering: Add configurable batch size and parallel request settings
- Filtering results: Fix duplicate criteria display
- Add seed scripts for notification settings and MOPC onboarding form

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 23:19:45 +01:00
parent 1d137ce93e
commit 3be6a743ed
12 changed files with 895 additions and 192 deletions

View File

@@ -94,14 +94,39 @@ export const roundRouter = router({
}
const { settingsJson, sortOrder: _so, ...rest } = input
// Auto-activate if voting start date is in the past
const now = new Date()
const shouldAutoActivate = input.votingStartAt && input.votingStartAt <= now
const round = await ctx.prisma.round.create({
data: {
...rest,
sortOrder,
status: shouldAutoActivate ? 'ACTIVE' : 'DRAFT',
settingsJson: settingsJson as Prisma.InputJsonValue ?? undefined,
},
})
// For FILTERING rounds, automatically add all projects from the program
if (input.roundType === 'FILTERING') {
const projects = await ctx.prisma.project.findMany({
where: { programId: input.programId },
select: { id: true },
})
if (projects.length > 0) {
await ctx.prisma.roundProject.createMany({
data: projects.map((p) => ({
roundId: round.id,
projectId: p.id,
status: 'SUBMITTED',
})),
skipDuplicates: true,
})
}
}
// Audit log
await ctx.prisma.auditLog.create({
data: {
@@ -148,10 +173,24 @@ export const roundRouter = router({
}
}
// Check if we should auto-activate (if voting start is in the past and round is DRAFT)
const now = new Date()
let autoActivate = false
if (data.votingStartAt && data.votingStartAt <= now) {
const existingRound = await ctx.prisma.round.findUnique({
where: { id },
select: { status: true },
})
if (existingRound?.status === 'DRAFT') {
autoActivate = true
}
}
const round = await ctx.prisma.round.update({
where: { id },
data: {
...data,
...(autoActivate && { status: 'ACTIVE' }),
settingsJson: settingsJson as Prisma.InputJsonValue ?? undefined,
},
})