Fix pipeline config crashes, settings UX, invite roles, seed expertise tags

- Fix critical crash when clicking Edit on INTAKE stage configs: normalize
  DB fileRequirements shape (type/required → acceptedMimeTypes/isRequired),
  add null guard in getActiveCategoriesFromMimeTypes
- Fix config summary display for all stage types to handle seed data key
  mismatches (votingEnabled→juryVotingEnabled, minAssignmentsPerJuror→
  minLoadPerJuror, deterministic.rules→rules, etc.)
- Add AWARD_MASTER role to invite page dropdown and user router validations
- Restructure settings sidebar: Tags and Webhooks as direct links instead
  of nested tabs, remove redundant Quick Links section
- Seed 38 expertise tags across 7 categories (Marine Science, Technology,
  Policy, Conservation, Business, Education, Engineering)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 11:40:44 +01:00
parent ae0ac58547
commit c88f540633
7 changed files with 187 additions and 118 deletions

View File

@@ -183,8 +183,8 @@ export const userRouter = router({
list: adminProcedure
.input(
z.object({
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).optional(),
roles: z.array(z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER'])).optional(),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'AWARD_MASTER', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).optional(),
roles: z.array(z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'AWARD_MASTER', 'JURY_MEMBER', 'MENTOR', 'OBSERVER'])).optional(),
status: z.enum(['NONE', 'INVITED', 'ACTIVE', 'SUSPENDED']).optional(),
search: z.string().optional(),
page: z.number().int().min(1).default(1),
@@ -274,7 +274,7 @@ export const userRouter = router({
z.object({
email: z.string().email(),
name: z.string().optional(),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).default('JURY_MEMBER'),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'AWARD_MASTER', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).default('JURY_MEMBER'),
expertiseTags: z.array(z.string()).optional(),
maxAssignments: z.number().int().min(1).max(100).optional(),
})
@@ -339,7 +339,7 @@ export const userRouter = router({
z.object({
id: z.string(),
name: z.string().optional().nullable(),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).optional(),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'AWARD_MASTER', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).optional(),
status: z.enum(['NONE', 'INVITED', 'ACTIVE', 'SUSPENDED']).optional(),
expertiseTags: z.array(z.string()).optional(),
maxAssignments: z.number().int().min(1).max(100).optional().nullable(),
@@ -472,7 +472,7 @@ export const userRouter = router({
z.object({
email: z.string().email(),
name: z.string().optional(),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).default('JURY_MEMBER'),
role: z.enum(['SUPER_ADMIN', 'PROGRAM_ADMIN', 'AWARD_MASTER', 'JURY_MEMBER', 'MENTOR', 'OBSERVER']).default('JURY_MEMBER'),
expertiseTags: z.array(z.string()).optional(),
// Optional pre-assignments for jury members
assignments: z