feat: round finalization with ranking-based outcomes + award pool notifications
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m0s
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m0s
- processRoundClose EVALUATION uses ranking scores + advanceMode config (threshold vs count) to auto-set proposedOutcome instead of defaulting all to PASSED - Advancement emails generate invite tokens for passwordless users with "Create Your Account" CTA; rejection emails have no link - Finalization UI shows account stats (invite vs dashboard link counts) - Fixed getFinalizationSummary ranking query (was using non-existent rankingsJson) - New award pool notification system: getAwardSelectionNotificationTemplate email, notifyEligibleProjects mutation with invite token generation, "Notify Pool" button on award detail page with custom message dialog Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
25
src/server/utils/invite.ts
Normal file
25
src/server/utils/invite.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import crypto from 'crypto'
|
||||
import type { PrismaClient } from '@prisma/client'
|
||||
|
||||
const DEFAULT_INVITE_EXPIRY_HOURS = 72 // 3 days
|
||||
|
||||
export function generateInviteToken(): string {
|
||||
return crypto.randomBytes(32).toString('hex')
|
||||
}
|
||||
|
||||
export async function getInviteExpiryHours(prisma: PrismaClient): Promise<number> {
|
||||
try {
|
||||
const setting = await prisma.systemSettings.findUnique({
|
||||
where: { key: 'invite_link_expiry_hours' },
|
||||
select: { value: true },
|
||||
})
|
||||
const hours = setting?.value ? parseInt(setting.value, 10) : DEFAULT_INVITE_EXPIRY_HOURS
|
||||
return isNaN(hours) || hours < 1 ? DEFAULT_INVITE_EXPIRY_HOURS : hours
|
||||
} catch {
|
||||
return DEFAULT_INVITE_EXPIRY_HOURS
|
||||
}
|
||||
}
|
||||
|
||||
export async function getInviteExpiryMs(prisma: PrismaClient): Promise<number> {
|
||||
return (await getInviteExpiryHours(prisma)) * 60 * 60 * 1000
|
||||
}
|
||||
Reference in New Issue
Block a user