feat(deploy): add production-ready Dockerfile, docker-compose, and un… - #1158
Conversation
|
@Myparadox-creator is attempting to deploy a commit to the itzzavdhesh's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds production Docker deployment and SPA serving. It updates speech-history tagging and analytics, recording extraction, subtitle state, startup error handling, imports, and the text-to-speech control. ChangesVoiceForge production and frontend runtime
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Browser
participant Express
participant ClientDist
Browser->>Express: GET browser route with text/html Accept
Express->>ClientDist: Serve client/dist/index.html
ClientDist-->>Browser: Return SPA entry document
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 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 |
✍️ DCO Sign-off NeededHey @Myparadox-creator! 👋 One or more commits in this PR are missing a Warning
How to fix: For the latest commit: git commit --amend --signoff
git push --force-with-leaseFor multiple commits, replace git rebase --signoff HEAD~N
git push --force-with-leaseThis comment will update automatically after you push. 🤖 VoiceForge Automation · Updates automatically on edits |
🎉 PR Ready for Mentor ReviewHey @Myparadox-creator! 👋 Your PR passed all checks and is now in the ELUSOC review queue. Note 🔗 Closing: #1109 · 📐 427 lines across 13 file(s) · 📬 Already requested or no eligible reviewer found @joyprakashk @rushi-k12, this PR is ready for your review — please confirm scope, check behavior and tests, then approve or request changes. Important This is not an approval. Please wait for mentor feedback before expecting a merge. If changes are requested, push them to this same branch and keep the PR focused on the linked issue. 🤖 VoiceForge Automation · Updates automatically on edits |
There was a problem hiding this comment.
2 issues found across 14 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="client/src/components/SpeechHistory.jsx">
<violation number="1" location="client/src/components/SpeechHistory.jsx:19">
P1: Tag management and quick-reply promotion in the history panel are non-functional because the new callbacks (`onAddTag`, `onRemoveTag`, `onAddToQuickReplies`) are passed to `MessageCard` but never wired from the parent `VoiceForge` component. Adding a tag in the history panel silently discards the input, and clicking the "Promote to Quick Reply" button does nothing even though `VoiceForge` already defines `handleAddToQuickReplies`. Wire all three callbacks from `VoiceForge` to `<SpeechHistory>` so these UI features work correctly.</violation>
</file>
<file name="client/src/pages/Call.jsx">
<violation number="1" location="client/src/pages/Call.jsx:27">
P1: Subtitle overlay settings are stored and rendered in the UI, but the state values are never passed to `<VideoPreview>`, which is the component responsible for drawing the subtitle overlay on canvas. The subtitle configuration UI has no observable effect, and `VideoPreview.jsx` additionally references undeclared refs (`subtitlesEnabledRef`, `subtitleFontSizeRef`, `subtitleBgOpacityRef`, `activeTextRef`) that would throw `ReferenceError` during the animation draw loop.
Pass `subtitlesEnabled`, `subtitleFontSize`, and `subtitleBgOpacity` as props to `<VideoPreview>`, and refactor `VideoPreview` to accept and use them (either via received props or declared refs). `activeTextRef` also needs to be provided from the parent to supply the subtitle text content.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…ified asset serving Signed-off-by: Aditya R. Satapathy <adityaranjanwxd@gmail.com>
8cfc49c to
1220566
Compare
…dingReady callback Signed-off-by: Aditya R. Satapathy <adityaranjanwxd@gmail.com>
… and client Signed-off-by: Aditya R. Satapathy <adityaranjanwxd@gmail.com>
…d verify tag callbacks Signed-off-by: Aditya R. Satapathy <adityaranjanwxd@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@client/src/components/SpeechHistory.jsx`:
- Around line 26-39: Update the SpeechHistory state flow around selectedTag and
allUniqueTags so history changes cannot leave selectedTag set to a tag no longer
present. Reset invalid selections to “All Tags” (or make filtering treat them
equivalently), while preserving valid tag selections and the existing
allUniqueTags derivation.
- Around line 41-56: The analyticsData memo currently uses deduplicated history,
undercounting repeated speech events. Update SpeechHistory to accept the event
history, use analyticsHistory or sessionTranscript as the memo’s input for
totalSentences, totalWords, and top counts, and update the dependency
accordingly while preserving the existing analytics shape.
- Around line 31-39: Normalize imported message tags in importBackup (or the
shared validation path) to an array of non-empty strings, removing invalid
values before storing messages. Also guard the allUniqueTags derivation and
downstream tag-search consumers so malformed tags cannot reach .some() or
.toLowerCase(), while preserving valid tags.
In `@client/src/components/VoiceRecorder.jsx`:
- Around line 189-203: In the file-extraction flow after await
extractAudioFromFile, return immediately when isMountedRef.current is false
before creating the object URL, updating refs/state, or calling
onRecordingReady. Also guard the catch and finally state updates so unmounted
extraction results do not call setRecorderError or setIsExtracting.
In `@client/src/main.jsx`:
- Around line 25-30: The error boundary render output currently exposes raw
stack or error text. Update the error display around this.state.error to show
stack/toString diagnostics only in the development build, and render a generic
user-safe message in production.
In `@client/src/pages/Call.jsx`:
- Around line 510-512: Update the Call component’s handleSpeak flow to store the
spoken text in state, then pass that state as activeText to VideoPreview
alongside the existing subtitle props. Ensure the stored value updates whenever
handleSpeak receives new text so subtitle rendering uses the current spoken
text.
In `@client/src/pages/Onboarding.jsx`:
- Around line 206-227: Update handleRecordingReady to detect when the normalized
blob is missing, including the onRecordingReady(null) case, then call
setRecording(null) and return before constructing the recording state object.
Preserve the existing validation and setRecording({ blob, duration, isValid })
behavior for valid recording payloads.
In `@docker-compose.yml`:
- Around line 8-9: Update the service ports mapping in the Docker Compose
configuration to bind host port 3001 explicitly to 127.0.0.1, preserving
container port 3001 and the intended localhost-only deployment.
In `@server/index.js`:
- Around line 57-66: Update the SPA fallback middleware around app.use so it
only serves index.html for GET document requests whose Accept header includes
text/html; continue passing /api requests and all other methods or non-HTML
resource requests to next() so they can resolve as 404s.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: dccba455-a32f-48e7-9d40-66994b3e823e
📒 Files selected for processing (14)
.dockerignoreDockerfileclient/src/App.jsxclient/src/components/SpeechHistory.jsxclient/src/components/VideoPreview.jsxclient/src/components/VoiceForge.jsxclient/src/components/VoiceRecorder.jsxclient/src/hooks/useSpeechHistory.jsclient/src/main.jsxclient/src/pages/Analytics.jsxclient/src/pages/Call.jsxclient/src/pages/Onboarding.jsxdocker-compose.ymlserver/index.js
| const analyticsData = useMemo(() => { | ||
| const totalSentences = history.length; | ||
| const totalWords = history.reduce((acc, msg) => acc + (msg.text ? msg.text.split(/\s+/).length : 0), 0); | ||
| const counts = {}; | ||
| history.forEach((msg) => { | ||
| if (msg.text) { | ||
| const key = msg.text.trim(); | ||
| counts[key] = (counts[key] || 0) + 1; | ||
| } | ||
| }); | ||
| const top = Object.entries(counts) | ||
| .sort((a, b) => b[1] - a[1]) | ||
| .slice(0, 3) | ||
| .map(([text, count]) => ({ text, count })); | ||
| return { totalSentences, totalWords, top }; | ||
| }, [history]); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Base analytics on non-deduplicated speech events.
history preserves only one entry per unique message text, while analyticsHistory and sessionTranscript record every utterance. Computing counts from history means repeated phrases can never have a count above one and usage totals are undercounted. Pass the event history into SpeechHistory and use it for this memo.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@client/src/components/SpeechHistory.jsx` around lines 41 - 56, The
analyticsData memo currently uses deduplicated history, undercounting repeated
speech events. Update SpeechHistory to accept the event history, use
analyticsHistory or sessionTranscript as the memo’s input for totalSentences,
totalWords, and top counts, and update the dependency accordingly while
preserving the existing analytics shape.
Signed-off-by: Aditya R. Satapathy <adityaranjanwxd@gmail.com>
Signed-off-by: Aditya R. Satapathy <adityaranjanwxd@gmail.com>
🎊 PR Merged SuccessfullyHey @Myparadox-creator! 👋 Congratulations and thank you for your contribution to VoiceForge! Note 🔗 Linked issue(s): #1109 · ✅ Marked as merged and complete Maintainers may still handle final cleanup, release notes, or follow-up tracking after the merge. 🤖 VoiceForge Automation · Updates automatically on edits |
🚀 Program
ELUSOC
📝 Description
This PR introduces a production-ready Docker setup for VoiceForge, streamlining containerized deployment with multi-stage builds, non-root security compliance, automated healthchecks, and unified static asset serving.
Key Changes:
Dockerfile: Built onnode:20-alpinewith separatebuilder(compiles React client) and unprivilegedrunner(USER node) stages.server/index.jsto serve compiled React SPA assets fromclient/distwhen in production mode (NODE_ENV=production) with SPA route fallback.docker-compose.ymlfor single-command stack orchestration (docker compose up -d --build)..dockerignore): Excludednode_modules, test artifacts, logs, and unnecessary binaries to minimize container context footprint (~150MB).App.jsx,Onboarding.jsx,Call.jsx,VoiceRecorder.jsx, andSpeechHistory.jsx.🔗 Related Issue
Closes #1109
🔄 Type of Change
🧪 How to Test
docker build -t voiceforge:latest .docker run -d --name voiceforge-app -p 3001:3001 voiceforge:latestcurl http://localhost:3001/api/health(Returns{"ok":true,"service":"voiceforge-api"})curl http://localhost:3001/api/voice/statusOpen
http://localhost:3001in Chrome or Edge browser.docker exec voiceforge-app id(Outputsuid=1000(node))docker compose up -d --build📸 Screenshots (if applicable)
Screenshot 1: Successful Docker Build
Screenshot 2: Active Container & Healthcheck
Screenshot 3: API Endpoint Verification
Screenshot 4: VoiceForge UI in Browser
Screenshot 5: Build matrics
✅ Checklist
feat: add voice preview)Summary by CodeRabbit