-
Notifications
You must be signed in to change notification settings - Fork 0
Notification Flow
l2juhan edited this page Apr 18, 2026
·
2 revisions
인앱 알림, 푸시 알림, 알림 설정에 대한 전체 플로우를 설명합니다.
| 항목 | 내용 |
|---|---|
| 대상 사용자 | WORKER, EMPLOYER 공통 |
| 인앱 알림 | SSE 실시간 구독 + Header 벨 아이콘 뱃지 |
| 푸시 알림 | FCM 토큰 기반 (앱 백그라운드/종료 시) |
| API 모듈 | src/api/notification/ |
┌─────────────────────────────────────────────────────────────────┐
│ 알림 시스템 구조 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [앱 Foreground] │
│ │ │
│ ├─→ SSE 구독 (/api/notifications/stream) │
│ │ → 새 알림 수신 시 unreadCount 증가 │
│ │ → Header 벨 아이콘에 숫자 뱃지 표시 (1~9, 10+→"9+") │
│ │ │
│ └─→ 벨 아이콘 클릭 → NotificationPopup (최근 5개) │
│ → "전체 보기" → NotificationScreen │
│ │
│ [앱 Background/종료] │
│ │ │
│ ├─→ FCM 푸시 알림 (OS 알림센터에 표시) │
│ │ │
│ └─→ 알림 탭 → 딥링크 네비게이션 (actionType 기반) │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ SSE 실시간 구독 플로우 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [로그인 성공] │
│ │ │
│ ▼ │
│ useNotificationStream() 활성화 │
│ │ │
│ ├─→ GET /api/notifications/unread-count │
│ │ → 초기 읽지 않은 알림 수 → notificationStore 저장 │
│ │ │
│ └─→ SSE 연결 (/api/notifications/stream) │
│ → XMLHttpRequest 기반 (React Native 호환) │
│ → 연결 끊김 시 5초 후 자동 재연결 │
│ → 새 이벤트 수신 시 incrementUnreadCount() │
│ │
│ [로그아웃/언마운트] │
│ │ │
│ ▼ │
│ SSE 연결 해제 │
│ │
└─────────────────────────────────────────────────────────────────┘
interface NotificationStoreState {
unreadCount: number;
setUnreadCount: (count: number) => void;
incrementUnreadCount: () => void;
decrementUnreadCount: () => void;
}┌─────────────────────────────────────────────────────────────────┐
│ FCM 토큰 관리 플로우 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [로그인 성공] │
│ │ │
│ ▼ │
│ useFcmToken() 활성화 │
│ │ │
│ ▼ │
│ GET /api/settings/me → pushEnabled 조회 (2026-03-09 변경) │
│ │ │
│ ├─→ pushEnabled: false → 토큰 등록하지 않음 │
│ │ │
│ └─→ pushEnabled: true → registerPushToken() │
│ │ │
│ ▼ │
│ expo-notifications로 Expo Push Token 발급 │
│ (디바이스마다 고유한 토큰) │
│ │ │
│ ▼ │
│ POST /api/notifications/fcm-token │
│ { token: "ExponentPushToken[xxx]", deviceInfo: "ios 18" }│
│ │ │
│ ▼ │
│ AsyncStorage에 토큰 저장 (로그아웃 시 삭제용) │
│ │
│ [로그아웃] │
│ │ │
│ ▼ │
│ unregisterPushToken() │
│ │ │
│ ▼ │
│ DELETE /api/notifications/fcm-token { token: "저장된 토큰" } │
│ │ │
│ ▼ │
│ AsyncStorage에서 토큰 제거 │
│ │ │
│ ▼ │
│ logout() 실행 (auth 토큰 삭제, 쿠키 삭제) │
│ │
└─────────────────────────────────────────────────────────────────┘
알림을 탭하면 actionType에 따라 해당 화면으로 이동합니다.
| actionType | 근로자 | 고용주 |
|---|---|---|
VIEW_WORK_RECORD |
WorkerHomeMain (주간 캘린더) | EmployerHomeMain (일간 캘린더) |
VIEW_CORRECTION_REQUEST |
SentRequests (보낸 요청) | EmployerReceivedRequests (받은 요청) |
VIEW_PENDING_APPROVAL |
Notifications | EmployerReceivedRequests |
VIEW_SALARY |
WorkerMonthlyCalendar | Notifications |
VIEW_PAYMENT_MANAGEMENT |
Notifications | RemittanceManage (송금관리) |
VIEW_WORKPLACE_INVITATION |
WorkplaceManage | WorkerManage (직원관리) |
VIEW_NOTICE |
Notifications | Notifications |
NONE |
Notifications | Notifications |
┌─────────────────────────────────────────────────────────────────┐
│ 딥링크 네비게이션 플로우 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [앱 종료 상태에서 알림 탭] │
│ │ │
│ ▼ │
│ getLastNotificationResponseAsync() │
│ → 마지막 알림 응답 확인 → actionType 추출 → navigate() │
│ │
│ [앱 백그라운드에서 알림 탭] │
│ │ │
│ ▼ │
│ addNotificationResponseReceivedListener() │
│ → 알림 응답 이벤트 수신 → actionType 추출 → navigate() │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 알림 상세 화면 구조 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ Header: [←] "알림" [전체 읽음] │ │
│ ├───────────────────────────────────────────┤ │
│ │ Filter Chips │ │
│ │ [전체] [읽지 않은 알림 N] │ │
│ ├───────────────────────────────────────────┤ │
│ │ NotificationItem (FlatList, pull-refresh) │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ [🔔] 근무 일정이 변경되었습니다. ×│ │ │
│ │ │ 3분 전 │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ [📋] 정정 요청이 승인되었습니다. ×│ │ │
│ │ │ 1시간 전 │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ ├───────────────────────────────────────────┤ │
│ │ Pagination (하단 고정) │ │
│ │ < [1] [2] [3] ... [10] > │ │
│ └───────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
GET /api/notifications?page=0&size=10&is_read=false
→ { content: [...], totalPages: 5, totalElements: 42 }
┌─────────────────────────────────────────────────────────────────┐
│ 알림 설정 화면 구조 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ Header: [←] "알림 설정" │ │
│ ├───────────────────────────────────────────┤ │
│ │ │ │
│ │ 푸시 알림 [Toggle ●] │ │
│ │ 앱을 사용하지 않을 때도 │ │
│ │ 알림을 받습니다. │ │
│ │ ───────────────────────── │ │
│ │ 디바이스 알림 설정 열기 🔗 │ │
│ │ ───────────────────────── │ │
│ │ 디바이스 설정에서 알림 권한을 끄면 │ │
│ │ 푸시 알림이 앱 내 설정과 관계없이 │ │
│ │ 수신되지 않습니다. │ │
│ │ │ │
│ └───────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
기존의 AsyncStorage 로컬 저장 방식에서 서버 API 동기화 방식으로 변경됐다.
[화면 진입]
→ GET /api/settings/me → { pushEnabled } 로드 → 토글 초기값 설정
[토글 OFF → ON]:
→ 디바이스 알림 권한 확인
→ 권한 OFF → Alert "디바이스 설정에서 알림을 허용해주세요" + 설정 이동
→ 권한 ON → PUT /api/settings/me { pushEnabled: true }
→ 성공 시 registerPushToken() 호출
[토글 ON → OFF]:
→ PUT /api/settings/me { pushEnabled: false }
→ 성공 시 unregisterPushToken() 호출
| 구분 | 이전 (로컬) | 현재 (서버) |
|---|---|---|
| 저장소 | AsyncStorage (PUSH_ENABLED_KEY) |
서버 DB (/api/settings/me) |
| 다중 디바이스 | 디바이스별 따로 관리 | 계정 단위로 통일 |
| 훅 연동 |
useFcmToken가 AsyncStorage 조회 |
useFcmToken가 GET /api/settings/me 조회 |
| 관련 파일 |
src/api/settings/{index,types}.ts 신규 생성 |
— |
| 메서드 | 엔드포인트 | 설명 |
|---|---|---|
| GET | /api/notifications |
알림 목록 조회 (page, size, is_read) |
| GET | /api/notifications/unread-count |
읽지 않은 알림 수 |
| GET | /api/notifications/stream |
SSE 실시간 알림 구독 |
| PUT | /api/notifications/{id}/read |
알림 읽음 처리 |
| PUT | /api/notifications/read-all |
전체 읽음 처리 |
| DELETE | /api/notifications/{id} |
알림 삭제 |
| 메서드 | 엔드포인트 | 설명 |
|---|---|---|
| POST | /api/notifications/fcm-token |
FCM 토큰 등록 |
| DELETE | /api/notifications/fcm-token |
FCM 토큰 삭제 |
| 메서드 | 엔드포인트 | 설명 |
|---|---|---|
| GET | /api/settings/me |
사용자 알림 설정 조회 (pushEnabled 등) |
| PUT | /api/settings/me |
사용자 알림 설정 갱신 |
| 분류 | 파일 | 설명 |
|---|---|---|
| API | api/notification/types.ts |
알림 타입 정의 (NotificationType, ActionType, PagedResponse 등) |
| API | api/notification/index.ts |
알림 API 함수 7개 |
| Store | stores/notificationStore.ts |
unreadCount 전역 상태 |
| Hook | hooks/common/useNotifications.ts |
알림 화면 데이터 관리 |
| Hook | hooks/common/useNotificationStream.ts |
SSE 구독 + 뱃지 업데이트 |
| Hook | hooks/common/useFcmToken.ts |
로그인 시 FCM 토큰 자동 등록 |
| Hook | hooks/common/useNotificationNavigation.ts |
푸시 탭 → 딥링크 |
| Util | utils/sse.ts |
XMLHttpRequest 기반 SSE 클라이언트 |
| Util | utils/pushToken.ts |
토큰 발급/등록/삭제 유틸 |
| Screen | screens/common/NotificationScreen.tsx |
알림 상세 화면 |
| Screen | screens/common/NotificationSettingsScreen.tsx |
알림 설정 화면 |
| Component | components/common/notification/NotificationPopup.tsx |
Header 알림 팝업 |