Codebase refactor#42
Conversation
fix: typechecker warnings
…move unused imports and enhance error handling
- Created comprehensive test suites for Chat, CustomRoom, and Documentation components to ensure proper rendering and functionality. - Implemented tests for JoinRoom component, covering both anonymous and registered user flows. - Added setup file for Vitest to configure testing environment and mock necessary browser APIs. - Updated Vite configuration to include testing setup and coverage reporting.
…structure, database schema, frontend structure, real-time messaging, and testing procedures
|
Warning Review limit reached
More reviews will be available in 47 minutes and 20 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThis PR adds Claude automation and safety hooks, refactors backend app/CORS/env wiring and some contracts, implements extensive backend and frontend test infra and suites, updates frontend chat/join runtime flows, and adds comprehensive documentation and CI configuration. ChangesIntegrated backend, frontend, tooling, and docs update
🎯 3 (Moderate) | ⏱️ ~25 minutes ✨ Finishing Touches🧪 Generate unit tests (beta)
|
- downgraded @tailwindcss/vite and tailwindcss to version 4.3.0 - updated @vitejs/plugin-react to version 6.0.2 - updated @vitest/coverage-v8 to version 4.1.8 - updated vite to version 8.0.16 - updated vitest to version 4.1.8
|
@coderabbitai its been 5 hours and your still processing changes, any issues? |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check the PR status and review comments
gh pr view 42 --repo wavey-waves/waves --json state,title,reviews,comments,updatedAt,createdAt
# Also check for any check runs / status
gh pr checks 42 --repo wavey-waves/waves 2>/dev/null || echo "No checks available"Length of output: 7910
The best fix is to kick off a fresh review. I'll trigger one now: (´• ω •`) ごめんなさい 🐇 ✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/ARCHITECTURE.md (1)
117-117:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winInconsistent env loading documentation.
Line 117 states environment variables are "Loaded via
dotenv.config()inapp.js", but according to the review stack context and BACKEND_STRUCTURE.md, environment loading is handled bylibs/env.jswhich is imported first. The statement should referencelibs/env.jsas the centralized environment loader.📝 Suggested fix
-`PORT`, `MONGODB_URI`, `JWT_SECRET`, `NODE_ENV`. Loaded via `dotenv.config()` in `app.js`. +`PORT`, `MONGODB_URI`, `JWT_SECRET`, `NODE_ENV`. Loaded via `libs/env.js` (which calls `dotenv.config()` and is imported by `app.js` and `index.js`).🤖 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 `@docs/ARCHITECTURE.md` at line 117, Update the statement on line 117 to reference the centralized environment loader instead of app.js: replace the claim that env vars are "Loaded via dotenv.config() in app.js" with text indicating they are loaded via libs/env.js (the module responsible for loading and exposing process env), and ensure any mention of dotenv is tied to libs/env.js rather than app.js so documentation matches the actual bootstrap sequence where libs/env.js is imported first.
🧹 Nitpick comments (8)
docs/BACKEND_STRUCTURE.md (2)
45-52: ⚡ Quick winAdd language identifier to fenced code block.
The request lifecycle diagram should have a language identifier for consistency.
📝 Suggested fix
-``` +```text HTTP request → app.js middleware: express.json → request-ip → cookieParser → cors → router (/api/auth | /api/messages | /api/rooms)🤖 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 `@docs/BACKEND_STRUCTURE.md` around lines 45 - 52, Add a language identifier to the fenced code block that starts with "HTTP request" so the block is rendered consistently; locate the triple-backtick block containing the HTTP request lifecycle (lines beginning "HTTP request → app.js middleware: express.json → request-ip → cookieParser → cors") and change the opening fence to include a language tag such as "text" (e.g., ```text) to ensure proper formatting.Source: Linters/SAST tools
7-29: ⚡ Quick winAdd language identifier to fenced code block.
The directory tree should have a language identifier for proper syntax highlighting.
📝 Suggested fix
-``` +```text backend/src/ ├── index.js # entry point: listens + connectDB ├── app.js # configures the shared Express app (middleware, routes, prod static, error handler)🤖 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 `@docs/BACKEND_STRUCTURE.md` around lines 7 - 29, The fenced code block in BACKEND_STRUCTURE.md lacks a language identifier; update the opening fence for the directory tree (the block showing backend/src/ and the file list including index.js, app.js, libs/socket.js, etc.) to include a language identifier such as "text" (e.g., change ``` to ```text) so the tree renders with proper syntax highlighting.Source: Linters/SAST tools
docs/ARCHITECTURE.md (2)
9-17: ⚡ Quick winAdd language identifier to fenced code block.
The code block should specify a language for proper syntax highlighting and tooling support.
📝 Suggested fix
-``` +```text waves/ ├── frontend/ # React 19 + Vite + Tailwind v4 (separate npm package) ├── backend/ # Express + Socket.IO, ES modules (separate npm package)🤖 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 `@docs/ARCHITECTURE.md` around lines 9 - 17, Update the fenced code block in docs/ARCHITECTURE.md that contains the "waves/" directory tree to include a language identifier for proper highlighting (e.g., change the opening ``` to ```text or ```bash); locate the block that starts with the lines showing "waves/" and the tree entries ("frontend/", "backend/", "docs/", etc.) and replace the fence accordingly so the snippet is ```text ... ``` (no other changes).Source: Linters/SAST tools
54-82: ⚡ Quick winAdd language identifier to fenced code block.
The ASCII diagram should have a language identifier for consistency and tooling support.
📝 Suggested fix
-``` +```text Sender (Chat.jsx) Receiver (Chat.jsx) ───────────────── ───────────────────🤖 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 `@docs/ARCHITECTURE.md` around lines 54 - 82, The fenced ASCII diagram block in ARCHITECTURE.md lacks a language identifier; update the opening triple-backtick for the diagram in the shown block to include a language token (e.g., ```text) so tooling and linters treat it correctly. Locate the ASCII diagram block (the triple-backtick that precedes "Sender (Chat.jsx) Receiver (Chat.jsx) …") and change it to include the language identifier, ensuring the closing triple-backtick remains unchanged; no other content modifications are needed.Source: Linters/SAST tools
frontend/src/App.jsx (1)
385-392: ⚡ Quick winDead state can be removed entirely.
The
userandroomTypestate (lines 385-387) andhandleJoinRoom(389-392) appear unused:ChatRoutemanages its own localuserstate (line 254) and doesn't read from App-level state, and no other component consumes these values. Consider removing both the state declarations andhandleJoinRoom, then updatingHometo no longer expect anonJoinRoomprop.🤖 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 `@frontend/src/App.jsx` around lines 385 - 392, Remove the dead App-level state and handler: delete the useState declarations that define the unused setters (const [, setUser] = useState(null); const [, setRoomType] = useState(null);) and remove the handleJoinRoom function; then update where App passes props to Home to stop supplying onJoinRoom and remove any references to setUser/setRoomType or handleJoinRoom. Confirm ChatRoute still manages its own user state (ChatRoute) and that no other components consume the removed App-level values before committing.frontend/src/test/setup.js (1)
46-61: ⚖️ Poor tradeoffWebRTC fake's
localDescriptionbehavior differs from the real API.The fake sets
localDescriptionimmediately in the constructor (Line 49), but realRTCPeerConnectionhas it asnulluntilsetLocalDescription()is called. Additionally, the fake'ssetLocalDescriptionmethod (Line 56) doesn't update thelocalDescriptionproperty.This could mask bugs where production code reads
localDescriptionbefore callingsetLocalDescription. However, for testing basic signaling flows (offer/answer/ICE) where the fake methods return resolved promises, this should be adequate.💡 Optional enhancement for more realistic behavior
If you want the fake to more closely match real WebRTC:
class FakeRTCPeerConnection { constructor() { this.connectionState = 'new' - this.localDescription = { type: 'offer', sdp: 'fake-sdp' } + this.localDescription = null this.onicecandidate = null this.onconnectionstatechange = null this.ondatachannel = null this.createDataChannel = vi.fn((label) => new FakeDataChannel(label)) this.createOffer = vi.fn(() => Promise.resolve({ type: 'offer', sdp: 'fake-offer' })) this.createAnswer = vi.fn(() => Promise.resolve({ type: 'answer', sdp: 'fake-answer' })) - this.setLocalDescription = vi.fn(() => Promise.resolve()) + this.setLocalDescription = vi.fn((desc) => { + this.localDescription = desc || { type: 'offer', sdp: 'fake-sdp' } + return Promise.resolve() + }) this.setRemoteDescription = vi.fn(() => Promise.resolve()) this.addIceCandidate = vi.fn(() => Promise.resolve()) this.close = vi.fn() } }🤖 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 `@frontend/src/test/setup.js` around lines 46 - 61, FakeRTCPeerConnection currently initializes localDescription in the constructor and never updates it; change it so localDescription is initialized to null and update the setLocalDescription method on FakeRTCPeerConnection to assign the passed description (e.g., the argument to setLocalDescription) to this.localDescription before resolving its promise; this preserves current promise behavior but makes reads of localDescription match real RTCPeerConnection semantics.backend/src/index.js (1)
14-14: 💤 Low valueInconsistent semicolon style.
Line 14 is missing a semicolon after the closing brace, while other statements in the file use semicolons consistently. Consider adding it for style consistency, although this is purely cosmetic.
📝 Proposed fix
connectDB(); -}) +});🤖 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 `@backend/src/index.js` at line 14, The file ends with a closing brace and parenthesis token "})" missing a trailing semicolon; add a semicolon after that token (change "})" to "});") to match the file's semicolon style and run the project's linter/Prettier to ensure consistency across statements (locate the final closing "})" in backend/src/index.js where the callback/block ends).backend/tests/socket.test.js (1)
83-97: Add isolation coverage tests forwebrtc-answerandwebrtc-ice-candidateThe
webrtc-answerandwebrtc-ice-candidaterelay handlers inbackend/src/libs/socket.jsalready gate on room sharing before emitting to the target, butbackend/tests/socket.test.jscurrently only asserts the “no relay across different rooms” behavior forwebrtc-offer(no tests mentionwebrtc-answer/webrtc-ice-candidate). Add analogous isolation tests for those events to cover the full guideline set.🤖 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 `@backend/tests/socket.test.js` around lines 83 - 97, Add two new tests mirroring the existing "does NOT relay signaling between peers that share no room" case for the events 'webrtc-answer' and 'webrtc-ice-candidate': use connect() to create sockets a and b, have a join 'room-a' and b join 'room-b', await once(a,'existing-room-users') and once(b,'existing-room-users'), create guards with never(b,'webrtc-answer') and never(b,'webrtc-ice-candidate'), emit a.emit('webrtc-answer', { answer: {...}, to: b.id }) and a.emit('webrtc-ice-candidate', { candidate: {...}, to: b.id }) respectively, and assert await expect(guard).resolves.toBeUndefined(); finally disconnect a and b—this will exercise the room-sharing gate implemented in the relay handlers in backend/src/libs/socket.js.Source: Coding guidelines
🤖 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 @.claude/agents/coderabbit-fixer.md:
- Around line 60-78: The GraphQL query relying on reviewThreads.nodes and
reviewThreads.nodes.comments.nodes must handle schema differences where
databaseId may be missing/deprecated; update the code that processes
reviewThreads, comments, and Step 7 to fall back from comments.nodes.databaseId
to other available identifiers (e.g., comment.id or
PullRequestReviewComment.fullDatabaseId / node.id) and detect presence of
PullRequestReviewComment fields (path, line) before using them; specifically,
adjust the comment-filtering and ID-capture logic that references reviewThreads,
comments, databaseId, PullRequestReviewComment, and Step 7 so it accepts either
databaseId or alternative IDs and skips reply-posting for cover-letter review
bodies without databaseId.
In @.claude/commands/fix-coderabbit.md:
- Around line 21-25: The lock key generation currently pipes the file path
through `sha1sum` which can fail on systems without that tool; update the lock
acquisition logic used by session-lock.sh (the `acquire` invocation) to compute
the hash portably by trying `sha1sum`, then `shasum -a 1`, then `openssl dgst
-sha1` (or similar fallbacks) and only error if none are available, or
alternatively add a short doc note listing required tooling; modify the code
that builds the `"cr-fixer:$(printf '%s' '<path>' | sha1sum | cut -c1-12)"`
token to use the chosen fallback sequence so `session-lock.sh acquire` receives
a valid opaque gate on all platforms.
In @.claude/hooks/block-destructive-git.js:
- Around line 56-72: The existing FORBIDDEN entry that matches git config only
catches explicit write flags but misses the two-argument write form (e.g., git
config user.name "Alice"); update the FORBIDDEN array by adding a second rule
after the current /\bgit\s+config\s+(--global|...)\b/ entry that detects the
simple write pattern (match commands like git config <key> <value> but not
options starting with -); use a regex such as /\bgit\s+config\s+[^\s-][^\s]*\s+/
with the same human-friendly message like "git config (write)" so simple
key/value writes are blocked alongside the existing flag-based rule.
In `@backend/src/libs/allowedOrigins.js`:
- Around line 16-18: The allowedOrigins array in allowedOrigins.js currently
contains bare IP strings (e.g., '13.228.225.19', '18.142.128.26',
'54.254.162.138') which won't match browser Origin headers; update those entries
to include the scheme (e.g., 'https://13.228.225.19' and/or
'http://13.228.225.19') or replace the array with a regex/function-based origin
matcher used by the CORS/Socket.IO config (locate the exported allowedOrigins
array or the origin-checking function in allowedOrigins.js and adjust the
entries/logic accordingly).
---
Outside diff comments:
In `@docs/ARCHITECTURE.md`:
- Line 117: Update the statement on line 117 to reference the centralized
environment loader instead of app.js: replace the claim that env vars are
"Loaded via dotenv.config() in app.js" with text indicating they are loaded via
libs/env.js (the module responsible for loading and exposing process env), and
ensure any mention of dotenv is tied to libs/env.js rather than app.js so
documentation matches the actual bootstrap sequence where libs/env.js is
imported first.
---
Nitpick comments:
In `@backend/src/index.js`:
- Line 14: The file ends with a closing brace and parenthesis token "})" missing
a trailing semicolon; add a semicolon after that token (change "})" to "});") to
match the file's semicolon style and run the project's linter/Prettier to ensure
consistency across statements (locate the final closing "})" in
backend/src/index.js where the callback/block ends).
In `@backend/tests/socket.test.js`:
- Around line 83-97: Add two new tests mirroring the existing "does NOT relay
signaling between peers that share no room" case for the events 'webrtc-answer'
and 'webrtc-ice-candidate': use connect() to create sockets a and b, have a join
'room-a' and b join 'room-b', await once(a,'existing-room-users') and
once(b,'existing-room-users'), create guards with never(b,'webrtc-answer') and
never(b,'webrtc-ice-candidate'), emit a.emit('webrtc-answer', { answer: {...},
to: b.id }) and a.emit('webrtc-ice-candidate', { candidate: {...}, to: b.id })
respectively, and assert await expect(guard).resolves.toBeUndefined(); finally
disconnect a and b—this will exercise the room-sharing gate implemented in the
relay handlers in backend/src/libs/socket.js.
In `@docs/ARCHITECTURE.md`:
- Around line 9-17: Update the fenced code block in docs/ARCHITECTURE.md that
contains the "waves/" directory tree to include a language identifier for proper
highlighting (e.g., change the opening ``` to ```text or ```bash); locate the
block that starts with the lines showing "waves/" and the tree entries
("frontend/", "backend/", "docs/", etc.) and replace the fence accordingly so
the snippet is ```text ... ``` (no other changes).
- Around line 54-82: The fenced ASCII diagram block in ARCHITECTURE.md lacks a
language identifier; update the opening triple-backtick for the diagram in the
shown block to include a language token (e.g., ```text) so tooling and linters
treat it correctly. Locate the ASCII diagram block (the triple-backtick that
precedes "Sender (Chat.jsx) Receiver (Chat.jsx)
…") and change it to include the language identifier, ensuring the closing
triple-backtick remains unchanged; no other content modifications are needed.
In `@docs/BACKEND_STRUCTURE.md`:
- Around line 45-52: Add a language identifier to the fenced code block that
starts with "HTTP request" so the block is rendered consistently; locate the
triple-backtick block containing the HTTP request lifecycle (lines beginning
"HTTP request → app.js middleware: express.json → request-ip → cookieParser →
cors") and change the opening fence to include a language tag such as "text"
(e.g., ```text) to ensure proper formatting.
- Around line 7-29: The fenced code block in BACKEND_STRUCTURE.md lacks a
language identifier; update the opening fence for the directory tree (the block
showing backend/src/ and the file list including index.js, app.js,
libs/socket.js, etc.) to include a language identifier such as "text" (e.g.,
change ``` to ```text) so the tree renders with proper syntax highlighting.
In `@frontend/src/App.jsx`:
- Around line 385-392: Remove the dead App-level state and handler: delete the
useState declarations that define the unused setters (const [, setUser] =
useState(null); const [, setRoomType] = useState(null);) and remove the
handleJoinRoom function; then update where App passes props to Home to stop
supplying onJoinRoom and remove any references to setUser/setRoomType or
handleJoinRoom. Confirm ChatRoute still manages its own user state (ChatRoute)
and that no other components consume the removed App-level values before
committing.
In `@frontend/src/test/setup.js`:
- Around line 46-61: FakeRTCPeerConnection currently initializes
localDescription in the constructor and never updates it; change it so
localDescription is initialized to null and update the setLocalDescription
method on FakeRTCPeerConnection to assign the passed description (e.g., the
argument to setLocalDescription) to this.localDescription before resolving its
promise; this preserves current promise behavior but makes reads of
localDescription match real RTCPeerConnection semantics.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 8a7ed168-dda8-46db-a427-eb73bcdae061
⛔ Files ignored due to path filters (2)
backend/package-lock.jsonis excluded by!**/package-lock.jsonfrontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (55)
.claude/.gitignore.claude/agents/coderabbit-fixer.md.claude/commands/fix-coderabbit.md.claude/hooks/block-destructive-git.js.claude/lib/session-lock.sh.claude/scripts/agent-progress-monitor.sh.claude/settings.json.gitignoreCLAUDE.mdbackend/.env.examplebackend/eslint.config.jsbackend/package.jsonbackend/src/app.jsbackend/src/controllers/auth.controller.jsbackend/src/controllers/message.controller.jsbackend/src/controllers/room.controller.jsbackend/src/index.jsbackend/src/libs/allowedOrigins.jsbackend/src/libs/env.jsbackend/src/libs/socket.jsbackend/src/middleware/auth.middleware.jsbackend/src/models/message.model.jsbackend/src/models/room.model.jsbackend/tests/allowedOrigins.test.jsbackend/tests/auth.controller.test.jsbackend/tests/auth.middleware.test.jsbackend/tests/helpers/index.jsbackend/tests/message.controller.test.jsbackend/tests/models.test.jsbackend/tests/room.controller.test.jsbackend/tests/setup.jsbackend/tests/socket.test.jsbackend/tests/utils.test.jsbackend/tsconfig.jsonbackend/vitest.config.jsdocs/API.mddocs/ARCHITECTURE.mddocs/BACKEND_STRUCTURE.mddocs/DATABASE_SCHEMA.mddocs/FRONTEND_STRUCTURE.mddocs/README.mddocs/REALTIME.mddocs/TESTING.mdfrontend/eslint.config.jsfrontend/package.jsonfrontend/src/App.jsxfrontend/src/App.test.jsxfrontend/src/components/Chat.jsxfrontend/src/components/Chat.test.jsxfrontend/src/components/CustomRoom.test.jsxfrontend/src/components/Documentation.test.jsxfrontend/src/components/JoinRoom.jsxfrontend/src/components/JoinRoom.test.jsxfrontend/src/test/setup.jsfrontend/vite.config.js
💤 Files with no reviewable changes (1)
- backend/src/models/message.model.js
…tend components for clarity
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
docs/TESTING.md (1)
54-54: ⚡ Quick winConsider adding caution about
npm audit fixbehavior.The guidance suggests running
npm audit fixto address vulnerabilities, but this command can introduce breaking changes by updating to newer major versions. Consider revising to recommend reviewingnpm auditoutput first and testing changes after applying fixes.Suggested addition: "triage by reviewing
npm auditoutput, then runnpm audit fixand test thoroughly (as it may introduce breaking changes) or manually bump the offending dependency."🤖 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 `@docs/TESTING.md` at line 54, Update the paragraph that recommends "triage by running `npm audit fix`" to warn that `npm audit fix` can introduce breaking changes by upgrading major versions: advise first reviewing `npm audit` output, running `npm audit fix` only after review, testing thoroughly, or manually bumping the offending dependency; include this guidance in the same block that references the `security-audit` job and `--audit-level` so readers see the caution alongside the existing remediation steps.backend/tests/socket.test.js (1)
36-45: 💤 Low valuePotential socket listener leak in
never()helper on success path.When the timeout resolves (event never arrived), the
socket.once()listener is not removed. If the event arrives afternever()resolves but before the socket disconnects, the listener callback will execute and callclearTimeout(timer)on an already-fired timer, which is harmless but wasteful. More importantly, this orphaned listener could theoretically interfere with subsequent assertions in the same test if the socket were reused.Since all tests disconnect sockets immediately after, this is benign in practice—but cleaning up the listener makes the helper robust for future use.
♻️ Suggested fix
function never(socket, event, window = 400) { return new Promise((resolve, reject) => { - const timer = setTimeout(resolve, window) - socket.once(event, () => { + const handler = () => { clearTimeout(timer) reject(new Error(`unexpectedly received ${event}`)) - }) + } + const timer = setTimeout(() => { + socket.off(event, handler) + resolve() + }, window) + socket.once(event, handler) }) }🤖 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 `@backend/tests/socket.test.js` around lines 36 - 45, The never() helper leaves the socket.once listener attached when the timeout resolves; update never(socket, event, window) to store the listener callback in a variable (e.g., handler) and on timeout call socket.off(event, handler) (or socket.removeListener(event, handler) depending on your socket API) before resolving, and likewise keep the existing clearTimeout/clear cleanup when the listener fires so both success and failure paths remove the opposite handler; update the listener registration in never() to use that handler reference so the listener is cleaned up on timeout.
🤖 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 @.github/workflows/ci.yml:
- Around line 30-33: Replace all mutable action tags in the workflow (e.g., the
uses entries like "actions/checkout@v4" and "actions/setup-node@v4") with their
corresponding immutable full 40-character commit SHAs; update every "uses:" line
throughout the file (including the other occurrences referenced) so each action
reference uses the pinned SHA instead of a floating tag to prevent supply-chain
drift.
- Line 30: The checkout steps using the actions/checkout@v4 action currently
default to persisting credentials; update every checkout step that invokes
actions/checkout@v4 (the steps that currently read "uses: actions/checkout@v4")
to explicitly set persist-credentials: false under the step's with: block so
credentials are not kept for later steps; ensure you add this to each occurrence
of the checkout step in the workflow.
In `@frontend/src/App.jsx`:
- Line 23: Docs still list Home as accepting onJoinRoom but the Home component
signature in App.jsx no longer accepts that prop; update the
FRONTEND_STRUCTURE.md entry for the "/" route to remove onJoinRoom from the Home
props and revise any documented "join-success" callback parameters to reflect
the current Home implementation (match the actual props/state handlers used by
the Home function). Locate references to Home and the route in the docs and
replace the old prop example with the new Home signature and the correct
callback parameter names/shape so the documentation matches the code.
---
Nitpick comments:
In `@backend/tests/socket.test.js`:
- Around line 36-45: The never() helper leaves the socket.once listener attached
when the timeout resolves; update never(socket, event, window) to store the
listener callback in a variable (e.g., handler) and on timeout call
socket.off(event, handler) (or socket.removeListener(event, handler) depending
on your socket API) before resolving, and likewise keep the existing
clearTimeout/clear cleanup when the listener fires so both success and failure
paths remove the opposite handler; update the listener registration in never()
to use that handler reference so the listener is cleaned up on timeout.
In `@docs/TESTING.md`:
- Line 54: Update the paragraph that recommends "triage by running `npm audit
fix`" to warn that `npm audit fix` can introduce breaking changes by upgrading
major versions: advise first reviewing `npm audit` output, running `npm audit
fix` only after review, testing thoroughly, or manually bumping the offending
dependency; include this guidance in the same block that references the
`security-audit` job and `--audit-level` so readers see the caution alongside
the existing remediation steps.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 70fa6c17-c540-4145-94b9-ce2e6f38772b
⛔ Files ignored due to path filters (2)
backend/package-lock.jsonis excluded by!**/package-lock.jsonfrontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (14)
.claude/agents/coderabbit-fixer.md.claude/commands/fix-coderabbit.md.claude/hooks/block-destructive-git.js.coderabbit.yaml.github/workflows/ci.ymlbackend/package.jsonbackend/src/index.jsbackend/src/libs/allowedOrigins.jsbackend/tests/socket.test.jsdocs/ARCHITECTURE.mddocs/BACKEND_STRUCTURE.mddocs/TESTING.mdfrontend/package.jsonfrontend/src/App.jsx
✅ Files skipped from review due to trivial changes (2)
- docs/BACKEND_STRUCTURE.md
- docs/ARCHITECTURE.md
🚧 Files skipped from review as they are similar to previous changes (7)
- backend/src/libs/allowedOrigins.js
- .claude/commands/fix-coderabbit.md
- backend/package.json
- frontend/package.json
- backend/src/index.js
- .claude/hooks/block-destructive-git.js
- .claude/agents/coderabbit-fixer.md
…ongoDB index handling in tests
Test framework, type-checking, docs, tooling & bug fixes
Hardens Waves for production: adds full test suites and CI-style checks to both packages, introduces backend type-checking, consolidates configuration, writes a
docs/reference set, ports the.claude/agent tooling, and fixes several latent bugs surfaced along the way.Branch:
refactor→main· 57 files changed (+10,875 / −408)Why
The app shipped to production with no automated tests, no backend linting or type-checking, duplicated/drifted configuration, and a handful of latent bugs. This PR puts a verifiable safety net under the codebase and documents how it actually behaves today.
What changed
🧪 Testing (new)
mongodb-memory-server. 68 tests covering every controller (auth, room, message), all three models, the auth middleware,generateToken, the shared CORS origins module, and the Socket.IO / WebRTC signaling relay (real client connections). ~88% statement coverage (100% on models/routes/utils).JoinRoom,CustomRoom,Documentation, andChat(axios /socket.io-client/RTCPeerConnection/ toastify mocked). 100% onCustomRoom/Documentation, ~97%JoinRoom, ~81%Chat.🔎 Backend lint + type-checking (new)
tsc --checkJsoversrc/**/*.jswith JSDoc — type safety with no runtime change and no TypeScript migration.lint,typecheck,test,test:watch,test:coverage, andcheck(lint + typecheck + test).🧱 Refactor & config consolidation
index.jsintosrc/app.js(the single source of app configuration; what tests import).index.jsis now a thin entry point (listen+connectDB).src/libs/allowedOrigins.js(previously duplicated acrossapp.jsandsocket.jsand drifted). Extensible per-deployment via theCLIENT_ORIGINSenv var;src/libs/env.jsguarantees.envloads first. Documented in.env.example.📚 Documentation (new
docs/)ARCHITECTURE,BACKEND_STRUCTURE,FRONTEND_STRUCTURE,DATABASE_SCHEMA,API,REALTIME,TESTING, and aREADMEindex with a doc-ownership map.CLAUDE.mdupdated with the new commands, conventions, and tooling notes.🛠️
.claude/toolingblock-destructive-gitPreToolUse hook (guards against destructive git verbs).coderabbit-fixeragent +/fix-coderabbitcommand + auto-delegation hook, with per-file locking (session-lock.sh), backgroundMonitorprogress, and aSendMessagedrip-feed concurrency model.🐛 Bug fixes
Chat.jsxsubscribed touser-left; server emitsuserLeft→ handler never fireduserLeftloginreturned{ id }whilesignup/checkreturn{ _id }loginreturns_id; frontend readers updatedprotectedRoutereturned 500 for an expired/invalid tokentransportswas nested insidecors(ignored)socketRef.currentsynchronously (null) → socket never disconnectedleave+ disconnectsp2pSent(sent, ignored) + unusedimageschema field; 6 unused-var lint errorsVerification
cd backend && npm run check→ lint ✓ · typecheck ✓ · 68 tests ✓cd frontend && npm run lint(0 errors) ·npm test→ 63 tests ✓Summary by CodeRabbit
New Features
Bug Fixes
_id.Documentation
Tests
Chores