Skip to content

staging into main#132

Merged
Darren4641 merged 150 commits intomainfrom
staging
Feb 13, 2026
Merged

staging into main#132
Darren4641 merged 150 commits intomainfrom
staging

Conversation

@Darren4641
Copy link
Member

Description

  • 현재까지 적용된 staging 버전을 main에 merge 합니다.

koosco and others added 30 commits December 3, 2025 01:18
- flyway, r2dbc 의존성 추가
- flyway 관련 설정 추가
- local 환경 개발용 docker compose 추가
- yapp-net network 추가
- postgresql container 추가
* chore: app url, version 설정 추가

* chore: swagger config 추가

* feat: test용 controller 추가
* feat: User Entity 생성 및 UserPrincipal 세팅

* feat: ExceptionHandler 및 BaseResponse 세팅

* feat: Swagger 403/500 이슈 해결 및 auth 패키지 분리

* fix: spotlessApply

* fix: @repository 제거

* fix: security 관련 설정 user 패키지로 이동

* fix: User Entity 및 repository 관련 파일 user 패키지로 이동

* fix: spotless 적용

---------

Co-authored-by: darren <darren@darrenui-MacBookPro.local>
feat: transactionRunner 추가
Darren4641 and others added 20 commits January 30, 2026 02:00
* feat: 앱 버전 관리 API 기능 개발

* feat: 클래스 주석 추가

* fix: spotless 적용
* fix: 포즈 추천시 인원수 필터링

* test: test 코드 수정

* feat: 1차 작업

* fix: 포즈 스크랩 오동작 수정 및 포즈 스크랩 목록 조회 개발

---------

Co-authored-by: darren <darren@darrenui-MacBookPro.local>
* chore: user domain dto 패키지명 통일

* feat: media domain 이미지 조회 후 업로드 usecase 추가

* feat: 사용자 정보 갱신 API

* feat: 회원가입시 임의 닉네임 생성

* fix: 이미지 업로드 제거

* fix: 사용자 정보 조회 API 프로필 이미지 포함

* docs: user 도메인 swagger 스키마 추가

* fix: 사용자 프로필 이미지 검증 로직 추가

* fix: 사용자 프로필 이미지가 storageKey를 사용하게 수정

* fix: 기본 프로필 이미지 설정 추가

* docs: 사용자 정보 갱신 swagger docs 수정
* feat: application-prod.yaml 생성 및 flyway 싱크

* fix: user 테이블 email, oid nullable flyway 적용 및 code formmater 적용
* chore: local profile kakak api key 추가

* chore: user domain request 파일 병합

* chore: 사용하지 않는 메서드, 파일 삭제

* fix: 사용자 정보 수정, 프로필 이미지 수정 API 분리

* fix: 사용자 프로필 기본 이미지 설정 로직 추가

* fix: 사용자 프로필 수정 멱등성 반영

* test: 사용자 프로필 변경 테스트 추가
* fix: 소셜로그인 providerType 타입 String으로 변경 (대소문자 모두 허용을 위해)

* fix: enum클래스 from 메서드 추가
* fix: 카카오 로그인 시 platform 파람 추가 할당

* fix: 프론트 검증을 위해 임시 배포

* fix: spotless 적용

* fix: 엑세스, 리프레쉬 토큰 expiry 변경

* fix: deploy-staging.yml fix/#106 브랜치 제거

* fix: auth Platform enum으로 타입 세이프

---------

Co-authored-by: darren <darren@darrenui-MacBookPro.local>
fix: Brand 목록조회 id 오름차순으로 변경
* chore: Prod 환경 자동화 배포 추가

* chore: 프로메테우스 적용

* feat: cors 추가

* fix: deploy-prod.yml chore/#104 브런치 제거

* fix: healchcheck 인증된 사용자만 상세 정보 확인

* fix: actuator 사용하는 경로만 허용

* fix: deploy-prod.yml chore/#104 브랜치 제거
* fix: 사용자 닉네임 최대 글자 수정

* fix: 사용자 닉네임 제약 조건 추가

* fix: 닉네임 제약 조건 메시지 수정

* chore: 닉네임 flyway 제약 조건 버전 추가
feat/#113: 포즈목록 조회시 scrap 여부 반환
* feat: 약관 목록 및 약관 동의 개발

* fix: 약관 목록 조회시 버전 컬럼 제거

* fix: Gemini 성능 개선 반영

* fix: 중복 정렬 코드 제거
* fix: 랜덤포즈 조회시 excludeIds 추가

* fix: 랜덤포즈 조회할 포즈 없을 시 문구 수정

* test: 테스트 코드 수정
Co-authored-by: darren <darren@darrenui-MacBookPro.local>
* fix: media 생성시 width, height 입력 받기

* fix: 포즈 상세 및 랜덤포즈 오동작 문제 해결 (관리자 계정만 동작했었음)

---------

Co-authored-by: darren <darren@darrenui-MacBookPro.local>
fix: : presignedURL 업로드 시 media 엔티티 size 추가 저장 (#129)
chore: iOS 개발/상용 키 분리 (#131)
@Darren4641 Darren4641 self-assigned this Feb 12, 2026
# Conflicts:
#	src/main/kotlin/com/yapp2app/auth/infra/oauth/OidcTokenValidator.kt
#	src/main/kotlin/com/yapp2app/auth/infra/oauth/oidc/KakaoOidc.kt
#	src/main/kotlin/com/yapp2app/common/exception/handler/ExceptionHandler.kt
#	src/main/kotlin/com/yapp2app/common/filter/ServletFilterConfig.kt
#	src/main/kotlin/com/yapp2app/media/api/converter/MediaCommandConverter.kt
#	src/main/kotlin/com/yapp2app/media/api/dto/UploadTicketRequest.kt
#	src/main/kotlin/com/yapp2app/media/application/command/MediaCommand.kt
#	src/main/kotlin/com/yapp2app/media/application/port/MediaRepositoryPort.kt
#	src/main/kotlin/com/yapp2app/media/application/result/MediaResult.kt
#	src/main/kotlin/com/yapp2app/media/application/usecase/GenerateUploadTicketUseCase.kt
#	src/main/kotlin/com/yapp2app/media/application/usecase/GetMediaStorageInfoUseCase.kt
#	src/main/kotlin/com/yapp2app/media/application/usecase/GetMediaStorageInfosUseCase.kt
#	src/main/kotlin/com/yapp2app/media/domain/entity/Media.kt
#	src/main/kotlin/com/yapp2app/media/infra/persist/MediaRepositoryAdapter.kt
#	src/main/kotlin/com/yapp2app/media/infra/persist/jpa/JpaMediaRepository.kt
#	src/main/kotlin/com/yapp2app/photo/api/converter/PhotoImageResultConverter.kt
#	src/main/kotlin/com/yapp2app/photo/api/dto/PhotoImageResponse.kt
#	src/main/kotlin/com/yapp2app/photo/application/contract/MediaContract.kt
#	src/main/kotlin/com/yapp2app/photo/application/result/GetPhotosResult.kt
#	src/main/kotlin/com/yapp2app/photo/application/usecase/GetFavoritePhotosUseCase.kt
#	src/main/kotlin/com/yapp2app/photo/application/usecase/GetPhotoUseCase.kt
#	src/main/kotlin/com/yapp2app/photo/application/usecase/GetPhotosUseCase.kt
#	src/main/kotlin/com/yapp2app/photo/infra/client/PhotoMediaClient.kt
#	src/main/kotlin/com/yapp2app/pose/api/converter/PoseResultConverter.kt
#	src/main/kotlin/com/yapp2app/pose/api/converter/ScrapPoseResultConverter.kt
#	src/main/kotlin/com/yapp2app/pose/api/dto/PoseResponse.kt
#	src/main/kotlin/com/yapp2app/pose/application/contract/MediaAvailability.kt
#	src/main/kotlin/com/yapp2app/pose/application/port/MediaClientPort.kt
#	src/main/kotlin/com/yapp2app/pose/application/result/GetPosesResult.kt
#	src/main/kotlin/com/yapp2app/pose/application/usecase/GetPoseUseCase.kt
#	src/main/kotlin/com/yapp2app/pose/application/usecase/GetPosesUseCase.kt
#	src/main/kotlin/com/yapp2app/pose/application/usecase/GetScrapPosesUseCase.kt
#	src/main/kotlin/com/yapp2app/pose/application/usecase/RandomPoseUseCase.kt
#	src/main/kotlin/com/yapp2app/pose/infra/client/PoseMediaClient.kt
#	src/main/kotlin/com/yapp2app/pose/infra/persist/jpa/PosesQueryRepository.kt
#	src/main/resources/application-staging.yaml
#	src/main/resources/logback-spring.xml
@github-actions
Copy link

Code Format Check ✅ PASSED

Spotless Check: success

✨ All code formatting checks passed!


Pushed by: @Darren4641, Action: pull_request

@github-actions
Copy link

Test ✅ PASSED

Test Result: success

✨ All tests passed!


Pushed by: @Darren4641, Action: pull_request

@gemini-code-assist
Copy link

Summary of Changes

Hello @Darren4641, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 풀 리퀘스트는 스테이징 환경의 변경 사항을 메인 브랜치로 병합하는 것을 목표로 합니다. 주요 변경 사항으로는 시스템 로깅 기능을 강화하여 API 요청의 수명주기 및 예외 처리에 대한 가시성을 높였습니다. 또한, 미디어 파일에 대한 width, height, size와 같은 추가 메타데이터를 저장하고 조회할 수 있도록 데이터 모델과 관련 API 및 비즈니스 로직을 확장했습니다. 이는 미디어 처리의 유연성을 높이고, 클라이언트 애플리케이션에서 더 풍부한 미디어 정보를 활용할 수 있게 합니다.

Highlights

  • 로깅 개선: API 요청의 수명주기(응답 시간, 상태 코드)를 로깅하는 RequestLoggingFilter를 추가하고, 기존 예외 로깅 형식을 개선하여 시스템 가시성을 높였습니다. logback-spring.xml에 새로운 MDC 키를 포함하여 구조화된 로그를 지원합니다.
  • 미디어 메타데이터 확장: 미디어 엔티티에 width, height, size 필드를 추가하여 이미지 및 미디어 파일에 대한 상세 정보를 저장할 수 있도록 데이터 모델을 확장했습니다. 이에 따라 미디어 업로드 요청 DTO, 관련 명령 및 결과 클래스, 그리고 데이터베이스 마이그레이션 스크립트가 모두 업데이트되었습니다.
  • 미디어 조회 로직 유연성 강화: MediaRepositoryPortownerId 없이 미디어를 조회할 수 있는 메서드를 추가하고, GetMediaStorageInfoUseCase에서 ownerId를 선택적으로 처리하도록 변경했습니다. 이는 미디어 정보 조회 시나리오의 유연성을 높입니다.
  • API 및 유스케이스 업데이트: 미디어 메타데이터 확장에 맞춰 GenerateUploadTicketUseCase, GetMediaStorageInfoUseCase, GetMediaStorageInfosUseCase 등 미디어 관련 유스케이스와 PhotoMediaClient, PoseMediaClient 등 클라이언트 로직이 업데이트되어 새로운 메타데이터를 처리하고 전달합니다.
  • 포즈 쿼리 최적화: PosesQueryRepositorygetOwnedPoseWithScrap 쿼리에서 불필요한 userId 조건을 제거하여 쿼리 성능을 개선했습니다.
  • 스테이징 환경 설정 업데이트: application-staging.yaml 파일에서 Kakao 및 Apple OAuth 클라이언트 ID가 최신 값으로 업데이트되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/main/kotlin/com/yapp2app/auth/infra/oauth/OidcTokenValidator.kt
    • 불필요한 로그 메시지와 스택 트레이스 출력을 제거했습니다.
  • src/main/kotlin/com/yapp2app/common/exception/handler/ExceptionHandler.kt
    • 비즈니스 예외 및 시스템 예외 로깅 형식을 개선하여 가독성을 높였습니다.
  • src/main/kotlin/com/yapp2app/common/filter/RequestLoggingFilter.kt
    • API 요청의 응답 시간과 상태 코드를 로깅하는 RequestLoggingFilter를 새로 추가했습니다.
    • 특정 URI에 대해서는 필터링을 건너뛰도록 설정했습니다.
  • src/main/kotlin/com/yapp2app/common/filter/ServletFilterConfig.kt
    • RequestMdcFilter의 필터 순서를 조정했습니다.
    • 새로 추가된 RequestLoggingFilter를 등록했습니다.
  • src/main/kotlin/com/yapp2app/media/api/converter/MediaCommandConverter.kt
    • GenerateUploadTicketCommand.UploadTicketItem 변환 시 width, height, size 필드를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/media/api/dto/UploadTicketRequest.kt
    • UploadTicketItem DTO에 width, height, size 필드를 추가했습니다.
    • Swagger 스키마 설명을 포함했습니다.
  • src/main/kotlin/com/yapp2app/media/application/command/MediaCommand.kt
    • GenerateUploadTicketCommand.UploadTicketItem에 width, height, size 필드를 추가했습니다.
    • GetMediaStorageInfoCommand의 ownerId를 nullable로 변경했습니다.
  • src/main/kotlin/com/yapp2app/media/application/port/MediaRepositoryPort.kt
    • getActiveMedia(id: Long) 메서드를 추가하여 ownerId 없이 미디어를 조회할 수 있도록 했습니다.
  • src/main/kotlin/com/yapp2app/media/application/result/MediaResult.kt
    • GetMediaStorageInfoResult 및 GetMediaStorageInfosResult.StorageInfo에 width와 height 필드를 추가했습니다.
  • src/main/kotlin/com/yapp2app/media/application/usecase/GenerateUploadTicketUseCase.kt
    • 미디어 생성 시 width, height, size 메타데이터를 저장하도록 로직을 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/media/application/usecase/GetMediaStorageInfoUseCase.kt
    • ownerId가 없는 경우에도 미디어를 조회할 수 있도록 로직을 변경했습니다.
    • 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/media/application/usecase/GetMediaStorageInfosUseCase.kt
    • 여러 미디어의 저장 정보를 조회할 때 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/media/domain/entity/Media.kt
    • Media 엔티티에 width, height, size 컬럼을 추가했습니다.
  • src/main/kotlin/com/yapp2app/media/infra/persist/MediaRepositoryAdapter.kt
    • getActiveMedia(id: Long) 메서드 구현을 추가했습니다.
  • src/main/kotlin/com/yapp2app/media/infra/persist/jpa/JpaMediaRepository.kt
    • findByIdAndStatus 메서드를 추가하여 ID와 상태로 미디어를 조회할 수 있도록 했습니다.
  • src/main/kotlin/com/yapp2app/photo/api/converter/PhotoImageResultConverter.kt
    • 사진 이미지 결과 변환 시 width와 height 필드를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/photo/api/dto/PhotoImageResponse.kt
    • GetPhotosResponse.PhotoInfo 및 GetPhotoResponse DTO에 width와 height 필드를 추가했습니다.
    • Swagger 스키마 설명을 포함했습니다.
  • src/main/kotlin/com/yapp2app/photo/application/contract/MediaContract.kt
    • MediaStorageInfo 계약에 width와 height 필드를 추가했습니다.
  • src/main/kotlin/com/yapp2app/photo/application/result/GetPhotosResult.kt
    • GetPhotosResult.PhotoInfo 및 GetPhotoResult에 width와 height 필드를 추가했습니다.
  • src/main/kotlin/com/yapp2app/photo/application/usecase/GetFavoritePhotosUseCase.kt
    • 즐겨찾기 사진 조회 시 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/photo/application/usecase/GetPhotoUseCase.kt
    • 단일 사진 조회 시 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/photo/application/usecase/GetPhotosUseCase.kt
    • 여러 사진 조회 시 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/photo/infra/client/PhotoMediaClient.kt
    • 미디어 클라이언트에서 미디어 저장 정보를 가져올 때 width와 height를 매핑하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/api/converter/PoseResultConverter.kt
    • 포즈 결과 변환 시 width와 height 필드를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/api/converter/ScrapPoseResultConverter.kt
    • 스크랩된 포즈 결과 변환 시 width와 height 필드를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/api/dto/PoseResponse.kt
    • GetPosesResponse.PoseInfo 및 GetPoseResponse DTO에 width와 height 필드를 추가했습니다.
    • Swagger 스키마 설명을 포함했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/contract/MediaAvailability.kt
    • MediaStorageInfo 계약에 width와 height 필드를 추가했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/port/MediaClientPort.kt
    • getMediaStorageInfo 메서드에서 ownerId 매개변수를 제거했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/result/GetPosesResult.kt
    • GetPosesResult.PoseInfo 및 GetPoseResult에 width와 height 필드를 추가했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/usecase/GetPoseUseCase.kt
    • 단일 포즈 조회 시 ownerId 없이 미디어 정보를 가져오도록 변경했습니다.
    • 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/usecase/GetPosesUseCase.kt
    • 여러 포즈 조회 시 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/usecase/GetScrapPosesUseCase.kt
    • 스크랩된 포즈 조회 시 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/application/usecase/RandomPoseUseCase.kt
    • 랜덤 포즈 조회 시 ownerId 없이 미디어 정보를 가져오도록 변경했습니다.
    • 결과에 width와 height를 포함하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/infra/client/PoseMediaClient.kt
    • getMediaStorageInfo 메서드 호출 시 ownerId를 null로 전달하도록 변경했습니다.
    • 결과에 width와 height를 매핑하도록 업데이트했습니다.
  • src/main/kotlin/com/yapp2app/pose/infra/persist/jpa/PosesQueryRepository.kt
    • getOwnedPoseWithScrap 쿼리에서 pose.userId.eq(userId) 조건을 제거하여 쿼리 로직을 최적화했습니다.
  • src/main/resources/application-staging.yaml
    • Kakao 및 Apple OAuth 클라이언트 ID를 업데이트했습니다.
  • src/main/resources/db/migration/V8__add_image_ratio_to_media.sql
    • TB_MEDIA 테이블에 width와 height 컬럼을 추가했습니다.
  • src/main/resources/db/migration/V9__add_size_to_media.sql
    • TB_MEDIA 테이블에 size 컬럼을 추가하고 주석을 달았습니다.
Activity
  • 이 풀 리퀘스트에 대한 활동은 제공되지 않았습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

staging 브랜치를 main으로 병합하는 대규모 PR이네요. 전체적으로 클린 아키텍처 원칙을 잘 따르고 있고, 도메인과 레이어(api, application, domain, infra) 간의 역할 분리가 명확합니다. Port와 Adapter 패턴도 일관성 있게 사용되었습니다. 복잡한 쿼리에 QueryDSL을 사용하고, 보안을 위해 토큰 로테이션을 구현하고, 외부 API 호출에 대한 재시도 메커니즘을 갖추는 등 좋은 개발 프랙티스를 많이 발견할 수 있었습니다. 코드도 전반적으로 잘 작성되었습니다. 몇 가지 이슈를 발견했으며, 인증 DTO의 심각한 버그, 성능 개선 기회, 로깅 개선점 등이 포함됩니다. 전반적으로 애플리케이션의 견고한 기반이 될 것이라고 생각합니다.

I am having trouble creating individual review comments. Click here to see my feedback.

src/main/kotlin/com/yapp2app/auth/api/dto/AuthRequest.kt (12-17)

critical

CreateAuthRequestidTokenString?으로 선언되어 있지만, AuthCommandConverter에서 !! (non-null assertion)을 사용하여 NPE가 발생할 수 있습니다. @NotBlank 어노테이션은 null 값 자체는 허용하므로, null이 들어올 경우 런타임 에러가 발생합니다. 이 필드는 필수 값이므로 nullable이 아니어야 합니다.

data class CreateAuthRequest(
    @field:NotBlank(message = "ID 토큰은 필수 입니다")
    val idToken: String,
    @field:Pattern(regexp = "^(android|ios)$", message = "플랫폼은 android 또는 ios만 가능합니다")
    val platform: String? = null,
)

src/main/kotlin/com/yapp2app/auth/api/dto/AuthRequest.kt (19)

critical

RefreshTokenRequestrefreshTokenString?으로 선언되어 있지만, AuthCommandConverter에서 !! (non-null assertion)을 사용하여 NPE가 발생할 수 있습니다. @NotBlank 어노테이션은 null 값 자체는 허용하므로, null이 들어올 경우 런타임 에러가 발생합니다. 이 필드는 필수 값이므로 nullable이 아니어야 합니다.

data class RefreshTokenRequest(@field:NotBlank(message = "Refresh 토큰은 필수입니다") val refreshToken: String)

build.gradle.kts (8)

high

Spring Boot 버전을 3.5.8로 설정하셨는데, 이는 아직 출시되지 않은 미래 버전입니다. 아마도 오타인 것 같습니다. 현재 안정 버전(예: 3.3.1)이나 프로젝트에서 의도한 다른 버전(예: 3.2.8)으로 수정해야 합니다. 잘못된 버전은 의존성 문제를 일으킬 수 있습니다.

    id("org.springframework.boot") version "3.3.1"

src/main/kotlin/com/yapp2app/auth/infra/oauth/helper/KakaoOauthHelper.kt (168-176)

medium

예외 처리 시 e.printStackTrace()를 사용하고 있습니다. 이는 로깅 프레임워크의 제어를 벗어나 표준 에러 스트림으로 출력되므로, 로그 수집 및 관리가 어려워질 수 있습니다. log.error()를 사용하여 예외를 기록하는 것이 좋습니다. AppleOauthHelper.kt 파일에도 동일한 패턴이 존재하니 함께 수정하는 것을 권장합니다.

    } catch (e: ExpiredJwtException) {
        log.error("Token verification failed: {}", e) // TODO 캐싱이후로 oidc검증 실패시 어떤 예외 찍히는지 모니터링용
        throw BusinessException(ResultCode.EXPIRED_TOKEN_ERROR)
    } catch (e: Exception) {
        log.error("Token verification failed: {}", e) // TODO 캐싱이후로 oidc검증 실패시 어떤 예외 찍히는지 모니터링용
        throw BusinessException(ResultCode.INVALID_TOKEN_ERROR)
    }

src/main/kotlin/com/yapp2app/photo/infra/persist/PhotoImageRepositoryAdapter.kt (47-57)

medium

deleteOwnedPhotos 메소드에서 jpaRepository.deleteAll(photos)를 사용하여 여러 사진을 삭제하고 있습니다. 이 방식은 각 엔티티에 대해 개별적인 DELETE 쿼리를 생성하여 성능 저하를 유발할 수 있습니다. 대량 삭제 시에는 deleteAllInBatch()를 사용하는 것이 더 효율적입니다.

    override fun deleteOwnedPhotos(userId: Long, photoIds: List<Long>): List<PhotoImage> {
        val photos = jpaRepository.findAllByUserIdAndIdIn(userId, photoIds)

        if (photos.isEmpty()) {
            return emptyList()
        }

        jpaRepository.deleteAllInBatch(photos)

        return photos
    }

* feat: 이미지 조회를 위한 분산락 추가

* feat: redis media 캐시 어댑터 추가

* ref: 메서드 시그니처 변경에 따른 media fake 구현체 메서드 수정

* chore: 사용하지 않는 클래스 제거

* feat: media 조회 usecase 분산락 추가

* feat: redis binary template 추가

* feat: async config 추가

* fix: Redis 분산락 test profile 추가

* fix: media S3 fallback 후 cache 재확인

* fix: RedisMediaBinaryCacheAdapter nullable type 수정

* fix: media 캐시 ttl 만료 전 expire로 갱신하도록 수정

* fix: async 설정 제거

* fix: media type별 캐시 ttl 적용

* fix: 분산락 single-flight 제거
@github-actions
Copy link

Code Format Check ✅ PASSED

Spotless Check: success

✨ All code formatting checks passed!


Pushed by: @Darren4641, Action: pull_request

@github-actions
Copy link

Test ✅ PASSED

Test Result: success

✨ All tests passed!


Pushed by: @Darren4641, Action: pull_request

@Darren4641 Darren4641 merged commit 6892f6e into main Feb 13, 2026
5 checks passed
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.

2 participants