Skip to content

fix(tests/essays): stable share links, live teacher-side sync, external media CSP - #531

Merged
NesiciCoding merged 2 commits into
mainfrom
claude/slip-modal-links-test-save-c0476d
Sep 17, 2026
Merged

NesiciCoding merged 2 commits into
mainfrom
claude/slip-modal-links-test-save-c0476d

Conversation

@NesiciCoding

Copy link
Copy Markdown
Owner

Summary

Audits the student→teacher hand-in path and fixes link-stability and sync/parse desyncs found along the way.

1. Stable assignment share links (tests + essays)

  • TestAssignmentModal minted a fresh nanoid teacherKey per student on every mount. Because saveTestAssignment upserts by id, reopening the modal handed out a different URL each time, piled up duplicate test_assignments rows, and — worst case — orphaned a placement-generator student's in-progress placement_sessions run (keyed on the assignment id). Now reconciles keys against the persisted rows on open (via fetchTestAssignmentTeacherKeys), gated so the DB auto-save can't race ahead and create a duplicate. Reopening re-serves the same link and upserts the same row.
  • GradeStudent essay modal now reuses this student's own persisted teacherKey (guarded to the student's own row, never the single-group fallback), so its link is stable too.

2. Teacher-side sync/parse audit

  • Tests already sync live and parse correctly — student_tests is realtime-published + subscribed + partial-hydratable, and generator/placement submissions render via askedQuestionSnapshots + levelPath. No change needed.
  • Essays were the desync: essay_submissions is not in the realtime publication and useOnlineEssaySubmissions fetched once on mount, so a student handing in online never refreshed the teacher's roster badges. Now refetches on tab focus/visibilitychange.

3. Realtime send() … falling back to REST API warning (student side)

Benign (delivery still succeeds over REST), but noisy — proctor events fire it before the channel joins. useLiveSessionTelemetry now gates the best-effort live-event broadcast on the channel being joined; events are buffered and flushed at submit regardless.

4. External media (archive.org audio) blocked by CSP

The deploy/docker CSPs had no media-src, so <audio> fell back to default-src 'self' and all external audio/image stimulus URLs were blocked. Added media-src 'self' https: data: blob: and widened img-src to https: across all 7 configs.

Reviewer notes

  • The CSP change lives in web-server config — self-hosted deploys need a server-config redeploy to take effect. deploy/.htaccess is auto-deployed by the deploy-hestiacp job; the *-hestiacp.conf / *-virtualmin.conf vhost templates are not.
  • archive.org may still refuse some items via its own hotlink/redirect behavior, but our CSP was blocking it outright first.

Tests

  • Added a TestAssignmentModal test for persisted-key reuse; updated the two modal test mocks with fetchTestAssignmentTeacherKeys.
  • typecheck ✅, eslint ✅, affected unit suites (Tests, Essay, hooks, GradeStudent) ✅.

🤖 Generated with Claude Code

…al media CSP

Stabilize assignment share links across modal reopens and close several
student→teacher sync/parse gaps found while auditing the hand-in path.

- TestAssignmentModal: reconcile teacherKeys against persisted test_assignments
  rows on open (gated so auto-save can't race and duplicate a row). Reopening
  now re-serves the SAME link and upserts the SAME row instead of minting a new
  nanoid — which handed out a different URL each time, piled up duplicate rows,
  and (for a placement-generator test) orphaned a student's in-progress
  placement_sessions run, keyed on the assignment id.
- GradeStudent essay modal: reuse this student's own persisted teacherKey so
  its link is stable too (guarded to the student's own row, never the fallback).
- useOnlineEssaySubmissions: refetch on tab focus/visibility. essay_submissions
  is not in the realtime publication (unlike student_tests), so a student handing
  in online never updated the teacher's roster badges until a reload.
- useLiveSessionTelemetry: gate the best-effort live-event broadcast on the
  channel actually being joined, silencing realtime-js's repeated "send() is
  falling back to REST API" warning on pre-join proctor events (events are
  buffered and flushed at submit regardless, so nothing is lost).
- CSP (deploy/docker configs): add media-src and widen img-src to https so
  external audio/image stimulus URLs (e.g. archive.org) load — the configs had
  no media-src, so <audio> fell back to default-src 'self' and all external
  media was blocked outright.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: b436259b-fe60-44e9-8f7d-f154d23d83c5


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…ks-test-save-c0476d

# Conflicts:
#	deploy/apache-hestiacp.conf
#	deploy/apache-virtualmin.conf
#	deploy/nginx-hestiacp.conf
#	deploy/nginx-virtualmin.conf
#	docker/nginx.conf
#	docker/nginx.prod.conf
#	src/hooks/useLiveSessionTelemetry.ts
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 99.36% (🎯 65%) 13852 / 13941
🟢 Statements 99.25% (🎯 65%) 16199 / 16321
🟢 Functions 99.19% (🎯 60%) 5535 / 5580
🟢 Branches 98.95% (🎯 58%) 12629 / 12763
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/components/Tests/TestAssignmentModal.tsx 96.11% 94.93% 91.66% 95.69% 76-77, 377, 465
src/hooks/useOnlineEssaySubmissions.ts 33.33% 25% 28.57% 33.33% 24-49
src/pages/GradeStudent.tsx 98.58% 99.37% 97.63% 98.61% 1553, 1816-1824
Generated in workflow #1503 for commit d429990 by the Vitest Coverage Report Action

@NesiciCoding
NesiciCoding merged commit 7bb43a8 into main Sep 17, 2026
15 checks passed
@NesiciCoding
NesiciCoding deleted the claude/slip-modal-links-test-save-c0476d branch September 17, 2026 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant