refactor(awards): remove AWARD_MASTER role, fold features into jury chair flow
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m5s
All checks were successful
Build and Push Docker Image / build (push) Successful in 8m5s
The AWARD_MASTER role split sponsor jurors into a parallel UI that hid project files (only showed when the award was anchored to an evaluation round) and duplicated the jury voting path with no real difference in authority — tie-break and finalize were already governed by AwardJuror.isChair regardless of the user's global role. Inviting a juror via the award page defaulted to AWARD_MASTER, randomly fragmenting jury panels. This collapses the role into JURY_MEMBER + isChair: - specialAward.getMyAwardDetail now returns evaluation scores, chair visibility into other jurors' votes, and juror roster - specialAward.submitVote accepts an optional justification per vote - specialAward.confirmWinner moves from awardMasterProcedure to protectedProcedure (juror+chair check inside) - bulkInviteJurors creates JURY_MEMBER accounts and, when the award has a juryGroupId, also adds them to that JuryGroup so they appear on the round-page jury panel - jury award page renders justification, eval-score badges, and a chair tools panel with vote tally + finalize-winner CTA - juryGroup.list includes attached SpecialAwards; the jury-list UI shows a trophy pill alongside round pills - (award-master) route group, awardMasterProcedure, AWARD_MASTER role enum value, and AWARD_MASTER_DECISION decisionMode are deleted - migration demotes any residual AWARD_MASTER users to JURY_MEMBER and recreates the UserRole enum without the value Coup de Coeur on prod: Didier (the sponsor juror added today as AWARD_MASTER by the buggy invite form) was migrated to JURY_MEMBER and attached to the existing "Coup de Coeur" JuryGroup; the SpecialAward itself was linked to that group (juryGroupId was NULL). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,6 @@ const roleColors: Record<string, 'default' | 'outline' | 'secondary'> = {
|
||||
PROGRAM_ADMIN: 'default',
|
||||
SUPER_ADMIN: 'default',
|
||||
APPLICANT: 'secondary',
|
||||
AWARD_MASTER: 'outline',
|
||||
AUDIENCE: 'outline',
|
||||
}
|
||||
|
||||
@@ -154,7 +153,7 @@ export default function MemberDetailPage() {
|
||||
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
const allRoles = [role, ...additionalRoles.filter((r) => r !== role)] as Array<'SUPER_ADMIN' | 'PROGRAM_ADMIN' | 'AWARD_MASTER' | 'JURY_MEMBER' | 'MENTOR' | 'OBSERVER' | 'APPLICANT' | 'AUDIENCE'>
|
||||
const allRoles = [role, ...additionalRoles.filter((r) => r !== role)] as Array<'SUPER_ADMIN' | 'PROGRAM_ADMIN' | 'JURY_MEMBER' | 'MENTOR' | 'OBSERVER' | 'APPLICANT' | 'AUDIENCE'>
|
||||
await updateUser.mutateAsync({
|
||||
id: userId,
|
||||
email: email || undefined,
|
||||
@@ -622,7 +621,6 @@ export default function MemberDetailPage() {
|
||||
<SelectItem value="MENTOR">Mentor</SelectItem>
|
||||
<SelectItem value="OBSERVER">Observer</SelectItem>
|
||||
<SelectItem value="APPLICANT">Applicant</SelectItem>
|
||||
<SelectItem value="AWARD_MASTER">Award Master</SelectItem>
|
||||
<SelectItem value="AUDIENCE">Audience</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
@@ -633,7 +631,7 @@ export default function MemberDetailPage() {
|
||||
Grant additional dashboard access beyond the primary role
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{(['JURY_MEMBER', 'OBSERVER', 'MENTOR', 'AWARD_MASTER'] as const)
|
||||
{(['JURY_MEMBER', 'OBSERVER', 'MENTOR'] as const)
|
||||
.filter((r) => r !== role)
|
||||
.map((r) => (
|
||||
<label key={r} className="flex items-center gap-2 text-sm cursor-pointer">
|
||||
|
||||
Reference in New Issue
Block a user