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()
|
utils.project.list.invalidate()
|
||||||
toast.success(
|
toast.success(
|
||||||
`Finalized: ${data.passed} passed, ${data.filteredOut} filtered out` +
|
`Finalized: ${data.passed} passed, ${data.filteredOut} filtered out` +
|
||||||
|
(data.routedToAwards > 0 ? `, ${data.routedToAwards} routed to award tracks` : '') +
|
||||||
(data.advancedToStageName ? `. Next round: ${data.advancedToStageName}` : '')
|
(data.advancedToStageName ? `. Next round: ${data.advancedToStageName}` : '')
|
||||||
)
|
)
|
||||||
if (data.categoryWarnings.length > 0) {
|
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.
|
This will mark PASSED projects as eligible and FILTERED_OUT projects as rejected.
|
||||||
{stats && (
|
{stats && (
|
||||||
<span className="block mt-2 font-medium">
|
<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>
|
</span>
|
||||||
)}
|
)}
|
||||||
This action can be reversed but requires manual intervention.
|
This action can be reversed but requires manual intervention.
|
||||||
|
|||||||
@@ -1153,6 +1153,19 @@ export const filteringRouter = router({
|
|||||||
|
|
||||||
const passedIds = passedResults.map((r) => r.projectId)
|
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>[] = []
|
const operations: Prisma.PrismaPromise<unknown>[] = []
|
||||||
|
|
||||||
if (filteredOutIds.length > 0) {
|
if (filteredOutIds.length > 0) {
|
||||||
@@ -1164,10 +1177,10 @@ export const filteringRouter = router({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passedIds.length > 0) {
|
if (mainPoolPassedIds.length > 0) {
|
||||||
operations.push(
|
operations.push(
|
||||||
ctx.prisma.project.updateMany({
|
ctx.prisma.project.updateMany({
|
||||||
where: { id: { in: passedIds } },
|
where: { id: { in: mainPoolPassedIds } },
|
||||||
data: { status: 'ELIGIBLE' },
|
data: { status: 'ELIGIBLE' },
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -1197,7 +1210,8 @@ export const filteringRouter = router({
|
|||||||
entityId: input.roundId,
|
entityId: input.roundId,
|
||||||
detailsJson: {
|
detailsJson: {
|
||||||
action: 'FINALIZE_FILTERING',
|
action: 'FINALIZE_FILTERING',
|
||||||
passed: passedIds.length,
|
passed: mainPoolPassedIds.length,
|
||||||
|
routedToAwards: awardRoutedIds.size,
|
||||||
filteredOut: filteredOutIds.length,
|
filteredOut: filteredOutIds.length,
|
||||||
demotedToFlagged: demotedIds.length,
|
demotedToFlagged: demotedIds.length,
|
||||||
categoryTargets: input.categoryTargets || null,
|
categoryTargets: input.categoryTargets || null,
|
||||||
@@ -1207,7 +1221,8 @@ export const filteringRouter = router({
|
|||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
passed: passedIds.length,
|
passed: mainPoolPassedIds.length,
|
||||||
|
routedToAwards: awardRoutedIds.size,
|
||||||
filteredOut: filteredOutIds.length,
|
filteredOut: filteredOutIds.length,
|
||||||
demotedToFlagged: demotedIds.length,
|
demotedToFlagged: demotedIds.length,
|
||||||
categoryCounts,
|
categoryCounts,
|
||||||
|
|||||||
Reference in New Issue
Block a user