feat: ranking in-progress indicator persists across all admin users
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m1s
All checks were successful
Build and Push Docker Image / build (push) Successful in 10m1s
- Create snapshot with status RUNNING before AI call starts - Update to COMPLETED/FAILED when done - Dashboard derives rankingInProgress from server snapshot status - All admins see the spinner, not just the one who triggered it - Poll snapshots every 3s so progress updates appear quickly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -278,37 +278,55 @@ export const rankingRouter = router({
|
||||
})
|
||||
}
|
||||
|
||||
const result = await aiQuickRank(criteriaText, roundId, ctx.prisma, ctx.user.id)
|
||||
|
||||
// Embed weights alongside rules for audit
|
||||
const criteriaWeights = config.criteriaWeights ?? undefined
|
||||
const parsedRulesWithWeights = { rules: result.parsedRules, weights: criteriaWeights } as unknown as Prisma.InputJsonValue
|
||||
// Create a RUNNING snapshot so all admins see the in-progress indicator
|
||||
const snapshot = await ctx.prisma.rankingSnapshot.create({
|
||||
data: {
|
||||
roundId,
|
||||
triggeredById: ctx.user.id,
|
||||
triggerType: 'MANUAL',
|
||||
criteriaText,
|
||||
parsedRulesJson: parsedRulesWithWeights,
|
||||
startupRankingJson: result.startup.rankedProjects as unknown as Prisma.InputJsonValue,
|
||||
conceptRankingJson: result.concept.rankedProjects as unknown as Prisma.InputJsonValue,
|
||||
parsedRulesJson: {} as Prisma.InputJsonValue,
|
||||
mode: 'QUICK',
|
||||
status: 'COMPLETED',
|
||||
status: 'RUNNING',
|
||||
},
|
||||
})
|
||||
|
||||
await logAudit({
|
||||
prisma: ctx.prisma,
|
||||
userId: ctx.user.id,
|
||||
action: 'RANKING_MANUAL_TRIGGERED',
|
||||
entityType: 'RankingSnapshot',
|
||||
entityId: snapshot.id,
|
||||
detailsJson: { roundId },
|
||||
ipAddress: ctx.ip,
|
||||
userAgent: ctx.userAgent,
|
||||
})
|
||||
try {
|
||||
const result = await aiQuickRank(criteriaText, roundId, ctx.prisma, ctx.user.id)
|
||||
|
||||
return { snapshotId: snapshot.id, startup: result.startup, concept: result.concept }
|
||||
// Embed weights alongside rules for audit
|
||||
const criteriaWeights = config.criteriaWeights ?? undefined
|
||||
const parsedRulesWithWeights = { rules: result.parsedRules, weights: criteriaWeights } as unknown as Prisma.InputJsonValue
|
||||
await ctx.prisma.rankingSnapshot.update({
|
||||
where: { id: snapshot.id },
|
||||
data: {
|
||||
status: 'COMPLETED',
|
||||
parsedRulesJson: parsedRulesWithWeights,
|
||||
startupRankingJson: result.startup.rankedProjects as unknown as Prisma.InputJsonValue,
|
||||
conceptRankingJson: result.concept.rankedProjects as unknown as Prisma.InputJsonValue,
|
||||
},
|
||||
})
|
||||
|
||||
await logAudit({
|
||||
prisma: ctx.prisma,
|
||||
userId: ctx.user.id,
|
||||
action: 'RANKING_MANUAL_TRIGGERED',
|
||||
entityType: 'RankingSnapshot',
|
||||
entityId: snapshot.id,
|
||||
detailsJson: { roundId },
|
||||
ipAddress: ctx.ip,
|
||||
userAgent: ctx.userAgent,
|
||||
})
|
||||
|
||||
return { snapshotId: snapshot.id, startup: result.startup, concept: result.concept }
|
||||
} catch (err) {
|
||||
// Mark snapshot as FAILED so the indicator clears
|
||||
await ctx.prisma.rankingSnapshot.update({
|
||||
where: { id: snapshot.id },
|
||||
data: { status: 'FAILED' },
|
||||
})
|
||||
throw err
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user