-
Notifications
You must be signed in to change notification settings - Fork 4
fix: bugs - SSR errors, foreign key constraints, hydration issues #138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes critical SSR errors, foreign key constraint violations, and hydration issues that were preventing core functionality from working. The changes address FFmpeg initialization errors during server-side rendering, database constraint violations when deleting assignments, and React hydration mismatches in loading components.
- Fixes foreign key constraint violations in assignment deletion by removing related records in proper order
- Resolves FFmpeg SSR errors by moving initialization to client-side useEffect hooks
- Eliminates React hydration mismatches by ensuring consistent server/client rendering patterns
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
File | Description |
---|---|
apps/api/src/api/admin/admin.service.ts | Adds proper deletion order for related records to prevent foreign key constraint violations |
apps/web/components/MarkdownViewer.tsx | Adds client-side checks and race condition protection for Quill editor initialization |
apps/web/components/MarkDownEditor.tsx | Adds client-side checks and async safety guards for Quill editor |
apps/web/components/Loading.tsx | Replaces SSR check with useState/useEffect pattern to prevent hydration mismatches |
apps/web/app/learner/(components)/Question/VideoPresentationEditor.tsx | Moves FFmpeg initialization from global scope to client-side useEffect |
apps/web/app/learner/(components)/Question/PresentationGrader.tsx | Replaces global FFmpeg with client-side initialization and removes duplicate loading logic |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
const targetTime = config?.targetTime ?? 0; | ||
|
||
// Fix: Initialize FFmpeg only on client-side to prevent SSR errors | ||
const [ffmpeg, setFfmpeg] = useState<any>(null); |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using any
type defeats TypeScript's type safety. Import the FFmpeg
type and use useState<FFmpeg | null>(null)
instead.
const [ffmpeg, setFfmpeg] = useState<any>(null); | |
const [ffmpeg, setFfmpeg] = useState<FFmpeg | null>(null); |
Copilot uses AI. Check for mistakes.
* ------------------------------------------------------------------ */ | ||
const useVideoProcessor = () => { | ||
const [processing, setProcessing] = useState(false); | ||
const [ffmpeg, setFfmpeg] = useState<any>(null); |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using any
type defeats TypeScript's type safety. Import the FFmpeg
type and use useState<FFmpeg | null>(null)
instead.
const [ffmpeg, setFfmpeg] = useState<any>(null); | |
const [ffmpeg, setFfmpeg] = useState<FFmpeg | null>(null); |
Copilot uses AI. Check for mistakes.
if (typeof window !== 'undefined') { | ||
import('@ffmpeg/ffmpeg').then(({ FFmpeg }) => { | ||
const ffmpegInstance = new FFmpeg(); | ||
setFfmpeg(ffmpegInstance); | ||
}); | ||
} |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for the dynamic import. If the FFmpeg module fails to load, the component will silently fail. Add a .catch() handler to log errors or show user feedback.
Copilot uses AI. Check for mistakes.
if (typeof window !== 'undefined') { | ||
import('@ffmpeg/ffmpeg').then(({ FFmpeg }) => { | ||
const ffmpegInstance = new FFmpeg(); | ||
setFfmpeg(ffmpegInstance); | ||
}); | ||
} |
Copilot
AI
Oct 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for the dynamic import. If the FFmpeg module fails to load, the component will silently fail. Add a .catch() handler to log errors or show user feedback.
Copilot uses AI. Check for mistakes.
1. Foreign Key Constraint Violation - Assignment Deletion
Location: apps/api/src/api/admin/admin.service.ts:2116
Problem: AdminService.removeAssignment() attempts to delete Assignment without removing related records first. Database has RESTRICT foreign key constraints instead of CASCADE. Deletion fails when GradingJob or GradingAudit records exist.
Impact: Assignment deletion completely broken, returns 500 errors
2. FFmpeg SSR Initialization Error
Location: apps/web/app/learner/(components)/Question/PresentationGrader.tsx:19
Problem: FFmpeg initialized globally at module load time. Executes during Server-Side Rendering in Next.js. FFmpeg.wasm only works in browser environment.
Impact: Page crashes when accessing presentation questions
3. FFmpeg SSR Error in Video Editor
Location: apps/web/app/learner/(components)/Question/VideoPresentationEditor.tsx:113
Problem: Same as above - global FFmpeg initialization during SSR
Impact: Video presentation editor completely broken
4. Quill Editor SSR Error
Location: apps/web/components/MarkdownViewer.tsx:50 & apps/web/components/MarkDownEditor.tsx:60
Problem: Quill Editor tries to access DOM elements during SSR. quillRef.current is null on server-side. Missing client-side checks.
Impact: Rich text editor components fail to render
5. Development Environment Configuration
Location: apps/api/dev.env:2
Problem: NODE_ENV=development missing, causing poor error visibility
Impact: Poor error visibility during development, harder debugging
6. React Hydration Mismatch in Loading Component
Location: apps/web/components/Loading.tsx:10
Problem: Loading component uses if (typeof document === "undefined") return null pattern. Server renders null, client renders
Impact: Hydration errors appear during Questions → Preview flow, causing reload dialogs
7. Quill Editor Race Condition in Async Operations
Location: apps/web/components/MarkdownViewer.tsx:85 & apps/web/components/MarkDownEditor.tsx:95
Problem: After async Quill import, quillRef.current might still be null due to React re-renders or component unmounting. Missing safety checks after await import('quill') operations.
Impact: Runtime errors when users quickly navigate between markdown editing components, causing editor initialization failures