Skip to content

[Feat] 정상 도달 알림 페이로드 보강 및 정상까지 거리/시간 API 추가 - #398

Merged
JangInho merged 1 commit into
developfrom
feat/#397-summit-payload-and-distance
Aug 31, 2026
Merged

JangInho merged 1 commit into
developfrom
feat/#397-summit-payload-and-distance

Conversation

@JangInho

Copy link
Copy Markdown
Contributor

🧾 요약

  • 정상 도달 시 프론트가 "정상 인증 바텀시트 + 사진 촬영" 을 띄울 수 있도록 알림 페이로드를 보강하고, 정상까지 거리/시간을 API 로 내려준다

🔗 이슈

✨ 변경 내용

  • TRACKING_SUMMIT_REACHEDmilestoneIndex, milestoneDistanceM 추가 (FCM data + WebSocket 양쪽)
  • TRACKING_PHOTO_MILESTONE FCM data 에 milestoneIndex 추가 (기존엔 distance 만 있었음)
  • LiveActivityCourseResponsesummitDistance(m), summitEstimatedTime(분) 추가
  • 정상까지 거리 계산을 CourseSummitDistanceCalculator 로 분리 — 마일스톤 계산과 Live Activity 응답이 같은 값을 써야 하기 때문
  • evaluate() 주석 정정 — photo 4/4 와 summit 은 동시가 아니라 -10% / 정각으로 시차가 있다
  • 테스트 추가·갱신 (신규 CourseSummitDistanceCalculatorTest 8건 포함)

✅ 확인

  • 빌드 OK
  • 테스트 OK

📡 프론트 연동 계약

FCM data (모든 값이 문자열이다 — AsyncNotificationDispatcherString.valueOf 로 넣는다)

// TRACKING_SUMMIT_REACHED
{ "type": "TRACKING_SUMMIT_REACHED", "title": "...", "body": "...",
  "notificationId": "123",
  "milestoneIndex": "3", "milestoneDistanceM": "2000.0" }

// TRACKING_PHOTO_MILESTONE
{ "type": "TRACKING_PHOTO_MILESTONE", "...": "...",
  "distance": "500", "milestoneIndex": "0" }

사진 업로드 API 는 Integer / Double 을 받으므로 프론트에서 파싱이 필요하다.

WebSocket /topic/tracking/{sessionId}/summit (네이티브 타입 그대로)

{ "milestoneIndex": 3, "milestoneDistanceM": 2000.0,
  "halfwayMark": 2000.0, "reachedAt": "..." }

halfwayMark 는 이미 배포된 클라이언트 호환용으로 남겨둔 값이다. 신규 코드는 milestoneDistanceM 을 쓰면 된다.

GET /api/tracking/live-activity/courses/{courseId}

{ "totalDistance": 5000.0, "estimatedTime": 180,
  "summitDistance": 2000.0, "summitEstimatedTime": 72 }

course.distance / 2 대신 summitDistance 를 쓰면 푸시가 오는 지점과 정확히 일치한다.
정상 좌표가 없어 계산 불가한 코스는 두 필드 모두 null 이라 프론트가 기존 방식으로 폴백하면 된다.

🔍 리뷰 포인트

1. 정상 마일스톤 인덱스는 상수가 아니다

  • 정상 좌표 있음: summitMark == milestones[3]3
  • 정상 좌표 없음(fallback): summitMark == course.distance/2 == milestones[1]1

하드코딩하면 fallback 코스에서 깨진다. summitMark 에 가장 가까운 마일스톤을 찾아 계산한다.
두 경우를 각각 검증하는 테스트를 넣었다.

2. 정상까지 거리 계산을 별도 컴포넌트로 분리한 이유
마일스톤 푸시가 오는 지점과 화면에 표시되는 "정상까지 거리" 가 반드시 같은 값이어야 한다.
TrackingMilestoneCalculator 의 private 메서드로 두면 Live Activity 응답이 같은 계산을 복제해야 해서
어긋날 여지가 생긴다. CourseSummitDistanceCalculator 하나를 양쪽이 주입받게 했다.

3. summitEstimatedTime 은 근사값이다
duration × summitDistance / totalDistance 비례배분이라 오르막이 평지보다 느리다는 점은 반영하지 못한다.
정상을 코스 중간으로 가정하던 것보다는 실제에 가깝다. 비율은 1.0 으로 상한을 뒀다 —
정상까지 거리는 polyline Haversine 누적이고 course.distance 는 출처가 달라 미세하게 넘길 수 있다.

4. ⚠️ /api/notifications/test 동작 변경
NotificationType.requiredKeys 에 새 키를 넣어서, 이 두 타입을 파라미터 없이 테스트 발송하면
이제 NOTIFICATION_PARAMS_INVALID 가 난다. 계약을 발송 전에 강제하려는 의도된 동작이지만
QA 에서 헷갈릴 수 있어 적어둔다.

📌 참고

  • 발송 타이밍은 이번에 바꾸지 않았고 주석으로 문서화만 했다.
    ±10% 윈도우 때문에 photo 4/4 OPEN 은 정상까지 거리의 90%, SUMMIT_REACHED 는 100% 지점이다(창은 110% 에서 닫힘).
    SUMMIT_REACHED 도착 시점에 4/4 촬영 창이 열려 있는 것은 보장되지만, GPS 가 드물어 한 점이
    ±10% 구간을 통째로 건너뛰면 photo 4/4 는 발송되지 않고 정상 알림만 나간다.
    → 프론트는 정상 인증 UI 를 SUMMIT_REACHED 에 물리는 것이 안전하다.
  • 설정/마이그레이션 변경 없음. 새 환경변수도 없다.
  • 테스트 828건 중 11건 실패는 전부 PostgreSQL 연결 거부(Flyway)로 인한 Spring 컨텍스트 로드 실패이며,
    develop 기준 baseline 과 동일하다. 이번 변경으로 인한 회귀는 없다.

- TRACKING_SUMMIT_REACHED 에 milestoneIndex, milestoneDistanceM 추가 (FCM data + WebSocket)
- TRACKING_PHOTO_MILESTONE FCM data 에 milestoneIndex 추가
- LiveActivityCourseResponse 에 summitDistance, summitEstimatedTime 추가
- 정상까지 거리 계산을 CourseSummitDistanceCalculator 로 분리
- evaluate() 주석 정정 — photo 4/4 와 summit 은 동시가 아니라 -10% / 정각으로 시차가 있음

정상 인증 사진 업로드 API 가 milestoneIndex, milestoneDistanceM 을 필수로 받는데
기존 SUMMIT_REACHED 는 빈 파라미터로 발송돼 프론트가 값을 꺼낼 수 없었다.
정상과 일치하는 마일스톤 인덱스는 정상 좌표가 있으면 3, 코스 절반을 정상으로 보는
fallback 코스는 1 이라 상수로 둘 수 없어 summitMark 에 가장 가까운 마일스톤으로 계산한다.

정상까지 거리 계산은 마일스톤과 Live Activity 응답이 같은 값을 써야 해서
(푸시 지점과 화면 표시가 어긋나면 안 됨) 별도 컴포넌트로 분리했다.
@JangInho JangInho added the enhancement New feature or request label Aug 31, 2026
@JangInho JangInho self-assigned this Aug 31, 2026
@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 635b5eb4-99e5-4cc0-8803-5c6ac53a4534


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

📊 테스트 커버리지 리포트

Overall Project 98.38% 🍏
Files changed 100% 🍏

File Coverage
LiveActivityCourseResponse.java 100% 🍏
TrackingService.java 100% 🍏
TrackingMilestoneCalculator.java 100% 🍏
NotificationType.java 100% 🍏
CourseSummitDistanceCalculator.java 100% 🍏
TrackingMilestoneTriggerService.java 99.86% 🍏

@JangInho
JangInho merged commit 1b89aa1 into develop Aug 31, 2026
5 checks passed
@JangInho
JangInho deleted the feat/#397-summit-payload-and-distance branch August 31, 2026 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 정상 도달 알림 페이로드 보강 및 정상까지 거리/시간 API 추가

1 participant