ID: key_26_22_05_25_P3_3_5 Created date: 5월 25 2026 월요일
연관 문서
개요
실시간 인앱 알림 시스템을 구현한다. SSE(Server-Sent Events) 또는 WebSocket을 사용한다.
- 예상 소요: 4~5일
- 선행 조건: 실시간 통신 방식 결정 (SSE 권장 — 단방향 알림에 적합)
- 완료 기준: 이슈 할당 시 담당자 브라우저에 실시간 알림 수신 확인
Claude Code 작업 수행서
작업 지시
CIRA 서버 + UI에 실시간 알림 시스템을 구현해줘.
방식: SSE (Server-Sent Events)
[서버 수행 작업]
1. 알림 도메인 패키지
com.tas.cira.notification/
├── controller/NotificationController.java
├── service/NotificationService.java
├── service/SseEmitterService.java
├── repository/NotificationRepository.java
├── entity/Notification.java
└── dto/NotificationResponse.java
2. SSE 연결 관리
SseEmitterService:
- emitters: ConcurrentHashMap<UUID(userId), SseEmitter>
- connect(userId): SseEmitter
* SseEmitter TTL: 600초
* onCompletion/onTimeout: emitter 맵에서 제거
- send(userId, NotificationResponse): void
* emitter 존재 시 sendEvent
* IOException 발생 시 emitter 제거
- broadcast(List<UUID> userIds, event): void
3. SSE 엔드포인트
GET /api/v1/notifications/subscribe
- 헤더: Accept: text/event-stream
- 연결 성공 시 "CONNECTED" 이벤트 발송
- Spring SseEmitter 반환
4. 알림 API
GET /api/v1/notifications — 알림 목록 (최근 50건)
PUT /api/v1/notifications/{id}/read — 단건 읽음 처리
PUT /api/v1/notifications/read-all — 전체 읽음
GET /api/v1/notifications/unread-count — 미읽음 수
5. 알림 발송 시점
NotificationService.send()를 다음 이벤트에서 호출:
- 이슈 할당: "'{이슈키}' 이슈가 회원님께 할당되었습니다"
- 이슈 상태 변경: "'{이슈키}' 상태가 {상태}로 변경되었습니다"
- 댓글 작성 (이슈 담당자/보고자): "'{이슈키}'에 새 댓글이 달렸습니다"
- 멘션(@): "'{작성자}'님이 댓글에서 회원님을 멘션했습니다"
- 스프린트 시작/종료: 스프린트 멤버 전체
6. 알림 설정 API
GET /api/v1/notification-preferences
PUT /api/v1/notification-preferences
Request: [
{ "type": "ISSUE_ASSIGNED", "inApp": true, "email": false },
{ "type": "COMMENT_ADDED", "inApp": true, "email": true },
...
]
[UI 수행 작업]
7. SSE 훅
파일: src/hooks/useNotifications.ts
- useEffect에서 EventSource 연결
- 이벤트 수신 시 React Query 캐시 업데이트 + toast 표시
- 컴포넌트 unmount 시 EventSource.close()
8. 알림 벨 UI
파일: src/components/layout/NotificationBell.tsx
- 헤더 우측 벨 아이콘
- 미읽음 배지 (최대 99+)
- 클릭 → 알림 드롭다운 패널
- 알림 항목 클릭 → 해당 이슈 이동 + 읽음 처리
9. 알림 드롭다운
- 최근 10건 표시
- "전체 보기" → /notifications 페이지
- "모두 읽음" 버튼
- 알림 타입별 아이콘 (이슈 할당, 댓글, 멘션 등)
- 상대 시간 표시
[준수 사항]
- SSE 연결은 로그인 후 자동 시작
- 브라우저 탭 전환 시 Visibility API로 재연결 처리
- 연결 끊김 감지 시 3초 후 재연결 시도 (최대 5회)
완료 기준
| 항목 | 기준 |
|---|---|
| SSE 연결 | 브라우저 로그인 후 자동 연결 |
| 실시간 알림 | 이슈 할당 시 1초 이내 수신 |
| 미읽음 배지 | 카운트 정확 |
| 읽음 처리 | 단건/전체 정상 동작 |
| 재연결 | 연결 끊김 후 자동 재시도 |