Skip to content

운영환경 1.0.0 버전 반영#143

Merged
Darren4641 merged 157 commits intomainfrom
staging
Feb 17, 2026
Merged

운영환경 1.0.0 버전 반영#143
Darren4641 merged 157 commits intomainfrom
staging

Conversation

@Darren4641
Copy link
Member

No description provided.

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 23 commits January 31, 2026 18:27
* 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)
# 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
* 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 제거
* fix: 폴더 목록 limit 추가

* fix: 이미지 추가에 따른 폴더 정렬

* fix: 폴더 목록 bean validation 추가
fix: photo 업로드 멱등성
* fix: 폴더명 글자수 제한 10자로 수정

* fix: bean validation 메시지 수정

* chore: 폴더명 제약 flyway schema에 추가
fix: 사진 등록 즐겨찾기 필드 추가
* fix: android 개발/상용 키 분리
# Conflicts:
#	src/main/resources/application-staging.yaml
@Darren4641 Darren4641 requested a review from koosco February 17, 2026 16:54
@Darren4641 Darren4641 self-assigned this Feb 17, 2026
@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!

이 Pull Request는 운영 환경 1.0.0 버전 반영을 위한 변경 사항을 포함합니다. 주요 변경 사항으로는 폴더명 길이 제한 조정 및 관련 DB 마이그레이션, 사진 업로드 API의 기능 확장 및 멱등성 보장, 폴더 목록 조회 API의 정렬 및 제한 기능 추가, 그리고 전반적인 예외 처리 강화 및 DB 스키마 개선이 있습니다. 이는 시스템의 안정성과 사용자 경험을 향상시키는 데 기여합니다.

Highlights

  • 버전 업데이트: 프로젝트 버전이 0.0.1에서 1.0.0으로 업데이트되었습니다.
  • 폴더명 길이 제한 변경 및 DB 마이그레이션: 폴더명 최대 길이가 16자에서 10자로 변경되었으며, 기존 데이터를 10자로 자르고 DB 스키마를 업데이트하는 마이그레이션 스크립트가 추가되었습니다.
  • 사진 업로드 API 개선 및 멱등성 보장: 사진 업로드 시 즐겨찾기 여부를 지정할 수 있는 기능이 추가되었고, 동일한 mediaId로 여러 번 요청해도 중복 저장을 방지하는 멱등성 로직이 구현되었습니다.
  • 폴더 목록 조회 API 개선: 폴더 목록 조회 시 limit 파라미터를 통해 반환 개수를 제한할 수 있게 되었으며, 최근 사진이 추가된 폴더가 우선적으로 정렬되도록 변경되었습니다.
  • 예외 처리 강화: 핸들러 메서드 유효성 검사 예외(HandlerMethodValidationException)에 대한 전역 예외 처리기가 추가되었습니다.
  • DB 유니크 제약 조건 추가: 사진 이미지 테이블(TB_PHOTO_IMAGE)에 media_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
  • build.gradle.kts
    • 프로젝트 버전이 '0.0.1'에서 '1.0.0'으로 업데이트되었습니다.
  • src/main/kotlin/com/yapp2app/common/exception/handler/ExceptionHandler.kt
    • HandlerMethodValidationException을 처리하는 새로운 예외 핸들러가 추가되었습니다.
    • HandlerMethodValidationException 임포트가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/api/controller/FolderController.kt
    • getAllFolder 메서드에 폴더 목록 조회 개수를 제한하는 'limit' 파라미터가 추가되었습니다.
    • 'limit' 파라미터에 @min(1) 유효성 검사 어노테이션이 추가되었습니다.
    • jakarta.validation.constraints.Min 임포트가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/api/converter/FolderCommandConverter.kt
    • toGetFoldersCommand 메서드가 'limit' 파라미터를 받도록 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/api/converter/PhotoImageCommandConverter.kt
    • toUploadPhotoCommand 메서드에 'favorite' 필드가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/api/dto/FolderRequest.kt
    • CreateFolderRequest 및 UpdateFolderRequest의 폴더명(name) 필드에 대한 @SiZe 유효성 검사 최대 길이가 16에서 10으로 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/api/dto/PhotoImageRequest.kt
    • UploadPhotoRequest에 'favorite' 필드가 추가되어 사진 업로드 시 즐겨찾기 여부를 지정할 수 있게 되었습니다.
    • jakarta.validation.constraints.Size 임포트가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/command/FolderCommand.kt
    • GetFoldersCommand에 'limit' 필드가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/command/PhotoImageCommand.kt
    • UploadPhotoCommand에 'favorite' 필드가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/port/FavoriteImageRepositoryPort.kt
    • 여러 사진을 한 번에 즐겨찾기에 추가하는 'addAll' 메서드가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/port/FolderRepositoryPort.kt
    • listOwnedFoldersWithStats 메서드가 'limit' 파라미터를 받도록 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/port/PhotoImageRepositoryPort.kt
    • 등록된 mediaId 목록을 조회하는 'getRegisteredMediaIds' 메서드가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/usecase/GetFoldersUseCase.kt
    • execute 메서드에서 folderRepository.listOwnedFoldersWithStats 호출 시 command.limit을 전달하도록 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/application/usecase/UploadPhotosUseCase.kt
    • FavoriteImageRepositoryPort가 주입되었습니다.
    • 이미 등록된 mediaId를 필터링하여 중복 업로드를 방지하는 'filterNewUploads' 로직이 추가되었습니다.
    • 업로드된 사진을 즐겨찾기에 추가하는 로직이 추가되었습니다.
    • BusinessException 발생 시 미디어 롤백 처리 로직이 추가되었습니다.
    • 클래스명이 BulkUploadPhotoUseCase에서 UploadPhotosUseCase로 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/infra/persist/FavoriteImageRepositoryAdapter.kt
    • FavoritePhoto 엔티티 목록을 저장하는 'addAll' 메서드가 구현되었습니다.
  • src/main/kotlin/com/yapp2app/photo/infra/persist/FolderRepositoryAdapter.kt
    • listOwnedFoldersWithStats 메서드에서 queryRepository.findOwnedFoldersWithStats 호출 시 'limit' 파라미터를 전달하도록 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/infra/persist/PhotoImageRepositoryAdapter.kt
    • DataIntegrityViolationException 발생 시 BusinessException(ResultCode.ALREADY_REQUEST)을 던지도록 saveAll 메서드에 예외 처리가 추가되었습니다.
    • 등록된 mediaId 목록을 조회하는 'getRegisteredMediaIds' 메서드가 구현되었습니다.
    • ResultCode, BusinessException, DataIntegrityViolationException 임포트가 추가되었습니다.
  • src/main/kotlin/com/yapp2app/photo/infra/persist/jpa/FolderQueryRepository.kt
    • findOwnedFoldersWithStats 메서드가 'limit' 파라미터를 받도록 변경되었습니다.
    • 폴더 목록 정렬 기준이 최근 사진 추가일(내림차순)과 폴더 생성일(내림차순)로 변경되었습니다.
  • src/main/kotlin/com/yapp2app/photo/infra/persist/jpa/PhotoImageQueryRepository.kt
    • 주어진 mediaId 목록 중 이미 등록된 mediaId를 반환하는 'getRegisteredMediaIds' 메서드가 추가되었습니다.
  • src/main/resources/application-staging.yaml
    • Kakao Android 클라이언트 ID가 업데이트되었습니다.
  • src/main/resources/db/migration/V10__add_unique_constraint_media_id_to_photo_image.sql
    • TB_PHOTO_IMAGE 테이블의 media_id 컬럼에 UNIQUE 제약 조건이 추가되었습니다.
  • src/main/resources/db/migration/V11__alter_folder_name_length.sql
    • 기존 데이터 중 10자를 초과하는 폴더명을 10자로 자르는 SQL이 추가되었습니다.
    • TB_FOLDER 테이블의 name 컬럼의 VARCHAR 길이를 10으로 변경하는 SQL이 추가되었습니다.
  • src/test/kotlin/com/yapp2app/e2e/photo/folder/CreateFolderE2ETest.kt
    • 폴더명이 10자를 초과할 경우 400 에러를 반환하는 테스트 케이스가 추가되었습니다.
  • src/test/kotlin/com/yapp2app/e2e/photo/folder/FolderE2ETestBase.kt
    • PhotoImageRepository와 MediaRepository가 주입되었습니다.
    • tearDown 메서드에 photoImageRepository와 mediaRepository의 데이터 삭제 로직이 추가되었습니다.
    • 테스트용 Media를 생성하는 'createMedia' 헬퍼 메서드가 추가되었습니다.
    • 테스트용 PhotoImage를 생성하는 'createPhotoImage' 헬퍼 메서드가 추가되었습니다.
  • src/test/kotlin/com/yapp2app/e2e/photo/folder/GetAllFolderE2ETest.kt
    • limit 파라미터 기능 및 유효성 검사에 대한 테스트 케이스가 추가되었습니다.
    • 최근 사진 추가일 기준으로 폴더가 정렬되는지에 대한 테스트 케이스가 추가되었습니다.
    • org.hamcrest.Matchers.equalTo 임포트가 추가되었습니다.
  • src/test/kotlin/com/yapp2app/e2e/photo/folder/UpdateFolderE2ETest.kt
    • 폴더명이 10자를 초과할 경우 400 에러를 반환하는 테스트 케이스가 추가되었습니다.
  • src/test/kotlin/com/yapp2app/e2e/photo/image/UploadPhotosIdempotencyE2ETest.kt
    • 사진 업로드 API의 멱등성을 검증하는 새로운 E2E 테스트 파일이 추가되었습니다.
Activity
  • 제공된 정보에 따르면, 이 Pull Request에 대한 특정 활동(댓글, 리뷰 등)은 아직 없습니다.
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.

@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 57de43f into main Feb 17, 2026
5 checks passed
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

이 PR은 애플리케이션 버전을 1.0.0으로 올리면서 여러 기능 개선과 버그 수정을 포함하고 있습니다. 주요 변경 사항으로는 사진 업로드 시 멱등성 보장, 폴더명 길이 제한 변경, 폴더 목록 조회 기능 개선 (정렬 및 개수 제한) 등이 있습니다. 전반적으로 코드 변경 사항이 명확하고, 특히 새로운 기능에 대한 E2E 테스트 케이스를 충실히 추가한 점이 인상적입니다. 몇 가지 개선 가능한 부분에 대해 리뷰 코멘트를 남겼습니다.

val command = commandConverter.toGetFoldersCommand(userId)
fun getAllFolder(
@AuthenticationPrincipal(expression = "id") userId: Long,
@RequestParam("limit") @Min(1) limit: Int?,

Choose a reason for hiding this comment

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

high

limit 파라미터는 Int? 타입으로 선언되어 선택적으로 사용될 수 있음을 나타내지만, @RequestParam("limit") 어노테이션은 기본적으로 required=true로 동작합니다. 따라서 클라이언트가 limit 파라미터를 전달하지 않으면 MissingServletRequestParameterException이 발생하여 API가 실패하게 됩니다. limit 파라미터를 선택적으로 만드려면 @RequestParam(name = "limit", required = false)로 명시해야 합니다.

Suggested change
@RequestParam("limit") @Min(1) limit: Int?,
@RequestParam(name = "limit", required = false) @Min(1) limit: Int?,

Comment on lines +119 to +125
fun handleMethodValidationExceptionHandler(ex: HandlerMethodValidationException): ResponseEntity<ExceptionMsg> =
ResponseEntity(
ExceptionMsg(
resultCode = ResultCode.INVALID_PARAMETER.code,
message = ResultCode.INVALID_PARAMETER.message,
),
HttpStatus.BAD_REQUEST,

Choose a reason for hiding this comment

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

medium

HandlerMethodValidationException에는 어떤 파라미터가 유효성 검사에 실패했는지에 대한 구체적인 정보가 포함되어 있습니다. 현재 구현은 일반적인 INVALID_PARAMETER 메시지를 반환하고 있어 디버깅이 어려울 수 있습니다. MethodArgumentNotValidException 핸들러와 유사하게, 예외 객체에서 실제 유효성 검사 실패 메시지를 추출하여 반환하는 것이 좋습니다. 이렇게 하면 클라이언트가 어떤 값이 잘못되었는지 명확하게 알 수 있습니다.

Suggested change
fun handleMethodValidationExceptionHandler(ex: HandlerMethodValidationException): ResponseEntity<ExceptionMsg> =
ResponseEntity(
ExceptionMsg(
resultCode = ResultCode.INVALID_PARAMETER.code,
message = ResultCode.INVALID_PARAMETER.message,
),
HttpStatus.BAD_REQUEST,
fun handleMethodValidationExceptionHandler(ex: HandlerMethodValidationException): ResponseEntity<ExceptionMsg> =
ResponseEntity(
ExceptionMsg(
resultCode = ResultCode.INVALID_PARAMETER.code,
message = ex.allErrors.firstOrNull()?.defaultMessage ?: ResultCode.INVALID_PARAMETER.message,
),
HttpStatus.BAD_REQUEST,
)

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