feat(final-docs): auto pre-deadline reminder cron

This commit is contained in:
Matt
2026-06-09 16:00:42 +02:00
parent 6e1dcc8cbf
commit e4f13aaed4
3 changed files with 96 additions and 0 deletions

View File

@@ -14,6 +14,7 @@ import {
import {
getFinalDocumentStatusForProject,
sendManualFinalDocReminders,
sendDueFinalDocReminders,
} from '@/server/services/final-documents'
import * as applicantRouter from '@/server/routers/applicant'
import * as finalistRouter from '@/server/routers/finalist'
@@ -167,6 +168,33 @@ describe('sendManualFinalDocReminders', () => {
})
})
describe('sendDueFinalDocReminders', () => {
const localPrograms: string[] = []
const localUsers: string[] = []
afterAll(async () => { for (const id of localPrograms) await cleanupTestData(id, localUsers) })
it('reminds once when within the window and stamps finalDocsReminderSentAt', async () => {
const program = await createTestProgram(); localPrograms.push(program.id)
const comp = await createTestCompetition(program.id, { status: 'ACTIVE' })
const round = await createTestRound(comp.id, {
roundType: 'LIVE_FINAL', status: 'ROUND_ACTIVE', sortOrder: 6,
windowCloseAt: new Date(Date.now() + 3_600_000), // 1h out → within 48h window
configJson: { finalDocsReminderHoursBeforeDeadline: 48 },
})
await prisma.fileRequirement.create({ data: { id: uid('req'), roundId: round.id, name: 'Executive Summary', acceptedMimeTypes: ['application/pdf'], isRequired: true, sortOrder: 1 } })
const project = await createTestProject(program.id)
await createTestProjectRoundState(project.id, round.id)
const lead = await createTestUser('APPLICANT'); localUsers.push(lead.id)
await prisma.teamMember.create({ data: { projectId: project.id, userId: lead.id, role: 'LEAD' } })
await prisma.finalistConfirmation.create({ data: { id: uid('fc'), projectId: project.id, status: 'CONFIRMED', category: 'STARTUP', deadline: new Date(Date.now() + 3_600_000), token: uid('tok') } })
const first = await sendDueFinalDocReminders(prisma)
expect(first.remindersSent).toBe(1)
const second = await sendDueFinalDocReminders(prisma)
expect(second.remindersSent).toBe(0) // idempotent: already stamped
})
})
describe('finalist.listReviewDocuments', () => {
const localPrograms: string[] = []
const localUsers: string[] = []