Skip to content

refactor: OAuth 서비스 네이밍 통일 및 AI 프롬프트 구조화#63

Merged
gratisreise merged 1 commit intomainfrom
dev
Mar 11, 2026
Merged

refactor: OAuth 서비스 네이밍 통일 및 AI 프롬프트 구조화#63
gratisreise merged 1 commit intomainfrom
dev

Conversation

@gratisreise
Copy link
Owner

@gratisreise gratisreise commented Mar 11, 2026

  • OAuthUserService → OAuthService로 네이밍 변경 (Google, Kakao, Naver)
  • Gemini DTO 클래스 5개 삭제 및 서비스 단순화
  • WritingStyle 프롬프트를 구조화된 템플릿으로 개선
  • AiSummaryResult DTO 추가로 AI 응답 처리 구조화
  • 커스텀 문체 스타일 엔티티에 필드 추가
  • 관련 테스트 코드 업데이트

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 새로운 글쓰기 스타일 변환 API 엔드포인트 추가 (POST /api/articles/summary)
    • AI 기반 태그 자동 생성 기능 추가 (요약과 함께 태그 제공)
  • Refactor

    • 기사 생성/수정 시 수동 태그 입력 제거
    • OAuth 서비스 인터페이스 이름 정규화
    • 예외 처리 로직 최적화
  • Chores

    • 코드 포매팅 및 스타일 개선
    • Docker Compose Redis 서비스 설정 업데이트

- OAuthUserService → OAuthService로 네이밍 변경 (Google, Kakao, Naver)
- Gemini DTO 클래스 5개 삭제 및 서비스 단순화
- WritingStyle 프롬프트를 구조화된 템플릿으로 개선
- AiSummaryResult DTO 추가로 AI 응답 처리 구조화
- 커스텀 문체 스타일 엔티티에 필드 추가
- 관련 테스트 코드 업데이트
@gratisreise gratisreise merged commit 259a2fb into main Mar 11, 2026
0 of 3 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Mar 11, 2026

Caution

Review failed

The pull request is closed.

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'linters', 'tools', 'pre_merge_checks', 'path_filters', 'path_instructions'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0104baf2-306f-44a2-83f5-4280a7989aad

📥 Commits

Reviewing files that changed from the base of the PR and between 4a781f2 and b7dc4a7.

📒 Files selected for processing (41)
  • compose.dev.yml
  • src/main/java/com/mylog/common/enums/WritingStyle.java
  • src/main/java/com/mylog/common/exception/ErrorCode.java
  • src/main/java/com/mylog/common/exception/GlobalExceptionHandler.java
  • src/main/java/com/mylog/common/response/BaseResponse.java
  • src/main/java/com/mylog/common/response/ErrorResponse.java
  • src/main/java/com/mylog/common/security/SecurityConfig.java
  • src/main/java/com/mylog/config/AsyncConfig.java
  • src/main/java/com/mylog/domain/article/ArticleController.java
  • src/main/java/com/mylog/domain/article/ArticleService.java
  • src/main/java/com/mylog/domain/article/dto/AiSummaryResult.java
  • src/main/java/com/mylog/domain/article/dto/request/ArticleCreateRequest.java
  • src/main/java/com/mylog/domain/article/dto/request/ArticleUpdateRequest.java
  • src/main/java/com/mylog/domain/article/dto/request/StyleTransformRequest.java
  • src/main/java/com/mylog/domain/article/dto/request/Temp.java
  • src/main/java/com/mylog/domain/article/repository/ArticleTagRepository.java
  • src/main/java/com/mylog/domain/article/service/AiService.java
  • src/main/java/com/mylog/domain/article/service/ArticleReader.java
  • src/main/java/com/mylog/domain/article/service/ArticleWriter.java
  • src/main/java/com/mylog/domain/article/service/TagWriter.java
  • src/main/java/com/mylog/domain/auth/AuthController.java
  • src/main/java/com/mylog/domain/auth/service/oauth/OAuthService.java
  • src/main/java/com/mylog/domain/auth/service/oauth/OAuthServiceFactory.java
  • src/main/java/com/mylog/domain/auth/service/oauth/impl/GoogleOAuthService.java
  • src/main/java/com/mylog/domain/auth/service/oauth/impl/KakaoOAuthService.java
  • src/main/java/com/mylog/domain/auth/service/oauth/impl/NaverOAuthService.java
  • src/main/java/com/mylog/domain/member/MemberController.java
  • src/main/java/com/mylog/domain/member/dto/CustomWritingStyleRequest.java
  • src/main/java/com/mylog/domain/member/dto/CustomWritingStyleResponse.java
  • src/main/java/com/mylog/domain/member/entity/CustomWritingStyle.java
  • src/main/java/com/mylog/domain/member/service/CustomWritingStyleWriter.java
  • src/main/java/com/mylog/external/gemini/GeminiService.java
  • src/main/java/com/mylog/external/gemini/dto/Candidate.java
  • src/main/java/com/mylog/external/gemini/dto/Content.java
  • src/main/java/com/mylog/external/gemini/dto/GeminiRequest.java
  • src/main/java/com/mylog/external/gemini/dto/GeminiResponse.java
  • src/main/java/com/mylog/external/gemini/dto/Part.java
  • src/test/java/com/mylog/domain/article/service/ArticleReaderTest.java
  • src/test/java/com/mylog/domain/article/service/ArticleServiceTest.java
  • src/test/java/com/mylog/domain/article/service/ArticleWriterTest.java
  • src/test/java/com/mylog/domain/article/service/TagWriterTest.java

📝 Walkthrough

Walkthrough

이번 PR은 OAuth 서비스 인터페이스 이름 변경, 태그 처리 로직 개선(AI 생성 태그 중심), Gemini DTO 제거 및 단순화, 그리고 AI 요약 기능 강화를 포함하는 다양한 변경사항을 다룹니다.

Changes

Cohort / File(s) Summary
OAuth 서비스 리팩토링
src/main/java/com/mylog/domain/auth/service/oauth/OAuthService.java, src/main/java/com/mylog/domain/auth/service/oauth/OAuthServiceFactory.java, src/main/java/com/mylog/domain/auth/service/oauth/impl/GoogleOAuthService.java, src/main/java/com/mylog/domain/auth/service/oauth/impl/KakaoOAuthService.java, src/main/java/com/mylog/domain/auth/service/oauth/impl/NaverOAuthService.java, src/main/java/com/mylog/domain/auth/AuthController.java
인터페이스 OAuthUserServiceOAuthService 이름 변경, 팩토리 클래스명 및 메서드명 통일 (getOAuthUserService → getOAuthService)
AI 요약 및 태그 처리 개선
src/main/java/com/mylog/domain/article/service/AiService.java, src/main/java/com/mylog/domain/article/service/TagWriter.java, src/main/java/com/mylog/domain/article/service/ArticleReader.java, src/main/java/com/mylog/domain/article/service/ArticleWriter.java
AI 기반 요약 JSON 파싱, 태그 저장 로직 추가(saveAiTags), TagReader → ArticleTagRepository 변경, ArticleWriter에서 직접 태그 저장 제거
요청 DTO 간소화
src/main/java/com/mylog/domain/article/dto/request/ArticleCreateRequest.java, src/main/java/com/mylog/domain/article/dto/request/ArticleUpdateRequest.java
tagNames 필드 제거, AI 기반 태그 생성으로 전환
API 엔드포인트 확장
src/main/java/com/mylog/domain/article/ArticleController.java, src/main/java/com/mylog/domain/article/ArticleService.java, src/main/java/com/mylog/domain/article/dto/AiSummaryResult.java, src/main/java/com/mylog/domain/article/dto/request/Temp.java
POST /api/articles/summary 새 엔드포인트 추가, Temp 요청 타입 신규, AiSummaryResult 응답 타입 신규
Gemini DTO 제거
src/main/java/com/mylog/external/gemini/dto/GeminiRequest.java, src/main/java/com/mylog/external/gemini/dto/GeminiResponse.java, src/main/java/com/mylog/external/gemini/dto/Candidate.java, src/main/java/com/mylog/external/gemini/dto/Content.java, src/main/java/com/mylog/external/gemini/dto/Part.java
Gemini API 응답 구조 DTO 제거, JSON 직렬화 단순화
글쓰기 스타일 템플릿 강화
src/main/java/com/mylog/common/enums/WritingStyle.java, src/main/java/com/mylog/domain/member/entity/CustomWritingStyle.java
단일행 문자열 → Java 텍스트 블록으로 변경, Role/Task/Constraint/Instruction 섹션 구조화
예외 처리 및 설정 정리
src/main/java/com/mylog/common/exception/ErrorCode.java, src/main/java/com/mylog/common/exception/GlobalExceptionHandler.java, src/main/java/com/mylog/external/gemini/GeminiService.java
NOT_LOGGED_IN 제거, 예외 핸들러 중복 제거, Gemini 로깅 제거
테스트 업데이트
src/test/java/com/mylog/domain/article/service/ArticleReaderTest.java, src/test/java/com/mylog/domain/article/service/ArticleServiceTest.java, src/test/java/com/mylog/domain/article/service/ArticleWriterTest.java, src/test/java/com/mylog/domain/article/service/TagWriterTest.java
TagReader → ArticleTagRepository 모킹 변경, AI 태그 기반 테스트 시나리오 추가, 직접 태그 저장 테스트 제거
기타 설정 및 정리
compose.dev.yml, src/main/java/com/mylog/common/response/BaseResponse.java, src/main/java/com/mylog/common/response/ErrorResponse.java, src/main/java/com/mylog/common/security/SecurityConfig.java, src/main/java/com/mylog/config/AsyncConfig.java, src/main/java/com/mylog/domain/member/MemberController.java
Redis 설정 추가, 응답 DTO ErrorDetail 추가, 불필요한 주석 제거

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant ArticleController
    participant ArticleService
    participant AiService
    participant GeminiAPI
    participant TagWriter
    participant ArticleTagRepository

    Client->>ArticleController: POST /api/articles/summary<br/>(Temp request)
    ArticleController->>ArticleService: getArticleSummary(Temp)
    ArticleService->>AiService: test(content)
    AiService->>GeminiAPI: callGemini(prompt)
    GeminiAPI-->>AiService: JSON 응답<br/>(summary + tags)
    AiService->>AiService: parseAiSummaryResponse()<br/>(JSON 파싱)
    AiService-->>ArticleService: AiSummaryResult
    ArticleService-->>ArticleController: SuccessResponse
    ArticleController-->>Client: AiSummaryResult
Loading
sequenceDiagram
    actor User
    participant ArticleWriter
    participant ArticleService
    participant AiService
    participant TagWriter
    participant ArticleRepository
    participant TagRepository
    participant ArticleTagRepository

    User->>ArticleWriter: create(ArticleCreateRequest)
    ArticleWriter->>ArticleRepository: save(article)
    ArticleRepository-->>ArticleWriter: saved article
    Note over ArticleWriter: 태그는 AI가<br/>생성
    ArticleWriter->>AiService: generateSummaryAsync()
    AiService->>AiService: buildSummaryPrompt()
    AiService->>TagWriter: saveAiTags(tagNames)
    TagWriter->>ArticleTagRepository: deleteByArticleId()
    TagWriter->>TagRepository: findByTagName()
    TagRepository-->>TagWriter: Tag or null
    alt Tag 존재
        TagWriter->>TagRepository: (reuse existing)
    else Tag 미존재
        TagWriter->>TagRepository: save(new Tag)
    end
    TagWriter->>ArticleTagRepository: save(ArticleTag)
    TagWriter-->>AiService: done
    AiService-->>ArticleWriter: done
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs


주요 검토 포인트 (코드 로직 관점)

🔴 보안 및 비즈니스 로직 관련 우려사항

  1. AiService.parseAiSummaryResponse() - JSON 파싱 안정성

    • Gemini API 응답 형식이 변경되면 파싱이 실패할 수 있음
    • fallback으로 raw response를 summary로 사용하는데, 실제 요약 품질 보장 불가
    • @JsonIgnoreProperties(ignoreUnknown = true) 사용했으나, 필수 필드(summary, tags) 누락 시 NPE 위험
    • 권장: JSON 파싱 실패 시 구체적인 에러 로깅 및 사용자에게 명확한 에러 메시지 필요
  2. TagWriter.saveAiTags() - 태그 저장 로직

    • 기존 ArticleTag를 모두 삭제 후 재저장하는 방식은 concurrent 요청에서 race condition 발생 가능
    • 권장: 트랜잭션 격리 수준 확인, 혹은 atomic 연산으로 보장
  3. ArticleReader.getTagNames() - N+1 쿼리 가능성

    • articleTagRepository.findAllByArticleId(articleId) 호출 후 각 ArticleTag의 Tag 엔티티 접근
    • Tag 엔티티가 lazy loading이면 N+1 발생
    • 권장: fetch join 또는 @EntityGraph 사용
  4. 새 엔드포인트 /api/articles/summary - 입력 검증 부족

    • Temp 요청에 @Valid만 있고, content 필드가 비어있거나 null인 경우 처리 미흡
    • 권장: content 필드에 @NotBlank, @Size 제약 추가
  5. ErrorCode enum 수정 - NOT_LOGGED_IN 제거

    • 인증 관련 에러 코드가 제거되었는데, 기존 코드에서 참조하고 있는지 확인 필요
    • 컴파일 오류가 없더라도 실행 시 MissingEnum 문제 발생 가능
  6. GeminiService 로깅 제거

    • 외부 API 호출 실패 시 로깅이 제거되어 운영 중 디버깅 어려움
    • 권장: 에러 로그 유지, 혹은 응답 상태 코드만이라도 기록

🎨 태그를 AI가 그리고
요약은 JSON으로 담고 🧠
OAuth의 이름을 바꿔 🔄
더 깔끔한 API로 🚀

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

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 and usage tips.

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