Improve AI filtering error handling and visibility
- Add listAvailableModels() and validateModel() to openai.ts - Improve testOpenAIConnection() to test configured model - Add checkAIStatus endpoint to filtering router - Add pre-execution AI config check in executeRules - Improve error messages in AI filtering service (rate limit, quota, etc.) - Add AI status warning banner on round detail page for filtering rounds Now admins get clear errors when AI is misconfigured instead of silent flags. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,48 @@ import { Prisma } from '@prisma/client'
|
||||
import { router, adminProcedure, protectedProcedure } from '../trpc'
|
||||
import { executeFilteringRules } from '../services/ai-filtering'
|
||||
import { logAudit } from '../utils/audit'
|
||||
import { isOpenAIConfigured, testOpenAIConnection } from '@/lib/openai'
|
||||
|
||||
export const filteringRouter = router({
|
||||
/**
|
||||
* Check if AI is configured and ready for filtering
|
||||
*/
|
||||
checkAIStatus: protectedProcedure
|
||||
.input(z.object({ roundId: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
// Check if round has AI rules
|
||||
const aiRules = await ctx.prisma.filteringRule.count({
|
||||
where: {
|
||||
roundId: input.roundId,
|
||||
ruleType: 'AI_SCREENING',
|
||||
isActive: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (aiRules === 0) {
|
||||
return { hasAIRules: false, configured: true, error: null }
|
||||
}
|
||||
|
||||
// Check if OpenAI is configured
|
||||
const configured = await isOpenAIConfigured()
|
||||
if (!configured) {
|
||||
return {
|
||||
hasAIRules: true,
|
||||
configured: false,
|
||||
error: 'OpenAI API key not configured',
|
||||
}
|
||||
}
|
||||
|
||||
// Test the connection
|
||||
const testResult = await testOpenAIConnection()
|
||||
return {
|
||||
hasAIRules: true,
|
||||
configured: testResult.success,
|
||||
error: testResult.error || null,
|
||||
model: testResult.modelTested,
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get filtering rules for a round
|
||||
*/
|
||||
@@ -146,6 +186,30 @@ export const filteringRouter = router({
|
||||
})
|
||||
}
|
||||
|
||||
// Check if any AI_SCREENING rules exist
|
||||
const hasAIRules = rules.some((r) => r.ruleType === 'AI_SCREENING' && r.isActive)
|
||||
|
||||
if (hasAIRules) {
|
||||
// Verify OpenAI is configured before proceeding
|
||||
const aiConfigured = await isOpenAIConfigured()
|
||||
if (!aiConfigured) {
|
||||
throw new TRPCError({
|
||||
code: 'PRECONDITION_FAILED',
|
||||
message:
|
||||
'AI screening rules require OpenAI to be configured. Go to Settings → AI to configure your API key.',
|
||||
})
|
||||
}
|
||||
|
||||
// Also verify the model works
|
||||
const testResult = await testOpenAIConnection()
|
||||
if (!testResult.success) {
|
||||
throw new TRPCError({
|
||||
code: 'PRECONDITION_FAILED',
|
||||
message: `AI configuration error: ${testResult.error}. Go to Settings → AI to fix.`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Get projects in this round
|
||||
const roundProjectEntries = await ctx.prisma.roundProject.findMany({
|
||||
where: { roundId: input.roundId },
|
||||
|
||||
Reference in New Issue
Block a user