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:
@@ -90,7 +90,7 @@ const updateProjectSchema = z.object({
|
||||
'SEMIFINALIST',
|
||||
'FINALIST',
|
||||
'REJECTED',
|
||||
]),
|
||||
]).optional(),
|
||||
tags: z.array(z.string()),
|
||||
competitionCategory: z.string().optional(),
|
||||
oceanIssue: z.string().optional(),
|
||||
@@ -186,7 +186,7 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
title: '',
|
||||
teamName: '',
|
||||
description: '',
|
||||
status: 'SUBMITTED',
|
||||
status: undefined,
|
||||
tags: [],
|
||||
competitionCategory: '',
|
||||
oceanIssue: '',
|
||||
@@ -221,7 +221,7 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
const tags = form.watch('tags')
|
||||
const selectedStatus = form.watch('status')
|
||||
const previousStatus = (project?.status ?? 'SUBMITTED') as UpdateProjectForm['status']
|
||||
const statusTriggersNotifications = ['SEMIFINALIST', 'FINALIST', 'REJECTED'].includes(selectedStatus)
|
||||
const statusTriggersNotifications = !!selectedStatus && ['SEMIFINALIST', 'FINALIST', 'REJECTED'].includes(selectedStatus)
|
||||
const requiresStatusNotificationConfirmation = Boolean(
|
||||
project && selectedStatus !== previousStatus && statusTriggersNotifications
|
||||
)
|
||||
@@ -439,7 +439,7 @@ function EditProjectContent({ projectId }: { projectId: string }) {
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue />
|
||||
<SelectValue placeholder="Select status..." />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
|
||||
@@ -296,8 +296,8 @@ export default function ProjectsPage() {
|
||||
const [selectedProgramForTagging, setSelectedProgramForTagging] = useState<string>('')
|
||||
const [activeTaggingJobId, setActiveTaggingJobId] = useState<string | null>(null)
|
||||
|
||||
// Fetch programs and rounds for the AI tagging dialog
|
||||
const { data: programs } = trpc.program.list.useQuery()
|
||||
// Fetch programs and rounds for the AI tagging dialog + assign-to-round
|
||||
const { data: programs } = trpc.program.list.useQuery({ includeStages: true })
|
||||
|
||||
// Start tagging job mutation
|
||||
const startTaggingJob = trpc.tag.startTaggingJob.useMutation({
|
||||
|
||||
Reference in New Issue
Block a user