Skip to content

[REFACTOR] 롱 폴링 기반 상담 채팅 API 리팩터링 #39

@clainyun

Description

@clainyun

📌 이슈 유형

  • ✨ 새 기능 추가 (feat)
  • 🐛 버그 수정 (fix)
  • 🔧 기능 개선 (refactor)
  • 📚 문서 (docs)
  • 🧪 테스트 (test)
  • 🏗️ 빌드/배포 (ci/build)
  • 🔥 핫픽스 (hotfix)
  • 🧹 기타 작업 (chore)

🎯 배경 / 목적

API 규칙에 따라 상담 채팅 API 전체를 회원/기관용으로 명확하게 분리해야 한다.

기존 문제점

  • 모든 채팅 API가 /api/v1/chat/...에 몰려 있어 가독성 및 보안 관리가 어려움.
  • 기관 전용 API에서 institutionId를 PathVariable로 받아 보안 위험 존재.
  • 회원/기관 API가 한 컨트롤러에 혼합됨 → Swagger 구분 어려움 → 의도치 않은 접근 위험.

개선 목표

  • 회원/기관 채팅 API 엔드포인트를 완전히 분리하여 구조/보안을 강화.
  • 기관용 API는 adminDetails 기반으로 기관 식별하도록 변경.
  • 서비스 레이어에서 institutionId 의존성을 제거.

완료 조건 (AC)

✔ 회원용

  • 모든 회원 채팅 API가 /api/v1/member/chat/...형태로 제공된다.
  • 회원 상담 내역 조회 API는 /api/v1/member/consult-requests로 이동한다.
  • 회원은 본인 상담 요청/채팅방만 접근 가능하다.

✔ 기관 관리자용

  • 모든 기관 관리자 채팅 API가 /api/v1/institution/chat/... 형태로 제공된다.
  • 기관 상담 내역 조회 API는 /api/v1/institution/consult-requests로 제공된다.
  • 기관 API에서 institutionId PathVariable이 완전히 제거된다.
  • 기관 식별은 InstitutionAdminDetails → InstitutionAdmin → Institution.id 방식으로만 이루어진다.
  • 다른 기관 상담 내역/채팅방 접근 시 403 Forbidden 처리된다.

✔ 구조 개선

  • 기존 ChatController는 제거하거나 2개로 분리한다.

    • MemberChatController
    • InstitutionChatController
  • 엔드포인트 /api/v1/chat/...는 전부 폐기한다.


🛠️ 구현 상세

1) Controller 구조 개편

회원용 — MemberChatController

  • Base URL: /api/v1/member/chat

  • 엔드포인트:

    • POST /start
    • POST /rooms/{chatRoomId}/messages
    • GET /rooms/{chatRoomId}/messages
    • GET /rooms/{chatRoomId}/messages/poll
    • DELETE /rooms/{chatRoomId}/messages/{messageId}
    • GET /rooms/{chatRoomId}
    • POST /rooms/{chatRoomId}/close
  • 상담 내역 목록:

    • GET /api/v1/member/consult-requests

기관용 — InstitutionChatController

  • Base URL: /api/v1/institution/chat

  • 엔드포인트:

    • POST /rooms/{chatRoomId}/messages
    • GET /rooms/{chatRoomId}/messages
    • GET /rooms/{chatRoomId}/messages/poll
    • DELETE /rooms/{chatRoomId}/messages/{messageId}
    • GET /rooms/{chatRoomId}
    • POST /rooms/{chatRoomId}/close
  • 상담 내역 목록:

    • GET /api/v1/institution/consult-requests

2) Service 레이어 수정

기존

getInstitutionConsultRequests(Long institutionId, ...)

변경

getInstitutionConsultRequests(Long adminId, ...)

Service 내부에서:

  1. adminId로 InstitutionAdmin 조회
  2. admin.getInstitution().getId() 로 기관 ID 추출
  3. 그 기관 ID로 상담 내역 조회

3) 기관 권한 검증 방식 변경

기관 API에서 다음은 금지:

/api/v1/institution/{institutionId}/consult-requests

다음 방식만 허용:

/api/v1/institution/consult-requests

컨트롤러 내부:

InstitutionAdmin admin = adminRepository.findById(adminDetails.getId())
Long institutionId = admin.getInstitution().getId();

[REFACTOR] 롱 폴링 기반 상담 채팅 API 리팩터링

🧩 변경 범위

파일 영향

  • 삭제/분리: ChatController
  • 생성: MemberChatController, InstitutionChatController
  • 수정: ChatService, ConsultRequestRepository, DTO, Swagger 문서

DB 영향 없음

(엔드포인트 및 권한 로직만 조정)


🧪 테스트 계획

단위 테스트

  • 기관 상담 내역 조회 시 다른 기관 데이터 조회 금지 로직

통합 테스트

  • 회원 채팅 전체 플로우
  • 기관 채팅 전체 플로우
  • 잘못된 접근 → 반드시 403 반환

수동 테스트

  • 회원 → start → 메시지 → 롱 폴링 → 종료
  • 기관 → 메시지 확인 → 롱 폴링 → 상담 종료
  • 권한 우회 시도 시 403 확인

🔐 보안/성능 고려사항

  • 기관 API는 관리자 계정에서만 호출 가능해야 한다.
  • PathVariable을 통한 기관 ID 접근은 전부 차단한다.
  • Service 내에서 기관 검증은 필수이다.

🚀 릴리즈 체크리스트

  • 프론트엔드에 변경된 엔드포인트 공유
  • Swagger 문서 갱신
  • 기존 /api/v1/chat/... API 삭제 여부 확인

👥 담당자


📎 참고 자료

  • 기존 채팅 기능 구현 코드
  • 로그인/인증 구조

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions