Skip to content

#141 [merge] v1.0.0 dev -> main 브랜치 병합#142

Merged
si-zero merged 70 commits intomainfrom
dev
Apr 9, 2026
Merged

#141 [merge] v1.0.0 dev -> main 브랜치 병합#142
si-zero merged 70 commits intomainfrom
dev

Conversation

@si-zero
Copy link
Copy Markdown
Contributor

@si-zero si-zero commented Apr 8, 2026

#️⃣ 연관된 이슈

📝 작업 내용

  • dev -> main 브랜치 병합

📌 공유 사항

  1. 앱 배포 이후, 개발 서버와 배포 서버를 분리하기 위한 병합 과정이 필요합니다.

✅ 체크리스트

  • Reviewer에 팀원들을 선택했나요?
  • Assignees에 본인을 선택했나요?
  • 컨벤션에 맞는 Type을 선택했나요?
  • Development에 이슈를 연동했나요?
  • Merge 하려는 브랜치가 올바르게 설정되어 있나요?
  • 컨벤션을 지키고 있나요?
  • 로컬에서 실행했을 때 에러가 발생하지 않나요?
  • 팀원들에게 PR 링크 공유를 했나요?

📸 스크린샷

없음

💬 리뷰 요구사항

없음

Dante0922 and others added 30 commits March 8, 2026 23:54
- user, notice-notification ERD 문서 분리
- home, mypage, user API 명세 문서 추가 및 정리
- Oauth2 ERD 및 API 정의
- user / oauth2 ERD 경계 및 필드 구조 재정리
- user 운영성 상세 ERD 분리
- user API 명세를 기준으로 oauth API 명세 통일
- 공개 식별자 `user_tag`, 프로필 필드, 토큰 사용 흐름 반영
- 문서 간 상충되던 user / oauth 명세 정합성 수정
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #10 

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

  ### 📚 Docs
  | 내용 | 파일 |
  |------|------|
  | 좋아요 도메인 API 명세서 신규 작성 | `likes-api.md` |
  | 댓글 도메인 API 명세서 신규 작성 | `comments-api.md` |
  | 관점 도메인 ERD 다이어그램 추가 | `perspectives.puml` |
  | 관점 도메인 API 명세서 신규 작성 | `perspectives-api.md` |
  | 추천 도메인 API 명세서 신규 작성 | `recommendations-api.md` |
  | 투표 도메인 API 명세서 수정 | `vote-api.md` |
  | 댓글 도메인 ERD 다이어그램 추가 | `comment.puml` |

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷

PERSPECTIVES (관점) + COMMENTS (댓글) + LIKES (좋아요)
<img width="412" height="370" alt="image"
src="https://github.com/user-attachments/assets/cc784867-d0fb-4e07-8e95-f8be5cd11142"
/>

COMMENTS (댓글)
<img width="277" height="162" alt="image"
src="https://github.com/user-attachments/assets/f726f55f-9c3c-462d-8b5d-a4ab8fec8bd8"
/>

## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
<!-- 종료 의도 판단을 Java 키워드 → AI 2차 검증 구조로 설계했는데
해당 구조가 유지보수 및 확장 측면에서 적절한지 의견 부탁드립니다. -->
> 1. 천수님 테이블 구조 위에다가 제가 필요한 테이블들 끼운거라 큰 문제는 없어보입니다.
## #️⃣ 연관된 이슈
- #21

## 📝 작업 내용

### ✨ Feat
| 내용 | 파일 |
|------|------|
| 사용자 도메인 엔티티 및 리포지토리 구현 |
`src/main/java/com/swyp/app/domain/user/entity/*`,
`src/main/java/com/swyp/app/domain/user/repository/*` |
| 온보딩/프로필/설정/성향 점수 API 구현 |
`src/main/java/com/swyp/app/domain/user/controller/UserController.java`,
`src/main/java/com/swyp/app/domain/user/service/UserService.java` |
| 필수 약관 동의 이력 저장 로직 추가 |
`src/main/java/com/swyp/app/domain/user/entity/UserAgreement.java`,
`src/main/java/com/swyp/app/domain/user/service/UserService.java` |
| request validation 및 입력 예외 처리 보강 |
`src/main/java/com/swyp/app/domain/user/dto/request/*`,
`src/main/java/com/swyp/app/global/common/exception/GlobalExceptionHandler.java`
|

### ♻️ Refactor
| 내용 | 파일 |
|------|------|
| `/me` 계열 호출을 auth 전 임시 현재 사용자 방식으로 단순화 |
`src/main/java/com/swyp/app/domain/user/controller/UserController.java`,
`src/main/java/com/swyp/app/domain/user/service/UserService.java` |
| 프로필 PATCH를 부분 수정 방식으로 보강 |
`src/main/java/com/swyp/app/domain/user/entity/UserProfile.java`,
`src/main/java/com/swyp/app/domain/user/dto/request/UpdateUserProfileRequest.java`
|

### 🐛 Fix
| 내용 | 파일 |
|------|------|
| 온보딩 재호출 시 중복 완료 방지 로직 추가 |
`src/main/java/com/swyp/app/domain/user/service/UserService.java` |
| 설정 기본값 및 응답 예시 정합성 수정 |
`src/main/java/com/swyp/app/domain/user/service/UserService.java`,
`docs/api-specs/user-api.md` |

## 📌 공유 사항
> 1. auth 미구현 상태라 `/me` 계열은 현재 가장 최근 사용자를 임시 current user로 간주합니다. OAuth
연동 시 교체 예정입니다.
> 2. `user_tag`는 prefix 없는 8자리 랜덤 문자열로 생성되도록 변경했습니다.

## ✅ 체크리스트
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
- 없음 (서버/API 구현)

## 💬 리뷰 요구사항
- 없음
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #17 

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

### ✨ Feat
<!-- 새로운 기능 구현 내용 작성 -->
| 내용 | 파일 |
  |------|------|
| Perspective 엔티티 및 상태(PerspectiveStatus) 구현 | `Perspective.java`,
`PerspectiveStatus.java` |
  | PerspectiveComment 엔티티 구현 | `PerspectiveComment.java` |
| PerspectiveLike 엔티티 구현 (UUID PK + UniqueConstraint) |
`PerspectiveLike.java` |
| 관점 생성 / 조회 / 수정 / 삭제 API 구현 | `PerspectiveController.java`,
`PerspectiveService.java` |
| 내 PENDING 관점 조회 API 구현 | `PerspectiveController.java`,
`PerspectiveService.java` |
| 관점 댓글 생성 / 조회 / 수정 / 삭제 API 구현 | `PerspectiveCommentController.java`,
`PerspectiveCommentService.java` |
| 관점 좋아요 조회 / 등록 / 취소 API 구현 | `PerspectiveLikeController.java`,
`PerspectiveLikeService.java` |
| 흥미 기반 배틀 추천 조회 API 구현 (커서 페이지네이션, 정책 미확정) |
`RecommendationController.java`, `RecommendationService.java` |
| 투표 통계 조회 / 내 투표 내역 조회 API 구현 | `VoteController.java`,
`VoteServiceImpl.java` |
| 타 도메인 의존 서비스 인터페이스 + 구현체 구현 (Battle, Vote, User, Tag) |
`BattleServiceImpl.java`,`UserQueryServiceImpl.java`,
`TagServiceImpl.java` |
  | User 엔티티 및 Repository 구현 | `User.java`, `UserRepository.java` |
| 에러코드 추가 (Perspective / Comment / Like / Vote / User) |
`ErrorCode.java` |
| 로컬 개발환경 DB 설정 (application-local.yml, .gitignore 추가) |
`application-local.yml`, `.gitignore` |
| perspectives-api.md 명세 업데이트 (내 PENDING 관점 조회 추가) |
`perspectives-api.md` |

### ♻️ Refactor
<!-- 기존 코드 리팩토링 내용 작성 -->
  | 내용 | 파일 |
  |------|------|
| 관점 목록 조회 시 PUBLISHED 상태만 반환하도록 수정 | `PerspectiveRepository.java`,
`PerspectiveService.java` |
| 좋아요 수 조회를 캐시 카운터 대신 실제 DB count로 변경 | `PerspectiveLikeService.java`,
`PerspectiveLikeRepository.java` |
| 추천 응답에 커서 페이지네이션(nextCursor, hasNext) 추가 |
`RecommendationListResponse.java` |

  ### 🐛 Fix

  | 내용 | 파일 |
  |------|------|
  | 본인 관점에 좋아요 방지 로직 추가 | `PerspectiveLikeService.java` |

## 📌 공유 사항
<!-- 팀원에게 공유할 내용이나 참고 사항 작성 -->
<!-- 노션 환경 설정 파일 확인 부탁드립니다! -->
> 1. Security 미적용으로 인해 userId가 각 Controller에 `1L`로 하드코딩되어 있습니다. Security
적용 후
  `@AuthenticationPrincipal`로 교체 필요합니다.
> 2. Battle / Vote / User / Tag 서비스는 각 도메인 병합 전 임시 구현으로, 추후 해당 도메인 담당자와
로직 통합이
  필요합니다.
  > 3. 흥미 기반 배틀 추천 정책이 미확정 상태로, 현재는 빈 리스트를 반환합니다.

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
<!-- Swagger, Postman, JUnit 테스트 화면 첨부 -->
<!-- 기능 동작 화면이나 테스트 결과 캡처를 첨부하면 좋습니다 -->

Perspective 도메인 관련 스웨거 명세입니다. 
<img width="1111" height="898" alt="image"
src="https://github.com/user-attachments/assets/e3ec31ba-a4ab-4daf-8783-b1ed1b3e4bf6"
/>

## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
<!-- 종료 의도 판단을 Java 키워드 → AI 2차 검증 구조로 설계했는데
해당 구조가 유지보수 및 확장 측면에서 적절한지 의견 부탁드립니다. -->
> 1. 타 도메인(Battle, User, Vote, Tag) 서비스 구현체를 임시로 포함했습니다. 리뷰하실때 엔티티랑 도메인
ServiceImpl 만 확인해주시면 Merge Confilict는 제가 해결해서 Merge 시켜놓겠습니다.
● ## #️⃣ 연관된 이슈
  - #25 

  ## 📝 작업 내용

  ### ✨ Feat
  | 내용 | 파일 |
  |------|------|
| GPT 비동기 검수 서비스 구현 (PENDING → PUBLISHED / REJECTED / MODERATION_FAILED)
| `GptModerationService.java` |
  | 관점 생성/수정 시 GPT 검수 비동기 호출 연동 | `PerspectiveService.java` |
| 검수 재시도 API 구현 (`POST /perspectives/{id}/moderation/retry`) |
`PerspectiveController.java`, `PerspectiveService.java` |
  | `MODERATION_FAILED` 상태 추가 | `PerspectiveStatus.java` |
  | `PERSPECTIVE_MODERATION_NOT_FAILED` 에러 코드 추가 | `ErrorCode.java` |
  | `@EnableAsync` 설정 추가 | `AsyncConfig.java` |
  | OpenAI API 설정 추가 (`api-key`, `url`, `model`) | `application.yml` |
  | 관점 상태 직접 변경 메서드 추가 | `Perspective.java` |

  ### ♻️ Refactor
  | 내용 | 파일 |
  |------|------|
  | | |

  ### 🐛 Fix
  | 내용 | 파일 |
  |------|------|
  | | |

  ## 📌 공유 사항
> 1. OpenAI API Key는 `.env` 에 `OPENAI_API_KEY`로 설정이 필요합니다. 노션 환경 설정 파일
확인 부탁드립니다!
> 2. `@Async` + `@Transactional` 동시 사용 시 트랜잭션이 호출 쓰레드에서 커밋되어 비동기 쓰레드에서
DB 반영이 안 되는
문제로, `GptModerationService`에서 `@Transactional` 제거 후 `save()` 명시 호출 방식으로
처리했습니다.

  ## ✅ 체크리스트
  - [x] Reviewer에 팀원들을 선택했나요?
  - [x] Assignees에 본인을 선택했나요?
  - [x] 컨벤션에 맞는 Type을 선택했나요?
  - [x] Development에 이슈를 연동했나요?
  - [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
  - [x] 컨벤션을 지키고 있나요?
  - [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
  - [x] 팀원들에게 PR 링크 공유를 했나요?

  ## 📸 스크린샷
수정 시 아래와 같습니다.

올바른 관점 수정
<img width="1435" height="827" alt="image"
src="https://github.com/user-attachments/assets/1492ec01-2bd2-4e99-8ec2-281a3e07575d"
/>
<img width="1599" height="282" alt="image"
src="https://github.com/user-attachments/assets/eab03869-2e29-4fc9-88c4-ba7157e40e08"
/>
<img width="1604" height="193" alt="image"
src="https://github.com/user-attachments/assets/c1f469a4-bcad-40ac-b6ee-0887a5be0357"
/>

욕설 관점
<img width="1415" height="661" alt="image"
src="https://github.com/user-attachments/assets/0f0a70bb-48bb-4741-883e-e04b0f45a34b"
/>
<img width="1590" height="242" alt="image"
src="https://github.com/user-attachments/assets/3ec72615-01c7-4f36-858c-869d840a45d9"
/>
<img width="1623" height="178" alt="image"
src="https://github.com/user-attachments/assets/8c7eff34-b082-4cdd-bf72-56d379057046"
/>


생성 시 아래와 같습니다. 

올바른 관점 생성
<img width="1422" height="757" alt="image"
src="https://github.com/user-attachments/assets/2f5520f2-a3d0-453a-9236-b7e877a84e39"
/>
<img width="1598" height="245" alt="image"
src="https://github.com/user-attachments/assets/b669e4c4-1e4d-432f-97ba-4a67c80f69af"
/>
<img width="1609" height="276" alt="image"
src="https://github.com/user-attachments/assets/223d4f32-e060-48f1-9109-90c79edc8557"
/>

욕설 관점 생성
<img width="1422" height="834" alt="image"
src="https://github.com/user-attachments/assets/b899c672-87e8-4202-bc5d-a97bc0e48aaf"
/>
<img width="1593" height="232" alt="image"
src="https://github.com/user-attachments/assets/6c3dea22-c677-4a45-9b8c-ea2e9294a5c3"
/>
<img width="1638" height="208" alt="image"
src="https://github.com/user-attachments/assets/a650d249-6416-4cec-a63b-761b6d06d893"
/>


  ## 💬 리뷰 요구사항
> 1. GPT API 호출 실패 시 최대 2회 재시도 후 `MODERATION_FAILED`로 전환되는 구조인데, 재시도 횟수나
대기 시간(현재 2초)
  조정이 필요한지 의견 부탁드립니다.
  > 2. Prompt 의 경우 임시로 
` "당신은 콘텐츠 검수 AI입니다. 입력된 텍스트에 욕설, 혐오 발언, 폭력적 표현, 성적 표현, 특정인을 향한 공격적 내용이
포함되어 있는지 판단하세요. " +
            "문제가 있으면 'REJECT', 없으면 'APPROVE' 딱 한 단어만 응답하세요.";`

로 진행 중입니다.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## 작업 내용
- GET /api/v1/home 집계 API 추가
- 홈 응답에 editorPicks, trendingBattles, bestBattles, todayPicks,
newBattles, newNotice 반영
- 공지 조회용 notice 도메인 및 공개 API 추가
- 홈/공지 관련 테스트 추가 및 보강

## 참고
- 홈 배틀 조회 V2 최적화 시도는 최종 반영 범위에서 제외했고 기존 경로로 정리했습니다.
- bash gradlew test 통과
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #52

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

### ✨ Feat
<!-- 새로운 기능 구현 내용 작성 -->
| 내용 | 파일 |
|------|------|
| JWT 관련 설정 파일 추가 | `application.properties` |
|  |  |

### 🐛 Fix
<!-- 버그 수정 내용 작성 -->
| 내용 | 파일 |
|------|------|
| 화이트리스트 API 주소 범위 넓게 수정 | `JwtFilter.java` |
|  |  |

## 📌 공유 사항
<!-- 팀원에게 공유할 내용이나 참고 사항 작성 -->
<!-- 노션 환경 설정 파일 확인 부탁드립니다! -->
> 1. `application.properties` 에 `JWT_SECRET` 추가되었으니 확인 부탁드립니다.

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
<!-- Swagger, Postman, JUnit 테스트 화면 첨부 -->
<!-- 기능 동작 화면이나 테스트 결과 캡처를 첨부하면 좋습니다 -->
> 수정 후 테스트
<img width="1131" height="228" alt="image"
src="https://github.com/user-attachments/assets/42007c09-a8bc-4622-a2ac-0e584484f3ef"
/>


## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
<!-- 종료 의도 판단을 Java 키워드 → AI 2차 검증 구조로 설계했는데
해당 구조가 유지보수 및 확장 측면에서 적절한지 의견 부탁드립니다. -->
> 없음
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #36
- #40

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

### ✨ Feat
<!-- 새로운 기능 구현 내용 작성 -->
| 내용 | 파일 |
|------|------|
| 마이페이지 API 추가 (`/me/mypage`, `/me/recap`, `/me/battle-records`,
`/me/content-activities`, `/me/notification-settings`, `/me/notices`) |
`MypageController.java`, `MypageService.java`, 관련 request/response DTO |
| 리캡/배틀기록/활동 조회용 Query Service 추가 및 집계 로직 구현 | `VoteQueryService.java`,
`PerspectiveQueryService.java`, `BattleQueryService.java` |
| 크레딧 적립/누적 포인트 기반 티어 계산 기능 추가 | `CreditService.java`,
`CreditHistory.java`, `CreditHistoryRepository.java`, `TierCode.java`,
`CreditType.java` |
|  |  |

### ♻️ Refactor
<!-- 기존 코드 리팩토링 내용 작성 -->
| 내용 | 파일 |
|------|------|
| onboarding/bootstrap/public-profile 계열 불필요 엔드포인트 및 관련 코드 제거 |
`UserController.java`, `AuthService.java`, 관련 DTO |
| `UserSettings`, `UserTendencyScore`, `UserTendencyScoreHistory` 필드명을
현재 도메인 용어 기준으로 정리 | `UserSettings.java`, `UserTendencyScore.java`,
`UserTendencyScoreHistory.java`, 관련 DTO |
| user 내부 공지 구현을 notice 도메인으로 통합하고 중복 로직 제거 | `MypageService.java`,
`NoticeService.java` 연동부 |
| USER ERD, API 문서, DB 마이그레이션 스크립트 최신화 | `user.puml`, `user-ops.puml`,
`user-api.md`, `mypage-api.md`,
`20260326_alter_credit_histories_reference_id_not_null.sql` |
|  |  |

### 🧪 Test
<!-- 기존 코드 리팩토링 내용 작성 -->
| 내용 | 파일 |
|------|------|
| user/mypage/credit 단위 테스트 추가 및 핵심 시나리오 검증 | `UserServiceTest.java`,
`MypageServiceTest.java`, `CreditServiceTest.java` |
| home/notice 테스트 보강 및 테스트 메서드명 정리 | `HomeServiceTest.java`,
`NoticeServiceTest.java` |
| `./gradlew test --tests '*UserServiceTest' --tests
'*MypageServiceTest' --tests '*CreditServiceTest' --tests
'*HomeServiceTest' --tests '*NoticeServiceTest'` 통과 | 테스트 실행 결과 |
|  |  |

## 📌 공유 사항
<!-- 팀원에게 공유할 내용이나 참고 사항 작성 -->
- 철학자 산출 로직은 아직 확정 전이라 `SOCRATES`, `PLATO`, `MARX`를 임시값으로 사용하고 있습니다.
- 크레딧/티어 계산은 붙었지만 실제 적립 이벤트 연결은 아직 남아 있습니다.
- 전체 `./gradlew test`는 `AppApplicationTests.contextLoads()`에서 로컬 환경 변수
placeholder 미설정으로 실패했습니다.
- 운영 반영 전 스키마 변경 대상(`user_settings`, tendency score 컬럼명,
`onboarding_completed`, `credit_histories.reference_id NOT NULL`)은 별도
마이그레이션 검증이 필요합니다.

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [ ] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
<!-- Swagger, Postman, JUnit 테스트 화면 첨부 -->
<!-- 기능 동작 화면이나 테스트 결과 캡처를 첨부하면 좋습니다 -->
> 없음

## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
> 1. `MypageService`에서 타 도메인 조회를 `QueryService`로 분리한 현재 경계가 적절한지 확인
부탁드립니다.
>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #60 

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

### ✨ Feat
| 내용 | 파일 |
|------|------|
| AdMob 보상 광고 서명 검증(SSV) 컨트롤러 구현 | `AdMobRewardController.java` |
| 보상 지급 로직 및 멱등성(중복 방지) 처리 서비스 구현 | `AdMobRewardServiceImpl.java` |
| 보상 상태 값(OK, Already Processed) 관리를 위한 Enum 추가 | `AdRewardStatus.java`
|
| 보상 요청 및 응답 전용 DTO 설계 | `AdMobRewardRequest.java`,
`AdMobRewardResponse.java` |
| 보상 지급 이력 관리를 위한 엔티티 및 레포지토리 구축 | `AdRewardHistory.java`,
`AdRewardHistoryRepository.java` |
| Google Tink 기반 서명 검증 빈(Bean) 설정 | `AdMobConfig.java` |

### ♻️ Refactor
| 내용 | 파일 |
|------|------|
| `build.gradle` 내 AdMob SSV 관련 의존성 및 저장소 설정 최적화 | `build.gradle` |
| 단위 테스트 내 불필요한 Stubbing 제거 및 검증 로직 정규화 | `AdMobRewardServiceTest.java`
|

### 🐛 Fix
| 내용 | 파일 |
|------|------|
| 테스트 환경의 'Cannot resolve symbol android' 참조 오류 수정 | `build.gradle` |
| Mockito Strict Stubbing 정책 위반으로 인한 테스트 실패 해결 |
`AdMobRewardServiceTest.java` |

## 📌 공유 사항
<!-- 팀원에게 공유할 내용이나 참고 사항 작성 -->
<!-- 노션 환경 설정 파일 확인 부탁드립니다! -->
> 1. @yaeunjess 예은님, 프론트엔드 작업하시면서 실제 시그니처 값 받아서 테스트가 더 필요해보입니다! 작업할 때,
알려주세요!
2. 그리고, 지금 보상 타입 부분인 `reward_item` 부분 `ITEM`, `POINT` 아니면 오류뜨게 해놨는데 오류
말고 기본값을 부여할지도 궁금합니다.

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
<!-- Swagger, Postman, JUnit 테스트 화면 첨부 -->
<!-- 기능 동작 화면이나 테스트 결과 캡처를 첨부하면 좋습니다 -->
> 성공
<img width="1127" height="170" alt="스크린샷 2026-03-27 오후 8 08 31"
src="https://github.com/user-attachments/assets/b0b51eaa-2081-465f-849e-5efa9fc31eaf"
/>

> 응답만 성공 (같은 사용자가 같은 광고를 봤을 때)
<img width="1124" height="161" alt="스크린샷 2026-03-27 오후 8 08 45"
src="https://github.com/user-attachments/assets/4461ddc5-7cf8-4030-9a81-50eead9bb293"
/>

> 에러: 유저
<img width="1126" height="190" alt="스크린샷 2026-03-27 오후 8 08 57"
src="https://github.com/user-attachments/assets/03811fb0-a449-4dad-9aec-bbe010d42272"
/>

> 에러: 보상 타입
<img width="1120" height="192" alt="스크린샷 2026-03-27 오후 8 09 12"
src="https://github.com/user-attachments/assets/b9064fda-68d1-405e-98f2-4d06016c9522"
/>

> 에러: 시그니처(서명) 검증 오류
<img width="1130" height="190" alt="스크린샷 2026-03-27 오후 9 24 04"
src="https://github.com/user-attachments/assets/47a39c43-bbfe-4992-a872-a22a5f1d0b06"
/>

## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
<!-- 종료 의도 판단을 Java 키워드 → AI 2차 검증 구조로 설계했는데
해당 구조가 유지보수 및 확장 측면에서 적절한지 의견 부탁드립니다. -->
> 없음
## Summary
- S3 Presigned URL 인프라 구축 및 홈 API 응답 구조를 섹션별 전용 DTO로 리팩토링
- 철학자·캐릭터 enum에 이미지 매핑(imageKey, label) 추가 및 정규화
- 마이페이지 철학자 유형 산출 로직 구현 (최초 5회 투표 → PHILOSOPHER 태그 기반 자동 산출·저장)
- PhilosopherType 확장: typeName, description, bestMatch/worstMatch, 6축 고정
성향 점수
- 탐색 탭 배틀 검색 API 신설 (`GET /api/v1/search/battles`) — 카테고리 필터, 인기순/최신순
정렬, offset 페이지네이션

## Changes
- **홈 API**: `HomeResponse`를 6개 섹션별 DTO로 분리 (EditorPick, Trending,
BestBattle, TodayQuiz, TodayVote, NewBattle)
- **S3**: `S3PresignedUrlService`, `S3Config` 신설, `FileUploadController`
presigned URL 응답 추가
- **Enum**: `PhilosopherType` 10종 (label, typeName, description,
bestMatch, worstMatch, 6축 점수, imageKey), `CharacterType` 8종 정규화
- **마이페이지**: `UserProfile.philosopherType` 필드 추가,
`MypageService.resolvePhilosopherType()` 산출 로직
- **서치**: `search` 도메인 신설 (Controller, Service, DTO, Enum),
`BattleRepository` 검색 쿼리 추가

## Test plan
- [x] `./gradlew build` 컴파일 확인 (contextLoads 제외 전 테스트 통과)
- [ ] Swagger에서 홈 API 호출 → 섹션별 응답 확인
- [ ] Swagger에서 마이페이지 API → 철학자 유형 산출 확인 (5회 투표 후)
- [ ] Swagger에서 탐색 API → 카테고리 필터/정렬 확인

Closes #64

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Vote, Perspective, PerspectiveComment, PerspectiveLike, CreditHistory의
`Long userId` → `@ManyToOne User` 엔티티 관계로 전환
- Perspective의 `Long battleId`, `Long optionId` → `@ManyToOne Battle`,
`@ManyToOne BattleOption`으로 전환
- 전 도메인 컨트롤러의 `Long userId = 1L` 하드코딩 → `@AuthenticationPrincipal Long
userId`로 교체 (VoteController, PerspectiveController,
PerspectiveCommentController, PerspectiveLikeController)
- 해소된 TODO 주석 제거 (S3 임시 구현 3건, AdMob 포인트 합산, Prevote 체크)
- #64 작업 포함: S3 Presigned URL, 홈 API 섹션별 DTO, 철학자 유형 산출/확장, 탐색 탭 검색 API

## Changes (29 files)
- **Entities** (5): Vote, Perspective, PerspectiveComment,
PerspectiveLike, CreditHistory
- **Repositories** (5): VoteRepository, PerspectiveRepository,
PerspectiveCommentRepository, PerspectiveLikeRepository,
CreditHistoryRepository
- **Services** (10): VoteServiceImpl, VoteQueryService,
PerspectiveService, PerspectiveCommentService, PerspectiveLikeService,
PerspectiveQueryService, CreditService, MypageService,
ScenarioServiceImpl, BattleServiceImpl
- **Controllers** (5): VoteController, PerspectiveController,
PerspectiveCommentController, PerspectiveLikeController,
ScenarioController
- **Infra** (3): S3Config, S3PresignedUrlService, FileUploadResponse —
TODO 제거
- **Tests** (2): CreditServiceTest, MypageServiceTest

## Test plan
- [x] `./gradlew compileJava compileTestJava` 컴파일 성공
- [x] CreditServiceTest 5개 통과
- [x] MypageServiceTest 12개 통과
- [ ] 로컬 Swagger에서 @AuthenticationPrincipal 동작 확인
- [ ] 투표 → 관점 → 좋아요/댓글 플로우 E2E 확인

Closes #51

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Dante0922 and others added 18 commits April 2, 2026 03:38
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #110 

  ## 📝 작업 내용
  ### 🐛 Fix      
  | 내용 | 파일 |
  |------|------|
| Swagger 스키마 이름 충돌 해결 - inner record에 고유 이름 지정 |
`CommentListResponse.java`, `PerspectiveListResponse.java`,
`RecommendationListResponse.java` |
  | 중복 메소드 선언 제거 | `Vote.java` |

  ## 📌 공유 사항
> 1. Swagger UI에서 inner record 클래스명 충돌로 인한 스키마 오류를 각 record에 고유한 이름을
지정하여 해결했습니다.

  ## ✅ 체크리스트
  - [x] Reviewer에 팀원들을 선택했나요?
  - [x] Assignees에 본인을 선택했나요?
  - [x] 컨벤션에 맞는 Type을 선택했나요?
  - [x] Development에 이슈를 연동했나요?
  - [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
  - [x] 컨벤션을 지키고 있나요?
  - [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
  - [x] 팀원들에게 PR 링크 공유를 했나요?

  ## 💬 리뷰 요구사항
  > 1. 없음

Co-authored-by: 현준혁 <guswnsgur2276@metabuild.co.kr>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #114 

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

  ### 🐛 Fix
  | 내용 | 파일 |
  |------|------|
| 관점 삭제 시 FK 제약 조건 위반 오류 수정 - 삭제 전 댓글 먼저 제거 | `PerspectiveService.java`,
`PerspectiveCommentRepository.java` |

  ## 📌 공유 사항
> 1. 관점 삭제 시 `perspective_comments` 테이블의 FK 제약 조건으로 인해 500 에러가 발생하던 문제를
수정했습니다. 관점 삭제 전 해당 관점의 댓글을 먼저 삭제하도록 처리했습니다.

  ## ✅ 체크리스트
  - [x] Reviewer에 팀원들을 선택했나요?
  - [x] Assignees에 본인을 선택했나요?
  - [x] 컨벤션에 맞는 Type을 선택했나요?
  - [x] Development에 이슈를 연동했나요?
  - [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
  - [x] 컨벤션을 지키고 있나요?
  - [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
  - [x] 팀원들에게 PR 링크 공유를 했나요?

  ## 💬 리뷰 요구사항
  > 1. 없음
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #118 

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

### 🐛 Fix
<!-- 버그 수정 내용 작성 -->
| 내용 | 파일 |
|------|------|
| 불필요한 import 제거 | `UserService.java` |
| Type 필터링 추가 |  `BattleRepository.java` |

## 📌 공유 사항
<!-- 팀원에게 공유할 내용이나 참고 사항 작성 -->
<!-- 노션 환경 설정 파일 확인 부탁드립니다! -->
> 1.

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [x] Reviewer에 팀원들을 선택했나요?
- [x] Assignees에 본인을 선택했나요?
- [x] 컨벤션에 맞는 Type을 선택했나요?
- [x] Development에 이슈를 연동했나요?
- [x] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [x] 컨벤션을 지키고 있나요?
- [x] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [x] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
<!-- Swagger, Postman, JUnit 테스트 화면 첨부 -->
<!-- 기능 동작 화면이나 테스트 결과 캡처를 첨부하면 좋습니다 -->

## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
<!-- 종료 의도 판단을 Java 키워드 → AI 2차 검증 구조로 설계했는데
해당 구조가 유지보수 및 확장 측면에서 적절한지 의견 부탁드립니다. -->
> 1.

Co-authored-by: 현준혁 <guswnsgur2276@metabuild.co.kr>
## Summary
- 마이페이지 콘텐츠 활동 내역 API 응답에 캐릭터 이미지 URL 추가
- 댓글: 현재 사용자(나)의 캐릭터 이미지 URL 반환
- 좋아요: 좋아요한 글 작성자의 캐릭터 이미지 URL 반환

## Changes
- `ContentActivityListResponse.AuthorInfo`에 `characterImageUrl` 필드 추가
- `MypageService.buildCommentActivities`: 현재 사용자 프로필에서 캐릭터 URL 조회
- `MypageService.buildLikeActivities`: 글 작성자의 캐릭터 URL 조회
- `MypageService.resolveCharacterImageUrl(String)` 오버로드 추가

## Test plan
- [ ] 댓글 활동 조회 시 `author.characterImageUrl`에 현재 사용자의 캐릭터 이미지 URL 반환 확인
- [ ] 좋아요 활동 조회 시 `author.characterImageUrl`에 글 작성자의 캐릭터 이미지 URL 반환 확인
- [ ] 캐릭터 타입이 null인 경우 `characterImageUrl`이 null로 반환되는지 확인

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## #️⃣ 연관된 이슈
<!-- Ex) - #이슈번호 -->
<!-- 연관된 이슈 번호를 링크 형태로 작성하세요 -->
- #114 

## 📝 작업 내용
<!-- 이번 PR/이슈에서 실제 수행한 작업 내용을 작성하세요 -->

### ✨ Feat
<!-- 새로운 기능 구현 내용 작성 -->
| 내용 | 파일 |
|------|------|
| 로그인 기능 구현 | `AuthController.java`, `AuthService.java` |
| 'API 설계 수정' |  |

### ♻️ Refactor
<!-- 기존 코드 리팩토링 내용 작성 -->
| 내용 | 파일 |
|------|------|
| 불필요한 import 제거 | `UserService.java` |
| 댓글 API 설계 수정 | 'perspectiveService.java'|

### 🐛 Fix
<!-- 버그 수정 내용 작성 -->
| 내용 | 파일 |
|------|------|
| 널 포인트 예외 처리 | `PaymentService.java` |
|  |  |

## 📌 공유 사항
<!-- 팀원에게 공유할 내용이나 참고 사항 작성 -->
<!-- 노션 환경 설정 파일 확인 부탁드립니다! -->
> 1.

## ✅ 체크리스트
<!-- PR 제출 전에 체크해야 할 사항들 -->
- [ ] Reviewer에 팀원들을 선택했나요?
- [ ] Assignees에 본인을 선택했나요?
- [ ] 컨벤션에 맞는 Type을 선택했나요?
- [ ] Development에 이슈를 연동했나요?
- [ ] Merge 하려는 브랜치가 올바르게 설정되어 있나요?
- [ ] 컨벤션을 지키고 있나요?
- [ ] 로컬에서 실행했을 때 에러가 발생하지 않나요?
- [ ] 팀원들에게 PR 링크 공유를 했나요?

## 📸 스크린샷
<!-- Swagger, Postman, JUnit 테스트 화면 첨부 -->
<!-- 기능 동작 화면이나 테스트 결과 캡처를 첨부하면 좋습니다 -->

## 💬 리뷰 요구사항
<!-- 리뷰어에게 요청하는 구체적인 사항 작성 -->
<!-- 종료 의도 판단을 Java 키워드 → AI 2차 검증 구조로 설계했는데
해당 구조가 유지보수 및 확장 측면에서 적절한지 의견 부탁드립니다. -->
> 1.
@si-zero si-zero self-assigned this Apr 8, 2026
@si-zero si-zero added the 🔀 Merge (병합) 브랜치를 Merge할 때 사용합니다. label Apr 8, 2026
@si-zero si-zero changed the title #141 [merge] v1.0.0 🔀 Merge: dev -> main 브랜치 병합 #141 #141 [merge] v1.0.0 dev -> main 브랜치 병합 Apr 9, 2026
Copy link
Copy Markdown
Member

@jucheonsu jucheonsu left a comment

Choose a reason for hiding this comment

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

이 PR Merge된 이후에 Merge하면 될 것 같습니다!

@si-zero si-zero linked an issue Apr 9, 2026 that may be closed by this pull request
1 task
@si-zero
Copy link
Copy Markdown
Contributor Author

si-zero commented Apr 9, 2026

이 PR Merge된 이후에 Merge하면 될 것 같습니다!

@jucheonsu 지금 헤당 부분 머지되면 앱 배포 서버 꺼졌다가 켜지는데 상관없는지 여쭤보고 싶습니다.

Copy link
Copy Markdown
Contributor

@HYH0804 HYH0804 left a comment

Choose a reason for hiding this comment

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

수고하셨어요

@jucheonsu
Copy link
Copy Markdown
Member

jucheonsu commented Apr 9, 2026

@jucheonsu 지금 헤당 부분 머지되면 앱 배포 서버 꺼졌다가 켜지는데 상관없는지 여쭤보고 싶습니다.

말씀해주신 부분 생각해보니 현재 PR Merge가 먼저인 것 같습니다.
한 분 더 Approve 해주시고 Merge 해주시면 될 것 같습니다!

@si-zero si-zero merged commit 8cd6c7d into main Apr 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔀 Merge (병합) 브랜치를 Merge할 때 사용합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🔀 Merge: dev -> main 브랜치 병합

4 participants