Exclude SEPARATE_POOL award projects from main pool finalization
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m47s
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m47s
- finalizeResults now queries confirmed SEPARATE_POOL shortlist and excludes those projects from the main pool ELIGIBLE set - Finalize confirmation dialog shows breakdown: main pool vs award-routed - Finalize toast includes award-routed count - Audit log records routedToAwards count Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -250,6 +250,7 @@ export function FilteringDashboard({ competitionId, roundId }: FilteringDashboar
|
||||
utils.project.list.invalidate()
|
||||
toast.success(
|
||||
`Finalized: ${data.passed} passed, ${data.filteredOut} filtered out` +
|
||||
(data.routedToAwards > 0 ? `, ${data.routedToAwards} routed to award tracks` : '') +
|
||||
(data.advancedToStageName ? `. Next round: ${data.advancedToStageName}` : '')
|
||||
)
|
||||
if (data.categoryWarnings.length > 0) {
|
||||
@@ -483,7 +484,12 @@ export function FilteringDashboard({ competitionId, roundId }: FilteringDashboar
|
||||
This will mark PASSED projects as eligible and FILTERED_OUT projects as rejected.
|
||||
{stats && (
|
||||
<span className="block mt-2 font-medium">
|
||||
{stats.passed} will pass, {stats.filteredOut} will be filtered out, {stats.flagged} flagged for review.
|
||||
{stats.passed - (stats.routedToAwards || 0)} will pass to main pool, {stats.filteredOut} will be filtered out{stats.flagged > 0 ? `, ${stats.flagged} flagged for review` : ''}.
|
||||
{(stats.routedToAwards || 0) > 0 && (
|
||||
<span className="block text-amber-700">
|
||||
{stats.routedToAwards} already routed to award tracks (excluded from main pool).
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
This action can be reversed but requires manual intervention.
|
||||
|
||||
@@ -1153,6 +1153,19 @@ export const filteringRouter = router({
|
||||
|
||||
const passedIds = passedResults.map((r) => r.projectId)
|
||||
|
||||
// Exclude projects confirmed for SEPARATE_POOL award tracks from main pool
|
||||
const awardRouted = await ctx.prisma.awardEligibility.findMany({
|
||||
where: {
|
||||
projectId: { in: passedIds },
|
||||
shortlisted: true,
|
||||
confirmedAt: { not: null },
|
||||
award: { eligibilityMode: 'SEPARATE_POOL' },
|
||||
},
|
||||
select: { projectId: true },
|
||||
})
|
||||
const awardRoutedIds = new Set(awardRouted.map((a) => a.projectId))
|
||||
const mainPoolPassedIds = passedIds.filter((id) => !awardRoutedIds.has(id))
|
||||
|
||||
const operations: Prisma.PrismaPromise<unknown>[] = []
|
||||
|
||||
if (filteredOutIds.length > 0) {
|
||||
@@ -1164,10 +1177,10 @@ export const filteringRouter = router({
|
||||
)
|
||||
}
|
||||
|
||||
if (passedIds.length > 0) {
|
||||
if (mainPoolPassedIds.length > 0) {
|
||||
operations.push(
|
||||
ctx.prisma.project.updateMany({
|
||||
where: { id: { in: passedIds } },
|
||||
where: { id: { in: mainPoolPassedIds } },
|
||||
data: { status: 'ELIGIBLE' },
|
||||
})
|
||||
)
|
||||
@@ -1197,7 +1210,8 @@ export const filteringRouter = router({
|
||||
entityId: input.roundId,
|
||||
detailsJson: {
|
||||
action: 'FINALIZE_FILTERING',
|
||||
passed: passedIds.length,
|
||||
passed: mainPoolPassedIds.length,
|
||||
routedToAwards: awardRoutedIds.size,
|
||||
filteredOut: filteredOutIds.length,
|
||||
demotedToFlagged: demotedIds.length,
|
||||
categoryTargets: input.categoryTargets || null,
|
||||
@@ -1207,7 +1221,8 @@ export const filteringRouter = router({
|
||||
})
|
||||
|
||||
return {
|
||||
passed: passedIds.length,
|
||||
passed: mainPoolPassedIds.length,
|
||||
routedToAwards: awardRoutedIds.size,
|
||||
filteredOut: filteredOutIds.length,
|
||||
demotedToFlagged: demotedIds.length,
|
||||
categoryCounts,
|
||||
|
||||
Reference in New Issue
Block a user