Skip to content

fix(web): normalize chat user id fields for own-message rendering#484

Merged
manNomi merged 1 commit intomainfrom
codex/investigate-chat-user-id-mismatch
Mar 14, 2026
Merged

fix(web): normalize chat user id fields for own-message rendering#484
manNomi merged 1 commit intomainfrom
codex/investigate-chat-user-id-mismatch

Conversation

@manNomi
Copy link
Contributor

@manNomi manNomi commented Mar 14, 2026

Background

  • In mentor chat, own messages could render as partner messages.
  • Root cause is id field mismatch across sources (senderId vs siteUserId) and token sub type mismatch (string / number).

What I changed

  • Added chat response normalization layer to accept both senderId and siteUserId.
  • Applied normalization to chat histories, chat room list, and chat partner API responses.
  • Applied the same normalization to WebSocket incoming messages.
  • Made JWT sub accept number | string and converted to numeric user id in chat content.

Bruno-based verification

  • Bruno chat history docs use siteUserId in message payload.
  • Bruno chat partner docs use siteUserId for partner id.
  • Bruno email-login docs show JWT payload with sub as string.

Validation

  • pnpm --filter @solid-connect/web run ci:check
  • pre-push CI parity hook (lint/typecheck/build)

@vercel
Copy link

vercel bot commented Mar 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
solid-connection-web Ready Ready Preview, Comment Mar 14, 2026 0:53am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
solid-connect-web-admin Skipped Skipped Mar 14, 2026 0:53am

@github-actions github-actions bot added the web label Mar 14, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

Walkthrough

이 변경사항은 채팅 API 계층에서 원본 데이터 정규화 처리를 도입합니다. 새로운 normalize.ts 모듈이 추가되어 원본 서버 응답(RawChatMessage, RawChatPartner, RawChatRoom)을 타입 안전한 모델로 변환합니다. API 엔드포인트 함수들(getChatHistories, getChatRooms, getChatPartner)은 이제 정규화 함수를 거쳐 데이터를 반환하며, WebSocket 메시지 처리와 JWT 페이로드 타입도 이 패턴에 맞춰 업데이트됩니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

상세 변경 사항

  1. apps/web/src/apis/chat/normalize.ts - 새로운 정규화 모듈 추가

    • 원본 데이터 타입(RawChatMessage, RawChatPartner, RawChatRoom)과 정규화 함수들(normalizeChatMessage, normalizeChatPartner, normalizeChatRoom)을 정의합니다.
    • 내부 헬퍼 타입(NumericLike)과 함수(toNumber, normalizeAttachment)를 통해 안전한 타입 강제와 기본값 처리를 수행합니다.
    • 선택적 필드와 배열에 대한 방어적 처리로 안정성을 보장합니다.
  2. apps/web/src/apis/chat/api.ts - API 레이어 정규화 적용

    • 원본 응답 타입(RawChatHistoriesResponse, RawChatRoomListResponse)을 정의하고 import합니다.
    • 각 API 함수(getChatHistories, getChatRooms, getChatPartner)에서 응답 데이터를 정규화 함수를 거쳐 반환하도록 수정합니다.
    • 배열 데이터에 기본값(빈 배열)을 적용하여 nullish 값을 방어합니다.
  3. apps/web/src/lib/web-socket/useConnectWebSocket.ts - WebSocket 메시지 정규화

    • 수신한 WebSocket 메시지를 normalizeChatMessage를 통해 처리하여 타입 일관성을 유지합니다.
  4. apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx - userId 변환 명시화

    • 접근 토큰에서 userId를 추출할 때 명시적 Number() 강제 변환으로 수치 타입을 보장합니다.
  5. apps/web/src/utils/jwtUtils.ts - JwtPayload 타입 확대

    • JwtPayload 인터페이스의 sub 필드를 number | string으로 변경하여 문자열 형태의 주제(subject) 클레임도 지원합니다.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive PR 설명이 기본 구조를 따르지만 한국어 템플릿 섹션(관련 이슈, 작업 내용, 특이 사항, 리뷰 요구사항)이 누락되고 영어로 작성되었습니다. 한국어 템플릿 구조에 맞춰 재작성하되, '관련 이슈', '작업 내용', '특이 사항', '리뷰 요구사항' 섹션을 명확히 구분하여 작성해 주세요.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 주요 변경사항인 채팅 사용자 ID 정규화 및 자신의 메시지 렌더링 수정을 명확하게 요약하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/investigate-chat-user-id-mismatch
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/web/src/lib/web-socket/useConnectWebSocket.ts (1)

57-65: 정규화 로직이 잘 적용되었으나, 빈 catch 블록은 개선이 필요합니다.

  1. 정규화 적용 - 좋습니다:

    • normalizeChatMessage()를 통해 WebSocket 메시지도 API 응답과 동일한 정규화 처리를 받습니다.
  2. createdAt 검증 - 훌륭합니다:

    • 유효하지 않은 날짜에 대한 방어적 코딩이 적용되어 있습니다.
  3. 빈 catch 블록 - 개선 권장:

    • 파싱 실패 시 완전히 무시되어 디버깅이 어려울 수 있습니다.
♻️ 최소한의 로깅 추가 제안
            } catch (error) {
+             console.warn("[WebSocket] Failed to parse message:", error);
            }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/lib/web-socket/useConnectWebSocket.ts` around lines 57 - 65, The
catch block swallowing JSON parse/normalize errors needs a minimal
logging/diagnostic step: in the try/catch inside useConnectWebSocket where you
parse and normalize messages (normalizeChatMessage, setSubmittedMessages),
replace the empty catch with code that logs the error and context (at least the
caught error and message.body or a summarized payload) using the existing logger
or console.error so parsing failures are visible for debugging; keep the
defensive createdAt fix and do not rethrow, just ensure the catch records error
details and context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/web/src/lib/web-socket/useConnectWebSocket.ts`:
- Around line 57-65: The catch block swallowing JSON parse/normalize errors
needs a minimal logging/diagnostic step: in the try/catch inside
useConnectWebSocket where you parse and normalize messages
(normalizeChatMessage, setSubmittedMessages), replace the empty catch with code
that logs the error and context (at least the caught error and message.body or a
summarized payload) using the existing logger or console.error so parsing
failures are visible for debugging; keep the defensive createdAt fix and do not
rethrow, just ensure the catch records error details and context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 91f71cd0-8d4b-4c3b-9e23-bb8f1eed825b

📥 Commits

Reviewing files that changed from the base of the PR and between 7244ef1 and 40be340.

📒 Files selected for processing (5)
  • apps/web/src/apis/chat/api.ts
  • apps/web/src/apis/chat/normalize.ts
  • apps/web/src/app/mentor/chat/[chatId]/_ui/ChatContent/index.tsx
  • apps/web/src/lib/web-socket/useConnectWebSocket.ts
  • apps/web/src/utils/jwtUtils.ts

@manNomi manNomi merged commit 1d50ae6 into main Mar 14, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant