Skip to content

[Feat] Q&A 페이지 SSE 실시간 갱신 적용#188

Merged
issuejong merged 8 commits into
developfrom
feat/#185
Jun 7, 2026
Merged

[Feat] Q&A 페이지 SSE 실시간 갱신 적용#188
issuejong merged 8 commits into
developfrom
feat/#185

Conversation

@issuejong

Copy link
Copy Markdown
Collaborator

#️⃣연관된 이슈

#185

📝작업 내용

Q&A 메인/상세 페이지에 SSE 구독을 연결하고, 질문·댓글·이해도 체크 관련 변경 사항이 실시간으로 반영되도록 구현했습니다.

  • 프론트 SSE 구독 유틸 추가

    • frontend/src/utils/sse.js 추가
    • fetch 기반 SSE 스트림 구독 로직 구현
    • JWT 토큰을 Authorization 헤더에 포함하여 SSE 연결
    • SSE 메시지 파싱, 재연결, 연결 종료 처리 지원
    • subscribeQuestionEvents(sessionId) 유틸로 질문방 이벤트 구독 공통화
  • 질문 메인 페이지 SSE 연결

    • QnAListPage에서 세션별 질문방 SSE 이벤트 구독
    • comment-created, comment-updated, question-created, question-updated, understanding-check-created, understanding-response-updated 이벤트 처리
    • 이벤트 수신 시 질문 목록, 댓글 미리보기, 이해도 체크 현황을 실시간 갱신
  • 질문 메인 댓글 실시간 반영

    • 댓글 생성/수정/삭제 이벤트 수신 시 해당 질문의 댓글 수와 미리보기 댓글 갱신
    • 전체 목록을 다시 불러오지 않고 이벤트 데이터 기준으로 필요한 질문만 업데이트
    • 질문 상태가 변경된 경우 인기/미해결/해결 그룹 재분류
  • 질문 메인 이해도 실시간 반영

    • 이해도 체크 생성 이벤트 수신 시 현재 이해도 영역 갱신
    • 이해도 응답 수 변경 이벤트 수신 시 respondedCount, attendanceCount, understoodCount, notUnderstoodCount 실시간 반영
    • 현재 보고 있는 이해도 체크 위치에 따라 인덱스와 이전/다음 여부 조정
  • 질문 상세 페이지 댓글 실시간 반영

    • QnADetailPage에서도 세션별 SSE 이벤트 구독
    • 댓글 생성/수정/삭제 이벤트 수신 시 질문 상세 정보를 다시 조회하여 댓글 목록 갱신
    • 대댓글 구조까지 반영할 수 있도록 댓글 렌더링 로직을 재귀 함수로 정리
    • 댓글/대댓글 이미지 blob 변환 로직 공통화
  • 질문 상태 변경 SSE 이벤트 반영

    • 좋아요, 질문 수정, 질문 삭제, 해결 상태 변경 시 question-updated 이벤트 발행
    • 메인 페이지에서는 질문 목록의 좋아요 수, 해결 상태, 삭제 여부를 실시간 반영
    • 상세 페이지에서는 현재 질문이 삭제된 경우 이전 페이지로 이동
  • 댓글 수정/삭제 SSE 이벤트 추가

    • 백엔드에 CommentUpdatedEvent 추가
    • 댓글 수정/삭제 후 댓글 수와 댓글 미리보기 목록을 SSE로 전파
    • 댓글 변경 이벤트도 트랜잭션 커밋 이후 발행되도록 처리

@issuejong issuejong requested a review from Copilot June 7, 2026 03:31
@issuejong issuejong self-assigned this Jun 7, 2026
@issuejong issuejong added the enhancement New feature or request label Jun 7, 2026
@issuejong issuejong linked an issue Jun 7, 2026 that may be closed by this pull request
3 tasks
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
piro-in Ready Ready Preview, Comment Jun 7, 2026 3:43am
piro-in-765d Ready Ready Preview, Comment Jun 7, 2026 3:43am

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Q&A 메인/상세 페이지에서 세션별 질문방 SSE를 구독해 질문/댓글/이해도 체크 변경 사항을 실시간으로 반영하고, 백엔드에서도 관련 이벤트 발행을 보강한 PR입니다.

Changes:

  • 프론트에 fetch 기반 SSE 구독 유틸을 추가하고, Q&A 목록/상세 페이지에 SSE 이벤트 처리 로직을 연결
  • Q&A 목록에서 댓글/질문/이해도 이벤트에 따라 질문 그룹(인기/미해결/해결)과 이해도 카운트를 실시간 갱신
  • 백엔드에서 질문 상태 변경 및 댓글 수정/삭제에 대한 SSE 이벤트 발행(트랜잭션 커밋 이후) 추가

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/src/utils/sse.js fetch 스트림 기반 SSE 구독/파싱/재연결 유틸 추가 및 세션 질문방 구독 헬퍼 제공
frontend/src/pages/qna/QnAListPage.js 세션 질문방 SSE 구독 및 질문/댓글/이해도 이벤트 기반 실시간 상태 갱신 로직 추가
frontend/src/pages/qna/QnADetailPage.module.css 대댓글(리플) 렌더링을 위한 레이아웃/반응형 스타일 추가
frontend/src/pages/qna/QnADetailPage.js 상세 페이지 SSE 구독 추가, 댓글/대댓글 트리 렌더링 및 이미지 blob 변환 로직 공통화
backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionService.java 좋아요/수정/삭제/해결/댓글 수정·삭제 시 커밋 후 SSE 이벤트 발행 로직 추가
backend/src/main/java/com/example/Piroin/project/domain/question/service/QuestionEventService.java comment-updated, question-updated 이벤트 브로드캐스트 메서드 추가
backend/src/main/java/com/example/Piroin/project/domain/question/dto/QuestionResDTO.java CommentUpdatedEvent, QuestionUpdatedEvent SSE DTO 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +34
const POPULAR_LIKE_THRESHOLD = 5;

const getCreatedAtTime = (question) => new Date(question.createdAt ?? 0).getTime();

const sortQuestionGroups = (groups) => ({
popularQuestions: [...groups.popularQuestions].sort(
(a, b) => (b.likeCount ?? 0) - (a.likeCount ?? 0) || getCreatedAtTime(b) - getCreatedAtTime(a)
),
unresolvedQuestions: [...groups.unresolvedQuestions].sort(
(a, b) => getCreatedAtTime(b) - getCreatedAtTime(a)
),
resolvedQuestions: [...groups.resolvedQuestions].sort(
(a, b) => getCreatedAtTime(b) - getCreatedAtTime(a)
),
});

const getQuestionGroupKey = (question) => {
if (question.isResolved) return 'resolvedQuestions';
if ((question.likeCount ?? 0) >= POPULAR_LIKE_THRESHOLD) return 'popularQuestions';
return 'unresolvedQuestions';
};
Comment on lines +291 to +297
let blobImageUrl = null;
if (eventData.imageUrl) {
try {
const imgRes = await authFetch(eventData.imageUrl);
const blob = await imgRes.blob();
blobImageUrl = URL.createObjectURL(blob);
} catch {
Comment on lines +30 to +37
const createBlobImageUrl = async (imageUrl) => {
if (!imageUrl) return null;

try {
const imgRes = await authFetch(imageUrl);
const blob = await imgRes.blob();
return URL.createObjectURL(blob);
} catch {
@issuejong issuejong merged commit 23adcc5 into develop Jun 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] SSE 빠진 기능 구현

2 participants