Conversation
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Codex <codex@openai.com>
📝 WalkthroughWalkthroughAdds PostgreSQL Priority: ➖ Normal Severity of issue fixed: Medium Merge Risk: 🔵 Low · up to Redacting the workstation paths avoids unnecessarily publishing local identity and directory details; this is localized and does not otherwise block the feature. 🚥 Pre-merge checks | ✅ 7 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (7 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 17 files. (10 skipped: 10 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: Codex <codex@openai.com>
There was a problem hiding this comment.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
.forge/features/instant-judging-updates/evidence/react-analyzer-baseline.txt-2-3 (1)
2-3: 🔒 Security & Privacy | 🛡️ Analyzed with Security Review | 🟡 Minor | ⚡ Quick winInformation Disclosure
Reachability: Internal
Exploitability: Trivial
CWE: CWE-200 — Exposure of Sensitive Information to an Unauthorized ActorRedact local paths from the committed analyzer evidence. Forge is a public monorepo, and this generated output exposes the local username
rhygonand workstation directory layout. Replace absolute paths with repository-relative or redacted paths.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: QUIET
Plan: Advanced
Run ID: 56af8028-258a-44ab-ab2a-a33cd4482ceb
⛔ Files ignored due to path filters (16)
.forge/features/instant-judging-updates/evidence/after.gifis excluded by!**/*.gif.forge/features/instant-judging-updates/evidence/after.mp4is excluded by!**/*.mp4.forge/features/instant-judging-updates/evidence/after/announcement.pngis excluded by!**/*.png.forge/features/instant-judging-updates/evidence/after/judge.webmis excluded by!**/*.webm.forge/features/instant-judging-updates/evidence/after/organizer-schedule.pngis excluded by!**/*.png.forge/features/instant-judging-updates/evidence/after/organizer.webmis excluded by!**/*.webm.forge/features/instant-judging-updates/evidence/after/reassignment.pngis excluded by!**/*.png.forge/features/instant-judging-updates/evidence/after/reconnected.pngis excluded by!**/*.png.forge/features/instant-judging-updates/evidence/before.gifis excluded by!**/*.gif.forge/features/instant-judging-updates/evidence/before.mp4is excluded by!**/*.mp4.forge/features/instant-judging-updates/evidence/before/announcement.pngis excluded by!**/*.png.forge/features/instant-judging-updates/evidence/before/judge.webmis excluded by!**/*.webm.forge/features/instant-judging-updates/evidence/before/organizer-schedule.pngis excluded by!**/*.png.forge/features/instant-judging-updates/evidence/before/organizer.webmis excluded by!**/*.webm.forge/features/instant-judging-updates/evidence/before/reassignment.pngis excluded by!**/*.pngpackages/api/src/tests/root/__snapshots__/api-surface.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (27)
.forge/features/instant-judging-updates/evidence/README.md.forge/features/instant-judging-updates/evidence/after/timings.json.forge/features/instant-judging-updates/evidence/before/timings.json.forge/features/instant-judging-updates/evidence/react-analyzer-baseline.txt.forge/features/instant-judging-updates/evidence/sse-response.json.forge/features/instant-judging-updates/pr-description.md.forge/features/instant-judging-updates/spec.md.forge/features/instant-judging-updates/srd.md.forge/features/instant-judging-updates/status.md.forge/features/instant-judging-updates/test-cases.mdapps/blade/src/app/_components/judging/judging-live-updates.tsxapps/blade/src/app/_components/projects/judge-project-workspace.tsxapps/blade/src/app/admin/judging/page.tsxapps/blade/src/app/api/trpc/[trpc]/route.tsapps/blade/src/app/judge/projects/page.tsxapps/blade/src/tests/judging/prod-flow-regressions.test.tsxapps/blade/src/tests/projects/judging-live-updates.test.tsxapps/blade/src/trpc/react.tsxpackages/api/src/judging-access.server.tspackages/api/src/routers/judging-schedule.tspackages/api/src/routers/judging-scores.tspackages/api/src/routers/judging.tspackages/api/src/tests/integration/judging-access.test.tspackages/api/src/tests/judging/realtime.test.tspackages/api/src/trpc.tspackages/api/src/utils/judging/evaluation-write.tspackages/api/src/utils/judging/realtime.ts
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.
Co-authored-by: Codex <codex@openai.com>
Why
Judges could wait up to the next 30-second poll to see an organizer's announcement.
Blade now pushes a change notification when a judging transaction commits, then
refreshes the existing authorized views. The recorded local announcement appeared
in 0.973 seconds, compared with 29.987 seconds on main.
What
Add a tRPC SSE subscription to the judge workspace and command center. PostgreSQL
LISTEN/NOTIFY carries invalidations between app processes. Announcements, room and
access changes, saved schedule changes, resets, and finalized scores publish
within their transactions.
The stream rechecks access, sends keepalives, and refetches on reconnect. Offline
page refreshes pause until networking returns. Existing queries retain their
room/guest filtering; polling remains for deadlines and recovery. Scope is Blade
and its API implementation.
Closes #574.
Before and after
Organizer on the left; judge on the right. These are inline animations of the
reviewed browser recordings, at normal speed. The full polling wait and the
simulated network outage are shown. Startup footage was trimmed; the final
three-second result screenshot in each recording is explicitly labeled as a still.
Before — main at
361d10a5: the announcement waits for the next poll.After — SSE: announcement, reassignment, and recovery from a network outage.
These are single local observations. The baseline reassignment happened just
before a poll, so it was already quick. Exact timings were measured from the
button click to visible text, independently of video clocks. The actual SSE
notification arrived 223 ms after Publish and 151 ms after Save; the visible
result includes the subsequent refetch and rendering.
Full-size result screenshots
Announcement visible in the judge's view:
Aurora reassigned to ENG 102:
Missed announcement received after restoring networking, without a page reload:
Recording setup and reproduction
Recorded September 16, 2026 in two independent Chromium sessions against a local
Next.js development server and disposable PostgreSQL database. People, projects,
and assignments are synthetic. Both versions use the same fixture and actions.
Discord was deliberately disconnected.
a future Aurora appointment in ENG 101. Sign an officer and a judge into
separate browser contexts.
so Aurora stays visible after reassignment. Let the initial queries finish.
from Publish to that text appearing in the judge's view.
from Save to ENG 102 appearing in the judge's Aurora row.
browser, wait at least 20 seconds, and restore networking. The judge should
receive the missed announcement without reloading.
The baseline opened no SSE connection. The after recording used native
EventSource with no substituted transport. The endpoint returned HTTP 200,
text/event-stream,X-Accel-Buffering: no, and an initial invalidation.Original WebMs, MP4s, screenshots, and timestamps are retained in this PR's
feature bundle for provenance; the comparison above is self-contained.
Test Plan
CI on
a9ee0e7e: passed, including all 2,481 tests, database tests, migrations, lint, formatting, typechecking, and the full production build.pnpm format,pnpm lint, andpnpm typecheck: passed.React element. Reproduced both failures locally and updated them to render the
page and inspect workspace props. The original hackathon-selection/read-only
assertions remain; both tests also check the listener's hackathon scope.
pnpm exec turbo run test --filter='!@forge/db',against a fresh PostgreSQL 16 container: 2,481 tests passed across 351 files,
including all 988 API tests and all 881 Blade tests. The database package has
its own CI job, which passed on the initial PR run.
Ran
pnpm build --env-mode=loosewith temporary process values from.env.example, allowing those CI example values through Turbo. No environmentfiles or build configuration were changed.
pnpm analyze:react:changedhits an existing parser error in the tRPC provider:Cannot read properties of undefined (reading 'type'). Reproduced on main at361d10a5; no check bypass was added.Local workstation roots in the analyzer transcript are redacted. CodeRabbit's
advisory docstring-coverage suggestion was not applied: the transport helpers
already document transaction delivery, listener ownership, and reconnect behavior;
extra docstrings repeating handler names would add little.
Production proxy streaming and database connection mode still need verification;
the recordings use loopback HTTP. No deployment was run. Schedule solver progress
and private draft autosaves retain their existing refresh behavior.
Checklist