Skip to content

fix: 공개 프로필 응답에서 email 등 PII 제거 (PublicUserResponse 신설) - #92

Merged
alexization merged 1 commit into
developfrom
feat/91-public-user-response
Jul 21, 2026
Merged

fix: 공개 프로필 응답에서 email 등 PII 제거 (PublicUserResponse 신설)#92
alexization merged 1 commit into
developfrom
feat/91-public-user-response

Conversation

@alexization

@alexization alexization commented Jul 21, 2026

Copy link
Copy Markdown
Owner

배경

공개 프로필 엔드포인트 GET /api/v1/users/{username}RegisterUserResponse를 그대로 반환해 email·githubId·role·userId·isNewUser 등 PII·내부 식별자를 노출했다. 특히 email은 OAuth user:email 스코프 값이라 공개 노출이 부적절하다. (P0-1)

공유 계약 정본은 추적 이슈 alexization/git-ranker-workflow#106. 채택안은 옵션 B(공개 응답에서 PII 제거).

Closes #91

변경

  • PublicUserResponse 신설 — 계약상 공개 19필드만 담는 record + of(User, ActivityLog) 정적 팩토리
  • UserQueryService.findByUsername·UserController.getUser 반환 타입을 PublicUserResponse로 교체
  • RegisterUserResponse는 무변경 — 소유자 전용 POST /users/{username}/refresh와 등록 경로는 본인 데이터라 그대로 유지
  • UserQueryServiceTest: 19필드 매핑 검증 + 리플렉션 기반 PII 미노출 검증(publicResponseExcludesPii) 추가

계약 준수

  • 제외 5필드(userId·githubId·email·role·isNewUser) — record accessor 부재로 컴파일 타임 보장 + 리플렉션 테스트로 명시 검증
  • 포함 19필드는 계약 JSON 순서 그대로 유지

검증

  • ./gradlew test → BUILD SUCCESSFUL
  • ./gradlew build -x test → BUILD SUCCESSFUL

⚠️ 배포 순서 (G3)

프로덕션 배포는 FE(alexization/git-ranker-client#11)의 email 의존 제거·배포가 완료된 뒤에만 한다. FE보다 BE가 먼저 배포되면 공개 응답 계약이 바뀌어 FE Settings·헤더 표시가 깨진다.

Summary by CodeRabbit

  • 새로운 기능

    • 사용자 공개 프로필 조회 API가 개인정보와 내부 식별자를 제외한 공개 정보만 제공합니다.
    • 프로필 이미지, 점수, 순위, 티어, 퍼센타일 및 최근 활동 기반 커밋·이슈·PR·리뷰 통계를 확인할 수 있습니다.
    • 변경된 활동 통계와 최신 프로필 갱신 시각을 함께 제공합니다.
  • 버그 수정

    • 공개 사용자 조회 응답이 등록용 정보와 혼용되지 않도록 응답 형식을 개선했습니다.
  • 테스트

    • 공개 응답 필드와 활동 통계가 올바르게 제공되는지 검증을 강화했습니다.

- PublicUserResponse 신설(계약 19필드), userId·githubId·email·role·isNewUser 제외
- UserQueryService.findByUsername·UserController.getUser 반환 타입을 PublicUserResponse로 교체
- UserQueryServiceTest에 리플렉션 기반 PII 미노출·19필드 매핑 검증 추가
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

공개 사용자 조회 응답을 RegisterUserResponse에서 개인정보와 내부 식별자를 제외한 PublicUserResponse로 전환했다. DTO 매핑, 서비스·컨트롤러 반환 타입, 공개 필드 및 메트릭 검증 테스트를 갱신했다.

Changes

공개 프로필 응답

Layer / File(s) Summary
공개 응답 DTO 계약
src/main/java/com/gitranker/api/domain/user/dto/PublicUserResponse.java
19개 공개 필드와 User, 최신 ActivityLog 값을 매핑하는 정적 팩토리를 추가했다.
조회 서비스와 엔드포인트 전환
src/main/java/com/gitranker/api/domain/user/service/UserQueryService.java, src/main/java/com/gitranker/api/domain/user/UserController.java, src/test/java/com/gitranker/api/domain/user/service/UserQueryServiceTest.java
사용자 조회 경로의 반환 타입을 PublicUserResponse로 변경하고, 공개 필드 집합·활동 카운트·프로필 조회 메트릭을 테스트한다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant UserController
  participant UserQueryService
  participant PublicUserResponse
  Client->>UserController: GET /api/v1/users/{username}
  UserController->>UserQueryService: findByUsername(username)
  UserQueryService->>PublicUserResponse: of(user, activityLog)
  PublicUserResponse-->>UserQueryService: 공개 응답 DTO
  UserQueryService-->>UserController: PublicUserResponse
  UserController-->>Client: ApiResponse<PublicUserResponse>
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 공개 프로필 응답에서 PII 제거와 PublicUserResponse 신설이라는 핵심 변경을 정확히 요약합니다.
Linked Issues check ✅ Passed PublicUserResponse 신설, 공개 조회 경로 반환 타입 변경, PII 제외 및 테스트 검증이 이슈 #91의 요구와 일치합니다.
Out of Scope Changes check ✅ Passed 변경은 공개 프로필 응답 축소와 관련 테스트에 한정되어 있어 범위를 벗어난 코드 변경이 보이지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/91-public-user-response

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/main/java/com/gitranker/api/domain/user/dto/PublicUserResponse.java (1)

9-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

계약 문서화를 위한 Javadoc 추가를 권장합니다.

19개 positional 파라미터로 구성된 record는 향후 필드 추가/순서 변경 시 실수 위험이 있습니다. userId, githubId, email, role, isNewUser를 의도적으로 제외했다는 계약을 클래스 레벨 Javadoc으로 남겨두면, 이후 이 DTO에 필드를 추가하는 개발자가 PII 재노출 위험을 인지하는 데 도움이 됩니다.

📝 제안 예시
+/**
+ * 공개 프로필 응답 DTO (계약: 19개 필드만 포함).
+ * PII(email) 및 내부 식별자(userId, githubId, role, isNewUser)는 절대 포함하지 않는다.
+ */
 public record PublicUserResponse(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/gitranker/api/domain/user/dto/PublicUserResponse.java`
around lines 9 - 53, 클래스 `PublicUserResponse`에 클래스 레벨 Javadoc을 추가해 공개 응답 DTO의
계약을 문서화하세요. `userId`, `githubId`, `email`, `role`, `isNewUser` 필드를 의도적으로 포함하지
않으며 PII를 노출하지 않는다는 점을 명시하고, 기존 record 필드와 `of(User, ActivityLog)` 동작은 변경하지 마세요.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/main/java/com/gitranker/api/domain/user/dto/PublicUserResponse.java`:
- Around line 9-53: 클래스 `PublicUserResponse`에 클래스 레벨 Javadoc을 추가해 공개 응답 DTO의 계약을
문서화하세요. `userId`, `githubId`, `email`, `role`, `isNewUser` 필드를 의도적으로 포함하지 않으며
PII를 노출하지 않는다는 점을 명시하고, 기존 record 필드와 `of(User, ActivityLog)` 동작은 변경하지 마세요.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 7841681f-1a5b-4628-89bd-f04b468c07a0

📥 Commits

Reviewing files that changed from the base of the PR and between b4bf305 and e9d7554.

📒 Files selected for processing (4)
  • src/main/java/com/gitranker/api/domain/user/UserController.java
  • src/main/java/com/gitranker/api/domain/user/dto/PublicUserResponse.java
  • src/main/java/com/gitranker/api/domain/user/service/UserQueryService.java
  • src/test/java/com/gitranker/api/domain/user/service/UserQueryServiceTest.java

@alexization
alexization merged commit 9f1cb82 into develop Jul 21, 2026
2 checks passed
@alexization
alexization deleted the feat/91-public-user-response branch July 21, 2026 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant