Skip to content

Frontend DeepLink Guide

howudong edited this page Oct 4, 2026 · 1 revision

알림 딥링크 가이드 · FE 요청 (푸시 · 알림 센터 공통)

상태: FE 수정 요청 2건 + 알림 유형별 딥링크 전체 표 작성: 2026-10-04 · 관련: #243 / PR #244, ditto-fe#23

알림을 눌렀을 때 어디로 가는지를 한 장에 모았습니다. 딥링크 표는 이 페이지가 기준입니다. 유형이 늘거나 경로가 바뀌면 이 표를 고칩니다.

요청 요약

# 요청 지금 증상 서버 상태
1 알림 센터에서 항목의 deepLink로 이동 여러 유형이 눌러도 이동하지 않고, 그룹 주 매칭 결과는 1:1 화면으로 가고, 방을 나간 사람의 평가 요청은 /chat으로 튕김 PR #244 리뷰 중. 머지되면 바로 배포
2 /matching/group/ 페이지 추가 (ditto-fe#23) 그룹 주 매칭 결과·인원 미달 푸시를 누르면 404 → 로그인 첫 화면 이미 배포됨. 이 경로로 푸시를 보내고 있음

1. 알림 센터에서 deepLink로 이동

지금 동작

  • 푸시 탭은 payload의 data.deepLink로 바로 이동합니다(openNotification). 정상입니다.
  • 알림 센터 탭은 목록 응답에 경로가 없어서 toNotificationTarget이 type과 targetId로 행선지를 직접 정합니다. 그래서 푸시와 결과가 다릅니다.
    • 매핑에 없는 유형은 눌러도 이동하지 않습니다: MATCH_REQUESTED MATCH_ACCEPTED MATCH_REJECTED NO_MATCH GROUP_NOT_FORMED QUIZ_OPENED QUIZ_CLOSING_SOON REMATCH_REQUESTED REMATCH_REJECTED CHAT_ROOM_OPENED CHAT_NO_MESSAGE VOTE_CREATED VOTE_CLOSED REPORT_ACTIONED SANCTION_IMPOSED
    • MATCH_RESULT는 그룹 주에도 /matching(1:1 화면)으로 갑니다.
    • 평가 요청은 방 목록(GET /chat/rooms)에서 방을 찾아 이동합니다. 그룹 방을 나간 사람은 목록에 그 방이 없어서 /chat으로 갑니다. #241부터 나간 사람도 평가를 받으므로 이 경우가 실제로 생깁니다.

서버 변경 (PR #244)

GET /api/v1/notifications 응답의 각 항목에 deepLink가 추가됩니다. 같은 알림의 푸시 data.deepLink와 같은 값이고, 서버의 같은 코드에서 나옵니다.

{
  "id": 8821,
  "type": "REVIEW_REQUEST",
  "category": "MATCHING",
  "title": "이번 만남은 어땠어요?",
  "body": "멤버들과의 만남을 기록해주세요. 다음 매칭에 도움이 돼요.",
  "targetId": 305,
  "deepLink": "/chat/group/305/rate/",
  "readAt": null,
  "createdAt": "2026-10-05T00:00:12"
}
  • 필드가 추가만 됩니다. 기존 필드는 그대로입니다.
  • 이동할 곳이 없으면 null입니다(아래 표의 "없음", 대상이 지워진 경우).

요청 수정

NotificationCenterContainer.handleSelect에서:

  1. item.deepLink가 있으면 그 경로로 이동합니다. 푸시 탭과 같은 처리(toInternalPath → router.push)를 쓰면 됩니다.
  2. deepLink가 null이면 이동하지 않습니다.
  3. 서버 배포 전 응답에는 필드가 아예 없습니다. 필드가 없을 때만 지금의 toNotificationTarget으로 처리하면, 배포 순서와 상관없이 안전합니다. 서버 배포가 확인되면 toNotificationTarget과 방 목록 조회(toChatRoomPath)는 지워도 됩니다.
  4. 읽음 처리(markRead)는 지금처럼 이동 전에 합니다.

QA 확인 항목

  1. 그룹 주 매칭 결과 알림 → /matching/group/ (2번 요청 반영 후)
  2. 1:1 신청·수락·거절 알림 → /matching/
  3. 그룹 방을 나간 뒤 받은 평가 요청 알림 → 그 방의 평가 화면 /chat/group/{id}/rate/
  4. 재매칭 신청 알림 → 쌍이 나온 그룹 방의 평가 화면
  5. 퀴즈 오픈 알림 → /quiz/current/
  6. 신고 처리·공지 알림 → 이동 없음

2. /matching/group/ 페이지 추가

지금 동작

  • 서버는 그룹 주의 MATCH_RESULT·NO_MATCH와 GROUP_NOT_FORMED를 /matching/group/으로 보냅니다(#228, 배포됨).
  • FE에는 src/app/matching/page.tsx만 있고 matching/group 페이지가 없습니다(deploy 브랜치 기준).
  • 없는 경로라 CloudFront가 루트 index.html을 돌려주고, 주소는 /matching/group/인데 로그인 첫 화면이 뜹니다.

요청

  • ditto-fe#23 "그룹 매칭 결과 페이지 /matching/group/"를 구현·배포해 주세요. 데이터는 GET /api/v1/matches/group입니다(Frontend-Group-Matching-Guide).
  • 정적 경로라 CloudFront 리라이트(rewrite-dynamic-routes.js)는 고칠 필요가 없습니다. 정적 export에 페이지가 생기면 됩니다.
  • 배포가 늦어지면 알려 주세요. 서버에서 그 사이 /matching/으로 잠시 되돌릴 수 있습니다(그 경우 그룹 주에 1:1 결과 화면이 뜹니다).

3. 알림 유형별 딥링크 전체 표

  • 경로는 항상 /로 시작하는 앱 내부 경로이고 끝 슬래시가 붙습니다(trailingSlash: true).
  • {roomId}는 채팅방 ID입니다. "방 종류로 갈림"은 서버가 방을 조회해 그룹이면 group, 1:1·재매칭이면 one-on-one으로 완성해서 보냅니다.
  • 푸시는 deepLink가 없으면 키가 빠지고(앱만 열기), 알림 목록은 null입니다.
  • FE 라우트 열은 deploy 브랜치 기준입니다(2026-10-04).
type 카테고리 targetId 이동 경로 (deepLink) 없음이 되는 경우 FE 라우트
QUIZ_OPENED MATCHING 그 주 대표 퀴즈셋 /quiz/current/ ✅
QUIZ_CLOSING_SOON MATCHING 그 주 대표 퀴즈셋 /quiz/current/ ✅
MATCH_RESULT MATCHING 퀴즈셋 1:1 주 /matching/ · 그룹 주 /matching/group/ 퀴즈셋이 지워짐 ✅ · ❌(요청 2)
NO_MATCH MATCHING 퀴즈셋 1:1 주 /matching/ · 그룹 주 /matching/group/ 퀴즈셋이 지워짐 ✅ · ❌(요청 2)
MATCH_REQUESTED MATCHING 1:1 매칭 건 /matching/ ✅
MATCH_ACCEPTED MATCHING 1:1 매칭 건 /matching/ ✅
MATCH_REJECTED MATCHING 1:1 매칭 건 /matching/ ✅
GROUP_FORMED MATCHING 그룹 방 /chat/group/{roomId}/ (금요일까지는 개방 전 화면) ✅
GROUP_NOT_FORMED MATCHING 미성사 그룹 매칭 /matching/group/ ❌(요청 2)
REMATCH_REQUESTED MATCHING 재매칭 쌍 /chat/group/{쌍이 나온 그룹 방}/rate/ 쌍이 지워짐 ✅
REMATCH_REJECTED MATCHING 재매칭 쌍 /chat/group/{쌍이 나온 그룹 방}/rate/ 쌍이 지워짐 ✅
REMATCH_MATCHED MATCHING 재매칭 방 /chat/one-on-one/{roomId}/ ✅
REVIEW_REQUEST MATCHING 끝난 방 /chat/{group·one-on-one}/{roomId}/rate/ (방 종류로 갈림) 방이 지워짐 ✅
REVIEW_REMINDER MATCHING 끝난 방 /chat/{group·one-on-one}/{roomId}/rate/ (방 종류로 갈림) 방이 지워짐 ✅
CHAT_ROOM_OPENED CHAT 열린 방 /chat/{group·one-on-one}/{roomId}/ (방 종류로 갈림) 방이 지워짐 ✅
CHAT_MESSAGE CHAT 방 /chat/{group·one-on-one}/{roomId}/ (방 종류로 갈림) 방이 지워짐 ✅
CHAT_NO_MESSAGE CHAT 방 /chat/{group·one-on-one}/{roomId}/ (방 종류로 갈림) 방이 지워짐 ✅
CHAT_ENDING_SOON CHAT 방 /chat/{group·one-on-one}/{roomId}/ (방 종류로 갈림) 방이 지워짐 ✅
VOTE_CREATED CHAT 그룹 방 /chat/group/{roomId}/ ✅
VOTE_CLOSED CHAT 그룹 방 /chat/group/{roomId}/ ✅
SYSTEM_NOTICE SYSTEM 공지 이력 없음 (앱만 열기) 항상
REPORT_ACTIONED SYSTEM 신고 건 없음 (앱만 열기) 항상
SANCTION_IMPOSED SYSTEM 제재 건 /sanction/ (정지·차단 회원도 열 수 있음) ✅
  • targetId로 경로를 직접 만들지 마세요. 유형마다 가리키는 대상이 다르고(퀴즈셋·매칭 건·쌍 등), 방 종류처럼 서버만 아는 값으로 갈리는 경로가 있습니다. deepLink를 그대로 쓰면 됩니다.
  • 유형은 늘어납니다. 모르는 type이어도 deepLink가 있으면 그대로 이동하면 됩니다.

서버 쪽 기준

  • 유형마다 갈 화면의 종류는 NotificationType.deepLinkTarget이 정하고, 실제 경로 문자열은 NotificationDeepLinks가 만듭니다. 새 유형은 화면 종류를 정하지 않으면 컴파일되지 않습니다.
  • 서버 설계 문서: 레포 docs/domains/notification.md의 deepLink 절.

Clone this wiki locally