Skip to content

[feat] #13 - 미션 인증 피드 API & 요즘 핫한 미션 로직 구현 - #18

Merged
laura-jung merged 11 commits into
mainfrom
feat/#13
Aug 14, 2026
Merged

[feat] #13 - 미션 인증 피드 API & 요즘 핫한 미션 로직 구현#18
laura-jung merged 11 commits into
mainfrom
feat/#13

Conversation

@laura-jung

Copy link
Copy Markdown
Contributor

Related issue 🛠

Work Description ✏️

미션 인증 피드에 필요한 백엔드 API를 구현했습니다.

1. 미션 인증 피드 조회GET /api/missions/proofs/feed

  • 상단 탭 단일 선택 기준으로 피드를 페이지 단위 조회
  • 탭별 정렬/필터
    • LATEST: 최신순 (createdAt desc, id desc)
    • POPULAR: 좋아요 많은 순
    • WEEKLY_HOT: '요즘 핫한 미션' 스냅샷(기존 HotMission 집계) 랭킹 재사용 — 선정된 미션의 인증글 우선
    • COMPLETED: 현재 사용자가 완료한 미션의 인증글만 최신순

2. 미션 인증 좋아요 토글POST /api/missions/proofs/{proofId}/likes/toggle

3. 회원가입 닉네임 추가 (와이어프레임에 이름 입력 추가 반영)

  • Membernickname 컬럼 추가, 이메일/구글 가입 시 저장
  • 미션 인증 작성자 응답(author.nickname)에 실제 닉네임 노출

Trouble Shooting ⚽️

  • 피드 N+1 우려: mission/member는 to-one이라 fetch join + 페이징을 함께 써도 안전하며, 그 외 파생값(likedByMe, weeklyCompletedCount)은 개별 조회 대신 id 목록 bulk query로 처리했습니다.
  • WEEKLY_HOT 정렬: 매 요청 완료수를 재집계하지 않고 이미 존재하는 HotMission 스냅샷 랭킹을 재사용해 비용을 낮췄습니다. 스냅샷이 아직 없으면 빈 목록을 반환합니다.
  • 좋아요 수 정합성: 조회 성능을 위해 MissionProof.likeCount(비정규화 컬럼)를 토글 트랜잭션에서 증감합니다. 동시성이 커지면 원자적 UPDATE로 보강이 필요할 수 있습니다.
  • nickname 컬럼 nullable: 기존 회원 호환을 위해 nullable로 두었고(신규 이메일 가입은 @NotBlank 필수), 응답도 nullable로 표기했습니다.

Related ScreenShot 📷

미션 인증 피드
스크린샷 2026-08-12 오전 3 39 49
미션 인증 피드 좋아요
스크린샷 2026-08-12 오전 3 40 38

Uncompleted Tasks 😅

  • 미션 추가 API는 세희가 담당 → 그에 따라 addedByMe/completedByMe(+ 추가 버튼 상태) 필드는 이번 응답에서 제외
  • 프로필 이미지 필드 미도입 → author.profileImageUrlnull 반환

To Reviewers 📢

없습니당

laura-jung and others added 8 commits August 11, 2026 01:56
이메일/구글 회원가입 시 이름(닉네임)을 받아 Member에 저장한다.
- Member에 nickname 컬럼 추가(기존 회원 호환 위해 nullable)
- EmailSignupRequest에 nickname 필드 추가(필수)
- 구글 가입은 구글 프로필 이름(name)을 닉네임으로 저장

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MissionProofLike 엔티티 추가(인증글+회원 unique, 조회용 인덱스)
- MissionProofLikeRepository 추가(토글 조회, likedByMe 벌크 조회)
- MissionProof에 likeCount 증감 메서드 추가(감소 시 음수 방지)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MissionProofFeedTab enum(LATEST/POPULAR/WEEKLY_HOT/COMPLETED)
- 피드/작성자/미션요약/좋아요토글 응답 record 추가
- 작성자 응답은 닉네임 노출, 프로필 이미지는 null(필드 미도입)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- GET /api/missions/proofs/feed: 탭별(LATEST/POPULAR/WEEKLY_HOT/COMPLETED)
  인증 피드 조회. mission/member fetch join, likedByMe/weeklyCompletedCount 벌크 계산
- WEEKLY_HOT은 요즘 핫한 미션 스냅샷(HotMission 집계) 랭킹 재사용
- POST /api/missions/proofs/{proofId}/likes/toggle: 좋아요 토글
- UserMissionRepository에 이번 주 완료수 집계 쿼리 추가
- 성공 코드/에러 코드 및 Swagger 문서 추가

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@laura-jung
laura-jung requested a review from sae2say August 11, 2026 18:41
@laura-jung laura-jung self-assigned this Aug 11, 2026
@laura-jung laura-jung linked an issue Aug 11, 2026 that may be closed by this pull request
1 task

@sae2say sae2say left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

너무 잘해주셨네요~ 항상 코드 스타일에 일관성이 있어서 좋은 것 같습니다.
공모전용이라서.. 릴리즈 할 거 아니라 성능쪽은 그냥 고려 안하고 읽었어요.. ㅎ
로직은 모두 기획의도대로 작동하는 것 같습니다! 코드 수정 안해도 그냥 이대로 머지하셔도 될 것 같아요~
너무 수고하셨습니다~

Comment on lines +40 to +44
public ResponseEntity<SuccessResponse<MissionProofFeedResponse>> getMissionProofFeed(
@CurrentMember CurrentAuth currentAuth,
@RequestParam(defaultValue = "LATEST") MissionProofFeedTab tab,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

오홍 피드면 보통 무한스크롤 형식일텐데 커서방식 대신 offset 방식으로 하신 이유가 있나요?

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.

데이터가 많아지면 커서 방식이 좋긴 한데, 현재는 데이터도 많이 없고 해서 Pageable 사용하여 좀더 간단하고 통일감 있게 구현했습니다!

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "미션 인증글에 연결된 미션 요약 정보")
public record MissionProofMissionSummaryResponse(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

요기 response에 '내 미션으로 추가되었는지 여부'를 추가로 반환해야 하는거죠?

Image

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 +21 to +23
@Schema(description = "댓글 작성 시각", example = "2026-08-13T14:27:00")
LocalDateTime createdAt
) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

서버에서 n분 전, n시간 전 이렇게 변형해서 주는 게 아니라, 프론트에서 처리하도록 고려하신건가요?

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.

네 맞습니다. 서버에서 보내주면 1분 지날때마다 API를 요청해야할 것 같다고 판단해서 작성 시각을 보내면 프론트에서 처리하는게 좋지 않을까 생각했습니다.

@laura-jung
laura-jung merged commit ef67a94 into main Aug 14, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 미션 인증 피드 조회 api

2 participants