/** * Resolve the winner of a PICK_WINNER award given all votes and the chair's userId. * Logic: count votes per project. If one project has the most, it wins. * If tied, the chair's pick wins among the tied projects. */ export function resolveAwardWinner( votes: Array<{ userId: string; projectId: string }>, chairUserId: string ): string { if (votes.length === 0) { throw new Error('Cannot resolve winner with no votes') } // Tally votes per project const tally = new Map() for (const v of votes) { tally.set(v.projectId, (tally.get(v.projectId) || 0) + 1) } const maxVotes = Math.max(...tally.values()) const topProjects = [...tally.entries()] .filter(([, count]) => count === maxVotes) .map(([pid]) => pid) if (topProjects.length === 1) { return topProjects[0] } // Tie: chair's pick wins if among tied projects const chairVote = votes.find((v) => v.userId === chairUserId) if (chairVote && topProjects.includes(chairVote.projectId)) { return chairVote.projectId } // Chair voted for a non-tied project — pick alphabetically for stability return topProjects.sort()[0] }