Repository navigation
Feature: feat/judging-pool to dev - #457
Conversation
# Conflicts: # sites/mainweb/app/(portal)/hackathons/[id]/judge/page.tsx
…cutoff Judges were handed a fixed list at Prepare time. Coverage then depended on exactly who showed up: a no-show's projects were never scored, a late judge got all ~500 projects in table order, and the auto split assumed 12 minutes a project. Claims were unlocked, so two judges could take one table. Judging now runs from a shared pool (routers/judge/dispatch.ts). When a judge asks for a table, the server takes a per-hackathon advisory lock and hands out the eligible project with the fewest looks that the judge has not had and nobody is at, nearest table first among equals. judge_queue rows become visits written at hand-out, so judges can join or leave at any point. Sponsor and special-label judges keep to their pool and their looks are counted separately. Timing: a table is held 4 minutes while the judge walks over, then the clock runs from the NFC tap or card scan. 3:00 is the target; at 4:00 (plus 15s grace) a first score is refused, the look is void and the project goes back into the pool. completeAndNext reports timedOut and hands over the next table. The judge page shows the clock, turns amber at 3:00 and locks the form at 4:00. Prepare judging only syncs submissions now and is safe to rerun while judging is live. assignJudgesToProjects, initializeQueue, queue appends on promote, forceSkip reassignment and the coverage queue builder are gone. Rows built in advance by the old flow are cleared rather than counted as visits. The live board shows unseen projects, active judges and measured time to two looks each. Tested against Postgres 18 (dispatch.db.test.ts, runs when JUDGING_TEST_DATABASE_URL is set): 60 judges asking at once get 60 distinct tables; 500 projects reach exactly two looks each with 15 of 40 judges joining 40 minutes late; no-shows, the cutoff, repeat requests, legacy rows and sponsor tracks. Dispatch takes about 18ms locally. No schema change.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned Files
|
|
Visit the preview URL for this PR (updated for commit a61cc63): https://hacklytics2027--pr-457-5cqj54xq.web.app (expires Fri, 09 Oct 2026 19:51:27 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: c48ba34db61581e25fe2978355160b5eefe0e83f |
# Conflicts: # sites/mainweb/app/(portal)/hackathons/[id]/judge/page.tsx
A live visit to a project withdrawn mid-handoff was never closed, so it kept matching as the judge's live visit and every later dispatch claimed another table. Close it with the lapsed visits. liveProgress counted sponsor scores toward the main panel's two-look floor and pace. Count main-group votes only, using the same grouping as dispatch (now shared as loadGroups).
One ci.yml lints, typechecks, tests and builds every PR and push to main/dev; Hacklytics preview and live deploys run only after it passes and ship that build. Replaces pnpm-ci, test, and the two Firebase Hosting workflows, drops the disabled deploy copy and the static CodeQL summary job, and points the labeler at pnpm-lock.yaml.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f60f513. Configure here.
|
|
||
| // Worst first: a judge who has stopped is the reason to open this screen. | ||
| const rank = { not_started: 0, judging: 1, between: 2, done: 3, suspended: 4 }; | ||
| const rank = { not_started: 0, between: 1, judging: 2, suspended: 3 }; |
There was a problem hiding this comment.
Finished judges look stalled
Medium Severity
liveProgress never emits a finished state. After dispatchNext returns done, a judge has visits but no live claim, so they stay between. The board sorts that status above people still judging and paints idle past 10 minutes red, so organisers chasing stalls get finished judges first.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f60f513. Configure here.
| ? ("judging" as const) | ||
| : visits.length === 0 | ||
| ? ("not_started" as const) | ||
| : ("between" as const); |
There was a problem hiding this comment.
Applicants shown as suspended
Medium Severity
liveProgress now lists every judges row for the edition and maps isActive: false to suspended. judge.register creates inactive rows, so unapproved applicants appear on the floor board as suspended judges rather than staying off it.
Reviewed by Cursor Bugbot for commit f60f513. Configure here.


Automated PR tracking changes from
feat/judging-poolintodev.Note
High Risk
Changes live hackathon judging assignment, scoring cutoffs, and production deploy gating—high impact on event-day behavior and what ships after merge.
Overview
Replaces pre-built per-judge queues with a shared judging pool: judges pull the next eligible table on demand via
dispatch.ts(coverage-awarepickNext, walk/judging time limits,pg_advisory_xact_lock), andjudge_queuerows represent visits rather than a fixed itinerary. Admin flows dropassignJudgesToProjects,initializeQueue, and queue-append onpromoteSubmissions; approving a judge only reports pool size, andliveProgress/ the admin floor UI track scored/voided visits, coverage, and pace instead of queue completion.CI/CD is consolidated into
.github/workflows/ci.yml: oneverifyjob (lint, typecheck, test, build + Hacklytics artifact), then PR preview and main live Firebase deploys that reuse that build; older pnpm/test/hosting workflows are removed. Docs and the labeler’s dependency globs are updated for pnpm monorepo layout.Reviewed by Cursor Bugbot for commit f60f513. Bugbot is set up for automated code reviews on this repo. Configure here.