Skip to content

feat: 메뉴 찜 및 찜한 메뉴 개인화 푸시 알림 - #488

Merged
sjinssun merged 1 commit into
developfrom
feat/#487-menu-favorite-push
Sep 27, 2026
Merged

sjinssun merged 1 commit into
developfrom
feat/#487-menu-favorite-push

Conversation

@sjinssun

Copy link
Copy Markdown
Contributor

#️⃣ Issue Number

📝 요약(Summary)

사용자가 학식 메뉴를 식당별로 찜하고, 찜한 메뉴가 오늘 점심/저녁에 나오면 오전 11시에 개인화 푸시를 받는 기능입니다.

  • 메뉴 찜 API (/menu-favorites, 로그인 필수)
    • GET /search?keyword= : 앞뒤 공백 제거 후 2글자 이상, 대소문자 무시, 단종 제외, 완전일치 → 시작 → 포함 순 정렬, 결과별 찜 여부 포함. 사용자 언어 번역이 있으면 번역명으로도 검색되고, 없으면 한국어 이름으로 폴백
    • GET 찜 목록(최신순, 단종 메뉴도 표시) / POST /{menuId} 찜(중복 시 무시, 단종 메뉴는 400) / DELETE /{menuId} 찜 취소
  • 푸시 토큰 API : PUT /users/push-token(등록·갱신, 기기 여러 대 허용), DELETE /users/push-token(로그아웃 시)
  • FCM 연동 : Firebase Admin SDK, 키는 환경변수 EATSSU_FIREBASE_CREDENTIALS(서비스 계정 JSON base64)로 주입. FCM이 UNREGISTERED/SENDER_ID_MISMATCH로 응답한 토큰은 자동 삭제
  • 스케줄러 : 매일 11:00(KST) 오늘 점심+저녁 식단과 찜 메뉴를 메뉴명+식당 기준으로 매칭 → 매칭된 사용자에게만 하루 1회 발송(기획 카피 4종). 푸시 data에 type, date(yyyyMMdd), timePart 포함
  • DB : menu_favorite, push_token, menu_favorite_push_history(V26~V28). 탈퇴/메뉴 삭제 시 ON DELETE CASCADE

💬 공유사항 to 리뷰어

  1. google-cloud-storage가 jackson-dataformat-xml을 끌어와 Accept 헤더 없는 요청에 전체 API가 XML로 응답합니다 → storage/firestore 모듈 exclude
    2. Boot 의존성 관리가 httpclient5/httpcore5를 구버전으로 고정해 발송 시 NoClassDefFoundError → Firebase는 NetHttpTransport 사용, google-http-client-jackson2 명시 추가 (DeepL 쪽 HTTP 클라이언트는 변경 없음)
  • 실제 서비스 계정 키로 FCM dry-run 발송(가짜 토큰)을 해서 인증과 전송이 정상이고 UNREGISTERED 응답이 오는 것까지 확인했습니다. 실제 사용자 발송은 없었습니다.
  • 매칭을 menu_id가 아니라 메뉴명+식당으로 한 이유: VARIABLE 메뉴는 get-or-create라 같은 이름의 Menu 행이 중복될 수 있어 menu_id만으로는 누락될 수 있습니다.
  • 스펙의 "동일 메뉴명은 한 번만 노출"은 식당별 찜 결정에 맞춰 메뉴명+식당 기준으로 한 번만 노출합니다.
  • 중복 방지를 위해 발송 이력을 먼저 저장하고 발송합니다(최대 1회 우선, 발송 실패 시 재발송 없음).
  • FIXED 메뉴(스낵코너 등)는 찜은 되지만 날짜별 식단에 오르지 않아 알림 대상이 아닙니다.
  • 배포: cd.yml에 EATSSU_FIREBASE_CREDENTIALS 전달 추가. Secret이 없으면 서버는 정상 기동하고 푸시만 경고 로그 후 건너뜁니다.
  • 앱 연동 필요: 토큰 등록/삭제 API 호출, 푸시 data의 date/timePart로 학식 화면 이동, 기존 11시 일반 알림과의 중복 여부 확인

✅ PR Checklist

PR이 다음 요구 사항을 충족하는지 확인하세요.

  • 커밋 메시지 컨벤션에 맞게 작성했습니다.
  • 변경 사항에 대한 테스트를 했습니다.(버그 수정/기능에 대한 테스트).

@github-actions

Copy link
Copy Markdown

📊 테스트 커버리지 리포트

Overall Project 95.94% 🍏
Files changed 100% 🍏

File Coverage
PushTokenController.java 100% 🍏
MenuFavoriteQueryRepository.java 100% 🍏
MenuFavoriteService.java 100% 🍏
MenuFavoriteMatch.java 100% 🍏
MenuFavoriteMatchQueryRepository.java 100% 🍏
UserPushToken.java 100% 🍏
BaseResponseStatus.java 100% 🍏
MenuFavoritePushHistory.java 100% 🍏
PushToken.java 100% 🍏
PushDelivery.java 100% 🍏
PushMessage.java 100% 🍏
FirebaseConfig.java 100% 🍏
FcmPushSender.java 100% 🍏
PushTokenRequest.java 100% 🍏
DeletePushTokenRequest.java 100% 🍏
MenuFavoritePushScheduler.java 100% 🍏
MenuFavoriteController.java 100% 🍏
MenuFavoritePushService.java 100% 🍏
MenuFavoritePushMessageFactory.java 100% 🍏
PushTokenService.java 100% 🍏
FavoriteMenuResponse.java 100% 🍏
MenuSearchResponse.java 100% 🍏
MenuFavorite.java 100% 🍏
SchedulingConfig.java 100% 🍏

@sjinssun
sjinssun merged commit 5c37888 into develop Sep 27, 2026
1 check passed
@sjinssun
sjinssun deleted the feat/#487-menu-favorite-push branch September 27, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feature: 메뉴 찜 및 찜한 메뉴 개인화 푸시 알림

1 participant