Implement 10 platform features: evaluation UX, admin tools, AI summaries, applicant portal
Batch 1 - Quick Wins: - F1: Evaluation progress indicator with touch tracking in sticky status bar - F2: Export filtering results as CSV with dynamic AI column flattening - F3: Observer access to analytics dashboards (8 procedures changed to observerProcedure) Batch 2 - Jury Experience: - F4: Countdown timer component with urgency colors + email reminder service with cron endpoint - F5: Conflict of interest declaration system (dialog, admin management, review workflow) Batch 3 - Admin & AI Enhancements: - F6: Bulk status update UI with selection checkboxes, floating toolbar, status history recording - F7: AI-powered evaluation summary with anonymized data, OpenAI integration, scoring patterns - F8: Smart assignment improvements (geo diversity penalty, round familiarity bonus, COI blocking) Batch 4 - Form Flexibility & Applicant Portal: - F9: Evaluation form flexibility (text, boolean, section_header types, conditional visibility) - F10: Applicant portal (status timeline, per-round documents, mentor messaging) Schema: 5 new models (ReminderLog, ConflictOfInterest, EvaluationSummary, ProjectStatusHistory, MentorMessage), ProjectFile extended with roundId + isLate. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -443,9 +443,25 @@ export const roundRouter = router({
|
||||
id: z.string(),
|
||||
label: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
scale: z.number().int().min(1).max(10),
|
||||
type: z.enum(['numeric', 'text', 'boolean', 'section_header']).default('numeric'),
|
||||
// Numeric fields
|
||||
scale: z.number().int().min(1).max(10).optional(),
|
||||
weight: z.number().optional(),
|
||||
required: z.boolean(),
|
||||
required: z.boolean().optional(),
|
||||
// Text fields
|
||||
maxLength: z.number().int().min(1).max(10000).optional(),
|
||||
placeholder: z.string().optional(),
|
||||
// Boolean fields
|
||||
trueLabel: z.string().optional(),
|
||||
falseLabel: z.string().optional(),
|
||||
// Conditional visibility
|
||||
condition: z.object({
|
||||
criterionId: z.string(),
|
||||
operator: z.enum(['equals', 'greaterThan', 'lessThan']),
|
||||
value: z.union([z.number(), z.string(), z.boolean()]),
|
||||
}).optional(),
|
||||
// Section grouping
|
||||
sectionId: z.string().optional(),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user