Skip to content

Commit f738a89

Browse files
Darren4641kooscodarren
authored
1차 버전 Main 브랜치 반영 (#118)
* chore: spotless plugin 추가 * feat: build, format make 명령어 추가 * chore: makefile PHONY에 stop 명령어 추가 * chore: jpa, flyway 의존성 추가 * fix: make run, start SPRING_PROFILES 인자 추가 * feat: clear-h2 명령어 추가 * chore: app url, version 설정 추가 * chore: swagger config 추가 * feat: test용 controller 추가 * chore : swagger 메서드 파라미터 오타 수정 * Revert "feat: test용 controller 추가" This reverts commit 7efaebe. * Revert "chore : swagger 메서드 파라미터 오타 수정" This reverts commit bf91a99. * Revert "feat: test용 controller 추가" * chore: jdbc 의존성 제거 및 r2dbc 의존성 추가 * chore: local 개발용 postgres docker compose 추가 * chore: make h2-clear 명령어 삭제 * infra : terraform s3 module 추가 * infra : terraform aws provider 추가 * infra : terraform staging workspace 추가 * feat/#9 -> staging: Squash Merge * 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> * fix: Referer 보안 이슈 방지를 위해 Ip 기반 조건 설정 * apply code formatter * fix: s3 private preset versioning 비활성화 * fix: S3 public access 제거 * feat: transactionRunner 추가 * chore: S3 의존성 추가 * chore: local s3 test용 local stack container 추가 * feat: image storage 인터페이스 추가 * feat: S3 storage 구현체 추가 * feat: Cors 설정 추가 * test: local test용 object CRD API 추가 * fix: S3 초기화 로그 제거 * ref: cors 중복 설정 제거 * chore: api 계층으로 cors 설정 이동 * chore: code quality check pipeline 추가 * feat: 폴더, 포토 이미지 엔티티 추가 * feat: Jpa Auditing 설정 추가 * feat: Usecase 식별용 annotation 추가 * feat: jpa folder 영속성 Port 추가 * feat: folder 기본 API * docs: file API swagger schema 추가 * feat/#14 -> staging mrege commit * 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 적용 * feat: Jasypt 설정 추가 * fix: application jasypt 적용 * fix: 암호화 알고리즘 변경 및 JasyptUtil 클래스 제거 * fix: spotlessApply --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * feat: 로컬 회원가입 api * fix: UserPrincipal 사용자 id 추가 * feat: PasswordEncoder config * chore: SecurityConfig 네이밍 변경 * feat: 로그인, 토큰 발급 api * feat: folder api converter 추가 * chore: 폴더명 변경 photobooth -> photo * apply spotless * feat: E2E Test용 Base 클래스 * feat: Folder E2E Test용 Base 클래스 * fix: test jasypt 설정 제거 * feat: test Media 구현체 추가 * ref: application layer에 맞게 Folder Port 메서드 시그니처 수정 * fix: 폴더 생성 중복 검사 로직 * fix: 폴더명 변경 중복 검사 * fix: 폴더 목록 조회 메서드 시그니처 변경 * fix: 폴더 목록 삭제 원자성 검증 * fix: 폴더 생성 응답 추가 * fix: 폴더 jpa 조회 메서드 추가 * fix: 일관성을 위해 ExceptionDto code 변수명 resultCode로 변경 * test: Folder API E2E Test 추가 * feat: 폴더 conflict code 추가 * fix: JasyptTest Spring 의존성 제거 * fix: r2dbc 설정 제거 * fix: jasypt 환경변수를 생성자 주입으로 변경 * chore: Media Aggregate 분리 * fix: DeleteFolder n+1 문제 해결 * fix: RequiresSecurity class Target 추가 * fix: Media 엔티티 추가 * Feat/#7 (#18) * 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 적용 * feat: Jasypt 설정 추가 * feat: kakao oauth idToken 발급 로직 추가 (테스트용) * fix: UseCase 어노테이션 추가 및 디렉토리 구조 변경 * feat: kakao oauth oidc 추출 * feat: k3s 배포를 위한 Dockerfile 생성 * feat: 카카오 OIDC 회원가입 기능 구현 * feat: 예외 addMessage 메서드 제거 * refactor: signup -> register 네이밍 변경 * fix: transactionRunner 추가 * fix: spotless 적용 * fix: login 기능 구현 1차 * fix: refreshToken 발행 추가 * fix: refreshToken을 통해 accessToken 갱신 API 추가 * fix: JasyptConfig profile 지정 * feat: CustomerUserDetailService 제거 (불필요) * feat: spotless 적용 * feat: converter 적용 * feat: E2E TEST 코드 추가 * feat: E2E TEST 코드 추가 * fix: JasyptTest 테스트코드 yml 의존성 제거 * feat: ci discord 알림 추가 * ci: 빌드 최적화 * ci: k3s 강제 재시작 적용 * fix: kakao oauth nativeID로 변경 * ci: 배포후 downtime 0로 변경 (health check 추가) * fix: app.version 공통 application.yaml로 이동 * fix: JasyptUtil 파일 제거 * fix: RestClientConfig 파일 infra 디렉토리로 이동 * fix: OIDCPublicKeysResponse 변수 var -> val 변경 * fix: KakaoClientResponse 주석 제거 * fix: Valid 어노테이션 @field로 변경 * fix: contract 디렉토리 생성 후 response 이동 * fix: ci yaml staging 브랜치로 변경 * fix: spotlessApply 적용 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * fix: oauth로그인 정책 변경 * fix: login관련 e2e 테스트코드 제거 * fix: spotless 적용 * fix: test코드 임시 제거 * test: HttpStatus 변경 * fix: acceess, refresh Token 만료 시간 변경 * chore: querydsl 설정 * chore: flyway 비활성화 * Feat/#23 (#24) * chore: logstach encoder 의존성 * chore: logback 설정 * feat: 요청 MDC Filter * feat: 인증 MDC Filter * chore: SecurityFilterChain MDC Filter 추가 * fix: RequestMdcFilter가 가장 먼저 오도록 순서 보장 * fix: AuthMdcFilter name 대신 userId 로깅 * fix: 로그에 Ip 정보 추가 * fix: 로그에 Ip 정보 삭제 * Fix/#44 카카오 OIDC 공개키 캐싱 처리 (#46) * fix: 카카오 OIDC PublicKey Cache 적용 * fix: spotless 적용 * fix: Cache 관련 클래스 Adapter 적용 * fix: spotless 적용 * refactor: cachePort 도메인 하위 infra 레이어로 이동 * fix: spotless 적용 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * fix: AuthFilter Authentication type 변경, 테스트 수정 * feat/#28 -> staging merge commit * feat: base time entity * feat: photo domain entity 추가 * feat: jpa auditing config 추가 * feat: PhotoImage UseCase 추가 * feat: PhotoImage persist jpa 구현체 추가 * feat: Local Media Client 구현체 추가 * feat: Media UseCase 추가 * feat: Media infra 계층 구현체 추가 * feat: RequiresSecurity class level target 추가 * feat: file upload fail result code 추가 * feat: usecase 애노테이션 추가 * feat: folder, photo, media flyway schema * chore: S3 구현체를 infra/storage/s3로 분리 * fix: jasypt config test profile 비활성화 * test: test profile 지정 * fix: S3 presigned 만료시간, contentType 추가 * test: PhotoImage E2E Test 추가 * fix: PhotoController bean validation 추가 * test: PhotoImageE2ETestBase 추가 * chore: rest assured 의존성 추가 * fix: AuthTokenProvider jwt에 providerType String을 저장하도록 수정 * feat: FakeMediaStorage 구현체 추가 * feat: JpaPhotoImage 목록 조회 구현 * fix: Jwt 검증 실패시에도 계속 진행되도록 수정 * fix: mediaId null이 0으로 casting되는 오류 수정 * docs: media swagger 추가 * chore: GenerateUploadTicketUseCase 불필요 주석 삭제 * fix: DeleteMediaUseCase cache 무효화 로직 추가 * ref: DeleteFolder 검증 로직 개선 * fix: testcode resultCode 수정 * fix: 401 E2ETest 삭제 * fix: memo 추가 * apply spotless * chore: 사용하지 않는 메서드 제거 * fix: UploadPhotoE2ETest memo 추가 * feat: photoImage Patch API * ref: 사진 목록 조회 paging 처리 * ref: Folder 삭제 query를 querydsl로 변경 * chore: 사용하지 않는 메서드 정리 * ref: photo domain contract 파일 분리 * feat: PhotoImage dynamic update 추가 * fix: 사진 등록 후 INITIAL media를 포함하여 조회 * test: 사진 업로드 e2e test * fix: 사진 extension이 저장되지 않는 문제 수정 * fix: photo 저장 실패시 롤백 * chore: staging S3 bucket 변경 * fix: 이미지 조회 contentType 필드 추가 * feat/#47 -> staging merge commit * feat: Apple OIDC 로그인 추가 * fix: staging merge * fix: 스웨거 주석 수정 * fix: oidc 검증 로직 Port로 분리 * fix: Port 제거 후 infra Layer에서 interface로 타입 통일 * fix: User엔티티 email Unique 제거 * fix: BaseResponse 공통 규격화 * fix: oauth 최초 로그인시만 DB저장 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * test: e2e 테스트 코드 BaseResponse success 체킹 제거 * feat/#56 -> staging merge commit * docs: CLAUDE.md 추가 * docs: TESTING.md 추가 * chore: 사용하지 않는 문서 제거 * feat/#59 -> staging merge commit * fix: AppProperties를 common 패키지로 이동 * fix: photo image 조회시 url을 내려주도록 수정 * feat: 이미지 조회 endpoint 추가 * test: 이미지 조회 endpoint 테스트 * chore: 클로드가 하위 문서를 반드시 읽도록 CLAUDE.md 수정 * fix/#29 -> staging merge commit fix: 폴더명 validation 적용 * feat/#43 -> merge commit * fix: 카카오맵 기반 위경도 수집 API 1차 개발 완료 (리펙토링 전) * fix: 애플로그인으로 인핸 oid Type String 으로 변경 * fix: 그리드방식으로 좌표 수집 * fix: Port, Adapter 적용 * fix: API 제한을 방지한 Delay 코드 추가 * fix: 내 위치기준 부스 조회, 다각형 내 부스 조회 개발 (브랜드 필터링은 추후 추가) * fix: 부스 위치 조회(다각형, 내위치) brandId 별 필터링 추가 * feat: Brand 조회 API 추가 * test: E2E Test 코드 추가 * fix: spotless 적용 * fix: 클래스명 변경 KakaoApiClient -> MapApiClient * fix: media queryDsl 제거 * fix: MediaType LOGO 추가 * fix: collectPhotoBooths API 컨벤션 * fix: collectPhotoBooths API Hidden 처리 * fix: 메서드명 변경 kakaoSearchByKeyword -> searchByKeyword * fix: SQL code formatter 적용 * fix: MapApiClient 구조 Clean Architecture 적용 * fix: postgis docker-compose 실행 추가 * fix: MapContract 클래스 Kakao 네이밍 hidden 처리 * fix: 한국 위경도 domain layer vo로 이동 * fix: CollectPhotoBoothLocationUseCase 트랜잭션 분리 * refactor: CollectPhotoBoothLocationUseCase 로직 분리 * refactor: 이미지 경로 Converter 수행 * fix: MediaClientPort 추가 * refactor: VO 클래스 수정 * refactor: MapVo 리펙토링 * refactor: 클래스명 명확화 * fix: KakaoApiRateLimitConfig -> KakaoApiRateLimitProperties 클래스명 수정 * fix: 부스 조회 API Coordinate 타입으로 변경 * fix: spotless 적용 * fix: 네이밍에 VO 키워드 제거 * fix: jasyptGeneratTest -> jasyptGenerateTest 오타 수정 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * feat/#35 -> staging merge commit * feat: 즐겨찾기 기능 및 페이징/정렬 구현 - 사진 즐겨찾기 추가/삭제/조회 API 구현 - 사진 목록 페이징 처리 - 정렬 순서(ASC/DESC) 지원 - E2E 테스트 추가 * fix: CLAUDE.md success 필드 삭제 * feat: 즐겨찾기 summary API 추가 * fix: 사진 삭제시 즐겨찾기 사진도 함께 삭제 * docs: CLAUDE.md batch delete에 대한 지침 추가 * docs: test base와 tear down 지침 추가 * fix: photo image command 페이징 기본값 삭제 * fix: 즐겨찾기 중복 저장 멱등성 로직 수정 * chore: apply spotlessApp * chore/#63 -> staging merge commit fix: entity 테이블명 대문자로 변경 * fix/#66 -> staging merge commit * fix: 부스 위치 조회 Paging 삭제 * fix: getPhotoBoothsByPoint API 좌표 nullable 기본값=강남역 * fix: 지도 응답 변수명 수정 brandId -> brandName, name -> branchName * fix: test 코드 Page 관련 변수 제거 * fix: Native Query 테이블명 대문자로 수정 * fix: getPhotoBoothsByPoint API Default 값 Converter에서 수행 * feat/#58 -> staging merge commit * ref: Media api Dto 파일 통합 * test : 사진 여러 장 업로드 테스트 * feat : Media application dto * ref : presigned upload ticket api 통합 * ref : UploadTicket 계약을 별도 파일로 분리 * test : 벌크 presigned e2e test 단일 테스트로 통합 * ref : PhotoImage 생성 로직 통합 (개별 + 벌크) * fix : UploadTicket test 변수명 동기화 * fix : 사진 생성시 하나의 folderId만 받도록 수정 * ref : 통합된 UploadTicket 결과 반환 방식 수정 * refactor : media upload 엔드포인트 수정 * ref : ConfirmMediaUploadedUseCase 벌크 처리로 수정 * ref : GenerateUploadTicketUseCase.kt transactional 애노테이션 추가 * chore: github-ci 추가, deploy 단계 test 제거 * feat/#74 -> staging merge commit * feat: 사진 상세 조회 API * fix : 이미지 목록 조회 folderId 삭제 * ref : 사진 목록 조회 쿼리 개선 * chore: code formatter * chore: 즐겨찾기용 조회 dto 추가 * feat: PhotoMediaClient 미디어 단건 조회 메서드 추가 * fix: 사진 상세 순환 호출 문제 수정 * test : 사진 상세 조회 api e2e test 추가 * ref : PhotoImageQueryRepository.kt query 개선 * fix : 사진 업로드 시 폴더 소유권 검사 * fix/#65 -> staging merge commit * ref/#69-> staging merge commit * fix: Json 날짜 포맷 통일 * ref: 사진 삭제 API 통합 (단건, 다중) * ref: 폴더 삭제 API 통합 (단건, 다중) * fix : 사용하지 않는 folder delete 관련 메서드 제거 * fix : folder 삭제시 image의 folder_id null 처리 * fix : photo 도메인 usecase 이름을 복수형으로 수정 * docs : 사용하지 않는 DeleteMediaUseCase.kt 주석 추가 * docs/#71 -> staging merge commit * docs: Swagger 공통 예외 문구 수정 * docs: Swagger 공통 예외 문구 수정 (500 Code 문서 제거) * fix: Response 값 @Schema 어노테이션 추가 * fix: Response 값 @Schema 어노테이션 추가 * fix: Spotless 적용 * fix: 토큰 MISSING 예외 처리 및 EntryPoint 컴포넌트 클래스 생성, ObjectMapper 사용하여 Error메시지 반환 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * fix/#77 -> staging merge commit * fix: Validate 검증 활성화를 위해 Request 객체 ? 인자 추가 * fix: security handler 추가 * fix: TestCode 수정사항 반영 * fix: TestCode 수정사항 반영 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * fix/#83 -> staging merge commit * chore: UpdatePhotoFavoriteRequest.kt 파일 통합 * fix : 폴더 목록 API에 사진 개수, 커버 사진 포함 * fix : 사진 삭제, 생성 시 폴더 커버 사진 업데이트 * chore : 폴더 커버 flyway schema 반영 * fix : 사진 목록 조회시 폴더 조건 추가 * ref : 폴더 목록 조회 쿼리 개선 * test : 폴더 커버 갱신 test 추가 * docs: presigned url 주석의 api endpoint 수정 * fix: folder 커버 이미지 생성 시간 제거 * fix: 조회 시점에 앨범 커버 이미지를 조인하도록 수정 * fix: 사용하지 않는 메서드 제거 * fix: 즐겨찾기 이미지 url을 usecase에서 분리 * fix: Folder storageKey 변수명 통일 * fix: PhotoImageQueryRepository.kt 미사용 코드 제거 * fix/#82-> staging merge commit * feat: Pose 업로드 (ADMIN 권한 체크) * feat: MediaType POSE 항목 추가 * feat: 포즈 목록 API 개발 * feat: 인원수 필터링 추가 * fix: 이미지 업로드 시 userId 필수로 설정 * feat: 포즈 스크랩 기능 개발 * feat: 포즈 스크랩 기능 개발 Swagger desc 추가 * feat: 포즈 상세보기 기능 개발 * feat: 랜덤 포즈 기능 개발 * refactor: rollbackIfFailed private method 분리 * test: 포즈 관련 E2E 테스트 코드 작성 * feature: 개발 admin cors 추가 * fix: ScrapPoseController 주석 name 변경 * fix: 변수명 수정 isScrap -> isScraped * fix: PoseMediaClient 주석 이름 수정 * fix: Pose 어그거트에서 사용할 Media Contract 생생 * fix: flyway TB_SCRAP_POSE DDL 쿼리 추가 * fix: UseCase Random추출 메서드 분리 * fix: Pose DTO 파일명 수정 GetPoseResponse * fix: upload만 admin 권한 * fix: toGetPoseResponse 객체 재사용 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * fix/#92 -> staging merge commit * fix: 즐겨찾기 요약이 즐겨찾기한 최근 사진을 조회하도록 수정 * ref: 폴더 목록 조회 쿼리 개선 * ref: 폴더 목록 조회 쿼리 롤백 * feat/#84 -> staging merge commit * chore: UpdatePhotoFavoriteRequest.kt 파일 통합 * fix : 폴더 목록 API에 사진 개수, 커버 사진 포함 * fix : 사진 삭제, 생성 시 폴더 커버 사진 업데이트 * chore : 폴더 커버 flyway schema 반영 * fix : 사진 목록 조회시 폴더 조건 추가 * ref : 폴더 목록 조회 쿼리 개선 * test : 폴더 커버 갱신 test 추가 * docs: presigned url 주석의 api endpoint 수정 * fix: folder 커버 이미지 생성 시간 제거 * feat: 폴더에서 사진 제외 기능 추가 * fix: 사용하지 않는 메서드 제거 * test: 사진 삭제 후 조회 시점에서 커버 사진을 확인하도록 테스트 수정 * ref: 폴더 삭제시 사진을 삭제하지 않는 경우 분기 처리 * feat/#89 -> staging merge commit * feat: 앱 버전 관리 API 기능 개발 * feat: 클래스 주석 추가 * fix: spotless 적용 * feat/#93 -> staging merge commit * fix: 포즈 추천시 인원수 필터링 * test: test 코드 수정 * feat: 1차 작업 * fix: 포즈 스크랩 오동작 수정 및 포즈 스크랩 목록 조회 개발 --------- Co-authored-by: darren <darren@darrenui-MacBookPro.local> * feat/#85 -> staging merge commit * 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#/97 -> staging merge commit * feat#/96 -> staging merge commit * feat: application-prod.yaml 생성 및 flyway 싱크 * fix: user 테이블 email, oid nullable flyway 적용 및 code formmater 적용 * fix/#100 -> staging merge commit * chore: local profile kakak api key 추가 * chore: user domain request 파일 병합 * chore: 사용하지 않는 메서드, 파일 삭제 * fix: 사용자 정보 수정, 프로필 이미지 수정 API 분리 * fix: 사용자 프로필 기본 이미지 설정 로직 추가 * fix: 사용자 프로필 수정 멱등성 반영 * test: 사용자 프로필 변경 테스트 추가 * fix/#102 -> staging merge commit * fix: 소셜로그인 providerType 타입 String으로 변경 (대소문자 모두 허용을 위해) * fix: enum클래스 from 메서드 추가 * fix: staging flyway 활성화 * fix/#106 -> staging merge commit * 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/#109 -> staging merge commit fix: Brand 목록조회 id 오름차순으로 변경 * chore/#104 -> staging merge commit * chore: Prod 환경 자동화 배포 추가 * chore: 프로메테우스 적용 * feat: cors 추가 * fix: deploy-prod.yml chore/#104 브런치 제거 * fix: healchcheck 인증된 사용자만 상세 정보 확인 * fix: actuator 사용하는 경로만 허용 * fix: deploy-prod.yml chore/#104 브랜치 제거 * fix/#105 -> staging merge commit * fix: 사용자 닉네임 최대 글자 수정 * fix: 사용자 닉네임 제약 조건 추가 * fix: 닉네임 제약 조건 메시지 수정 * chore: 닉네임 flyway 제약 조건 버전 추가 * feat: 포즈목록 조회시 scrap 여부 반환 * fix/#116 -> staging merge commit * feat: 약관 목록 및 약관 동의 개발 * fix: 약관 목록 조회시 버전 컬럼 제거 * fix: Gemini 성능 개선 반영 * fix: 중복 정렬 코드 제거 * fix/#119 -> staging merge commit * fix: 랜덤포즈 조회시 excludeIds 추가 * fix: 랜덤포즈 조회할 포즈 없을 시 문구 수정 * test: 테스트 코드 수정 --------- Co-authored-by: Koo <koosco136@gmail.com> Co-authored-by: Teahyung Koo <150074724+koosco@users.noreply.github.com> Co-authored-by: darren <darren@darrenui-MacBookPro.local>
1 parent 91d512a commit f738a89

File tree

340 files changed

+22146
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

340 files changed

+22146
-4
lines changed

.claude/CLAUDE.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# CLAUDE.md
2+
3+
Instructions for Claude Code when working with this repository.
4+
5+
## Quick Reference
6+
7+
```bash
8+
# Build & Run
9+
./gradlew build # Build project
10+
./gradlew bootRun # Run locally (requires Docker)
11+
./gradlew test # Run all tests
12+
./gradlew spotlessApply # Format code (ktlint)
13+
14+
# Docker (local development)
15+
docker compose up -d # Start PostgreSQL + Redis
16+
docker compose down # Stop containers
17+
```
18+
19+
---
20+
21+
## Project Overview
22+
23+
**Yapp** is a photo booth platform API server providing:
24+
- **Photo Poses**: Users share photo booth pose recommendations
25+
- **Photo Archiving**: Store and organize photos in folders
26+
- **Booth Location Search**: Map-based search across multiple photo booth brands
27+
28+
| Profile | Infrastructure |
29+
|---------|---------------|
30+
| `local` | Docker Compose |
31+
| `staging` | k3s (Linux) |
32+
| `prod` | k3s (Linux) |
33+
34+
---
35+
36+
## Technology Stack
37+
38+
| Category | Technology |
39+
|----------|------------|
40+
| Language | Kotlin 2.0, Java 21 |
41+
| Framework | Spring Boot 3.5 |
42+
| Database | PostgreSQL (main), Redis (cache) |
43+
| ORM | JPA + QueryDSL |
44+
| Auth | JWT, OAuth (Kakao, Apple OIDC) |
45+
| Storage | AWS S3 |
46+
| Docs | SpringDoc OpenAPI (Swagger) |
47+
| Testing | Kotest, MockK |
48+
| Code Style | ktlint via Spotless |
49+
50+
---
51+
52+
## Pre-Task Checklist (Mandatory)
53+
54+
Before starting any task, load the relevant context document:
55+
56+
| Task Type | Required Document |
57+
|-----------|-------------------|
58+
| Writing tests | `@.claude/docs/TESTING.md` |
59+
| API development | `@.claude/docs/API_PATTERNS.md` |
60+
| Architecture/Design | `@.claude/docs/ARCHITECTURE.md` |
61+
| Configuration | `@.claude/docs/CONFIGURATION.md` |
62+
| Logging/Metrics | `@.claude/docs/OBSERVABILITY.md` |
63+
64+
---
65+
66+
## Critical Constraints
67+
68+
### ❌ NEVER DO
69+
70+
| Constraint | Reason |
71+
|------------|--------|
72+
| Import from other domains | Breaks module isolation |
73+
| Bypass ports to access infra directly | Violates Clean Architecture (exception: auth/user) |
74+
| Remove observability code | Critical for production debugging |
75+
76+
### ✅ ALWAYS DO
77+
78+
| Practice | Reason |
79+
|----------|--------|
80+
| Wrap responses in `BaseResponse` | Consistent API format |
81+
| Use `BusinessException` for errors | Centralized error handling |
82+
| Write E2E tests for new endpoints | Quality assurance |
83+
| Follow existing package structure | Maintainability |
84+
| Run `spotlessApply` before commit | Code style consistency |
85+
| Delete dependent entities first | Prevents orphan records and FK violations |
86+
87+
---
88+
89+
## Code Modification Guidelines
90+
91+
1. **Minimal changes**: Prefer targeted fixes over large refactors
92+
2. **Follow conventions**: Match existing naming and package patterns
93+
3. **No new dependencies**: Unless explicitly requested
94+
4. **No reformatting**: Only modify relevant files
95+
5. **Test coverage**: Add E2E tests for new endpoints
96+
97+
---
98+
99+
## Context Loading Guide
100+
101+
Load additional context as needed using `@` references:
102+
103+
| Task | Load Command |
104+
|------|--------------|
105+
| Writing tests | `@.claude/docs/TESTING.md` |
106+
| API development | `@.claude/docs/API_PATTERNS.md` |
107+
| Architecture/Design | `@.claude/docs/ARCHITECTURE.md` |
108+
| Configuration | `@.claude/docs/CONFIGURATION.md` |
109+
| Logging/Metrics | `@.claude/docs/OBSERVABILITY.md` |
110+
111+
### Quick File Reference
112+
113+
| Component | Location |
114+
|-----------|----------|
115+
| UseCase annotation | `src/main/kotlin/com/yapp2app/common/annotation/UseCase.kt` |
116+
| Base response | `src/main/kotlin/com/yapp2app/common/api/dto/BaseResponse.kt` |
117+
| Result codes | `src/main/kotlin/com/yapp2app/common/api/dto/ResultCode.kt` |
118+
| Business exception | `src/main/kotlin/com/yapp2app/common/exception/BusinessException.kt` |
119+
| E2E test base | `src/test/kotlin/com/yapp2app/e2e/E2ETestBase.kt` |

.claude/docs/API_PATTERNS.md

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# API Development Patterns
2+
3+
Load this context when creating or modifying API endpoints.
4+
5+
---
6+
7+
## Response Wrapper
8+
9+
ALL API responses MUST use `BaseResponse<T>`:
10+
11+
```kotlin
12+
data class BaseResponse<T>(
13+
val resultCode: String = ResultCode.SUCCESS.code,
14+
val message: String = ResultCode.SUCCESS.message,
15+
val data: T? = null,
16+
)
17+
```
18+
19+
**Usage in Controller:**
20+
```kotlin
21+
@GetMapping
22+
fun getAllFolders(): BaseResponse<GetAllFolderResponse> {
23+
val result = getFoldersUseCase.execute(command)
24+
val response = resultConverter.toResponse(result)
25+
return BaseResponse(data = response)
26+
}
27+
```
28+
29+
Reference: `src/main/kotlin/com/yapp2app/common/api/dto/BaseResponse.kt`
30+
31+
---
32+
33+
## Data Flow Pattern
34+
35+
```
36+
Request → Controller → Converter → Command → UseCase → Result → Converter → Response
37+
```
38+
39+
### Complete Example
40+
41+
```kotlin
42+
@RestController
43+
@RequestMapping("/api/folders")
44+
class FolderController(
45+
private val createFolderUseCase: CreateFolderUseCase,
46+
private val commandConverter: FolderCommandConverter,
47+
private val resultConverter: FolderResultConverter,
48+
) {
49+
@PostMapping
50+
fun createFolder(
51+
@AuthenticationPrincipal(expression = "id") userId: Long,
52+
@Valid @RequestBody request: CreateFolderRequest,
53+
): BaseResponse<CreateFolderResponse> {
54+
// 1. Convert request to command
55+
val command = commandConverter.toCreateFolderCommand(request, userId)
56+
57+
// 2. Execute use case
58+
val result = createFolderUseCase.execute(command)
59+
60+
// 3. Convert result to response
61+
val response = resultConverter.toCreateFolderResponse(result)
62+
63+
// 4. Wrap in BaseResponse
64+
return BaseResponse(data = response)
65+
}
66+
}
67+
```
68+
69+
---
70+
71+
## Exception Handling
72+
73+
Use `BusinessException` with `ResultCode`:
74+
75+
```kotlin
76+
// Throwing exceptions
77+
throw BusinessException(ResultCode.CONFLICT_FOLDER)
78+
throw BusinessException(ResultCode.NOT_FOUND)
79+
80+
// Available result codes
81+
enum class ResultCode(val code: String, val message: String) {
82+
SUCCESS("D-0", "OK"),
83+
ERROR("D-99", "ERROR"),
84+
INVALID_PARAMETER("D-01", "Invalid input"),
85+
ALREADY_SIGNUP("D-02", "Already registered"),
86+
NOT_FOUND_USER("D-03", "User not found"),
87+
NOT_FOUND("D-04", "Data not found"),
88+
ALREADY_REQUEST("D-05", "Already processed"),
89+
CONFLICT_FOLDER("D-06", "Folder already exists"),
90+
// Token errors
91+
EXPIRED_TOKEN_ERROR("D-997", "Token expired"),
92+
INVALID_TOKEN_ERROR("D-998", "Invalid token"),
93+
SECURITY_ERROR("D-999", "Authentication failed"),
94+
}
95+
```
96+
97+
Key files:
98+
- `src/main/kotlin/com/yapp2app/common/exception/BusinessException.kt`
99+
- `src/main/kotlin/com/yapp2app/common/api/dto/ResultCode.kt`
100+
- `src/main/kotlin/com/yapp2app/common/exception/handler/ExceptionHandler.kt`
101+
102+
---
103+
104+
## Swagger Documentation
105+
106+
Every endpoint MUST include `@Operation`:
107+
108+
```kotlin
109+
@Operation(
110+
summary = "Create folder", // Short description
111+
description = "Creates a new photo folder for the user." // Detailed for frontend devs
112+
)
113+
@PostMapping
114+
fun createFolder(...): BaseResponse<CreateFolderResponse>
115+
```
116+
117+
### Multi-Step Workflow Documentation
118+
119+
For endpoints that are part of a workflow, document the full flow:
120+
121+
```kotlin
122+
@Operation(
123+
summary = "Register photo image",
124+
description = """
125+
Photo upload workflow:
126+
1. Call GET /api/media/presigned-url → Get S3 upload URL
127+
2. Client uploads file directly to S3
128+
3. Call this API to register the photo metadata
129+
130+
The imageKey from step 1 must be passed to this endpoint.
131+
"""
132+
)
133+
```
134+
135+
### Security Annotation
136+
137+
Protected endpoints use `@RequiresSecurity`:
138+
139+
```kotlin
140+
@RequiresSecurity // Marks endpoint as requiring authentication in Swagger
141+
@Tag(name = "folder", description = "Folder APIs")
142+
@RestController
143+
@RequestMapping("/api/folders")
144+
class FolderController
145+
```
146+
147+
Reference: `src/main/kotlin/com/yapp2app/common/api/document/SwaggerConfig.kt`
148+
149+
---
150+
151+
## Request Validation
152+
153+
Use Jakarta validation annotations:
154+
155+
```kotlin
156+
data class CreateFolderRequest(
157+
@field:NotBlank(message = "Folder name is required")
158+
@field:Size(max = 50, message = "Folder name must be 50 characters or less")
159+
val name: String,
160+
)
161+
```
162+
163+
Validation errors are automatically handled and return:
164+
```json
165+
{
166+
"resultCode": "D-01",
167+
"message": "Folder name is required",
168+
"success": false,
169+
"errors": [
170+
{ "field": "name", "message": "Folder name is required" }
171+
]
172+
}
173+
```
174+
175+
---
176+
177+
## Authentication
178+
179+
Get current user ID from JWT:
180+
181+
```kotlin
182+
@PostMapping
183+
fun createFolder(
184+
@AuthenticationPrincipal(expression = "id") userId: Long, // Extracts user ID from token
185+
@RequestBody request: CreateFolderRequest,
186+
): BaseResponse<CreateFolderResponse>
187+
```
188+
189+
---
190+
191+
## Checklist for New Endpoints
192+
193+
- [ ] Use `BaseResponse<T>` wrapper
194+
- [ ] Create Request/Response DTOs in `api/dto/`
195+
- [ ] Create Command in `application/command/`
196+
- [ ] Create Result in `application/result/`
197+
- [ ] Create Converters in `api/converter/`
198+
- [ ] Add `@Operation` with summary and description
199+
- [ ] Add `@RequiresSecurity` if authentication required
200+
- [ ] Add validation annotations to request DTOs
201+
- [ ] Write E2E tests (see `@.claude/docs/TESTING.md`)

0 commit comments

Comments
 (0)