Skip to content

[BOM-1160] feat: 마이페이지 랭킹 기록 api#785

Merged
kysub99 merged 10 commits into
server-devfrom
BOM-1160-마이페이지-랭킹-기록-api
Jun 27, 2026

Hidden character warning

The head ref may contain hidden characters: "BOM-1160-\ub9c8\uc774\ud398\uc774\uc9c0-\ub7ad\ud0b9-\uae30\ub85d-api"
Merged

[BOM-1160] feat: 마이페이지 랭킹 기록 api#785
kysub99 merged 10 commits into
server-devfrom
BOM-1160-마이페이지-랭킹-기록-api

Conversation

@kysub99

@kysub99 kysub99 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

📌 What

마이페이지 랭킹 요약 API를 구현했습니다.

  • GET /api/v1/members/me/rank
  • GET /api/v1/members/me/rank?type=streak
  • GET /api/v1/members/me/rank?type=reading

[데스크탑]
image

[모바일]
image

❓ 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)

image
  • 몇월에 대한 데이터인지 나타내는 label 값을 작년 데이터는 YY.MM 형식, 올해 데이터는 M월로 표현중인데, 다른 방식으로 표현하는게 나을지 확인 바랍니다.
  • OpenAPI Codegen 사용법 틀린부분 없는지..?

@github-actions github-actions Bot added BE backend PR D-2 feat 새로운 기능 추가 labels Jun 17, 2026
@kysub99 kysub99 added D-3 and removed D-2 labels Jun 17, 2026
Comment on lines +99 to +104
private Long findLatestRank(List<RankHistoryResponse> rankHistories) {
if (rankHistories.isEmpty()) {
return null;
}
return rankHistories.getLast().rank();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

K2

currentRank는 현재월 실시간 순위가 아니라, 현재월을 제외한 이전달까지의 랭킹 이력 중 가장 최신 순위를 사용했습니다.

랭킹 이력이 없는 신규 유저는 임의 순위 값을 만들지 않고 null로 응답하도록 했습니다.

MyPageRankType.READING.value(),
findLatestRank(rankHistories),
rankHistories,
articleReadHistoryRepository.countByMemberId(memberId)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

K2

다독왕 카드의 value는 현재월 읽은 수가 아니라 지금까지 읽은 누적 아티클 수이기 때문에, MonthlyReadingRealtime.currentCount 대신 article_read_history 기준 count를 사용했습니다.

Comment on lines +36 to +39
if (type == null) {
return myPageService.getRankSummary(member);
}
return myPageService.getRankSummary(member, type);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

K5

type이 없으면 전체 랭킹 카드를 반환하고, type이 있으면 해당 타입의 카드만 반환하도록 분기했습니다.

데스크탑에서는 전체 카드 조회, 모바일에서는 토글 변경 시 타입별 조회가 가능하도록 같은 엔드포인트에서 처리했습니다.

@kysub99 kysub99 changed the base branch from BOM-1157-마이페이지-월간-리포트-api-구현 to server-dev June 17, 2026 12:02
@kysub99 kysub99 changed the base branch from server-dev to BOM-1157-마이페이지-월간-리포트-api-구현 June 17, 2026 12:10

@Choidongjun0830 Choidongjun0830 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일단 이거 먼저 드릴게요

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 산출물이라 직접 수정하면 다음 빌드에서 덮어써질 수 있습니다.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어렵네요.. 아직 프론트와 협의한 방식은 아니라, 일단 다시 백엔드 로컬 DTO 방식으로 되돌렸습니다.

@Ryan-Dia Ryan-Dia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

몇월에 대한 데이터인지 나타내는 label 값을 작년 데이터는 YY.MM 형식, 올해 데이터는 M월로 표현중인데, 다른 방식으로 표현하는게 나을지 확인 바랍니다.

지금 표현 방법이 더 좋은 것 같아요!!

return rankHistories.getLast().rank();
}

private RankHistoryResponse toRankHistoryResponse(LocalDate period, long rank) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p1

해당 코드는 따로 dto 레코드로 만들어서 관리하면 좋을 것 같아요 어떤건 dto response에서 관리하고 어떤건 이렇게 private 메서드로 관리하면 일관성이 덜어질 것 같아요

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kysub99 kysub99 force-pushed the BOM-1160-마이페이지-랭킹-기록-api branch from c467c47 to 7b35ab9 Compare June 22, 2026 17:41

@Choidongjun0830 Choidongjun0830 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

몇월에 대한 데이터인지 나타내는 label 값을 작년 데이터는 YY.MM 형식, 올해 데이터는 M월로 표현중인데, 다른 방식으로 표현하는게 나을지 확인 바랍니다.

이거 좋습니다!

리뷰 남겼습니다~! pr 머지 대상 브랜치 server-dev로 수정하셔도 될거 같아용

Comment on lines +30 to +31
@GetMapping("/rank")
public RankSummaryResponse getRankSummary(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p1

api 계약이 없어요!
MyPageControllerApi 인터페이스를 만들어서 다중 상속하면 될거 같아요!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +16 to +24
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
);

@Choidongjun0830 Choidongjun0830 Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3

month2026-06처럼 화면에서 가공 가능한 값으로 내려가고 있어서, label처럼 화면 표시용 값을 서버에서 함께 만들어주는 이유가 있을까요? 2026-05 형식의 month만 내려줘도 클라이언트에서 5월, 25.12 같은 라벨은 만들 수 있을 것 같습니다.

그리고 month 생성은 period.toString().substring(0, 7)보다 아래처럼 YearMonth를 쓰는 편이 의도가 더 명확해 보입니다.

String month = YearMonth.from(period).toString();

결과 포맷도 동일하게 yyyy-MM으로 내려갑니다!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

month 생성 방식은 반영했습니다.

refactor: 랭킹 응답 월 생성 방식 개선

label은 기존에 전달받은 API 명세를 기준으로 구현한 값이긴 한데,
말씀해주신 것처럼 화면 표시용 값이라 프론트에서 처리하는 편이 더 깔끔할 수도 있을 것 같습니다.
프론트와 확인한 뒤, 제거해도 되는 값이면 month만 내려가도록 정리하겠습니다.

Comment on lines +32 to +33
@ExtendWith(MockitoExtension.class)
class MyPageServiceTest {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p4

해당 서비스 테스트만 mock 기반으로 작성하신 이유가 있을까여

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인 잘 못하고 올려버렸네요.
기존 방식과 동일하게 수정했습니다!

test: 마이페이지 테스트를 통합 테스트로 변경

@Ryan-Dia Ryan-Dia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수정해주시면 답변에 수정 내용 링크 꼭 남겨주세요

@kysub99 kysub99 changed the base branch from BOM-1157-마이페이지-월간-리포트-api-구현 to server-dev June 26, 2026 06:25
@kysub99 kysub99 force-pushed the BOM-1160-마이페이지-랭킹-기록-api branch from cfe0025 to 90ad0c1 Compare June 26, 2026 06:34
@kysub99 kysub99 requested a review from Choidongjun0830 June 26, 2026 08:18

@Choidongjun0830 Choidongjun0830 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변경 사항 모두 확인했습니다! 수고하셨습니당

@kysub99 kysub99 merged commit a627389 into server-dev Jun 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BE backend PR D-0 feat 새로운 기능 추가

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants