[BOM-1160] feat: 마이페이지 랭킹 기록 api#785
Hidden character warning
Conversation
| private Long findLatestRank(List<RankHistoryResponse> rankHistories) { | ||
| if (rankHistories.isEmpty()) { | ||
| return null; | ||
| } | ||
| return rankHistories.getLast().rank(); | ||
| } |
There was a problem hiding this comment.
K2
currentRank는 현재월 실시간 순위가 아니라, 현재월을 제외한 이전달까지의 랭킹 이력 중 가장 최신 순위를 사용했습니다.
랭킹 이력이 없는 신규 유저는 임의 순위 값을 만들지 않고 null로 응답하도록 했습니다.
| MyPageRankType.READING.value(), | ||
| findLatestRank(rankHistories), | ||
| rankHistories, | ||
| articleReadHistoryRepository.countByMemberId(memberId) |
There was a problem hiding this comment.
K2
다독왕 카드의 value는 현재월 읽은 수가 아니라 지금까지 읽은 누적 아티클 수이기 때문에, MonthlyReadingRealtime.currentCount 대신 article_read_history 기준 count를 사용했습니다.
| if (type == null) { | ||
| return myPageService.getRankSummary(member); | ||
| } | ||
| return myPageService.getRankSummary(member, type); |
There was a problem hiding this comment.
K5
type이 없으면 전체 랭킹 카드를 반환하고, type이 있으면 해당 타입의 카드만 반환하도록 분기했습니다.
데스크탑에서는 전체 카드 조회, 모바일에서는 토글 변경 시 타입별 조회가 가능하도록 같은 엔드포인트에서 처리했습니다.
There was a problem hiding this comment.
p1
openapi-spec는 백엔드 내부 파일이 아니라 프론트와 함께 보는 API 계약 repo라서, submodule 안에서 직접 수정하면 협업 기준점이 깨집니다.
API 변경은 bom-bom-api-spec repo에 PR로 올려 프론트/백엔드가 같은 계약 변경을 리뷰하고 공유해야 합니다.
이후 백엔드에서는 submodule인 openapi-spec를 머지된 spec commit으로 checkout하고, 그 spec 기준으로 생성된 codegen 결과를 반영하는 흐름이 맞습니다.
아니면 머지 전에도 ai한테 pr 링크 보내서 서브모듈 해당 커밋 버전으로 해달라하면 바꿔주긴합니다 ㅋㅋ
특히 openapi.yaml은 TypeSpec 산출물이라 직접 수정하면 다음 빌드에서 덮어써질 수 있습니다.
There was a problem hiding this comment.
어렵네요.. 아직 프론트와 협의한 방식은 아니라, 일단 다시 백엔드 로컬 DTO 방식으로 되돌렸습니다.
Ryan-Dia
left a comment
There was a problem hiding this comment.
몇월에 대한 데이터인지 나타내는 label 값을 작년 데이터는 YY.MM 형식, 올해 데이터는 M월로 표현중인데, 다른 방식으로 표현하는게 나을지 확인 바랍니다.
지금 표현 방법이 더 좋은 것 같아요!!
| return rankHistories.getLast().rank(); | ||
| } | ||
|
|
||
| private RankHistoryResponse toRankHistoryResponse(LocalDate period, long rank) { |
There was a problem hiding this comment.
p1
해당 코드는 따로 dto 레코드로 만들어서 관리하면 좋을 것 같아요 어떤건 dto response에서 관리하고 어떤건 이렇게 private 메서드로 관리하면 일관성이 덜어질 것 같아요
There was a problem hiding this comment.
답변 다는걸 깜빡했네요 ㅎ
c467c47 to
7b35ab9
Compare
Choidongjun0830
left a comment
There was a problem hiding this comment.
몇월에 대한 데이터인지 나타내는 label 값을 작년 데이터는 YY.MM 형식, 올해 데이터는 M월로 표현중인데, 다른 방식으로 표현하는게 나을지 확인 바랍니다.
이거 좋습니다!
리뷰 남겼습니다~! pr 머지 대상 브랜치 server-dev로 수정하셔도 될거 같아용
| @GetMapping("/rank") | ||
| public RankSummaryResponse getRankSummary( |
There was a problem hiding this comment.
p1
api 계약이 없어요!
MyPageControllerApi 인터페이스를 만들어서 다중 상속하면 될거 같아요!
There was a problem hiding this comment.
| String month = period.toString().substring(0, 7); | ||
| String label = period.getYear() == today.getYear() | ||
| ? period.getMonthValue() + "월" | ||
| : String.format("%02d.%02d", period.getYear() % 100, period.getMonthValue()); | ||
| return new RankHistoryResponse( | ||
| month, | ||
| label, | ||
| rank | ||
| ); |
There was a problem hiding this comment.
p3
month가 2026-06처럼 화면에서 가공 가능한 값으로 내려가고 있어서, label처럼 화면 표시용 값을 서버에서 함께 만들어주는 이유가 있을까요? 2026-05 형식의 month만 내려줘도 클라이언트에서 5월, 25.12 같은 라벨은 만들 수 있을 것 같습니다.
그리고 month 생성은 period.toString().substring(0, 7)보다 아래처럼 YearMonth를 쓰는 편이 의도가 더 명확해 보입니다.
String month = YearMonth.from(period).toString();결과 포맷도 동일하게 yyyy-MM으로 내려갑니다!
There was a problem hiding this comment.
month 생성 방식은 반영했습니다.
label은 기존에 전달받은 API 명세를 기준으로 구현한 값이긴 한데,
말씀해주신 것처럼 화면 표시용 값이라 프론트에서 처리하는 편이 더 깔끔할 수도 있을 것 같습니다.
프론트와 확인한 뒤, 제거해도 되는 값이면 month만 내려가도록 정리하겠습니다.
| @ExtendWith(MockitoExtension.class) | ||
| class MyPageServiceTest { |
There was a problem hiding this comment.
p4
해당 서비스 테스트만 mock 기반으로 작성하신 이유가 있을까여
There was a problem hiding this comment.
확인 잘 못하고 올려버렸네요.
기존 방식과 동일하게 수정했습니다!
Ryan-Dia
left a comment
There was a problem hiding this comment.
수정해주시면 답변에 수정 내용 링크 꼭 남겨주세요
cfe0025 to
90ad0c1
Compare
Choidongjun0830
left a comment
There was a problem hiding this comment.
변경 사항 모두 확인했습니다! 수고하셨습니당
📌 What
마이페이지 랭킹 요약 API를 구현했습니다.
GET /api/v1/members/me/rankGET /api/v1/members/me/rank?type=streakGET /api/v1/members/me/rank?type=reading[데스크탑]

[모바일]

❓ Why
마이페이지에서 사용자의 랭킹 정보를 연속 읽기 / 다독왕 기준으로 보여주기 위해 API가 필요했습니다.
🔧 How
마이페이지 랭킹 API 스펙은openapi-spec서브모듈의 TypeSpec에 정의했고, 서버에서는 OpenAPI codegen으로 생성된 API 인터페이스와 응답 모델을 사용했습니다.랭킹 정보는 현재월을 제외한 이전달까지의 확정 랭킹 기준으로 조회합니다.
rankHistory: 현재월 제외, 이전달까지의 최근 6개 랭킹 이력currentRank:rankHistory중 가장 최신 월의 순위currentRank = null,rankHistory = []카드의
value는 타입별로 다르게 내려줍니다.streak: 현재 연속 읽기 일수reading: 지금까지 읽은 누적 아티클 수다독왕 카드의 누적 읽은 아티클 수는
article_read_history기준으로 count하도록 했습니다.👀 Review Point (Optional)
label값을 작년 데이터는YY.MM형식, 올해 데이터는M월로 표현중인데, 다른 방식으로 표현하는게 나을지 확인 바랍니다.OpenAPI Codegen 사용법 틀린부분 없는지..?