From f9a62e389aa457cd276d039635389079ecd28c9b Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Fri, 19 Jul 2024 01:45:22 +0900 Subject: [PATCH 1/8] [deploy] merge to main (#145) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) --------- Co-authored-by: hyerinhwang-sailin --- .../global/external/s3/controller/FileController.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/beat/global/external/s3/controller/FileController.java b/src/main/java/com/beat/global/external/s3/controller/FileController.java index b3d5b851..eec8614e 100644 --- a/src/main/java/com/beat/global/external/s3/controller/FileController.java +++ b/src/main/java/com/beat/global/external/s3/controller/FileController.java @@ -23,9 +23,14 @@ public class FileController { @GetMapping("/presigned-url") public ResponseEntity>> getPresignedUrls( @RequestParam String posterImage, - @RequestParam List castImages, - @RequestParam List staffImages) { - + @RequestParam(required = false) List castImages, + @RequestParam(required = false) List staffImages) { + if (castImages == null) { + castImages = List.of(); + } + if (staffImages == null) { + staffImages = List.of(); + } Map> response = fileService.getPresignedUrls(posterImage, castImages, staffImages); return ResponseEntity.ok(response); } From b017b00a8bbea8a1fc45b2a8df7ffddee1ca039b Mon Sep 17 00:00:00 2001 From: hyerinhwang-sailin Date: Fri, 19 Jul 2024 14:24:30 +0900 Subject: [PATCH 2/8] [deploy] merge to main (#146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Co-authored-by: DongHoon Lee --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bb9b71ff..f75c8e01 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| :---: | | branch |branch | | [hoonyworld](https://github.com/hoonyworld) | [hyerinhwang-sailin](https://github.com/hyerinhwang-sailin) | -| prod 서버용 EC2. RDS 구축
dev, prod 서버 github action CI 구축(dockerhub push까지)
Jenkins multibranch pipeline으로 dev 서버에서 dev, prod CD 및
prod 서버에서 nginx 무중단 배포 구축
ERD 및 DB 설계
Entity 초기 세팅 | AWS dev 서버 구축
ERD 및 DB 설계
인증 / 인가 구현 (Redis)
웹 발신
Entity 초기 세팅
카카오 소셜 로그인
Swagger 세팅 | +| prod 서버용 EC2, RDS 구축
dev, prod github action
CI 구축(~dockerhub push)
Jenkins multibranch pipeline
dev 서버에서 dev, prod CD
prod 서버 nginx 무중단배포
ERD 및 DB 설계
Entity 초기 세팅 | dev 서버용 EC2, RDS 구축
ERD 및 DB 설계
인증 / 인가 구현 (Redis)
웹 발신
Entity 초기 세팅
카카오 소셜 로그인
Swagger 세팅 | ### 🏡 Git Convention [Git Convention](https://www.notion.so/jiwoothejay/git-convention-9bee60c3bb0a45f1913616b3e72b87b7) From a5e8c72e36686599706234732882fc78a238e45d Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Fri, 19 Jul 2024 17:39:37 +0900 Subject: [PATCH 3/8] [deploy] merge to main (#149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md * [#147] refactor: 예금주 필드 추가 (#148) --------- Co-authored-by: hyerinhwang-sailin --- .../booking/application/GuestBookingRetrieveService.java | 1 + .../booking/application/MemberBookingRetrieveService.java | 1 + .../booking/application/dto/GuestBookingRetrieveResponse.java | 3 +++ .../booking/application/dto/MemberBookingRetrieveResponse.java | 3 +++ 4 files changed, 8 insertions(+) diff --git a/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java b/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java index 998178c0..8a3aaa24 100644 --- a/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java +++ b/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java @@ -81,6 +81,7 @@ private GuestBookingRetrieveResponse toBookingResponse(Booking booking) { performance.getPerformanceContact(), performance.getBankName(), performance.getAccountNumber(), + performance.getAccountHolder(), calculateDueDate(schedule.getPerformanceDate()), booking.isPaymentCompleted(), booking.getCreatedAt(), diff --git a/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java b/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java index 45fbbeef..82c6981c 100644 --- a/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java +++ b/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java @@ -62,6 +62,7 @@ private MemberBookingRetrieveResponse toMemberBookingResponse(Booking booking) { performance.getPerformanceContact(), performance.getBankName(), performance.getAccountNumber(), + performance.getAccountHolder(), calculateDueDate(schedule.getPerformanceDate()), booking.isPaymentCompleted(), booking.getCreatedAt(), diff --git a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java index ade0a452..9a490638 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java +++ b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java @@ -18,6 +18,7 @@ public record GuestBookingRetrieveResponse( String performanceContact, BankName bankName, String accountNumber, + String accountHolder, int dueDate, boolean isPaymentCompleted, LocalDateTime createdAt, @@ -37,6 +38,7 @@ public static GuestBookingRetrieveResponse of( String performanceContact, BankName bankName, String accountNumber, + String accountHolder, int dueDate, boolean isPaymentCompleted, LocalDateTime createdAt, @@ -56,6 +58,7 @@ public static GuestBookingRetrieveResponse of( performanceContact, bankName, accountNumber, + accountHolder, dueDate, isPaymentCompleted, createdAt, diff --git a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java index 58af4285..134767bc 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java +++ b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java @@ -19,6 +19,7 @@ public record MemberBookingRetrieveResponse( String performanceContact, BankName bankName, String accountNumber, + String accountHolder, int dueDate, boolean isPaymentCompleted, LocalDateTime createdAt, @@ -39,6 +40,7 @@ public static MemberBookingRetrieveResponse of( String performanceContact, BankName bankName, String accountNumber, + String accountHolder, int dueDate, boolean isPaymentCompleted, LocalDateTime createdAt, @@ -59,6 +61,7 @@ public static MemberBookingRetrieveResponse of( performanceContact, bankName, accountNumber, + accountHolder, dueDate, isPaymentCompleted, createdAt, From ac5aeb279c6fe46ef009885614c81b7cccab46f6 Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Fri, 19 Jul 2024 18:34:35 +0900 Subject: [PATCH 4/8] [deploy] merge to main (#153) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md * [#147] refactor: 예금주 필드 추가 (#148) * [feat] #150 - 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 (#151) * [#150] feat(Jenkinsfile): 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 * [#150] refactor(prod-CI.yml): prod에서 PR시에만 빌드 되도록 수정 --------- Co-authored-by: hyerinhwang-sailin --- .github/workflows/prod-CI.yml | 2 -- Jenkinsfile | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/prod-CI.yml b/.github/workflows/prod-CI.yml index c6b65583..c478ff71 100644 --- a/.github/workflows/prod-CI.yml +++ b/.github/workflows/prod-CI.yml @@ -3,8 +3,6 @@ name: prod-CI on: pull_request: branches: [ "main" ] - push: - branches: [ "main" ] jobs: prod-ci: diff --git a/Jenkinsfile b/Jenkinsfile index 5ac08b0d..ece360a8 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -84,6 +84,7 @@ pipeline { // 새로운 컨테이너 실행 sshCommand remote: remote, command: ( 'docker run -d --name springboot' + + ' --network beat-network' + ' -p 8080:' + INTERNAL_PORT + ' -e "SPRING_PROFILES_ACTIVE=' + OPERATION_ENV + '"' + ' ' + DOCKER_IMAGE_NAME + ':latest' From 90f240a1237b3f1bf6e93be7cb8301aa9364894c Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:39:12 +0900 Subject: [PATCH 5/8] [deploy] merge to main (#156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md * [#147] refactor: 예금주 필드 추가 (#148) * [feat] #150 - 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 (#151) * [#150] feat(Jenkinsfile): 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 * [#150] refactor(prod-CI.yml): prod에서 PR시에만 빌드 되도록 수정 * [#150] deploy(application-prod.yml): 운영서버 ddl-auto create로 초기화 (#155) --------- Co-authored-by: hyerinhwang-sailin --- src/main/resources/application-prod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 79ce5b77..c7a9f86e 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -19,7 +19,7 @@ spring: jpa: hibernate: - ddl-auto: update + ddl-auto: create show-sql: true properties: hibernate: From 1eebd85dd318b64fa7d55eba7b944faab2233138 Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:52:02 +0900 Subject: [PATCH 6/8] =?UTF-8?q?[release]=20v1.0.0=20=EB=A6=B4=EB=A6=AC?= =?UTF-8?q?=EC=A6=88=20(#158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md * [#147] refactor: 예금주 필드 추가 (#148) * [feat] #150 - 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 (#151) * [#150] feat(Jenkinsfile): 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 * [#150] refactor(prod-CI.yml): prod에서 PR시에만 빌드 되도록 수정 * chore(application-prod.yml): ddl-auto none으로 변경 --------- Co-authored-by: hyerinhwang-sailin --- src/main/resources/application-prod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index c7a9f86e..e21062b0 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -19,7 +19,7 @@ spring: jpa: hibernate: - ddl-auto: create + ddl-auto: none show-sql: true properties: hibernate: From eb3ec1ba08e517e08123b9c1695f9fd4c017e6a4 Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Wed, 14 Aug 2024 01:01:41 +0900 Subject: [PATCH 7/8] =?UTF-8?q?[release]=20v1.0.1=20=EB=A6=B4=EB=A6=AC?= =?UTF-8?q?=EC=A6=88=20(#174)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md * [#147] refactor: 예금주 필드 추가 (#148) * [feat] #150 - 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 (#151) * [#150] feat(Jenkinsfile): 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 * [#150] refactor(prod-CI.yml): prod에서 PR시에만 빌드 되도록 수정 * [#150] deploy(application-prod.yml): 운영서버 ddl-auto create로 초기화 (#155) * [#159] docs(README.md): 서비스 소개 내용 업데이트 (#160) * docs(README.md): README 수정 * docs(README.md): 기획 의견 반영 * [fix] #162 - 공연 삭제 로직 변경 (#163) * [#162] refactor(Performance): Promotion 엔티티 양방향 매핑 * [#162] refactor(BookingRepository): JPQL을 사용해 회차 아이디가 담긴 리스트의 회차 아이디가 예매 테이블에도 존재하는지 비교하도록 변경 * [#162] refactor(PerformanceController): 메서드 네이밍 리팩토링 * [#162] refactor(PerformanceErrorCode): 에러 상태 변경 및 해당 공연의 메이커가 아닐 때 발생하는 에러메시지 추가 * [#162] refactor(PerformanceManagementService): 변경된 JPA 메서드에 맞추어 서비스 로직 변경 및 해당 공연의 메이커만 공연삭제가 가능하도록 변경 * [#162] refactor(PerformanceService): 변경된 JPA 메서드에 맞추어 공연 수정 시 공연 정보를 반환하는 서비스 로직 변경 * [#162] fix(TicketController): 예매자 삭제 시 불필요한 pathVariable 속성 삭제 * [#162] refactor(ScheduleRepository): 공연 id에 해당하는 모든 회차 id를 리스트로 반환하는 메서드 추가 * [#162] refactor(TicketService): 해당 공연의 메이커가 아니면 예매자를 삭제하지 못하는 로직 추가 * [fix] #164 - 입금여부수정 api 경로 수정 및 dev db 초기화 (#165) * [#164] fix(TicketController): 예매자 입금여부 수정 api 경로 수정 * [#164] chore(application-dev): dev db 초기화 * [feat] #166 - 사용하지 않는 도커이미지를 서버에서 삭제하도록 Jenkinsfile에 스크립트 추가 (#167) * [#168] comment: 불필요한 주석 제거 (#169) * [fix] #170 - 예매자 삭제 시 판매 티켓 수에 반영하는 로직 구현 (#171) * [#170] feat: 예매자 삭제 관련 에러 메세지 추가 * [#170] feat(Schedule): soldTicketCount 변경 메소드 추가 * [#170] fix(TicketService): 예매자 삭제 시 soldTicketCount에 반영되도록 메소드 수정 * [#170] fix(Schedule): 예매자 삭제 시 exception 처리 방식 수정 --------- Co-authored-by: hyerinhwang-sailin --- Jenkinsfile | 6 + README.md | 209 +++++++++--------- .../domain/booking/api/TicketController.java | 12 +- .../booking/application/TicketService.java | 29 ++- .../domain/booking/dao/BookingRepository.java | 3 +- .../member/application/MemberService.java | 2 - .../api/PerformanceController.java | 2 +- .../PerformanceManagementService.java | 20 +- .../application/PerformanceService.java | 12 +- .../performance/domain/Performance.java | 7 + .../exception/PerformanceErrorCode.java | 3 +- .../schedule/dao/ScheduleRepository.java | 3 +- .../beat/domain/schedule/domain/Schedule.java | 11 + .../schedule/exception/ScheduleErrorCode.java | 3 +- 14 files changed, 185 insertions(+), 137 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ece360a8..f1c1fd40 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -89,6 +89,12 @@ pipeline { ' -e "SPRING_PROFILES_ACTIVE=' + OPERATION_ENV + '"' + ' ' + DOCKER_IMAGE_NAME + ':latest' ) + + // Docker dangling 이미지 정리 + sshCommand remote: remote, command: ''' + docker images -f "dangling=true" -q | \ + xargs -r docker rmi + ''' } } } diff --git a/README.md b/README.md index f75c8e01..1329a49e 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,68 @@ -# BEAT-SERVER +# BEAT - 소규모 공연을 등록하고 관리할 수 있는 티켓 예매 플랫폼 -## 💗 BEAT Information 💗 +# BEAT + + Hits + -``` -모두를 위한, 그래서 대학생을 위한 공연 예매 플랫폼 -``` +

-## 🥁 BEAT Server Developers 🥁 +**📱 BEAT |** [사이트 바로가기](https://www.beatlive.kr/) +

+**📝 Team Blog |** [BEAT Blog](https://team-beat.tistory.com/)
+**📌 Official Account |** [BEAT Instagram](https://www.instagram.com/be_at_beat?igsh=MTJmank3N3phZHYzeA==)
+**💌 Email |** [beatlebeatle.official@gmail.com](mailto:beatlebeatle.official@gmail.com) -| 이동훈 | 황혜린 | -|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| :---: | -| branch |branch | -| [hoonyworld](https://github.com/hoonyworld) | [hyerinhwang-sailin](https://github.com/hyerinhwang-sailin) | -| prod 서버용 EC2, RDS 구축
dev, prod github action
CI 구축(~dockerhub push)
Jenkins multibranch pipeline
dev 서버에서 dev, prod CD
prod 서버 nginx 무중단배포
ERD 및 DB 설계
Entity 초기 세팅 | dev 서버용 EC2, RDS 구축
ERD 및 DB 설계
인증 / 인가 구현 (Redis)
웹 발신
Entity 초기 세팅
카카오 소셜 로그인
Swagger 세팅 | +

+

+ + +## 💓 Introduction +![intro1](https://github.com/user-attachments/assets/229ca2dd-9fd0-4177-87dd-ce41b4a5186c) +![intro2](https://github.com/user-attachments/assets/7c083b82-6f97-424e-9c70-83706d16e345) + +

+ +### 🎤 학생 여러분, 아직도 구글폼으로 공연 등록하세요? BEAT로 더 쉽고 빠르게! +![intro3](https://github.com/user-attachments/assets/7a0009a4-a73d-40fb-8976-2b1fa1d7d5f7) +![intro4](https://github.com/user-attachments/assets/7002609e-d4c6-45dd-9fd2-db1547929d1a) + +학생 공연 단체들은 대부분 구글폼을 사용하여 공연을 등록하고 관리하고 있습니다.
+하지만 예매자의 입금여부를 직접 추적하고 다양한 문의사항을 개인 연락처를 통해 처리해야 하므로 번거로움과 부담을 느끼고 있죠 😭 + +BEAT는 이러한 문제를 해결하기 위해 탄생했습니다.
+**공연 등록, 관리, 예매, 조회까지 한 번에 할 수 있는 통합 플랫폼 BEAT**를 소개합니다!
+공연 단체들은 기존의 번거롭고 복잡한 구글폼 대신, BEAT를 사용하여 더 쉽고 편리하게 공연을 관리할 수 있습니다 😁 + +- **공연 등록**: 등록한 공연 정보를 수정 업데이트 할 수 있으며, 예매자 관리까지 한 곳에서 할 수 있습니다. +- **공연 관리**: 모든 공연 정보를 한 곳에서 관리하고 업데이트할 수 있습니다. +- **공연 예매**: 회원과 비회원 모두 쉽게 사용할 수 있는 예매 시스템으로 관객들이 편리하게 티켓을 구매할 수 있습니다. +- **공연 조회**: 실시간으로 내가 예매한 공연 내역을 조회할 수 있습니다. + +BEAT와 함께 효율적이고 체계적으로 공연을 관리해 볼까요? 👏 + +

+

+ +## ✨ Main Feature +![feature1](https://github.com/user-attachments/assets/3a9cba25-e481-427e-85dd-3231e98a0c30) +![feature2](https://github.com/user-attachments/assets/a2ad201f-80b5-4115-b13a-9f8521f3b984) + +

+

+ +## 🧑🏻‍💻 Developers + +| 이동훈 | 황혜린 | +|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------------------------------------------------:| +| branch | branch | +| [hoonyworld](https://github.com/hoonyworld) | [hyerinhwang-sailin](https://github.com/hyerinhwang-sailin) | +| 티켓 예매 동시성 처리
github action CI 구축
Jenkins multibranch pipeline CD 구축
Jenkins Pipeline에 Slack 연동
Presigned Url(S3) 이미지 서비스
ERD 및 DB 설계
Entity 초기 세팅 | 운영 및 테스트 서버 EC2, RDS 구축
카카오 소셜 로그인
인증 / 인가 구현 (Redis)
웹 발신
Swagger 세팅
ERD 및 DB 설계
Entity 초기 세팅 | + +

+

+ +## 🤝 Convention ### 🏡 Git Convention [Git Convention](https://www.notion.so/jiwoothejay/git-convention-9bee60c3bb0a45f1913616b3e72b87b7) @@ -23,102 +73,45 @@ ### 🌳 Commit Convention [Commit Convention](https://www.notion.so/jiwoothejay/issue-pr-templates-44f118ed82904febae246518ef150e25) -### 📁 Foldering -``` - src - ├── main - │ ├── java - │ │ └── com - │ │ └── beat - │ │ ├── domain - │ │ │ ├── booking - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── cast - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── member - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── performance - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── promotion - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── schedule - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── staff - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ │ ├── users - │ │ │ │ ├── api - │ │ │ │ ├── application - │ │ │ │ ├── dao - │ │ │ │ ├── domain - │ │ │ │ └── exception - │ │ ├── global - │ │ │ ├── common - │ │ │ │ ├── config - │ │ │ │ ├── dto - │ │ │ │ └── exception - │ │ │ │ ├── base - │ │ │ │ └── handler - │ │ │ ├── auth - │ │ │ │ ├── feign - │ │ │ │ │ └── kakao - │ │ │ │ ├── filter - │ │ │ │ ├── jwt - │ │ │ │ ├── redis - │ │ │ │ ├── security - │ │ │ ├── external - │ │ │ │ ├── discord - │ │ │ │ │ ├── exception - │ │ │ │ │ └── model - │ │ │ │ ├── s3 - │ │ │ │ │ ├── dto - │ │ │ │ │ ├── exception - │ │ │ │ │ └── service - │ │ ├── infra - │ │ │ ├── email - │ │ │ └── sms - │ │ └── BeatApplication - │ └── resources - │ ├── application.yml - │ ├── application-dev.yml - │ ├── application-local.yml - │ └── application-prod.yml -``` - -## 🔗 ERD -erd_beat - -## 📄 API 명세서 -[API specification](https://jiwoothejay.notion.site/1-API-c34df726fd464899a31841d35a69ab32?pvs=4) - -## 🛠️ Tech +

+

+ +## 📄 API Specification +api_spec + +## 📈 ERD +erd + +## 🖥️ Tech Stack +#### Framework + + +#### ORM + + +#### Authorization + + +#### Test + + +#### Database + + +#### AWS + + +#### CI/CD + + +#### Monitoring + + +#### Other + ## 🔨 Architecture -image + + +## 👥 Contributors +- [BEAT Client Repository](https://github.com/TEAM-BEAT/BEAT-Client) \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/api/TicketController.java b/src/main/java/com/beat/domain/booking/api/TicketController.java index 907bc74f..1e03e66e 100644 --- a/src/main/java/com/beat/domain/booking/api/TicketController.java +++ b/src/main/java/com/beat/domain/booking/api/TicketController.java @@ -32,22 +32,20 @@ public ResponseEntity> getTickets( } @Operation(summary = "예매자 입금여부 수정 및 웹발신 API", description = "메이커가 자신의 공연에 대한 예매자의 입금여부 정보를 수정한 뒤 예매확정 웹발신을 보내는 PUT API입니다.") - @PutMapping("/{performanceId}") + @PutMapping public ResponseEntity> updateTickets( @CurrentMember Long memberId, - @PathVariable Long performanceId, @RequestBody TicketUpdateRequest request) { ticketService.updateTickets(memberId, request); return ResponseEntity.ok(SuccessResponse.of(BookingSuccessCode.TICKET_UPDATE_SUCCESS, null)); } @Operation(summary = "예매자 삭제 API", description = "메이커가 자신의 공연에 대한 예매자의 정보를 삭제하는 DELETE API입니다.") - @DeleteMapping("/{performanceId}") + @DeleteMapping public ResponseEntity> deleteTickets( @CurrentMember Long memberId, - @PathVariable Long performanceId, - @RequestBody TicketDeleteRequest request) { - ticketService.deleteTickets(memberId, request); - return ResponseEntity.ok(SuccessResponse.of(BookingSuccessCode.TICKET_DELETE_SUCCESS, null)); + @RequestBody TicketDeleteRequest ticketDeleteRequest) { + ticketService.deleteTickets(memberId, ticketDeleteRequest); + return ResponseEntity.ok(SuccessResponse.from(BookingSuccessCode.TICKET_DELETE_SUCCESS)); } } diff --git a/src/main/java/com/beat/domain/booking/application/TicketService.java b/src/main/java/com/beat/domain/booking/application/TicketService.java index 4cc5be81..4a5a4e58 100644 --- a/src/main/java/com/beat/domain/booking/application/TicketService.java +++ b/src/main/java/com/beat/domain/booking/application/TicketService.java @@ -9,8 +9,11 @@ import com.beat.domain.performance.dao.PerformanceRepository; import com.beat.domain.performance.domain.Performance; import com.beat.domain.performance.exception.PerformanceErrorCode; +import com.beat.domain.schedule.dao.ScheduleRepository; +import com.beat.domain.schedule.domain.Schedule; import com.beat.domain.schedule.domain.ScheduleNumber; import com.beat.domain.booking.exception.BookingErrorCode; +import com.beat.global.common.exception.ForbiddenException; import com.beat.global.common.exception.NotFoundException; import com.beat.domain.user.dao.UserRepository; import com.beat.domain.user.domain.Users; @@ -31,6 +34,7 @@ public class TicketService { private final PerformanceRepository performanceRepository; private final MemberRepository memberRepository; private final UserRepository userRepository; + private final ScheduleRepository scheduleRepository; private final CoolSmsService coolSmsService; public TicketRetrieveResponse getTickets(Long memberId, Long performanceId, ScheduleNumber scheduleNumber, Boolean isPaymentCompleted) { @@ -99,7 +103,6 @@ public void updateTickets(Long memberId, TicketUpdateRequest request) { try { coolSmsService.sendSms(detail.bookerPhoneNumber(), message); } catch (CoolsmsException e) { - // 문자 발송 실패 시 로깅 또는 다른 처리를 추가할 수 있습니다. e.printStackTrace(); } } @@ -107,21 +110,31 @@ public void updateTickets(Long memberId, TicketUpdateRequest request) { } @Transactional - public void deleteTickets(Long memberId, TicketDeleteRequest request) { - Member member = memberRepository.findById(memberId).orElseThrow( - () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + public void deleteTickets(Long memberId, TicketDeleteRequest ticketDeleteRequest) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - Users user = userRepository.findById(member.getUser().getId()).orElseThrow( - () -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); + Long userId = member.getUser().getId(); - Performance performance = performanceRepository.findById(request.performanceId()) + Performance performance = performanceRepository.findById(ticketDeleteRequest.performanceId()) .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_PERFORMANCE_FOUND)); - for (Long bookingId : request.bookingList()) { + if (!performance.getUsers().getId().equals(userId)) { + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + + for (Long bookingId : ticketDeleteRequest.bookingList()) { Booking booking = ticketRepository.findById(bookingId) .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND)); ticketRepository.delete(booking); + + Schedule schedule = booking.getSchedule(); + + ticketRepository.delete(booking); + + schedule.decreaseSoldTicketCount(booking.getPurchaseTicketCount()); + scheduleRepository.save(schedule); } } } diff --git a/src/main/java/com/beat/domain/booking/dao/BookingRepository.java b/src/main/java/com/beat/domain/booking/dao/BookingRepository.java index 20f91aed..111be517 100644 --- a/src/main/java/com/beat/domain/booking/dao/BookingRepository.java +++ b/src/main/java/com/beat/domain/booking/dao/BookingRepository.java @@ -32,5 +32,6 @@ Optional findFirstByBookerNameAndBookerPhoneNumberAndBirthDateAndPasswo List findByUsersId(Long userId); - boolean existsBySchedulePerformanceId(Long performanceId); + @Query("SELECT COUNT(b) > 0 FROM Booking b WHERE b.schedule.id IN :scheduleIds") + boolean existsByScheduleIdIn(@Param("scheduleIds") List scheduleIds); } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/member/application/MemberService.java b/src/main/java/com/beat/domain/member/application/MemberService.java index c4535cd5..d0c68a6f 100644 --- a/src/main/java/com/beat/domain/member/application/MemberService.java +++ b/src/main/java/com/beat/domain/member/application/MemberService.java @@ -53,11 +53,9 @@ public MemberInfoResponse getUserInfoResponse( @Transactional public Long createUser(final MemberInfoResponse userResponse) { - // Users 엔티티를 먼저 생성 Users users = Users.create(); users = userRepository.save(users); - // Users 엔티티가 생성된 후 Member 엔티티 생성 Member member = Member.create( userResponse.nickname(), userResponse.email(), diff --git a/src/main/java/com/beat/domain/performance/api/PerformanceController.java b/src/main/java/com/beat/domain/performance/api/PerformanceController.java index beaa97b8..adf3a9a4 100644 --- a/src/main/java/com/beat/domain/performance/api/PerformanceController.java +++ b/src/main/java/com/beat/domain/performance/api/PerformanceController.java @@ -94,6 +94,6 @@ public ResponseEntity> deletePerformance( @CurrentMember Long memberId, @PathVariable Long performanceId) { performanceManagementService.deletePerformance(memberId, performanceId); - return ResponseEntity.ok(SuccessResponse.of(PerformanceSuccessCode.PERFORMANCE_DELETE_SUCCESS, null)); + return ResponseEntity.ok(SuccessResponse.from(PerformanceSuccessCode.PERFORMANCE_DELETE_SUCCESS)); } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java b/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java index e619f158..0e3efa88 100644 --- a/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java +++ b/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java @@ -18,10 +18,8 @@ import com.beat.domain.schedule.domain.Schedule; import com.beat.domain.staff.dao.StaffRepository; import com.beat.domain.staff.domain.Staff; -import com.beat.domain.user.dao.UserRepository; import com.beat.domain.user.domain.Users; -import com.beat.domain.user.exception.UserErrorCode; -import com.beat.global.common.exception.BadRequestException; +import com.beat.global.common.exception.ForbiddenException; import com.beat.global.common.exception.NotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -164,14 +162,24 @@ private int calculateDueDate(LocalDate performanceDate) { @Transactional public void deletePerformance(Long memberId, Long performanceId) { - memberRepository.findById(memberId).orElseThrow(() -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Long userId = member.getUser().getId(); Performance performance = performanceRepository.findById(performanceId) .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - boolean hasBookings = bookingRepository.existsBySchedulePerformanceId(performanceId); + if (!performance.getUsers().getId().equals(userId)) { + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + + List scheduleIds = scheduleRepository.findIdsByPerformanceId(performanceId); + + boolean hasBookings = bookingRepository.existsByScheduleIdIn(scheduleIds); + if (hasBookings) { - throw new BadRequestException(PerformanceErrorCode.PERFORMANCE_DELETE_FAILED); + throw new ForbiddenException(PerformanceErrorCode.PERFORMANCE_DELETE_FAILED); } performanceRepository.delete(performance); diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceService.java b/src/main/java/com/beat/domain/performance/application/PerformanceService.java index b8a92a7e..1907a176 100644 --- a/src/main/java/com/beat/domain/performance/application/PerformanceService.java +++ b/src/main/java/com/beat/domain/performance/application/PerformanceService.java @@ -26,6 +26,7 @@ import com.beat.domain.user.dao.UserRepository; import com.beat.domain.user.domain.Users; import com.beat.domain.user.exception.UserErrorCode; +import com.beat.global.common.exception.ForbiddenException; import com.beat.global.common.exception.NotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -37,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; + @Service @RequiredArgsConstructor public class PerformanceService { @@ -221,10 +223,18 @@ public PerformanceEditResponse getPerformanceEdit(Long memberId, Long performanc Member member = memberRepository.findById(memberId) .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + Long userId = member.getUser().getId(); + Performance performance = performanceRepository.findById(performanceId) .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - boolean isBookerExist = bookingRepository.existsBySchedulePerformanceId(performanceId); + if (!performance.getUsers().getId().equals(userId)) { + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + + List scheduleIds = scheduleRepository.findIdsByPerformanceId(performanceId); + + boolean isBookerExist = bookingRepository.existsByScheduleIdIn(scheduleIds); List schedules = scheduleRepository.findAllByPerformanceId(performanceId); List casts = castRepository.findAllByPerformanceId(performanceId); diff --git a/src/main/java/com/beat/domain/performance/domain/Performance.java b/src/main/java/com/beat/domain/performance/domain/Performance.java index a0e33883..78cc146e 100644 --- a/src/main/java/com/beat/domain/performance/domain/Performance.java +++ b/src/main/java/com/beat/domain/performance/domain/Performance.java @@ -1,6 +1,7 @@ package com.beat.domain.performance.domain; import com.beat.domain.BaseTimeEntity; +import com.beat.domain.promotion.domain.Promotion; import com.beat.domain.user.domain.Users; import jakarta.persistence.*; import lombok.AccessLevel; @@ -10,6 +11,9 @@ import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; +import java.util.ArrayList; +import java.util.List; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -66,6 +70,9 @@ public class Performance extends BaseTimeEntity { @Column(nullable = false) private int totalScheduleCount; + @OneToMany(mappedBy = "performance", cascade = CascadeType.ALL, orphanRemoval = true) + private List promotions = new ArrayList<>(); + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) @OnDelete(action = OnDeleteAction.CASCADE) diff --git a/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java b/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java index d51a81a5..5b1ab3ea 100644 --- a/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java +++ b/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java @@ -12,7 +12,8 @@ public enum PerformanceErrorCode implements BaseErrorCode { INVALID_DATA_FORMAT(400, "잘못된 데이터 형식입니다."), INVALID_REQUEST_FORMAT(400, "잘못된 요청 형식입니다."), NO_PERFORMANCE_FOUND(404, "공연을 찾을 수 없습니다."), - PERFORMANCE_DELETE_FAILED(400, "예매자가 1명 이상 있을 경우, 공연을 삭제할 수 없습니다."), + PERFORMANCE_DELETE_FAILED(403, "예매자가 1명 이상 있을 경우, 공연을 삭제할 수 없습니다."), + NOT_PERFORMANCE_OWNER(403, "해당 공연의 메이커가 아닙니다."), INTERNAL_SERVER_ERROR(500, "서버 내부 오류입니다.") ; diff --git a/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java b/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java index 84cae538..a67b18b6 100644 --- a/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java +++ b/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java @@ -20,4 +20,5 @@ public interface ScheduleRepository extends JpaRepository { List findAllByPerformanceId(Long performanceId); -} \ No newline at end of file + @Query("SELECT s.id FROM Schedule s WHERE s.performance.id = :performanceId") + List findIdsByPerformanceId(@Param("performanceId") Long performanceId);} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/schedule/domain/Schedule.java b/src/main/java/com/beat/domain/schedule/domain/Schedule.java index 6ed02fde..d3e33df4 100644 --- a/src/main/java/com/beat/domain/schedule/domain/Schedule.java +++ b/src/main/java/com/beat/domain/schedule/domain/Schedule.java @@ -1,6 +1,8 @@ package com.beat.domain.schedule.domain; import com.beat.domain.performance.domain.Performance; +import com.beat.domain.schedule.exception.ScheduleErrorCode; +import com.beat.global.common.exception.ConflictException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -78,4 +80,13 @@ public void update(LocalDateTime performanceDate, int totalTicketCount, Schedule this.totalTicketCount = totalTicketCount; this.scheduleNumber = scheduleNumber; } + + public void decreaseSoldTicketCount(int count) { + if (this.soldTicketCount >= count) { + this.soldTicketCount -= count; + } else { + throw new ConflictException(ScheduleErrorCode.EXCESS_TICKET_DELETE); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java b/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java index f35e921c..e9af170a 100644 --- a/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java +++ b/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java @@ -9,7 +9,8 @@ public enum ScheduleErrorCode implements BaseErrorCode { INVALID_DATA_FORMAT(400, "잘못된 데이터 형식입니다."), NO_SCHEDULE_FOUND(404, "해당 회차를 찾을 수 없습니다."), - INSUFFICIENT_TICKETS(409, "요청한 티켓 수량이 잔여 티켓 수를 초과했습니다. 다른 수량을 선택해 주세요.") + INSUFFICIENT_TICKETS(409, "요청한 티켓 수량이 잔여 티켓 수를 초과했습니다. 다른 수량을 선택해 주세요."), + EXCESS_TICKET_DELETE(409, "예매된 티켓 수 이상을 삭제할 수 없습니다.") ; private final int status; From 3a814c15e49d6c3b80c895452f41ff8e4a313674 Mon Sep 17 00:00:00 2001 From: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> Date: Tue, 8 Oct 2024 11:58:07 +0900 Subject: [PATCH 8/8] =?UTF-8?q?[release]=20v1.1.0=20=EB=A6=B4=EB=A6=AC?= =?UTF-8?q?=EC=A6=88=20(#240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 * Main redis host yml 수정 (#105) * [deploy] merge to main (#104) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) * [chore] #88 - 레디스 환경변수 추가 (#89) * [#88] chore(dev-CI.yml): dev서버 레디스 환경변수 설정 추가 * [#88] chore(prod-CI.yml): prod 서버 레디스 환경변수 설정 추가 * [deploy] merge to main (#90) * [deploy] merge to main (#83) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) --------- Co-authored-by: hyerinhwang-sailin * [deploy] merge to main (#87) * [deploy] merge to develop (#27) * [deploy] merge to main (#26) * [#2] chore(.gitignore): .gradle, .idea 파일 삭제 (#3) * [refactor] #4 - 도메인형 디렉터리 구조 변경 및 local, dev, prod 운영 환경 분리 (#5) * [#4] fix: 클래스 첫글자 대문자로 수정 * [#4] remove: enum 삭제 * [#4] feat(BaseSuccessCode): 성공 상태 관리를 위한 인터페이스 생성 * [#4] feat(BaseErrorCode): 에러 상태 관리를 위한 인터페이스 생성 * [#4] refactor: global 패키지로 이동 * [#4] refactor: 서버 운영 환경 분리 * [feat] #6 - dev, prod Dockerfile 분리 및 github Action CI workflow 구현 (#7) * [#6] feat(Dockerfile): prod용 도커 파일 구현 * [#6] feat(Dockerfile-dev): dev용 도커 파일 구현 * [#6] feat(dev-CI.yml): dev용 CI workflow 구현 * [#6] feat(prod-CI.yml): prod용 CI workflow 구현 * [#6] chore(.gitignore): gradle-wrapper.jar 파일은 레포지토리에 포함되도록 설정 * [#6] fix(gradle-wrapper.jar): .gitignore로 누락된 파일 추가 * [#6] chore(build.grade): plain jar 생성 방지 * [#9] docs(README.md): 서비스 소개 README v1 작성 (#10) * [#11] docs(README.md): 리드미 업데이트 (#12) * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [feat] #14 - 회원, 홍보, 등장인물, 스태프 엔티티 생성 (#16) * [#14] feat(Member): 멤버 엔티티 생성 * [#14] feat(Promotion): 홍보 엔티티 생성 * [#14] feat(Cast): 등장인물 엔티티 생성 * [#14] feat(Staff): 스태프 엔티티 생성 * [feat] #13 - 유저, 예매, 공연, 회차 엔티티 생성 (#15) * [#13] feat(Users): 사용자 엔티티 생성 * [#13] feat(Genre): 장르 열거형 생성 * [#13] feat(BankName): 은행명 열거형 생성 * [#13] refactor(BaseTimeEntity): 업데이트 시간 관리 필드 활성화 * [#13] feat(Performance): 공연 엔티티 생성 * [#13] feat(ScheduleNumber): 회차 번호 열거형 생성 * [#13] feat(Schedule): 회차 엔티티 생성 * [#13] feat(Booking): 예매 엔티티 생성 * [#13] refactor(ScheduleNumber): 네이밍 수정 * [#14} fix: 스태프, 등장인물, 홍보 엔티티 상속관계 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [#18] feat(Jenkinsfile): 젠킨스 파일 생성 (#19) * [#20] refactor(Jenkinsfile): 젠킨스 파일 Webhook 테스트용 커밋 (#21) * [#22] feat(Jenkinsfile): Jenkins multibranch 스크립트 작성 (#23) * HOTFIX(Jenkinsfile): Jenkins multibranch 스크립트 수정 * HOTFIX(workflows): 빌드 후 젠킨스 배포가 진행되도록 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * HOTFIX(workflows): Jenkinsfile 스크립트 수정 * [#24] feat(Jenkinsfile): slack 연동 스크립트 작성 (#25) --------- Co-authored-by: hyerinhwang-sailin * HOTFIX(workflow): 오타 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #28 - 비회원 예매 조회 POST API 구현 (#29) * chore(application-dev.yml): dialect 추가 * chore(application-prod.yml): dialect 추가 * [#28] chore(build.gradle): security 의존성 비활성화 - security 일시적으로 비활성화 * [#28] refactor(Booking): 예매 엔티티에 빌더 및 정적팩토리 메서드 추가 * [#28] refactor(ErrorResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(Schedule): 회차 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(Performance): 공연 엔티티에 빌더 및 정적 팩토리 메서드 추가 * [#28] refactor(SuccessResponse): 정적 팩토리 메서드 네이밍 변환 * [#28] refactor(GlobalExceptionHandler): INTERNAL_SERVER_ERROR 핸들러 메서드 추가 * [#28] feat(BookingSuccessCode): 예매 성공 메시지를 관리하는 열거형 생성 * [#28] feat(BookingErrorCode): 예매 에러 메시지를 관리하는 열거형 생성 * [#28] feat(BookingRetrieveResponse): 예매 조회 응답 DTO 생성 * [#28] feat(BookingRetrieveRequest): 예매 조회 요청 DTO 생성 * [#28] feat(BookingRepository): 예매 레포지토리 생성 및 비회원 예매 조회 시 예매 내역 가져오는 메서드 구현 * [#28] feat(BookingService): 예매 서비스 레이어 생성 및 비회원 조회 메서드 구현 * [#28] feat(BookingController): 예매 컨트롤러 생성 및 비회원 예매조회 POST API 구현 * [feat] #30 - SwaggerConfig 및 WebConfig 구현 (#31) * [#30] chore(build.gradle): springdoc 의존성 추가 * [#30] feat(SwaggerConfig): SwaggerConfig 추가 * [#30] feat(WebConfig): WebConfig 추가 * HOTFIX(workflows): push 이벤트 시 github action이 빌드 되지 않도록 수정 * HOTFIX(Jenkinsfile): 포트 수정 * [feat] #32 - 티켓 예매 가능 여부 GET API 구현 (#33) * [#32] refactor(BookingController): 메서드명 수정 * [#32] feat(ConflictException): Conflict 409에러 클래스 생성 * [#32] feat(GlobalExceptionHandler): ConflictException 등록 * [#32] feat(TicketAvailabilityRequest): TicketAvailabilityRequest DTO 생성 * [#32] feat(TicketAvailabilityResponse): TicketAvailabilityResponse DTO 생성 * [#32] feat(ScheduleSuccessCode): ScheduleSuccessCode 열거형 생성 * [#32] feat(ScheduleErrorCode): ScheduleErrorCode 열거형 생성 * [#32] feat(ScheduleRepository): ScheduleRepository 생성 * [#32] feat(ScheduleService): ScheduleService 생성 및 회차별 티켓 구매 가능 여부 판단 메서드 구현 * [#32] feat(ScheduleController): 회차별 티켓 수량 조회 GET API 구현 * [feat] #17 - 카카오 소셜 로그인 API 구현 (#36) * [#17] feat(build.gradle): jwt, security, open feign, Redis 의존성 추가 * [#17] feat(BeatApplication): OpenFeign 관련 어노테이션 추가 * [#17] feat(RedisConfig): redis 설정 * [#17] feat: redis 활용 jwt 토큰 생성 로직 구현 * [#17] feat(SecurityConfig): security 설정 * [#17] refactor: Member, Users 엔티티 수정 및 관련 enum 추가 * [#17] feat: Member, Users 도메인 관련 인증 로직 구현 * [#17] feat(MemberController): Member 관련 API 엔드포인트 구현 * [#17] feat: Security 관련 인증 객체 구현 * [#17] feat: 소셜로그인 로직 구현 * [#17] fix: 소셜로그인 오류 해결 * [#17] refactor: 코드리뷰 반영 * [#17] refactor: 코드리뷰 반영 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #34 - 비회원 예매 POST API 구현 (#35) * [#34] feat(Users): 빌더 및 정적 팩토리 메서드 추가 * [#34] feat(Entity): 엔티티 id 필드 수정 * [#34] refactor(application.yml): dialect 추가 * [#34] refactor(ScheduleService): 네이밍 수정 * [#34] refactor(BookingSuccessCode): 비회원 예매 조회 성공 메시지 추가 * [#34] feat(GuestBookingRequest): 비회원 예매 요청 DTO 생성 * [#34] feat(GuestBookingResponse): 비회원 예매 응답 DTO 생성 * [#34] refactor(BookingRetrieveService): 네이밍 수정 * [#34] feat(PerformanceRepository): 공연 레포지토리 생성 * [#34] feat(UserRepository): 유저 레포지토리 생성 * [#34] refactor(BookingRepository): 비회원 예매 시 네가지 정보가 모두 일치 해야만 다른 유저로 판단하는 메서드 구현 * [#34] refactor(ScheduleRepository): 비관적 락 적용 * [#34] feat(GuestBookingService): 비관적 락을 이용해 비회원 예매 로직 구현 * [#34] feat(BookingController): 비회원 예매 POST API 구현 * [#34] test(GuestBookingServiceConcurrencyTest): 동시성 테스트 구현 * [Refactor] #37 - 카카오 로그인 API response 수정 (#39) * [#37] rename: 빈 충돌 해결 위해 UserRepository를 UsersRepository로 rename * [#37] refactor: login response에서 refreshToken을 cookie에 담아주도록 변경 * [#37] fix: dao, repository 충돌 해결 * [#37] refactor: 어노테이션 수정 * [feat] #40 - 소개 관련 공연 정보 조회 GET API 구현 (#41) * [#40] feat: repository 추가 * [#40] feat: 공연 관련 성공, 실패 메세지 추가 * [#40] feat(PerformanceDetailResponse): 공연 상세페이지 조회 응답 dto * [#40] feat(PerformanceService): 공연 상세페이지 조회 로직 구현 * [#40] feat(PerformanceController): 공연 상세페이지 엔드포인트 구현 * [#40] feat(SecurityConfig): auth whitelist update * [#40] refactor: dto 분리 및 rename * [feat] #42 - 예매 관련 공연 정보 GET API 구현 (#43) * [#42] feat: 예매 관련 정보 조회 dto 생성 * [#42] feat: 예매 관련 정보 조회 성공 메세지 추가 * [#42] feat(ScheduleService): 잔여티켓계산, 예매가능여부확인, 예매가능여부 update 메소드 구현 * [#42] feat(PerformanceService): 예매관련공연정보의 response 생성하는 로직 구현 * [#42] feat(PerformanceController): 예매관련공연정보 조회 엔드포인트 구현 * [#42] feat(SecurityConfig): auth_whitelist update * [#42] refactor(ScheduleService): findTicketAvailability에서 getAvailableTicketCount method 사용하도록 수정 * [feat] #38 - 회원 예매 POST API 구현 (#45) * [#38] fix(Cast): Join 하는 부분 수정 및 빌더와 정적 팩토리 메서드 패턴 도입 * [#38] chore(application.yml): 계층 수정 * [#38] feat: 커스텀 어노테이션 생성 * [#38] fix(UserRepository): 중복된 클래스 삭제 * [#38] feat(UserErrorCode): 유저의 에러 메시지를 관리하는 열거형 생성 * [#38] refactor(MemberErrorCode): message 목적에 맞게 변경 * [#38] refactor(BookingSuccessCode): 회원 예매 성공 메시지 추가 * [#38] feat: 커스텀 어노테이션 생성 커밋에 누락된 클래스 추가 * [#38] refactor(GuestBookingService): schedule에서 바로 get 하도록 수정 * [#38] test(GuestBookingServiceConcurrencyTest): import문 경로명 변경 * [#38] refactor(MemberService): @Transactional 어노테이션이 필요한 메서드에 해당 옵션 추가 * [#38] feat(MemberBookingRequest): 회원 예매 요청 DTO 생성 * [#38] feat(MemberBookingResponse): 회원 예매 응답 DTO 생성 * [#38] refactor(MemberController): refreshToken을 쿠키에 넣어주도록 구현 * [#38] feat(MemberBookingService): 회원 예매 서비스 로직 구현 * [#38] feat(BookingController): 회원 예매 요청 POST API 구현 * [#38] fix: 빌드 안되는 부분 수정 * [#38] remove(MemberBookingService): 사용하지 않는 import문 삭제 * [#38] refactor: 커스텀 어노테이션 이름 수정 * [feat] #44 - 홈페이지 공연 및 홍보 조회 GET API 구현 (#47) * [#44] refactor: 코드리뷰 반영 * [#44] fix(Promotion): 기본키 이름 수정, performanceId 연관관계 설정 * [#44] feat: Repository 및 관련 로직 추가 * [#44] feat: errorcode, successcode 추가 * [#44] feat: 홈페이지 request, response dto 생성 * [#44] feat(ScheduleService): dueDate 관련 로직 구현 * [#44] feat(PerformanceService): 홈페이지 정렬 및 response 생성 로직 구현 * [#44] chore: import문 추가 * [feat] #46 - 회원 예매 조회 GET API 구현 (#48) * [#46] remove(BookingRetrieveRequest): 클래스 삭제 * [#46] refactor(BookingSuccessCode): 회원 예매 조회 성공 메시지 추가 * [#46] refactor(GuestBookingRetrieveResponse): 클래스 명 변경 * [#46] refactor(GuestBookingRetrieveRequest): 안쓰는 코드 주석처리 * [#46] refactor(GuestBookingRetrieveService): 클래스 명 수정으로 인한 리팩토링 * [#46] refactor(SecurityConfig): 토큰 사용하지 않는 api 경로 추가하기 * [#46] refactor(BookingRepository): userId로 예약 정보를 가져오는 JPA 메서드 구현 * [#46] feat(MemberBookingRetrieveResponse): 회원 조회 응답 DTO 생성 * [#46] feat(MemberBookingRetrieveService): 회원 예매 조회 로직을 담당하는 서비스 레이어 구현 * [#46] feat(BookingController): 회원 예매 조회 GET API 구현 * [feat] #49 - 예매자 관리 API 구현 (#51) * [#49] feat: 티켓 관련 success, error code 추가 * [#49] feat(Booking): 입금여부 setter 메소드 추가 * [#49] feat(TicketRetrieveResponse): 예매자 확인 response dto 생성 * [#49] feat(Ticket): 예매자 확인용 티켓 정보 response dto 생성 * [#49] feat(TicketRepository): 예매자 필터링용 메소드 생성 * [#49] feat: 예매자 입금정보 수정 request dto 생성 * [#49] feat(TicketDeleteRequest): 예매자 삭제 request dto 생성 * [#49] feat(TicketService): 예매자 관리 관련 로직 구현 * [#49] feat(TicketController): 예매자 관리 엔드포인트 구현 * [#49] chore: swagger annotation 추가 * HOTFIX(SecurityConfig): WHITELIST 경로명 수정 * [fix] #52 - auth whitelist 수정 (#53) * [#52]fix(SecurityConfig): auth_whitelist 수정 * [#52]fix(SecurityConfig): auth_whitelist 수정 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #54 - 등록한 공연 목록 조회 GET API 구현 (#55) * [#54] feat(PerformanceSuccessCode): success code 추가 * [#54] feat: 회원이 등록한 공연목록 조회 dto 생성 * [#54] feat(PerformanceService): 회원이 등록한 공연목록 조회 로직 구현 * [#54] feat(PerformanceRepository): 회원이 등록한 공연목록 조회 관련 메소드 추가 * [#54] feat(PerformanceController): 회원이 등록한 공연목록 조회 엔드포인트 생성 * [#54] fix(TicketService): exception error 수정 * [#54] chore(application.yml): yml 수정 * [fix] #58 - dev-ci.yml, prod-ci.yml 환경변수 추가 (#59) * [#58] fix(dev-CI.yml): Dev 서버 CI 워크플로우 수정 * [#58] fix(prod-CI.yml): Prod 서버 CI 워크플로우 수정 * [refactor] #61 - Performance Entity field 추가 (#62) * [#61] refactor(Performance): bankHolder 필드 추가 * [#61] chore(BookingController): swagger annotation 수정 * [feat] #63 - healthCheckController 생성 (#64) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [feat] #63 - health check URL 화이트리스트에 등록 (#67) * [#63] remove(UsersRepository): 중복 클래스 삭제 * [#63] feat(HealthCheckController): healthcheck 컨트롤러 생성 * [#63] feat(SecurityConfig): healthcheck url white_list에 등록 * [fix] #57 - entity 연관관계 설정 SecurityConfig 수정 (#65) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [fix] #57 - security 관련 에러 대응 (#71) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [fix] #73 - security 수정 (#74) * [#57] refactor: entity 연관관계 설정 및 수정 * [#57] fix(SecurityConfig): auth_whitelist update * [#57] chore(UsersRepository): 중복된 파일 및 불필요한 패키지 제거 * [#57] refactor(SecurityConfig): auth_whitelist update * [#57] refactor: 엔티티 정적팩토리 메소드 추가 * [#57] comment(SecurityConfig): 주석 제거 * [#57] fix(JwtAuthenticationFilter): 에러 로직 수정 * fix(SecurityConfig): webSecurityCustomizer 로직 추가 * [#57] fix:security 수정 * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 (#77) * [fix] #76 - 누락된 코드 추가 (#79) * [#76] fix(SecurityConfig): Base64 인코딩을 하도록 변경 * [#76] chore(SecurityConfig): 누락된 import문 추가 * [#76] chore(JwtTokenProvider): 누락된 코드 추가 * [#81] fix(JwtTokenProvider): jwtsecret을 인코딩하고 디코딩을 하도록 수정 (#82) * [#85] chore(application.yml): 환경변수 설정 (#86) --------- Co-authored-by: hyerinhwang-sailin --------- Co-authored-by: hyerinhwang-sailin * Revert "[deploy] merge to main (#90)" (#91) This reverts commit f519b0c82a2f01d4374eb045b9e90c6303381e50. * [fix] #93 - 누락된 어노테이션 및 누락된 경로명 추가 (#94) * [#93] fix(HealthCheckController): 누락된 어노테이션 추가 * [#93] refactor(SecurityConfig): 누락된 경로명 추가 * [bug] #84 - actuator/health 의존성 및 설정 추가 (#96) * [#84] chore(build.gradle): 의존성 추가 * [#84] chore: health/actuator yml 설정 추가 * [#84] chore: redis yml 설정 추가 * [#84] chore: yml 수정 (#99) * [bug] #101 - yml, s3 수정 (#102) * [#101] chore: yml 수정 * [#101] feat: s3 추가 * HOTIFX: prod ci-yml 수정 --------- Co-authored-by: hyerinhwang-sailin * Update application-prod.yml --------- Co-authored-by: DongHoon Lee <125895298+hoonyworld@users.noreply.github.com> * [feat] #50 - 공연 생성 POST API 생성 (#108) * [#50] chore: 폴더 이동 * [#50] feat: request DTO 생성 * [#50] feat: response DTO 생성 * [#50] refactor(PerformanceSuccessCode): 공연 생성 성공 메시지 추가 * [#50] chore(PerformanceService): import문 변 * [#50] chore(HomeController): import문 변 * [#50] feat(PerformanceCreateService): 공연 생성 서비스 로직 생성 * [#50] feat(PerformanceController): 공연 생성 POST API 생성 * [feat] #111 - 웹발신 구현 (#114) * [#111] feat(build.gradle): coolsms 의존성 추가 * [#111] feat: yml에 coolsms 환경변수 세팅 * [#111] feat(CoolSmsService): coolsms 웹발신 로직 구현 * [#111] feat(TicketService): coolsms 웹발신 트리거 로직 구현 * [#111] comment(TicketController): swagger 설명 수정 * [feat] #110 - 공연 수정 PUT API 구현 (#112) * [#110] feat: request DTO 생성 * [#110] feat: response DTO 생성 * [#110] feat(CastErrorCode): 등장인물 열거형 생성 * [#110] feat(StaffErrorCode): 스태프 에러 열거형 생성 * [#110] refactor(PerformanceSuccessCode): 공연 성공 수정 메시지 추가 * [#110] refactor(Performance): 업데이트 메서드 추가 * [#110] refactor(Schedule): 업데이트 메서드 추가 * [#110] refactor(Staff): 업데이트 메서드 추가 * [#110] test(GuestBookingServiceConcurrencyTest): 변경된 필드 추가 * [#110] refactor(Cast): 업데이트 메서드 추 * [#110] feat(PerformanceUpdateService): 공연 수정 서비스 로직 구현 * [#110] feat(PerformanceController): 공연 수정 PUT API 추가 * [feat] #113 - 공연 삭제 DELETE API 구현 (#116) * [#113] refactor(BookingRepository): 해당 공연을 예매한 사람이 있는지 판단하는 메서드 구현 * [#113] refactor(PerformanceErrorCode): 예매자가 한명 있을 경우 공연 취소가 안될때 보여주는 에러메시지 추가 * [#113] refactor(PerformanceSuccessCode): 공연이 삭제되었을 때 보여주는 성공 메시지 추가 * [#113] refactor(PerformanceManagementService): 멤버 아이디를 인자로 받도록 수정 및 공연 삭제 메서드 구현 * [#113] feat(PerformanceController): 공연 삭제 DELETE API 구현 * Update README.md * HOTFIX: 코드 수정 * [#119] refactor: response에 필요 필드 추가 (#120) * [feat] #117 - 공연 수정 페이지 정보 조회 GET API 구현 (#121) * [#117] remove(PerformanceCreateService): 사용하지 않는 클래스 삭제 * [#117] refactor(CastRepository): DB에 등록된 등장인물을 모두 가져오는 메서드 구현 * [#117] refactor(ScheduleRepository): DB에 등록된 회차를 모두 가져오는 메서드 구현 * [#117] refactor(StaffRepository): DB에 등록된 스태프를 모두 가져오는 메서드 구현 * [#117] refactor(PerformanceSuccessCode): 공연 수정 페이지 조회 성공 메시지 추가 * [#117] refactor(PerformanceEditResponse): 공연 수정 페이지 조회 응답 DTO 생성 * [#117] refactor(PerformanceService): 수정 페이지의 정보를 조회하는 서비스 로직 구현 * [#117] feat(PerformanceController): 공연 수정 페이지의 정보를 조회하는 GET API 구현 * [#123] fix(PerformanceController): 중복 코드 제거 (#124) * [#128] fix: 누락된 환경 변수 주입 및 수정 (#129) * [feat] #127 - presigned-url로 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트를 반환하도록 구현 (#131) * [#127] feat(SecurityConfig): 화이트 리스트에 presigned-url 추가 * [#127] refactor(FileService): 포스터 이미지, 등장인물 이미지 리스트, 스태프 이미지 리스트의 presigned-url을 반환하는 메서드 구현 * [#127] feat(FileController): presigned-url GET API 구현 * [refactor] #133 - presigned URL의 만료 시간 늘리기 (#134) * [#133] remove: 삭제된 클래스 커밋 * [#133] refactor(FileService): URL의 유효시간 2시간으로 설정 * [#135] refactor(SwaggerConfig): SwaggerConfig 리팩토링 (#136) * [#128] fix(BankName): bankname enum 추가 (#139) * [refactor] #126 - 프론트 요청 필드 반영 (#140) * [#126] refactor(BookingController): 회원 예매 조회시 성공 메시지 변경 * [#126] refactor(BookingRepository): 쿼리문 추가 * [#126] refactor(GuestBookingRequest): enum으로 리턴값 변경 * [#126] refactor(GuestBookingResponse): enum으로 리턴값 변경 * [#126] chore(GuestBookingRetrieveRequest): 주석 삭제 * [#126] refactor(GuestBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveResponse): performanceId, posterImage, totalPaymentAmount 추가 * [#126] refactor(MemberBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingRetrieveService): response에 추가된 필드 리턴하도록 리팩토링 * [#126] refactor(GuestBookingService): displayName이 아닌 열거형으로 리턴하도록 수정 * [#126] refactor(MemberBookingRequest): 정적 팩토리 메서드 삭제 * [#126] refactor(MemberBookingResponse): enum으로 리턴하도록 수정 * [#126] refactor(MemberBookingService): enum으로 리턴하도록 수정 * [#126] test(GuestBookingServiceConcurrencyTest): DTO에서 수정된 리턴 방법 반영 * [#142] refactor(FileController): castImages, staffImages의 파라미터 value를 주지 않아도 presigned-url을 발급하도록 변경 (#143) * Update README.md * [#147] refactor: 예금주 필드 추가 (#148) * [feat] #150 - 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 (#151) * [#150] feat(Jenkinsfile): 스프링 서버를 redis와 동일한 네트워크에서 실행되도록 구현 * [#150] refactor(prod-CI.yml): prod에서 PR시에만 빌드 되도록 수정 * [#150] deploy(application-prod.yml): 운영서버 ddl-auto create로 초기화 (#155) * [#159] docs(README.md): 서비스 소개 내용 업데이트 (#160) * docs(README.md): README 수정 * docs(README.md): 기획 의견 반영 * [fix] #162 - 공연 삭제 로직 변경 (#163) * [#162] refactor(Performance): Promotion 엔티티 양방향 매핑 * [#162] refactor(BookingRepository): JPQL을 사용해 회차 아이디가 담긴 리스트의 회차 아이디가 예매 테이블에도 존재하는지 비교하도록 변경 * [#162] refactor(PerformanceController): 메서드 네이밍 리팩토링 * [#162] refactor(PerformanceErrorCode): 에러 상태 변경 및 해당 공연의 메이커가 아닐 때 발생하는 에러메시지 추가 * [#162] refactor(PerformanceManagementService): 변경된 JPA 메서드에 맞추어 서비스 로직 변경 및 해당 공연의 메이커만 공연삭제가 가능하도록 변경 * [#162] refactor(PerformanceService): 변경된 JPA 메서드에 맞추어 공연 수정 시 공연 정보를 반환하는 서비스 로직 변경 * [#162] fix(TicketController): 예매자 삭제 시 불필요한 pathVariable 속성 삭제 * [#162] refactor(ScheduleRepository): 공연 id에 해당하는 모든 회차 id를 리스트로 반환하는 메서드 추가 * [#162] refactor(TicketService): 해당 공연의 메이커가 아니면 예매자를 삭제하지 못하는 로직 추가 * [fix] #164 - 입금여부수정 api 경로 수정 및 dev db 초기화 (#165) * [#164] fix(TicketController): 예매자 입금여부 수정 api 경로 수정 * [#164] chore(application-dev): dev db 초기화 * [feat] #166 - 사용하지 않는 도커이미지를 서버에서 삭제하도록 Jenkinsfile에 스크립트 추가 (#167) * [#168] comment: 불필요한 주석 제거 (#169) * [fix] #170 - 예매자 삭제 시 판매 티켓 수에 반영하는 로직 구현 (#171) * [#170] feat: 예매자 삭제 관련 에러 메세지 추가 * [#170] feat(Schedule): soldTicketCount 변경 메소드 추가 * [#170] fix(TicketService): 예매자 삭제 시 soldTicketCount에 반영되도록 메소드 수정 * [#170] fix(Schedule): 예매자 삭제 시 exception 처리 방식 수정 * [feat] #172 - promotion 필드 추가 및 지난 공연 캐러샐 자동 삭제 구현, response에 dueDate 추가 (#175) * [#172] feat(BeatApplication): cron 관련 annotation 추가 * [#172] feat(Promotion): promotion entity에 추가로 필요한 필드 추가 * [#172] feat(PromotionService): 지나간 공연에 해당하는 promotion 캐러셀 삭제하는 로직 구현 * [#172] feat(PerformanceDetailResponse): 공연 상세 정보 조회 response에 minDueDate 추가 * [#172] feat(PerformanceDetailResponse): 공연 상세 정보 조회 response에 schedule별 dueDate 추가 * [#172] feat(BookingPerformanceDetailSchedule): 예매하기에 필요한 공연 상세 정보 조회 response에 schedule별 dueDate 추가 * [#172] feat(MakerPerformanceDetail): 등록한 공연 조회 response에 MinDueDate 추가 * [#172] feat(PerformanceService): response에 추가한 필드 반영 및 등록한 공연 조회 정렬 로직 구현 * [#172] refactor(PromotionService): checkAndDeleteInvalidPromotions 성능 및 확장성 고려한 refactor * [feat] #172 - 캐러셀 response에 필드 추가 (#176) * [#172] feat(BeatApplication): cron 관련 annotation 추가 * [#172] feat(Promotion): promotion entity에 추가로 필요한 필드 추가 * [#172] feat(PromotionService): 지나간 공연에 해당하는 promotion 캐러셀 삭제하는 로직 구현 * [#172] feat(PerformanceDetailResponse): 공연 상세 정보 조회 response에 minDueDate 추가 * [#172] feat(PerformanceDetailResponse): 공연 상세 정보 조회 response에 schedule별 dueDate 추가 * [#172] feat(BookingPerformanceDetailSchedule): 예매하기에 필요한 공연 상세 정보 조회 response에 schedule별 dueDate 추가 * [#172] feat(MakerPerformanceDetail): 등록한 공연 조회 response에 MinDueDate 추가 * [#172] feat(PerformanceService): response에 추가한 필드 반영 및 등록한 공연 조회 정렬 로직 구현 * [#172] refactor(PromotionService): checkAndDeleteInvalidPromotions 성능 및 확장성 고려한 refactor * [#172] feat(HomePromotionDetail): 캐러셀 response에 필드 추가 * [#172] feat(PerformanceService): 캐러셀 response에 필드 추가 * [#178] feat(TokenService): deleteRefreshToken에 logging 추가 (#179) * [#180] refactor - isBooking 로직 조건 개선 (#181) * [#180] refactor(ScheduleService): isBooking update 기준 중 공연날짜를 공연종료시간으로 변경 * [#180] refactor(PerformanceDetailSchedule): 공연상세페이지 response에 isBooking 추가 * [#180] refactor(PerformanceService): 공연상세페이지 response에 isBooking 추가 * [refactor] #177 - 공연 수정 API에서 회차, 등장인물, 스태프를 추가, 삭제, 업데이트가 가능하도록 리팩토링 및 예매자가 존재하지 않을 시 가격정보 업데이트가 가능하도록 리팩토링 (#184) * [#177] feat(ScheduleAddRequest): 회차 추가 요청 DTO 생성 * [#177] feat(ScheduleDeleteRequest): 회차 삭제 요청 DTO 생성 * [#177] feat(CastAddRequest): 등장인물 추가 요청 DTO 생성 * [#177] feat(CastDeleteRequest): 등장인물 삭제 요청 DTO 생성 * [#177] feat(StaffAddRequest): 스태프 추가 요청 DTO 생성 * [#177] feat(StaffDeleteRequest): 스태프 삭제 요청 DTO 생성 * [#177] feat(ScheduleAddResponse): 회차 추가 응답 DTO 생성 * [#177] feat(ScheduleDeleteResponse): 회차 삭제 응답 DTO 생성 * [#177] feat(CastAddResponse): 등장인물 추가 응답 DTO 생성 * [#177] feat(CastDeleteResponse): 등장인물 삭제 응답 DTO 생성 * [#177] feat(StaffAddResponse): 스태프 추가 응답 DTO 생성 * [#177] feat(StaffDeleteResponse): 스태프 삭제 응답 DTO 생성 * [#177] refactor(PerformanceUpdateRequest): 추가된 요청 DTO필드로 변경 * [#177] refactor(PerformanceUpdateResponse): 추가된 응답 DTO필드로 변경 * [#177] refactor(ScheduleUpdateRequest): 객체로 자료형 변경 * [#177] refactor(PerformanceUpdateRequest): 업데이트 변수 추가 * [#177] refactor(PerformanceUpdateResponse): 업데이트 변수 추가 * [#177] chore(build.gradle): devtools 비활성화 * [#177] refactor(PerformanceUpdateService): 회차, 등장인물, 스태프 추가,삭제,수정이 가능하도록 서비스 로직 변 * [#177] refactor(PerformanceUpdateService): 롬복 라이브러리로 변경 * [#177] refactor: 경로명 변경 * [#177] refactor(PerformanceErrorCode): 회차 추가 3개 초과 시 에러 메시지 추가 * [#177] refactor(ScheduleRepository): 공연 아이디로 회차 개수를 반환하는 메서드 추가 * [#177] refactor(PerformanceUpdateService): 기존 회차 수 + 회차 추가 수가 3 초과시 에러처리 추가 * [#177] refactor(PerformanceUpdateService): 해당 공연의 메이커만 공연 수정이 가능하도록 검증하는 메서드 추가 * [#177] refactor(PerformanceController): Swagger ApiResponse 추가 * [#177] refactor(application-dev.yml): 로그 레벨 속성 추가 * [#177] refactor(Performance): 티켓 가격 업데이트 메서드 추가 * [#177] refactor(PerformanceErrorCode): 변경 티켓 가격이 음수일 시, 예매자가 존재하는데 가격수정을 시도할 때 보여줄 에러 메시지 추가 * [#177] refactor(PerformanceUpdateRequest): ticketPrice 변수 추가 * [#177] refactor(PerformanceUpdateService): 예매자 여부에 따른 티켓 가격 변경 서비스 로직 추가 * [#177] refactor(PerformanceController): ApiResponse 추가 * [#177] refactor(PerformanceController): ApiResponse description 설명 변경 * [feat] #183 - 공연 등록 시 공연상세이미지 추가 및 상세페이지, 수정페이지에서의 조회 기능 구현과 웹발신 문자내용 수정 (#186) * [#183] feat(FileService): 공연상세이미지 presignedUrl 할당 로직 구현 * [#183] feat(FileController): 공연상세이미지 presignedUrl 할당 로직 구현 * [#183] feat(Performance): 공연상세이미지 연관관계 설정 * [#183] feat(PerformanceDetailImage): 공연상세페이지에서의 상세이미지 조회 response 생성 * [#183] feat(PerformanceImage): 공연상세이미지 엔티티 생성 * [#183] feat(PerformanceImageRepository): 공연상세이미지 repository 생성 * [#183] feat(PerformanceDetailResponse): 공연상세페이지 조회 response에 상세이미지목록 추가 * [#183] feat(PerformanceEditResponse): 공연수정페이지 조회 response에 상세이미지목록 추가 * [#183] feat(PerformanceService): 공연상세페이지, 수정페이지 조회 시 상세이미지목록 같이 조회하도록 추가 * [#183] feat: 공연 생성 시 상세이미지 request, response 추가 * [#183] feat: 공연 생성 request, response에 상세이미지 추가 * [#183] feat(PerformanceManagementService): 공연 생성 시 상세이미지도 등록가능하도록 구현 * [#183] feat(TicketService): 웹발신 문자 내용 수정 * [#183] feat(Performance): 누락된 메소드 추가 * [#183] feat: dev, prod CI yml에 토큰 관련 환경변수 추가 * [#183] feat: dev, prod yml에 토큰 관련 환경변수 추가 * [refactor] #185 - schedule, staff, cast의 add, delete, update DTO를 하나의 DTO로 변경 및 scheduleNumber를 서버측에서 부여하도록 변경 (#187) * [feat] #188 - 공연 상세이미지 수정 구현 및 패키지구조 정리, dto 이름 변경 (#189) * [#188] feat(PerformanceImage): PerformanceImage update 로직 추가 * [#188] feat(PerformanceImageErrorCode): PerformanceImageErrorCode 추가 * [#188] feat(PerformanceImageModifyRequest): PerformanceImageModifyRequest 추가 * [#188] feat(PerformanceImageModifyResponse): PerformanceImageModifyResponse 추가 * [#188] feat(PerformanceImageRepository): findIdsByPerformanceId 추가 * [#188] feat(PerformanceModifyRequest): PerformanceModifyRequest에 staffModifyRequests 추가 * [#188] feat(PerformanceModifyResponse): PerformanceModifyResponse에 performanceImageModifyResponses 추가 * [#188] feat(PerformanceModifyService): performanceImage 수정 로직 구현 * [#188] Comment(PerformanceController): updatePerformance swagger 에러 추가 * [#188] Comment(PerformanceService): 공연상세정보 조회 시 perfomanceId 포함하는 로그 추가 * [#188] rename: 공연 관련 dto 패키지 정리 및 파일 이름 수정 * [refactor] #192 - 공연소개 & 유의사항 최대 글자수 500자로 구현 (#193) * [#192] refactor(Performance): 공연소개, 유의사항 최대 글자수 500자로 변경 * [#192] refactor(PerformanceErrorCode): 공연소개, 유의사항 글자 수 500자 초과 시 보여줄 에러메시지 추가 * [#192] refactor(PerformanceManagementService): 공연소개, 유의사항 글자수 500자 초과 시 예외처리 서비스 로직 구현 * [feat] #191 - 예매 취소 및 취소된 티켓 1년 후 자동삭제 구현, 입금 완료된 예매자 미입금으로 바꾸지 못하도록 구현 (#194) * [#191] feat(BookingStatus): 예매 상태 enum 추가 * [#191] feat(Booking): bookingStatus, cancellationDate 필드 추가 * [#191] feat(BookingSuccessCode): SuccessCode 수정 * [#191] feat(TicketErrorCode): TicketErrorCode 추가 * [#191] feat(TicketRepository): Booking 조회 메소드 추가 * [#191] rename(TicketCancelRequest): dto 이름 변경 * [#191] feat(TicketService): isPaymentCompleted를 bookingStatus로 변경, updateTickets 입금완료티켓 변경 요청 error 처리, 예매취소 로직 수정, 예매취소 티켓 1년 뒤 삭제 로직 구현 * [#191] feat(TicketUpdateDetail): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(TicketDetail): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(TicketController): isPaymentCompleted를 bookingStatus로 변경 및 http method 변경, 메소드 rename * [#191] feat(MemberBookingService): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(MemberBookingRetrieveService): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(MemberBookingRetrieveResponse): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(MemberBookingResponse): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(MemberBookingRequest): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(GuestBookingService): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(GuestBookingRetrieveService): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(GuestBookingRetrieveResponse): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(GuestBookingResponse): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(GuestBookingRequest): isPaymentCompleted를 bookingStatus로 변경 * [#191] feat(GuestBookingServiceConcurrencyTest): isPaymentCompleted를 bookingStatus로 변경 * [#191] refactor(Booking): import문 변경 * [#191] refactor(TicketController): successResponse 메서드 변경 * [#191] refactor(TicketService): findBookings 메서드 분리, 오래된 예매취소내역 삭제 시간 변경 * [#196] fix(PerformanceService): getPromotions 로직 performanceId null인 경우 고려해 수정 (#197) * [feat] #200 - 공연회차 등록 10회까지 가능하도록 수정 (#201) * [#200] fix(ScheduleNumber): 10회차까지 추가 * [#200] fix(PerformanceModifyService): 공연 회차 수정 중 회차 추가 시 검증 로직 10회차까지 허용 가능하도록 변경 * [#200] feat(PerformanceErrorCode): MAX_SCHEDULE_LIMIT_EXCEEDED message 수정 * feat #202 - allowedMethods에 PATCH 메서드 추가 및 allowedOriginPatterns에 도메인 명시 (#203) * [#202] feat(WebConfig): PATCH 메서드 추가 및 allowedOriginPatterns에 도메인 명시 * [#202] feat(WebConfig): 클라이언트 localhost 주소 추가 * [#202] fix(WebConfig): 문자열 오타 수정 * [fix] #204 - SuccessReponse 메서드 타입 수정 및 회원 예매 조회 타입 일치 완료 (#205) * [#204] fix(SuccessResponse): 메서드에 제네릭 타입 명시 * [#204] fix(BookingController): 회원 예매 조회 response 타입 일치하도록 수정 * [#206] fix(TokenErrorCode): 토큰 만료 메시지 status 401로 변경 (#207) * [feat] #190 - admin 기능 구현 (#208) * [#190] chore(Booking): 공백 제거 * [#190] feat(FileSuccessCode): S3 관련 성공 메시지를 관리하는 열거형 생성 * [#190] feat(PresignedUrlFindAllResponse): 공연 생성 관련 presignedUrl 응답 DTO 구현 * [#190] refactor(FileService): 메서드 명 변경 및 정적 팩토리 메서드로 반환하도록 변경 * [#190] feat(FileApi): Performance PreSigned Url 스웨거 명세서 작성 * [#190] feat(FileController): FileApi 인터페이스를 구현하도록 리팩토링 및 SuccessResponse로 반환하도록 변경 * [#190] refactor(SecurityConfig): AUTH_WHITELIST에 /error url 추가 * [#190] refactor(SwaggerConfig): 릴리즈 버전 수정 * [#190] refactor: 폴더 변경 및 이동 * [feat] #200 - 공연회차 등록 10회까지 가능하도록 수정 (#201) * [#200] fix(ScheduleNumber): 10회차까지 추가 * [#200] fix(PerformanceModifyService): 공연 회차 수정 중 회차 추가 시 검증 로직 10회차까지 허용 가능하도록 변경 * [#200] feat(PerformanceErrorCode): MAX_SCHEDULE_LIMIT_EXCEEDED message 수정 * feat #202 - allowedMethods에 PATCH 메서드 추가 및 allowedOriginPatterns에 도메인 명시 (#203) * [#202] feat(WebConfig): PATCH 메서드 추가 및 allowedOriginPatterns에 도메인 명시 * [#202] feat(WebConfig): 클라이언트 localhost 주소 추가 * [#202] fix(WebConfig): 문자열 오타 수정 * [fix] #204 - SuccessReponse 메서드 타입 수정 및 회원 예매 조회 타입 일치 완료 (#205) * [#204] fix(SuccessResponse): 메서드에 제네릭 타입 명시 * [#204] fix(BookingController): 회원 예매 조회 response 타입 일치하도록 수정 * [#206] fix(TokenErrorCode): 토큰 만료 메시지 status 401로 변경 (#207) * [#190] refactor: 패키지명 변경 - service에서 application으 * [#190] refactor(KakaoSocialService): 변수명 camelCase로 변경 * [#190] refactor(MemberService): 가독성을 위한 소셜로그인 서비스 로직 리팩토링 * [#190] refactor(MemberService): 메서드명을 역할에 부합하도록 수정 * [#190] refactor(MemberController): 변경된 메서드명으로 리팩토링 * [#190] feat(MemberRegistrationService): 서비스 분리 및 회원 등록 서비스 생성 * [#190] feat(AuthenticationService): 서비스 분리 및 인증 서비스 생성 * [#190] feat(SocialLoginService): 서비스 분리 및 소셜로그인 관리 서비스 생성 * [#190] refactor(MemberService): 회원 서비스 분리를 위한 리팩토링 * [#190] refactor(MemberController): 서비스 객체 변경 * [#190] feat(Role): 사용자의 역할을 관리하는 열거형 생성 * [#190] refactor(Users): 열거형 필드 추가 및 protected 기본생성자 추가 * [#190] refactor(LoginSuccessResponse): 로그인 성공 응답 DTO에 역할 필드 추가 * [#190] refactor(Member): 기본생성자의 접근제어자 protected로 수정 및 user 필드 지연 로딩으로 변경 * [#190] feat(AuthenticationService): 역할에 따른 토큰 발급 및 유효성 검사 추가 - 리프레시 토큰이 만료된 경우, generateAccessTokenFromRefreshToken 메서드에서 만료 에러 반환을 추가. - 사용자의 Role (Admin 또는 Member)에 따라 각각의 권한으로 새로운 Access Token을 발급하도록 수정. - generateLoginSuccessResponse 메서드에서 로그인 성공 시 사용자 역할에 따라 인증 객체를 생성하고, Access 및 Refresh 토큰을 발급. * [#190] feat(AdminAuthentication): Admin 사용자 인증 객체 추가 - Spring Security의 UsernamePasswordAuthenticationToken을 상속하여, 관리자 권한을 포함한 인증 객체 생성 가능. * [#190] refactor(JwtTokenProvider): JWT 토큰 발급시 역할 부여 및 검증 로직 개선 - JWT 토큰 발급 시 사용자 정보(memberId)와 역할(role)을 포함한 클레임 생성. - getMemberIdFromJwt 및 getRoleFromJwt 메서드를 통해 토큰에서 사용자 정보와 역할을 추출하는 기능 구현. - "ROLE_" 접두사를 제거한 후, 역할을 추출하여 Role Enum에 맞게 변환하는 로직 추가. * [#190] refactor(SocialLoginService): 사용자 정보 조회 로직 수정 - `generateLoginResponseFromMemberInfo` 메서드에서 회원 정보를 조회할 때 `memberService.findUserByMemberId(memberId)`를 통해 Users 객체를 조회하도록 수정. * [#190] refactor(MemberRegistrationService): 유저 정보로 회원등록시 역할을 MEMBER로 설정하도록 변경 * [#190] feat(MemberService): 회원 ID로 Users 정보 조회 메서드 추가 * [#190] feat(TokenErrorCode): 리프레시 토큰 만료 에러 코드 추가 * [#190] refactor(MemberController): 로그인/회원가입 API에서 역할도 반환하도록 수정 * [#190] refactor(JwtAuthenticationFilter): JWT 토큰 검증 및 인증 설정 로직 개선 - JWT 토큰이 만료되었거나 유효하지 않은 경우 적절한 HTTP 상태 코드(401, 400)를 반환하도록 처리 추가. - `setAuthentication` 메서드를 통해 토큰에서 추출한 memberId와 role로 권한 설정. - `handleInvalidToken` 메서드를 분리하여 토큰 상태에 따른 응답 처리 설정. - `createAuthentication` 메서드에서 role에 따라 Admin 또는 Member 인증 객체 생성. * [#190] chore(.gitignore): application-local.yml을 .gitignore에 추가 * [#190] chore(JwtAuthenticationFilter): 불필요한 import문 삭제 * [#190] chore(TokenService): 코드 가독성을 위한 리팩토링 * [#190] refactor(JwtTokenProvider): SignatureException 에러처리 추가 및 로그 추가 * [#190] refactor(AuthenticationService): 리프레시 토큰을 이용해 새로운 액세스 토큰 발급 시 토큰 검증 구체화 및 로그 추가 * [#190] refactor(TokenErrorCode): 리프레쉬 토큰 관련 에러코드 추가 * [#190] refactor(AuthenticationService): 에러코드 변경 * [#190] feat(SecurityConfig): ADMIN 권한 설정 추가 * [#190] feat(UserFindAllResponse): 유저 테이블의 정보를 반환하는 응답 DTO 생성 * [#190] delete(UserResponse): UserResponse 삭제 * [#190] feat(AdminSuccessCode): 관리자 성공 코드 및 모든 유저 조회 성공메시지 생성 * [#190] feat(AdminService): 관리자가 모든 유저를 불러올 수 있는 서비스 로직 생성 * [#190] feat(AdminController): 관리자가 모든 유저를 불러오는 GET API 생성 * [#190] refactor(AdminController): 토큰을 줘서 역할 검증을 하도록 변경 * [#190] feat(UserResponse): 유저 정보를 객체로 반환하는 응답 DTO 생성 * [#190] refactor: CurrentMemberArgumentResolver로 클래스 이름 수정 * [#190] fix(UserFindAllResponse): Users 객체가 Hibernate 프록시 객체로 반환되어 직렬화되지 못했던 부분 수정 * [#190] chore(GlobalExceptionHandler): ExceptionHandler 분리 및 로그 명시 * [#190] chore(CustomAccessDeniedHandler): 권한 부족 로그 명시 * [#190] chore(CustomJwtAuthenticationEntryPoint): 인증되지 않은 요청 로그 명시 * [#190] refactor(CustomJwtAuthenticationEntryPoint): 토큰에서 추출한 memberId가 DB에 존재하는지 확인하는 로직 추가 * [#190] chore(FileApi): 스웨거 문서 수정 * [#190] chore(AdminApi): 관리자 API 스웨거 문서 작성 * [#190] chore(AdminController): 스웨거 인터페이스 implements 및 메서드 오버라이딩 * [#190] rename(PerformanceMakerPresignedUrlFindAllResponse): 공연 메이커를 위한 presignedUrl을 발급하는 응답 DTO 역할에 맞게 레코드 rename * [#190] rename(UserFindResponse): 기존 UserResponse를 역할에 부합하는 이름으로 rename * [#190] refactor(UserFindAllResponse): rename된 이름으로 변경 * [#190] chore(FileSuccessCode): 성공메시지 구체화 * [#190] refactor(AdminSuccessCode): 캐러셀, 배너 presignedUrl 발급 성공메시지 추가 * [#190] refactor(AdminUserManagementService): AdminUserManagementService로 rename 및 ifPresentOrElse로 가독성 개선 * [#190] refactor(BannerPresignedUrlFindResponse): 배너 presignedUrl 응답 DTO 생성 * [#190] refactor(CarouselPresignedUrlFindAllResponse): 캐러셀 presignedUrl 응답 DTO 생성 * [#190] refactor(FileController): 공연 메이커를 위한 presignedUrl 응답 DTO의 이름 변경으로 인한 반환 레코드명 수정 * [#190] refactor(FileService): 캐러셀/배너 presignedUrl 서비스 로직 구현 및 컨벤션에 맞게 메서드명 수정 * [#190] feat(AdminController): 캐러셀/배너 presignedUrl GET API 구현 * [#190] feat(AdminApi): 캐러셀/배너 presignedUrl GET API 스웨거 명세 작성 * [#190] refactor(FileApi): DTO 이름 변경으로 인한 명세서 수정 --------- Co-authored-by: hyerinhwang-sailin * [feat] #209 - Admin 캐러셀 조회, 수정 API 구현 (#210) * [#209] chore(FileApi): Swagger 명세 수정 * [#209] chore(AdminApi): Swagger 명세 수정 * [#209] refactor(AdminController): 캐러셀 presigned-url 경로명 변경 - /carousel/presigned-url에서 /carousels/presigned-url로 변경 * [#209] feat(CarouselNumber): 캐러셀의 순서를 나타내는 열거형 생성 * [#209] refactor(Promotion): 캐러셀의 순서를 나타내는 필드 추가 * [#209] refactor(AdminSuccessCode): 관리자 권한으로 캐러셀에 등록된 모든 공연 조회 성공 메시지 추가 * [#209] refactor(Promotion): redirectUrl nullable을 true로 변경 * [#209] feat(PromotionSchedulerService): 캐러셀에 등록된 공연이미지 자동 삭제 cron잡을 수행하는 메서드를 새로운 클래스로 이동 * [#209] feat(PromotionRepository): DB에 등록된 모든 Promotion 객체를 가져오는 JPA 메서드 추 * [#209] feat(PromotionService): Promotion 전체 조회 기능 구현 * [#209] feat(PromotionUseCase): Promotion 유스케이스 인터페이스 정의 * [#209] refactor(UserFindAllResponse): User 조회 응답 DTO를 Nested Record로 리팩토링 * [#209] feat(CarouselFindAllResponse): Carousel 조회 응답 DTO를 Nested Record로 생성 * [#209] feat(FileUseCase): Presigned-url 발급 유스케이스 인터페이스 정의 * [#209] refactor(FileService): FileUseCase 구현 및 캐러셀 및 반환값 변경 * [#209] feat(MemberUseCase): 회원 유스케이스 인터페이스 정의 * [#209] refactor(MemberService): 회원 유스케이스 구현 * [#209] feat(UserUseCase): 유저 유스케이스 인터페이스 정의 * [#209] refactor(UserService): 유저 유스케이스 구현 및 DB에 존재하는 모든 유저를 반환하는 메서드 구현 * [#209] refactor(FileController): 유스케이스로 객체 변경 * [#209] delete(AdminUserManagementService): AdminUserManagementService 클래스 삭제 * [#209] feat(AdminUseCase): AdminUseCase 유스케이스 인터페이스 정의 * [#209] feat(AdminService): AdminUseCase 유스케이스 구현 및 캐러셀 넘버로 정렬된 모든 프로모션 객체를 반환하는 메서드 추가 * [#209] feat(AdminFacade): AdminFacade에 파사드 패턴 도입하여 멤버 검증 후 서비스 호출 로직 구현 * [#209] refactor(AdminController): AdminController에 파사드 패턴 적용 및 캐러셀에 등록된 모든 공연 조회 GET API 구현 * [#209] feat(AdminApi): 캐러셀에 등록된 모든 공연 정보 조회 Swagger 명세 추가 * [#209] feat(AdminSuccessCode): 관리자 권한으로 수정 성공 메시지 추가 * [#209] chore: 포맷터 작동 * [#209] feat(Promotion): 공연 수정 도메인 메서드 추가 * [#209] feat(CarouselModifyRequest): 공연 수정 요청 DTO 생성 * [#209] feat(CarouselModifyAllResponse): 공연 수정 응답 DTO 생성 * [#209] delete(CarouselModifyRequest): 캐러셀 수정 요청 DTO 삭제 * [#209] rename(CarouselProcessAllResponse): 캐러셀 수정 응답 DTO 네이밍 변경 * [#209] feat(CarouselProcessRequest): 캐러셀 등록/수정/삭제 요청 DTO 생성 * [#209] feat(PromotionErrorCode): Promotion 에러코드 생성 * [#209] feat(AdminUseCase): 프로모션 등록/수정/삭제 메서드 선언 * [#209] feat(PerformanceUseCase): findById 메서드 선언 * [#209] feat(PerformanceService): findById 메서드 구현 * [#209] feat(PromotionUseCase): 프로모션 등록/수정/삭제/캐러셀 넘버 반환 메서드 선언 * [#209] feat(PromotionService): 프로모션 등록/수정/삭제/캐러셀 넘버 반환 메서드 구현 * [#209] feat(PromotionRepository): 프로모션 삭제/캐러셀 넘버 반환 spring data jpa 메서드 구현 * [#209] feat(AdminService): 캐러셀 등록/수정/삭제 후 캐러셀 번호에 따라 정렬하는 서비스 로직 구현 * [#209] rename(AdminUseCase): 메서드 네이밍 변경 * [#209] feat(AdminFacade): 파사드 패턴을 적용해 각 도메인에 맞게 캐러셀 등록/수정/삭제를 하도록 구현 * [#209] feat(AdminController): 캐러셀 등록/수정/삭제 API 구현 * [#209] feat(AdminApi): 캐러셀 등록/수정/삭제 API Swagger 명세 * [#209] fix(PromotionRepository): JPQL로 Enum 필드만 반환하도록 수정 * [#209] refactor: 패키지 이동 * [#209] feat(PromotionHandleRequest): PromotionHandleRequest 인터페이스 분리 생성 * [#209] delete(CarouselProcessRequest): 인터페이스 삭제 * [#209] chore(AdminFacade): import문 경로 변경 * [#209] refactor: admin 패키지 도메인 패키지에서 분리 * [fix] #198 - isBooking update 안되는 이슈 해결 (#199) * [#198] fix(Schedule): updateIsBooking 로직 추가 * [#198] fix(ScheduleService): IsBooking update 로직 변경 및 불필요한 주석 제거 * [#198] fix(PerformanceService): getPerformanceDetail readOnly 설정 변경 및 불필요한 주석 제거 * [#198] feat(BeatApplication): EnableAsync 어노테이션 추가 * [#198] feat(SchedulerConfig): TaskScheduler 스레드 풀 크기 설정 * [#198] feat(JobSchedulerService): TaskScheduler 서비스 구현 * [#198] feat(PerformanceManagementService): 공연 생성, 삭제에 따른 스케쥴링 리스트 변화 구현 * [#198] feat(PerformanceModifyService): 공연 수정에 따른 스케쥴링 리스트 변화 구현 * [#198] feat(ScheduleRepository): isBooking true인 공연 조회 로직 추가 * [#198] fix(ScheduleService): isBooking 관련 불필요한 로직 삭제 * [#198] fix(PerformanceService): 조회 메소드 annotation @Transactional(readOnly = true)로 변경 * [#198] refactor(GuestBookingService): 매진 여부 확인 메소드 분리 및 log 수정 * [#198] refactor(MemberBookingService): 매진 여부 확인 메소드 분리 및 log 수정 * [#198] feat(TicketService): 예매취소 시 isBooking update 구현 * [#198] chore(PerformanceService): 코드 포맷터 적용 * [#198] remove(SchedulerConfig): SchedulerConfig 삭제 * [#198] refactor(TicketService): isBooking update 검증 추가 및 코드 포맷팅 적용 * [#212] fix(CurrentMember): 파라미터 옵션 hidden으로 설정 (#213) * [#211] fix(BookingRepository): 예매자 존재 여부 확인 로직 변경 (#216) * [fix] #211 - 스케쥴 날짜 및 티켓수 변경 관련 에러 처리 (#214) * [#211] fix(PerformanceErrorCode):PAST_SCHEDULE_NOT_ALLOWED 추가 및 코드 포맷팅 적용 * [#211] fix(PerformanceManagementService):공연 생성 시 과거 스케쥴 포함 방지 에러처리 추가 및 코드 포맷팅 적용 * [#211] fix(PerformanceModifyService):공연 수정 시 과거 스케쥴 포함 방지 에러처리 추가 및 코드 포맷팅 적용 * [#211] fix(PerformanceErrorCode): 공연 수정 관련 에러코드 추가 * [#211] fix(PerformanceModifyService): 공연 날짜 및 티켓수 수정으로 인한 예외상황 고려해 검증 로직 추가 * [#211] chore(PerformanceErrorCode): 에러메시지 수정 * [fix] #217 - CORS 허용 도메인 환경변수 처리 완료 (#218) * [#217] fix(application-dev.yml): DEV 환경에서 cors 허용 도메인 환경변수 처리 * [#217] fix(application-prod.yml): PROD 환경에서 cors 허용 도메인 환경변수 처리 * [#217] refactor(WebConfig): allowedOrigins 환경변수 주입 설정 * [#217] chore: CI 스크립트에 허용 도메인 환경변수 추가 * [fix] #219 - 캐러셀 번호가 중복된 항목 중에서 promotionId가 다른 경우에만 삭제하도록 수정 (#220) * [#219] fix(AdminFacade): 중복된 캐러셀 번호 처리 및 삭제 로직 수정 - Promotion ID가 다른 중복된 캐러셀 번호만 삭제하도록 수정 - 삭제할 캐러셀 번호와 중복된 캐러셀 번호를 분리하여 처리 - 중복된 캐러셀 번호를 처리하는 로직을 메서드로 분리하여 가독성 향상 - Promotion 수정 및 생성 요청을 명확하게 분리하여 처리 * [#219] feat(AdminService): 중복된 캐러셀 번호 처리 및 프로모션 삭제 로직 추가 * [#219] refactor(AdminUseCase): 메서드 시그니처 변경 * [#219] refactor(PromotionService): 캐러셀넘버로 Promotion 객체를 찾는 메서드 구현 및 캐러셀 넘버로 삭제 시 리스트 형태로 주도록 변경 * [#219] refactor(PromotionUseCase): 메서드 시그니처 변경 및 캐러셀 넘버로 Promotion 객체를 조회하는 메서드 선언 * [#219] refactor(PromotionRepository): 캐러셀 번호 기반 프로모션 삭제 로직 변경 및 조회 기능 추가 - `deleteByCarouselNumbers` 메서드 변: 여러 캐러셀 번호에 해당하는 프로모션을 한 경에 삭제하도록 로직 변경 - `findByCarouselNumber` 메서드 추가: 캐러셀 번호로 프로모션을 조회하는 기능 구현 - JPA 쿼리 최적화를 위해 `@Modifying` 및 `@Transactional` 어노테이션 추가 * [refactor] #221 - 메인페이지에서 캐러셀 응답 시 캐러셀 번호로 정렬해서 주도록 변경 및 메인 페이지 조회 코드 최적화 (#222) * [#221] rename: DTO 이름 변경 및 import문 최신화 * [#221] chore(AdminApi): 통일성을 위해 mapping 어노테이션 삭제 * [#221] rename(HomeFindRequest): 요청 DTO 네이밍 구체화 * [#221] rename(HomeFindAllResponse): 응답 DTO 네이밍 구체화 * [#221] refactor(PerformanceService): getHomePerformanceList, getPromotions 메서드 이동 및 코드 포맷팅 적용 * [#221] feat(HomeService): 공연 및 홍보 조회 서비스 로직 최적화 * [#221] feat(ScheduleService): 공연의 회차 중 가장 dueDate가 적은 회차의 dueDate를 반환하는 메서드 구현 * [#221] refactor(HomePromotionDetail): 정적 팩토리 메서드 내에서 초기화해서 return 하도록 변경 * [#221] refactor(HomePerformanceDetail): 정적 팩토리 메서드 내에서 초기화해서 return 하도록 변경 * [#221] feat(HomeApi): Home API 스웨거 명세서 작성 * [#221] refactor(HomeController): 로직 최적화 * [#221] fix(HomeService): 음수는 내림차순, 양수는 오름차순으로 정렬하도록 수정 * [#223] HOTFIX: 캐러셀 삭제 시 promotionId로 판단하도록 수정 (#224) * [#225] HOTFIX: ROLE 접두사 2번 붙는 오류 해결 (#226) * [HOTFIX] #227 - 권한 체크를 위한 로그 추가 (#228) * [#227] HOTFIX: 권한 체크를 위한 로그 추가 * [#227] chore: 임시 비활성화 * HOTFIX #229 - 회원 등록 후 flush()를 호출하여 DB에 반영 (#230) * [#229] fix(SocialLoginService): 회원 등록 후 flush()를 호출하여 DB에 반영 * [#229] refactor: flush 호출 위치 변경 * [#231] HOTFIX: role 관련 상세로그 추가 (#232) * [HOTFIX] #233 - memberId로 User객체를 잘못 조회했던 문제 해결 (#234) * [#233] refactor(MemberUseCase): 메서드 이름 변경 및 추가 메서드 선언 * [#233] refactor(AdminFacade): 메서드 이름 변경사항 반영 * [#233] refactor(AdminFacade): findUserByMemberId 삭제 및 메서드 이름 변경 및 읽기 전용 트랜잭션 선언 * [#233] feat(UserUseCase): userId로 User 객체를 조회하는 메서드 선언 * [#233] feat(UserService): userId로 User 객체를 조회하는 메서드 구현 * [#233] fix(SocialLoginService): memberId로 Member 객체를 조회 후 그 회원의 userId로 User 객체를 조회하도록 수정 * [#233] refactor(SocialLoginService): Member 객체에서 직접 Users 객체를 참조하도록 변경 * [#235] fix(Token): 초 단위에 맞게 TTL 변경 (#236) * [chore] #237 - Swagger Versioning 업데이트, 서버 url 명시, 사용하지 않는 파일 삭제 (#238) * [#237] delete(HELP.md): 파일 삭제 * [#237] chore: 버저닝 업데이트 및 url 명시 완료 * chore: 일시적으로 주석처리 --------- Co-authored-by: hyerinhwang-sailin --- .github/workflows/dev-CI.yml | 20 +- .github/workflows/prod-CI.yml | 20 +- .gitignore | 3 + HELP.md | 30 - README.md | 2 +- build.gradle | 2 +- src/main/java/com/beat/BeatApplication.java | 4 + .../beat/admin/adapter/in/api/AdminApi.java | 134 ++++ .../admin/adapter/in/api/AdminController.java | 79 +++ .../beat/admin/application/AdminService.java | 89 +++ .../dto/request/CarouselHandleRequest.java | 29 + .../dto/request/PromotionHandleRequest.java | 28 + .../dto/response/CarouselFindAllResponse.java | 41 ++ .../response/CarouselHandleAllResponse.java | 36 ++ .../dto/response/UserFindAllResponse.java | 28 + .../admin/exception/AdminSuccessCode.java | 19 + .../com/beat/admin/facade/AdminFacade.java | 111 ++++ .../com/beat/admin/port/in/AdminUseCase.java | 14 + .../domain/booking/api/BookingController.java | 2 +- .../domain/booking/api/TicketController.java | 21 +- .../GuestBookingRetrieveService.java | 2 +- .../application/GuestBookingService.java | 22 +- .../MemberBookingRetrieveService.java | 2 +- .../application/MemberBookingService.java | 20 +- .../booking/application/TicketService.java | 267 ++++---- .../application/dto/GuestBookingRequest.java | 7 +- .../application/dto/GuestBookingResponse.java | 7 +- .../dto/GuestBookingRetrieveResponse.java | 7 +- .../application/dto/MemberBookingRequest.java | 3 +- .../dto/MemberBookingResponse.java | 7 +- .../dto/MemberBookingRetrieveResponse.java | 7 +- ...eRequest.java => TicketCancelRequest.java} | 6 +- .../booking/application/dto/TicketDetail.java | 8 +- .../application/dto/TicketUpdateDetail.java | 8 +- .../domain/booking/dao/BookingRepository.java | 51 +- .../domain/booking/dao/TicketRepository.java | 8 +- .../beat/domain/booking/domain/Booking.java | 24 +- .../domain/booking/domain/BookingStatus.java | 14 + .../booking/exception/BookingSuccessCode.java | 2 +- .../booking/exception/TicketErrorCode.java | 14 + .../beat/domain/cast/dao/CastRepository.java | 4 + .../domain/cast/exception/CastErrorCode.java | 1 + .../domain/member/api/MemberController.java | 12 +- .../application/AuthenticationService.java | 134 ++++ .../MemberRegistrationService.java | 49 ++ .../member/application/MemberService.java | 152 +---- .../application/SocialLoginService.java | 119 ++++ .../com/beat/domain/member/domain/Member.java | 16 +- .../member/dto/LoginSuccessResponse.java | 8 +- .../domain/member/port/in/MemberUseCase.java | 14 + .../beat/domain/performance/api/HomeApi.java | 33 + .../performance/api/HomeController.java | 39 +- .../api/PerformanceController.java | 42 +- .../performance/application/HomeService.java | 71 +++ .../PerformanceManagementService.java | 362 ++++++----- .../application/PerformanceModifyService.java | 603 ++++++++++++++++++ .../application/PerformanceService.java | 483 ++++++-------- .../application/PerformanceUpdateService.java | 165 ----- .../dto/BookingPerformanceDetailSchedule.java | 16 - .../dto/MakerPerformanceDetail.java | 18 - .../dto/PerformanceDetailCast.java | 12 - .../dto/PerformanceDetailResponse.java | 43 -- .../dto/PerformanceDetailSchedule.java | 13 - .../dto/PerformanceDetailStaff.java | 12 - .../BookingPerformanceDetailResponse.java | 6 +- ...kingPerformanceDetailScheduleResponse.java | 17 + .../dto/create/PerformanceImageRequest.java | 6 + .../dto/create/PerformanceImageResponse.java | 16 + .../dto/create/PerformanceRequest.java | 3 +- .../dto/create/PerformanceResponse.java | 9 +- .../dto/home/HomeFindAllResponse.java | 12 + ...{HomeRequest.java => HomeFindRequest.java} | 4 +- .../dto/home/HomePerformanceDetail.java | 36 +- .../dto/home/HomePromotionDetail.java | 24 +- .../application/dto/home/HomeResponse.java | 12 - .../MakerPerformanceDetailResponse.java | 20 + .../MakerPerformanceResponse.java | 6 +- .../PerformanceModifyDetailResponse.java} | 18 +- .../dto/modify/PerformanceModifyRequest.java | 33 + .../dto/modify/PerformanceModifyResponse.java | 83 +++ .../dto/modify/cast/CastModifyRequest.java | 12 + .../dto/modify/cast/CastModifyResponse.java | 11 + .../PerformanceImageModifyRequest.java | 10 + .../PerformanceImageModifyResponse.java | 11 + .../schedule/ScheduleModifyRequest.java | 13 + .../schedule/ScheduleModifyResponse.java | 16 + .../dto/modify/staff/StaffModifyRequest.java | 12 + .../dto/modify/staff/StaffModifyResponse.java | 11 + .../PerformanceDetailCastResponse.java | 12 + .../PerformanceDetailImageResponse.java | 10 + .../PerformanceDetailResponse.java | 63 ++ .../PerformanceDetailScheduleResponse.java | 15 + .../PerformanceDetailStaffResponse.java | 12 + .../dto/update/CastUpdateRequest.java | 8 - .../dto/update/CastUpdateResponse.java | 12 - .../dto/update/PerformanceUpdateRequest.java | 27 - .../dto/update/PerformanceUpdateResponse.java | 37 -- .../dto/update/ScheduleUpdateRequest.java | 10 - .../dto/update/ScheduleUpdateResponse.java | 17 - .../dto/update/StaffUpdateRequest.java | 8 - .../dto/update/StaffUpdateResponse.java | 12 - .../dao/PerformanceImageRepository.java | 14 + .../performance/domain/Performance.java | 16 +- .../performance/domain/PerformanceImage.java | 41 ++ .../exception/PerformanceErrorCode.java | 30 +- .../exception/PerformanceImageErrorCode.java | 16 + .../port/in/PerformanceUseCase.java | 7 + .../PromotionSchedulerService.java | 44 ++ .../application/PromotionService.java | 57 ++ .../promotion/dao/PromotionRepository.java | 19 +- .../promotion/domain/CarouselNumber.java | 18 + .../domain/promotion/domain/Promotion.java | 90 ++- .../exception/PromotionErrorCode.java | 15 + .../promotion/port/in/PromotionUseCase.java | 21 + .../schedule/application/ScheduleService.java | 33 +- .../schedule/dao/ScheduleRepository.java | 9 +- .../beat/domain/schedule/domain/Schedule.java | 7 + .../schedule/domain/ScheduleNumber.java | 9 +- .../schedule/exception/ScheduleErrorCode.java | 1 + .../domain/staff/dao/StaffRepository.java | 4 + .../staff/exception/StaffErrorCode.java | 1 + .../domain/user/application/UserService.java | 33 +- .../user/application/dto/UserResponse.java | 7 - .../com/beat/domain/user/domain/Role.java | 33 + .../com/beat/domain/user/domain/Users.java | 20 +- .../beat/domain/user/port/in/UserUseCase.java | 11 + .../global/auth/annotation/CurrentMember.java | 3 + .../KakaoSocialService.java | 7 +- .../SocialService.java | 2 +- .../auth/jwt/application/TokenService.java | 17 +- .../auth/jwt/exception/TokenErrorCode.java | 13 +- .../jwt/filter/JwtAuthenticationFilter.java | 120 +++- .../auth/jwt/provider/JwtTokenProvider.java | 185 ++++-- .../com/beat/global/auth/redis/Token.java | 2 +- ...ava => CurrentMemberArgumentResolver.java} | 2 +- .../auth/security/AdminAuthentication.java | 18 + .../security/CustomAccessDeniedHandler.java | 6 + .../CustomJwtAuthenticationEntryPoint.java | 10 +- .../global/common/config/SecurityConfig.java | 29 +- .../beat/global/common/config/WebConfig.java | 38 +- .../global/common/dto/SuccessResponse.java | 8 +- .../handler/GlobalExceptionHandler.java | 57 +- .../application/JobSchedulerService.java | 120 ++++ .../beat/global/external/s3/api/FileApi.java | 41 ++ .../external/s3/api/FileController.java | 44 ++ .../external/s3/application/FileService.java | 115 ++++ .../dto/BannerPresignedUrlFindResponse.java | 9 + .../CarouselPresignedUrlFindAllResponse.java | 11 + ...manceMakerPresignedUrlFindAllResponse.java | 11 + .../external/s3/{ => config}/S3Config.java | 2 +- .../s3/controller/FileController.java | 37 -- .../s3/exception/FileSuccessCode.java | 13 + .../external/s3/port/in/FileUseCase.java | 17 + .../external/s3/service/FileService.java | 80 --- .../beat/global/swagger/SwaggerConfig.java | 10 +- src/main/resources/application-dev.yml | 14 +- src/main/resources/application-local.yml | 21 - src/main/resources/application-prod.yml | 15 +- .../GuestBookingServiceConcurrencyTest.java | 5 +- 159 files changed, 4212 insertions(+), 1689 deletions(-) delete mode 100644 HELP.md create mode 100644 src/main/java/com/beat/admin/adapter/in/api/AdminApi.java create mode 100644 src/main/java/com/beat/admin/adapter/in/api/AdminController.java create mode 100644 src/main/java/com/beat/admin/application/AdminService.java create mode 100644 src/main/java/com/beat/admin/application/dto/request/CarouselHandleRequest.java create mode 100644 src/main/java/com/beat/admin/application/dto/request/PromotionHandleRequest.java create mode 100644 src/main/java/com/beat/admin/application/dto/response/CarouselFindAllResponse.java create mode 100644 src/main/java/com/beat/admin/application/dto/response/CarouselHandleAllResponse.java create mode 100644 src/main/java/com/beat/admin/application/dto/response/UserFindAllResponse.java create mode 100644 src/main/java/com/beat/admin/exception/AdminSuccessCode.java create mode 100644 src/main/java/com/beat/admin/facade/AdminFacade.java create mode 100644 src/main/java/com/beat/admin/port/in/AdminUseCase.java rename src/main/java/com/beat/domain/booking/application/dto/{TicketDeleteRequest.java => TicketCancelRequest.java} (51%) create mode 100644 src/main/java/com/beat/domain/booking/domain/BookingStatus.java create mode 100644 src/main/java/com/beat/domain/booking/exception/TicketErrorCode.java create mode 100644 src/main/java/com/beat/domain/member/application/AuthenticationService.java create mode 100644 src/main/java/com/beat/domain/member/application/MemberRegistrationService.java create mode 100644 src/main/java/com/beat/domain/member/application/SocialLoginService.java create mode 100644 src/main/java/com/beat/domain/member/port/in/MemberUseCase.java create mode 100644 src/main/java/com/beat/domain/performance/api/HomeApi.java create mode 100644 src/main/java/com/beat/domain/performance/application/HomeService.java create mode 100644 src/main/java/com/beat/domain/performance/application/PerformanceModifyService.java delete mode 100644 src/main/java/com/beat/domain/performance/application/PerformanceUpdateService.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailCast.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailStaff.java rename src/main/java/com/beat/domain/performance/application/dto/{ => bookingPerformanceDetail}/BookingPerformanceDetailResponse.java (82%) create mode 100644 src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailScheduleResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageRequest.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/home/HomeFindAllResponse.java rename src/main/java/com/beat/domain/performance/application/dto/home/{HomeRequest.java => HomeFindRequest.java} (70%) delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/home/HomeResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceDetailResponse.java rename src/main/java/com/beat/domain/performance/application/dto/{ => makerPerformance}/MakerPerformanceResponse.java (55%) rename src/main/java/com/beat/domain/performance/application/dto/{PerformanceEditResponse.java => modify/PerformanceModifyDetailResponse.java} (80%) create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyRequest.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyRequest.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyRequest.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyRequest.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyRequest.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailCastResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailImageResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailScheduleResponse.java create mode 100644 src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailStaffResponse.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateRequest.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateResponse.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateRequest.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateResponse.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateRequest.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateResponse.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateRequest.java delete mode 100644 src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateResponse.java create mode 100644 src/main/java/com/beat/domain/performance/dao/PerformanceImageRepository.java create mode 100644 src/main/java/com/beat/domain/performance/domain/PerformanceImage.java create mode 100644 src/main/java/com/beat/domain/performance/exception/PerformanceImageErrorCode.java create mode 100644 src/main/java/com/beat/domain/performance/port/in/PerformanceUseCase.java create mode 100644 src/main/java/com/beat/domain/promotion/application/PromotionSchedulerService.java create mode 100644 src/main/java/com/beat/domain/promotion/application/PromotionService.java create mode 100644 src/main/java/com/beat/domain/promotion/domain/CarouselNumber.java create mode 100644 src/main/java/com/beat/domain/promotion/exception/PromotionErrorCode.java create mode 100644 src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java delete mode 100644 src/main/java/com/beat/domain/user/application/dto/UserResponse.java create mode 100644 src/main/java/com/beat/domain/user/domain/Role.java create mode 100644 src/main/java/com/beat/domain/user/port/in/UserUseCase.java rename src/main/java/com/beat/global/auth/client/{service => application}/KakaoSocialService.java (96%) rename src/main/java/com/beat/global/auth/client/{service => application}/SocialService.java (83%) rename src/main/java/com/beat/global/auth/resolver/{CurrentUserArgumentResolver.java => CurrentMemberArgumentResolver.java} (94%) create mode 100644 src/main/java/com/beat/global/auth/security/AdminAuthentication.java create mode 100644 src/main/java/com/beat/global/common/scheduler/application/JobSchedulerService.java create mode 100644 src/main/java/com/beat/global/external/s3/api/FileApi.java create mode 100644 src/main/java/com/beat/global/external/s3/api/FileController.java create mode 100644 src/main/java/com/beat/global/external/s3/application/FileService.java create mode 100644 src/main/java/com/beat/global/external/s3/application/dto/BannerPresignedUrlFindResponse.java create mode 100644 src/main/java/com/beat/global/external/s3/application/dto/CarouselPresignedUrlFindAllResponse.java create mode 100644 src/main/java/com/beat/global/external/s3/application/dto/PerformanceMakerPresignedUrlFindAllResponse.java rename src/main/java/com/beat/global/external/s3/{ => config}/S3Config.java (96%) create mode 100644 src/main/java/com/beat/global/external/s3/exception/FileSuccessCode.java create mode 100644 src/main/java/com/beat/global/external/s3/port/in/FileUseCase.java delete mode 100644 src/main/java/com/beat/global/external/s3/service/FileService.java delete mode 100644 src/main/resources/application-local.yml diff --git a/.github/workflows/dev-CI.yml b/.github/workflows/dev-CI.yml index 9e682ab2..3776a7c6 100644 --- a/.github/workflows/dev-CI.yml +++ b/.github/workflows/dev-CI.yml @@ -53,6 +53,10 @@ jobs: DEV_COOLSMS_KEY: ${{ secrets.DEV_COOLSMS_KEY }} DEV_COOLSMS_NUMBER: ${{ secrets.DEV_COOLSMS_NUMBER }} DEV_COOLSMS_SECRET: ${{ secrets.DEV_COOLSMS_SECRET }} + DEV_ACCESS_TOKEN_EXPIRE_TIME: ${{ secrets.DEV_ACCESS_TOKEN_EXPIRE_TIME }} + DEV_REFRESH_TOKEN_EXPIRE_TIME: ${{ secrets.DEV_REFRESH_TOKEN_EXPIRE_TIME }} + DEV_ALLOWED_ORIGINS: ${{ secrets.DEV_ALLOWED_ORIGINS }} + DEV_SERVER_URL: ${{ secrets.DEV_SERVER_URL }} run: | cd ./src/main/resources envsubst < application-dev.yml > application-dev.tmp.yml && mv application-dev.tmp.yml application-dev.yml @@ -81,11 +85,11 @@ jobs: docker build -f Dockerfile-dev --platform linux/amd64 -t hoonyworld/beat-dev . docker push hoonyworld/beat-dev - # Trigger Jenkins job - Jenkins 작업 트리거 - - name: Trigger Jenkins job - uses: appleboy/jenkins-action@master - with: - url: ${{ secrets.DEV_WEBHOOK_URL }} - user: "beat" - token: ${{ secrets.DEV_JENKINS_API_TOKEN }} - job: "beat-project" \ No newline at end of file +# # Trigger Jenkins job - Jenkins 작업 트리거 +# - name: Trigger Jenkins job +# uses: appleboy/jenkins-action@master +# with: +# url: ${{ secrets.DEV_WEBHOOK_URL }} +# user: "beat" +# token: ${{ secrets.DEV_JENKINS_API_TOKEN }} +# job: "beat-project" \ No newline at end of file diff --git a/.github/workflows/prod-CI.yml b/.github/workflows/prod-CI.yml index c478ff71..deed64ad 100644 --- a/.github/workflows/prod-CI.yml +++ b/.github/workflows/prod-CI.yml @@ -53,6 +53,10 @@ jobs: PROD_COOLSMS_KEY: ${{ secrets.PROD_COOLSMS_KEY }} PROD_COOLSMS_NUMBER: ${{ secrets.PROD_COOLSMS_NUMBER }} PROD_COOLSMS_SECRET: ${{ secrets.PROD_COOLSMS_SECRET }} + PROD_ACCESS_TOKEN_EXPIRE_TIME: ${{ secrets.PROD_ACCESS_TOKEN_EXPIRE_TIME }} + PROD_REFRESH_TOKEN_EXPIRE_TIME: ${{ secrets.PROD_REFRESH_TOKEN_EXPIRE_TIME }} + PROD_ALLOWED_ORIGINS: ${{ secrets.PROD_ALLOWED_ORIGINS }} + PROD_SERVER_URL: ${{ secrets.PROD_SERVER_URL }} run: | cd ./src/main/resources envsubst < application-prod.yml > application-prod.tmp.yml && mv application-prod.tmp.yml application-prod.yml @@ -81,11 +85,11 @@ jobs: docker build --platform linux/amd64 -t donghoon0203/beat-prod . docker push donghoon0203/beat-prod - # Trigger Jenkins job - Jenkins 작업 트리거 - - name: Trigger Jenkins job - uses: appleboy/jenkins-action@master - with: - url: ${{ secrets.PROD_WEBHOOK_URL }} - user: "beat" - token: ${{ secrets.PROD_JENKINS_API_TOKEN }} - job: "beat-project" +# # Trigger Jenkins job - Jenkins 작업 트리거 +# - name: Trigger Jenkins job +# uses: appleboy/jenkins-action@master +# with: +# url: ${{ secrets.PROD_WEBHOOK_URL }} +# user: "beat" +# token: ${{ secrets.PROD_JENKINS_API_TOKEN }} +# job: "beat-project" diff --git a/.gitignore b/.gitignore index e0586444..bf9eeb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -178,3 +178,6 @@ Temporary Items # End of https://www.toptal.com/developers/gitignore/api/intellij,java,macos.gradle/ .idea/ + +# Ignore application-local.yml +src/main/resources/application-local.yml \ No newline at end of file diff --git a/HELP.md b/HELP.md deleted file mode 100644 index 8826d98e..00000000 --- a/HELP.md +++ /dev/null @@ -1,30 +0,0 @@ -# Getting Started - -### Reference Documentation -For further reference, please consider the following sections: - -* [Official Gradle documentation](https://docs.gradle.org) -* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.3.1/gradle-plugin/reference/html/) -* [Create an OCI image](https://docs.spring.io/spring-boot/docs/3.3.1/gradle-plugin/reference/html/#build-image) -* [Spring Web](https://docs.spring.io/spring-boot/docs/3.3.1/reference/htmlsingle/index.html#web) -* [Spring Data JPA](https://docs.spring.io/spring-boot/docs/3.3.1/reference/htmlsingle/index.html#data.sql.jpa-and-spring-data) -* [Spring Security](https://docs.spring.io/spring-boot/docs/3.3.1/reference/htmlsingle/index.html#web.security) -* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/3.3.1/reference/htmlsingle/index.html#using.devtools) - -### Guides -The following guides illustrate how to use some features concretely: - -* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) -* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) -* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/) -* [Accessing data with MySQL](https://spring.io/guides/gs/accessing-data-mysql/) -* [Accessing Data with JPA](https://spring.io/guides/gs/accessing-data-jpa/) -* [Securing a Web Application](https://spring.io/guides/gs/securing-web/) -* [Spring Boot and OAuth2](https://spring.io/guides/tutorials/spring-boot-oauth2/) -* [Authenticating a User with LDAP](https://spring.io/guides/gs/authenticating-ldap/) - -### Additional Links -These additional references should also help you: - -* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle) - diff --git a/README.md b/README.md index 1329a49e..675db961 100644 --- a/README.md +++ b/README.md @@ -114,4 +114,4 @@ BEAT와 함께 효율적이고 체계적으로 공연을 관리해 볼까요? ## 👥 Contributors -- [BEAT Client Repository](https://github.com/TEAM-BEAT/BEAT-Client) \ No newline at end of file +- [BEAT Client Repository](https://github.com/TEAM-BEAT/BEAT-Client) diff --git a/build.gradle b/build.gradle index 82a3303b..dd665e45 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ repositories { dependencies { // Spring implementation 'org.springframework.boot:spring-boot-starter-web' - developmentOnly 'org.springframework.boot:spring-boot-devtools' +// developmentOnly 'org.springframework.boot:spring-boot-devtools' implementation 'org.springframework.boot:spring-boot-starter-actuator' // Database diff --git a/src/main/java/com/beat/BeatApplication.java b/src/main/java/com/beat/BeatApplication.java index 263f8261..da272990 100644 --- a/src/main/java/com/beat/BeatApplication.java +++ b/src/main/java/com/beat/BeatApplication.java @@ -5,9 +5,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignAutoConfiguration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableFeignClients +@EnableScheduling +@EnableAsync @ImportAutoConfiguration({FeignAutoConfiguration.class}) public class BeatApplication { diff --git a/src/main/java/com/beat/admin/adapter/in/api/AdminApi.java b/src/main/java/com/beat/admin/adapter/in/api/AdminApi.java new file mode 100644 index 00000000..f5fb2ea6 --- /dev/null +++ b/src/main/java/com/beat/admin/adapter/in/api/AdminApi.java @@ -0,0 +1,134 @@ +package com.beat.admin.adapter.in.api; + +import com.beat.admin.application.dto.response.CarouselFindAllResponse; +import com.beat.admin.application.dto.response.UserFindAllResponse; +import com.beat.admin.application.dto.request.CarouselHandleRequest; +import com.beat.admin.application.dto.response.CarouselHandleAllResponse; +import com.beat.global.auth.annotation.CurrentMember; +import com.beat.global.common.dto.ErrorResponse; +import com.beat.global.common.dto.SuccessResponse; +import com.beat.global.external.s3.application.dto.BannerPresignedUrlFindResponse; +import com.beat.global.external.s3.application.dto.CarouselPresignedUrlFindAllResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@Tag(name = "Admin", description = "관리자 제어 API") +public interface AdminApi { + + @Operation(summary = "유저 정보 조회", description = "관리자가 유저들의 정보를 조회하는 GET API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "관리자 권한으로 모든 유저 조회에 성공하였습니다.", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "회원이 없습니다", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + } + ) + ResponseEntity> readAllUsers( + @CurrentMember Long memberId + ); + + @Operation(summary = "캐러셀에 업로드 할 이미지에 대한 presigned URL 발급", description = "관리자가 캐러셀에 업로드 할 이미지에 대한 presigned URL을 발급 받는 GET API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "캐러셀 Presigned URL 발급 성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "회원이 없습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + } + ) + ResponseEntity> createAllCarouselPresignedUrls( + @CurrentMember Long memberId, + @RequestParam List carouselImages + ); + + @Operation(summary = "배너에 업로드 할 이미지에 대한 presigned URL 발급", description = "관리자가 배너에 업로드 할 이미지에 대한 presigned URL을 발급 받는 GET API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "배너 Presigned URL 발급 성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "회원이 없습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + } + ) + ResponseEntity> createBannerPresignedUrl( + @CurrentMember Long memberId, + @RequestParam String bannerImage + ); + + @Operation(summary = "캐러셀에 등록된 모든 공연 정보 조회", description = "관리자가 현재 캐러셀에 등록된 모든 공연 정보를 조회하는 GET API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "관리자 권한으로 현재 캐러셀에 등록된 모든 공연 조회에 성공하였습니다.", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "회원이 없습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + } + ) + ResponseEntity> readAllCarouselImages( + @CurrentMember Long memberId + ); + + @Operation(summary = "캐러셀 이미지 수정", description = "관리자가 캐러셀 이미지를 수정하는 PUT API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "캐러셀 이미지 수정 성공", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "회원이 없습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "해당 홍보 정보를 찾을 수 없습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ), + @ApiResponse( + responseCode = "404", + description = "해당 공연 정보를 찾을 수 없습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + } + ) + ResponseEntity> processCarouselImages( + @CurrentMember Long memberId, + @RequestBody CarouselHandleRequest request + ); +} diff --git a/src/main/java/com/beat/admin/adapter/in/api/AdminController.java b/src/main/java/com/beat/admin/adapter/in/api/AdminController.java new file mode 100644 index 00000000..20dd1f31 --- /dev/null +++ b/src/main/java/com/beat/admin/adapter/in/api/AdminController.java @@ -0,0 +1,79 @@ +package com.beat.admin.adapter.in.api; + +import com.beat.admin.application.dto.response.CarouselFindAllResponse; +import com.beat.admin.application.dto.request.CarouselHandleRequest; +import com.beat.admin.application.dto.response.CarouselHandleAllResponse; +import com.beat.admin.exception.AdminSuccessCode; +import com.beat.admin.application.dto.response.UserFindAllResponse; +import com.beat.admin.facade.AdminFacade; +import com.beat.global.auth.annotation.CurrentMember; +import com.beat.global.common.dto.SuccessResponse; +import com.beat.global.external.s3.application.dto.BannerPresignedUrlFindResponse; +import com.beat.global.external.s3.application.dto.CarouselPresignedUrlFindAllResponse; + +import lombok.RequiredArgsConstructor; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/admin") +@RequiredArgsConstructor +public class AdminController implements AdminApi { + + private final AdminFacade adminFacade; + + @Override + @GetMapping("/users") + public ResponseEntity> readAllUsers(@CurrentMember Long memberId) { + UserFindAllResponse response = adminFacade.checkMemberAndFindAllUsers(memberId); + return ResponseEntity.status(HttpStatus.OK) + .body(SuccessResponse.of(AdminSuccessCode.FETCH_ALL_USERS_SUCCESS, response)); + } + + @Override + @GetMapping("/carousels/presigned-url") + public ResponseEntity> createAllCarouselPresignedUrls( + @CurrentMember Long memberId, @RequestParam List carouselImages) { + CarouselPresignedUrlFindAllResponse response = adminFacade.checkMemberAndIssueAllPresignedUrlsForCarousel( + memberId, carouselImages); + return ResponseEntity.ok(SuccessResponse.of(AdminSuccessCode.CAROUSEL_PRESIGNED_URL_ISSUED, response)); + } + + @Override + @GetMapping("/banner/presigned-url") + public ResponseEntity> createBannerPresignedUrl( + @CurrentMember Long memberId, @RequestParam String bannerImage) { + BannerPresignedUrlFindResponse response = adminFacade.checkMemberAndIssuePresignedUrlForBanner(memberId, + bannerImage); + return ResponseEntity.status(HttpStatus.OK) + .body(SuccessResponse.of(AdminSuccessCode.BANNER_PRESIGNED_URL_ISSUED, response)); + } + + @Override + @GetMapping("/carousels") + public ResponseEntity> readAllCarouselImages( + @CurrentMember Long memberId) { + CarouselFindAllResponse response = adminFacade.checkMemberAndFindAllPromotionsSortedByCarouselNumber(memberId); + return ResponseEntity.status(HttpStatus.OK) + .body(SuccessResponse.of(AdminSuccessCode.FETCH_ALL_CAROUSEL_PROMOTIONS_SUCCESS, response)); + } + + @Override + @PutMapping("/carousels") + public ResponseEntity> processCarouselImages( + @CurrentMember Long memberId, + @RequestBody CarouselHandleRequest request) { + CarouselHandleAllResponse response = adminFacade.checkMemberAndProcessAllPromotionsSortedByCarouselNumber(memberId, request); + return ResponseEntity.status(HttpStatus.OK) + .body(SuccessResponse.of(AdminSuccessCode.UPDATE_ALL_CAROUSEL_PROMOTIONS_SUCCESS, response)); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/application/AdminService.java b/src/main/java/com/beat/admin/application/AdminService.java new file mode 100644 index 00000000..530e79ec --- /dev/null +++ b/src/main/java/com/beat/admin/application/AdminService.java @@ -0,0 +1,89 @@ +package com.beat.admin.application; + +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionGenerateRequest; +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionModifyRequest; +import com.beat.admin.port.in.AdminUseCase; +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.performance.port.in.PerformanceUseCase; +import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.promotion.port.in.PromotionUseCase; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class AdminService implements AdminUseCase { + + private final PromotionUseCase promotionUseCase; + private final PerformanceUseCase performanceUseCase; + + @Override + @Transactional(readOnly = true) + public List findAllPromotionsSortedByCarouselNumber() { + List promotions = promotionUseCase.findAllPromotions(); + return sortPromotionsByCarouselNumber(promotions); + } + + @Override + @Transactional + public List processPromotionsAndSortByPromotionId(List modifyRequests, + List generateRequests, List deletePromotionIds) { + + handlePromotionDeletion(deletePromotionIds); + List modifiedPromotions = handlePromotionModification(modifyRequests); + List addedPromotions = handlePromotionGeneration(generateRequests); + + List applyPromotionChanges = new ArrayList<>(modifiedPromotions); + applyPromotionChanges.addAll(addedPromotions); + + return sortPromotionsByCarouselNumber(applyPromotionChanges); + } + + private void handlePromotionDeletion(List deletePromotionIds) { + if (!deletePromotionIds.isEmpty()) { + promotionUseCase.deletePromotionsByPromotionIds(deletePromotionIds); + } + } + + private List handlePromotionModification(List modifyRequests) { + return modifyRequests.stream() + .map(modifyRequest -> { + + Promotion promotion = promotionUseCase.findById(modifyRequest.promotionId()); + + Performance performance = Optional.ofNullable(modifyRequest.performanceId()) + .map(performanceUseCase::findById) + .orElse(null); + + return promotionUseCase.modifyPromotion(promotion, performance, modifyRequest); + }) + .toList(); + } + + private List handlePromotionGeneration(List generateRequests) { + return generateRequests.stream() + .map(generateRequest -> { + Performance performance = Optional.ofNullable(generateRequest.performanceId()) + .map(performanceUseCase::findById) + .orElse(null); + + return promotionUseCase.createPromotion(generateRequest.newImageUrl(), performance, + generateRequest.redirectUrl(), generateRequest.isExternal(), generateRequest.carouselNumber()); + }) + .toList(); + } + + private List sortPromotionsByCarouselNumber(List promotions) { + return promotions.stream() + .sorted(Comparator.comparing(Promotion::getCarouselNumber, Comparator.comparingInt(Enum::ordinal))) + .toList(); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/application/dto/request/CarouselHandleRequest.java b/src/main/java/com/beat/admin/application/dto/request/CarouselHandleRequest.java new file mode 100644 index 00000000..c5aa18a7 --- /dev/null +++ b/src/main/java/com/beat/admin/application/dto/request/CarouselHandleRequest.java @@ -0,0 +1,29 @@ +package com.beat.admin.application.dto.request; + +import java.util.List; + +import com.beat.domain.promotion.domain.CarouselNumber; + +public record CarouselHandleRequest( + List carousels +) { + + public record PromotionModifyRequest( + Long promotionId, + CarouselNumber carouselNumber, + String newImageUrl, + boolean isExternal, + String redirectUrl, + Long performanceId + ) implements PromotionHandleRequest { + } + + public record PromotionGenerateRequest( + CarouselNumber carouselNumber, + String newImageUrl, + boolean isExternal, + String redirectUrl, + Long performanceId + ) implements PromotionHandleRequest { + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/application/dto/request/PromotionHandleRequest.java b/src/main/java/com/beat/admin/application/dto/request/PromotionHandleRequest.java new file mode 100644 index 00000000..e293d603 --- /dev/null +++ b/src/main/java/com/beat/admin/application/dto/request/PromotionHandleRequest.java @@ -0,0 +1,28 @@ +package com.beat.admin.application.dto.request; + +import static com.beat.admin.application.dto.request.CarouselHandleRequest.*; + +import com.beat.domain.promotion.domain.CarouselNumber; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "type" +) +@JsonSubTypes({ + @JsonSubTypes.Type(value = PromotionModifyRequest.class, name = "modify"), + @JsonSubTypes.Type(value = PromotionGenerateRequest.class, name = "generate") +}) +public sealed interface PromotionHandleRequest + permits PromotionModifyRequest, PromotionGenerateRequest { + CarouselNumber carouselNumber(); + + String newImageUrl(); + + boolean isExternal(); + + String redirectUrl(); + + Long performanceId(); +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/application/dto/response/CarouselFindAllResponse.java b/src/main/java/com/beat/admin/application/dto/response/CarouselFindAllResponse.java new file mode 100644 index 00000000..878aa861 --- /dev/null +++ b/src/main/java/com/beat/admin/application/dto/response/CarouselFindAllResponse.java @@ -0,0 +1,41 @@ +package com.beat.admin.application.dto.response; + +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.promotion.domain.CarouselNumber; +import com.beat.domain.promotion.domain.Promotion; + +import java.util.List; +import java.util.Optional; + +public record CarouselFindAllResponse( + List carousels +) { + public static CarouselFindAllResponse from(List promotions) { + List responses = promotions.stream() + .map(CarouselFindResponse::from) + .toList(); + return new CarouselFindAllResponse(responses); + } + + public record CarouselFindResponse( + Long promotionId, + CarouselNumber carouselNumber, + String newImageUrl, + boolean isExternal, + String redirectUrl, + Long performanceId + ) { + public static CarouselFindResponse from(Promotion promotion) { + return new CarouselFindResponse( + promotion.getId(), + promotion.getCarouselNumber(), + promotion.getPromotionPhoto(), + promotion.isExternal(), + promotion.getRedirectUrl(), + Optional.ofNullable(promotion.getPerformance()) + .map(Performance::getId) + .orElse(null) + ); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/application/dto/response/CarouselHandleAllResponse.java b/src/main/java/com/beat/admin/application/dto/response/CarouselHandleAllResponse.java new file mode 100644 index 00000000..999224b0 --- /dev/null +++ b/src/main/java/com/beat/admin/application/dto/response/CarouselHandleAllResponse.java @@ -0,0 +1,36 @@ +package com.beat.admin.application.dto.response; + +import java.util.List; +import java.util.stream.Collectors; + +import com.beat.domain.promotion.domain.Promotion; + +public record CarouselHandleAllResponse( + List modifiedPromotions +) { + + public static CarouselHandleAllResponse from(List promotions) { + List modifiedPromotions = promotions.stream() + .map(PromotionResponse::from) + .collect(Collectors.toList()); + return new CarouselHandleAllResponse(modifiedPromotions); + } + + public record PromotionResponse( + Long promotionId, + String newImageUrl, + boolean isExternal, + String redirectUrl, + String carouselNumber + ) { + public static PromotionResponse from(Promotion promotion) { + return new PromotionResponse( + promotion.getId(), + promotion.getPromotionPhoto(), + promotion.isExternal(), + promotion.getRedirectUrl(), + promotion.getCarouselNumber().name() + ); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/application/dto/response/UserFindAllResponse.java b/src/main/java/com/beat/admin/application/dto/response/UserFindAllResponse.java new file mode 100644 index 00000000..a5274131 --- /dev/null +++ b/src/main/java/com/beat/admin/application/dto/response/UserFindAllResponse.java @@ -0,0 +1,28 @@ +package com.beat.admin.application.dto.response; + +import com.beat.domain.user.domain.Users; + +import java.util.List; + +public record UserFindAllResponse( + List users +) { + public static UserFindAllResponse from(List users) { + List userFindResponses = users.stream() + .map(UserFindResponse::from) + .toList(); + return new UserFindAllResponse(userFindResponses); + } + + public record UserFindResponse( + Long id, + String role + ) { + public static UserFindResponse from(Users user) { + return new UserFindResponse( + user.getId(), + user.getRole().getRoleName() + ); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/exception/AdminSuccessCode.java b/src/main/java/com/beat/admin/exception/AdminSuccessCode.java new file mode 100644 index 00000000..7125c6a3 --- /dev/null +++ b/src/main/java/com/beat/admin/exception/AdminSuccessCode.java @@ -0,0 +1,19 @@ +package com.beat.admin.exception; + +import com.beat.global.common.exception.base.BaseSuccessCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum AdminSuccessCode implements BaseSuccessCode { + FETCH_ALL_USERS_SUCCESS(200, "관리자 권한으로 모든 유저 조회에 성공하였습니다."), + CAROUSEL_PRESIGNED_URL_ISSUED(200, "캐러셀 Presigned URL 발급 성공"), + BANNER_PRESIGNED_URL_ISSUED(200, "배너 Presigned URL 발급 성공"), + FETCH_ALL_CAROUSEL_PROMOTIONS_SUCCESS(200, "관리자 권한으로 현재 캐러셀에 등록된 모든 공연 조회에 성공하였습니다."), + UPDATE_ALL_CAROUSEL_PROMOTIONS_SUCCESS(200, "관리자 권한으로 캐러셀 수정에 성공하였습니다.") + ; + + private final int status; + private final String message; +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/facade/AdminFacade.java b/src/main/java/com/beat/admin/facade/AdminFacade.java new file mode 100644 index 00000000..968b1d5b --- /dev/null +++ b/src/main/java/com/beat/admin/facade/AdminFacade.java @@ -0,0 +1,111 @@ +package com.beat.admin.facade; + +import com.beat.admin.application.dto.request.PromotionHandleRequest; +import com.beat.admin.application.dto.response.CarouselFindAllResponse; +import com.beat.admin.application.dto.response.UserFindAllResponse; +import com.beat.admin.application.dto.request.CarouselHandleRequest; +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionGenerateRequest; +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionModifyRequest; +import com.beat.admin.application.dto.response.CarouselHandleAllResponse; +import com.beat.admin.port.in.AdminUseCase; +import com.beat.domain.member.port.in.MemberUseCase; +import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.promotion.port.in.PromotionUseCase; +import com.beat.domain.user.domain.Users; +import com.beat.domain.user.port.in.UserUseCase; +import com.beat.global.external.s3.application.dto.BannerPresignedUrlFindResponse; +import com.beat.global.external.s3.application.dto.CarouselPresignedUrlFindAllResponse; +import com.beat.global.external.s3.port.in.FileUseCase; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@Transactional +@RequiredArgsConstructor +public class AdminFacade { + private final FileUseCase fileUseCase; + private final AdminUseCase adminUsecase; + private final MemberUseCase memberUseCase; + private final UserUseCase userUseCase; + private final PromotionUseCase promotionUseCase; + + public UserFindAllResponse checkMemberAndFindAllUsers(Long memberId) { + memberUseCase.findMemberByMemberId(memberId); + List users = userUseCase.findAllUsers(); + return UserFindAllResponse.from(users); + } + + public CarouselPresignedUrlFindAllResponse checkMemberAndIssueAllPresignedUrlsForCarousel(Long memberId, + List carouselImages) { + memberUseCase.findMemberByMemberId(memberId); + Map carouselPresignedUrls = fileUseCase.issueAllPresignedUrlsForCarousel(carouselImages); + return CarouselPresignedUrlFindAllResponse.from(carouselPresignedUrls); + } + + public BannerPresignedUrlFindResponse checkMemberAndIssuePresignedUrlForBanner(Long memberId, String bannerImage) { + memberUseCase.findMemberByMemberId(memberId); + String bannerPresignedUrl = fileUseCase.issuePresignedUrlForBanner(bannerImage); + return BannerPresignedUrlFindResponse.from(bannerPresignedUrl); + } + + public CarouselFindAllResponse checkMemberAndFindAllPromotionsSortedByCarouselNumber(Long memberId) { + memberUseCase.findMemberByMemberId(memberId); + List promotions = adminUsecase.findAllPromotionsSortedByCarouselNumber(); + return CarouselFindAllResponse.from(promotions); + } + + public CarouselHandleAllResponse checkMemberAndProcessAllPromotionsSortedByCarouselNumber(Long memberId, + CarouselHandleRequest request) { + + memberUseCase.findMemberByMemberId(memberId); + + List modifyRequests = new ArrayList<>(); + List generateRequests = new ArrayList<>(); + Set requestPromotionIds = new HashSet<>(); + + categorizePromotionRequestsByPromotionId(request, modifyRequests, generateRequests, requestPromotionIds); + + List allExistingPromotions = promotionUseCase.findAllPromotions(); + + List deletePromotionIds = extractDeletePromotionIds(allExistingPromotions, requestPromotionIds); + + List sortedPromotions = adminUsecase.processPromotionsAndSortByPromotionId(modifyRequests, + generateRequests, deletePromotionIds); + + return CarouselHandleAllResponse.from(sortedPromotions); + } + + private void categorizePromotionRequestsByPromotionId(CarouselHandleRequest request, + List modifyRequests, List generateRequests, + Set requestPromotionIds) { + + for (PromotionHandleRequest promotionRequest : request.carousels()) { + if (promotionRequest instanceof PromotionModifyRequest modifyRequest) { + modifyRequests.add(modifyRequest); + requestPromotionIds.add(modifyRequest.promotionId()); + } else if (promotionRequest instanceof PromotionGenerateRequest generateRequest) { + generateRequests.add(generateRequest); + } + } + } + + private List extractDeletePromotionIds(List allExistingPromotions, Set requestPromotionIds) { + Set allExistingPromotionIds = allExistingPromotions.stream() + .map(Promotion::getId) + .collect(Collectors.toSet()); + + return allExistingPromotionIds.stream() + .filter(existingId -> !requestPromotionIds.contains(existingId)) + .toList(); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/admin/port/in/AdminUseCase.java b/src/main/java/com/beat/admin/port/in/AdminUseCase.java new file mode 100644 index 00000000..93fa39fc --- /dev/null +++ b/src/main/java/com/beat/admin/port/in/AdminUseCase.java @@ -0,0 +1,14 @@ +package com.beat.admin.port.in; + +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionGenerateRequest; +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionModifyRequest; +import com.beat.domain.promotion.domain.Promotion; + +import java.util.List; + +public interface AdminUseCase { + List findAllPromotionsSortedByCarouselNumber(); + + List processPromotionsAndSortByPromotionId(List modifyRequests, + List generateRequests, List deletePromotionIds); +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/api/BookingController.java b/src/main/java/com/beat/domain/booking/api/BookingController.java index 3f54b30b..dae62784 100644 --- a/src/main/java/com/beat/domain/booking/api/BookingController.java +++ b/src/main/java/com/beat/domain/booking/api/BookingController.java @@ -47,7 +47,7 @@ public ResponseEntity> createMemberBookin @Operation(summary = "회원 예매 조회 API", description = "회원이 예매를 조회하는 GET API입니다.") @GetMapping("/member/retrieve") - public ResponseEntity> getMemberBookings( + public ResponseEntity>> getMemberBookings( @CurrentMember Long memberId) { List response = memberBookingRetrieveService.findMemberBookings(memberId); return ResponseEntity.status(HttpStatus.OK) diff --git a/src/main/java/com/beat/domain/booking/api/TicketController.java b/src/main/java/com/beat/domain/booking/api/TicketController.java index 1e03e66e..ef10a3d7 100644 --- a/src/main/java/com/beat/domain/booking/api/TicketController.java +++ b/src/main/java/com/beat/domain/booking/api/TicketController.java @@ -1,9 +1,10 @@ package com.beat.domain.booking.api; import com.beat.domain.booking.application.TicketService; -import com.beat.domain.booking.application.dto.TicketDeleteRequest; +import com.beat.domain.booking.application.dto.TicketCancelRequest; import com.beat.domain.booking.application.dto.TicketRetrieveResponse; import com.beat.domain.booking.application.dto.TicketUpdateRequest; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.booking.exception.BookingSuccessCode; import com.beat.global.auth.annotation.CurrentMember; import com.beat.global.common.dto.SuccessResponse; @@ -26,8 +27,8 @@ public ResponseEntity> getTickets( @CurrentMember Long memberId, @PathVariable Long performanceId, @RequestParam(required = false) ScheduleNumber scheduleNumber, - @RequestParam(required = false) Boolean isPaymentCompleted) { - TicketRetrieveResponse response = ticketService.getTickets(memberId, performanceId, scheduleNumber, isPaymentCompleted); + @RequestParam(required = false) BookingStatus bookingStatus) { + TicketRetrieveResponse response = ticketService.getTickets(memberId, performanceId, scheduleNumber, bookingStatus); return ResponseEntity.ok(SuccessResponse.of(BookingSuccessCode.TICKET_RETRIEVE_SUCCESS, response)); } @@ -37,15 +38,15 @@ public ResponseEntity> updateTickets( @CurrentMember Long memberId, @RequestBody TicketUpdateRequest request) { ticketService.updateTickets(memberId, request); - return ResponseEntity.ok(SuccessResponse.of(BookingSuccessCode.TICKET_UPDATE_SUCCESS, null)); + return ResponseEntity.ok(SuccessResponse.from(BookingSuccessCode.TICKET_UPDATE_SUCCESS)); } - @Operation(summary = "예매자 삭제 API", description = "메이커가 자신의 공연에 대한 예매자의 정보를 삭제하는 DELETE API입니다.") - @DeleteMapping - public ResponseEntity> deleteTickets( + @Operation(summary = "예매자 취소 API", description = "메이커가 자신의 공연에 대한 1명 이상의 예매자의 정보를 취소 상태로 변경하는 PATCH API입니다.") + @PatchMapping + public ResponseEntity> cancelTickets( @CurrentMember Long memberId, - @RequestBody TicketDeleteRequest ticketDeleteRequest) { - ticketService.deleteTickets(memberId, ticketDeleteRequest); - return ResponseEntity.ok(SuccessResponse.from(BookingSuccessCode.TICKET_DELETE_SUCCESS)); + @RequestBody TicketCancelRequest ticketCancelRequest) { + ticketService.cancelTickets(memberId, ticketCancelRequest); + return ResponseEntity.ok(SuccessResponse.from(BookingSuccessCode.TICKET_CANCEL_SUCCESS)); } } diff --git a/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java b/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java index 8a3aaa24..831d796b 100644 --- a/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java +++ b/src/main/java/com/beat/domain/booking/application/GuestBookingRetrieveService.java @@ -83,7 +83,7 @@ private GuestBookingRetrieveResponse toBookingResponse(Booking booking) { performance.getAccountNumber(), performance.getAccountHolder(), calculateDueDate(schedule.getPerformanceDate()), - booking.isPaymentCompleted(), + booking.getBookingStatus(), booking.getCreatedAt(), performance.getPosterImage(), totalPaymentAmount diff --git a/src/main/java/com/beat/domain/booking/application/GuestBookingService.java b/src/main/java/com/beat/domain/booking/application/GuestBookingService.java index f15601c8..0aee93f7 100644 --- a/src/main/java/com/beat/domain/booking/application/GuestBookingService.java +++ b/src/main/java/com/beat/domain/booking/application/GuestBookingService.java @@ -12,17 +12,15 @@ import com.beat.global.common.exception.BadRequestException; import com.beat.global.common.exception.NotFoundException; import lombok.RequiredArgsConstructor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +@Slf4j @Service @RequiredArgsConstructor public class GuestBookingService { - private static final Logger logger = LoggerFactory.getLogger(GuestBookingService.class); - private final ScheduleRepository scheduleRepository; private final BookingRepository bookingRepository; private final UserRepository userRepository; @@ -37,7 +35,7 @@ public GuestBookingResponse createGuestBooking(GuestBookingRequest guestBookingR throw new BadRequestException(ScheduleErrorCode.INSUFFICIENT_TICKETS); } - schedule.setSoldTicketCount(schedule.getSoldTicketCount() + guestBookingRequest.purchaseTicketCount()); + updateSoldTicketCountAndIsBooking(schedule, guestBookingRequest.purchaseTicketCount()); Users users = bookingRepository.findFirstByBookerNameAndBookerPhoneNumberAndBirthDateAndPassword( guestBookingRequest.bookerName(), @@ -58,7 +56,7 @@ public GuestBookingResponse createGuestBooking(GuestBookingRequest guestBookingR guestBookingRequest.purchaseTicketCount(), guestBookingRequest.bookerName(), guestBookingRequest.bookerPhoneNumber(), - guestBookingRequest.isPaymentCompleted(), + guestBookingRequest.bookingStatus(), guestBookingRequest.birthDate(), guestBookingRequest.password(), schedule, @@ -66,7 +64,7 @@ public GuestBookingResponse createGuestBooking(GuestBookingRequest guestBookingR ); bookingRepository.save(booking); - logger.info("Booking created: {}", booking); + log.info("Guest Booking created: {}", booking); return GuestBookingResponse.of( booking.getId(), @@ -76,11 +74,19 @@ public GuestBookingResponse createGuestBooking(GuestBookingRequest guestBookingR schedule.getScheduleNumber(), booking.getBookerName(), booking.getBookerPhoneNumber(), - booking.isPaymentCompleted(), + booking.getBookingStatus(), schedule.getPerformance().getBankName(), schedule.getPerformance().getAccountNumber(), totalPaymentAmount, booking.getCreatedAt() ); } + + private void updateSoldTicketCountAndIsBooking(Schedule schedule, int purchaseTicketCount) { + schedule.setSoldTicketCount(schedule.getSoldTicketCount() + purchaseTicketCount); + + if (schedule.getTotalTicketCount() == schedule.getSoldTicketCount()) { + schedule.updateIsBooking(false); + } + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java b/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java index 82c6981c..a12f20ec 100644 --- a/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java +++ b/src/main/java/com/beat/domain/booking/application/MemberBookingRetrieveService.java @@ -64,7 +64,7 @@ private MemberBookingRetrieveResponse toMemberBookingResponse(Booking booking) { performance.getAccountNumber(), performance.getAccountHolder(), calculateDueDate(schedule.getPerformanceDate()), - booking.isPaymentCompleted(), + booking.getBookingStatus(), booking.getCreatedAt(), performance.getPosterImage(), totalPaymentAmount diff --git a/src/main/java/com/beat/domain/booking/application/MemberBookingService.java b/src/main/java/com/beat/domain/booking/application/MemberBookingService.java index 2d6d9ccb..fbe57b3e 100644 --- a/src/main/java/com/beat/domain/booking/application/MemberBookingService.java +++ b/src/main/java/com/beat/domain/booking/application/MemberBookingService.java @@ -16,9 +16,11 @@ import com.beat.global.common.exception.BadRequestException; import com.beat.global.common.exception.NotFoundException; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +@Slf4j @Service @RequiredArgsConstructor public class MemberBookingService { @@ -38,7 +40,7 @@ public MemberBookingResponse createMemberBooking(Long memberId, MemberBookingReq throw new BadRequestException(ScheduleErrorCode.INSUFFICIENT_TICKETS); } - schedule.setSoldTicketCount(schedule.getSoldTicketCount() + memberBookingRequest.purchaseTicketCount()); + updateSoldTicketCountAndIsBooking(schedule, memberBookingRequest.purchaseTicketCount()); Member member = memberRepository.findById(memberId).orElseThrow( () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); @@ -50,7 +52,7 @@ public MemberBookingResponse createMemberBooking(Long memberId, MemberBookingReq memberBookingRequest.purchaseTicketCount(), memberBookingRequest.bookerName(), memberBookingRequest.bookerPhoneNumber(), - memberBookingRequest.isPaymentCompleted(), + memberBookingRequest.bookingStatus(), null, null, schedule, @@ -59,6 +61,8 @@ public MemberBookingResponse createMemberBooking(Long memberId, MemberBookingReq bookingRepository.save(booking); scheduleRepository.save(schedule); + log.info("Member Booking created: {}", booking); + return MemberBookingResponse.of( booking.getId(), schedule.getId(), @@ -67,11 +71,19 @@ public MemberBookingResponse createMemberBooking(Long memberId, MemberBookingReq schedule.getScheduleNumber(), booking.getBookerName(), booking.getBookerPhoneNumber(), - booking.isPaymentCompleted(), + booking.getBookingStatus(), schedule.getPerformance().getBankName(), schedule.getPerformance().getAccountNumber(), - memberBookingRequest.totalPaymentAmount(), + memberBookingRequest.totalPaymentAmount(), // 비회원 예매처럼 int totalPaymentAmount = ticketPrice * guestBookingRequest.purchaseTicketCount();로 계산해서 반영하기 + 요청한 총 가격 == 티켓 가격 * 수 같은지 검증하는 로직 추가하기 booking.getCreatedAt() ); } + + private void updateSoldTicketCountAndIsBooking(Schedule schedule, int purchaseTicketCount) { + schedule.setSoldTicketCount(schedule.getSoldTicketCount() + purchaseTicketCount); + + if (schedule.getTotalTicketCount() == schedule.getSoldTicketCount()) { + schedule.updateIsBooking(false); + } + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/application/TicketService.java b/src/main/java/com/beat/domain/booking/application/TicketService.java index 4a5a4e58..cd0b9e4a 100644 --- a/src/main/java/com/beat/domain/booking/application/TicketService.java +++ b/src/main/java/com/beat/domain/booking/application/TicketService.java @@ -1,8 +1,25 @@ package com.beat.domain.booking.application; -import com.beat.domain.booking.application.dto.*; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import net.nurigo.java_sdk.exceptions.CoolsmsException; + +import com.beat.domain.booking.application.dto.TicketCancelRequest; +import com.beat.domain.booking.application.dto.TicketDetail; +import com.beat.domain.booking.application.dto.TicketRetrieveResponse; +import com.beat.domain.booking.application.dto.TicketUpdateDetail; +import com.beat.domain.booking.application.dto.TicketUpdateRequest; import com.beat.domain.booking.dao.TicketRepository; import com.beat.domain.booking.domain.Booking; +import com.beat.domain.booking.domain.BookingStatus; +import com.beat.domain.booking.exception.BookingErrorCode; +import com.beat.domain.booking.exception.TicketErrorCode; import com.beat.domain.member.dao.MemberRepository; import com.beat.domain.member.domain.Member; import com.beat.domain.member.exception.MemberErrorCode; @@ -12,129 +29,145 @@ import com.beat.domain.schedule.dao.ScheduleRepository; import com.beat.domain.schedule.domain.Schedule; import com.beat.domain.schedule.domain.ScheduleNumber; -import com.beat.domain.booking.exception.BookingErrorCode; -import com.beat.global.common.exception.ForbiddenException; -import com.beat.global.common.exception.NotFoundException; import com.beat.domain.user.dao.UserRepository; import com.beat.domain.user.domain.Users; import com.beat.domain.user.exception.UserErrorCode; -import lombok.RequiredArgsConstructor; -import net.nurigo.java_sdk.exceptions.CoolsmsException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; +import com.beat.global.common.exception.BadRequestException; +import com.beat.global.common.exception.ForbiddenException; +import com.beat.global.common.exception.NotFoundException; -import java.util.List; -import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class TicketService { - private final TicketRepository ticketRepository; - private final PerformanceRepository performanceRepository; - private final MemberRepository memberRepository; - private final UserRepository userRepository; - private final ScheduleRepository scheduleRepository; - private final CoolSmsService coolSmsService; - - public TicketRetrieveResponse getTickets(Long memberId, Long performanceId, ScheduleNumber scheduleNumber, Boolean isPaymentCompleted) { - Member member = memberRepository.findById(memberId).orElseThrow( - () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Users user = userRepository.findById(member.getUser().getId()).orElseThrow( - () -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); - - Performance performance = performanceRepository.findById(performanceId) - .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - - List bookings; - - if (scheduleNumber != null && isPaymentCompleted != null) { - bookings = ticketRepository.findBySchedulePerformanceIdAndScheduleScheduleNumberAndIsPaymentCompleted(performanceId, scheduleNumber, isPaymentCompleted); - } else if (scheduleNumber != null) { - bookings = ticketRepository.findBySchedulePerformanceIdAndScheduleScheduleNumber(performanceId, scheduleNumber); - } else if (isPaymentCompleted != null) { - bookings = ticketRepository.findBySchedulePerformanceIdAndIsPaymentCompleted(performanceId, isPaymentCompleted); - } else { - bookings = ticketRepository.findBySchedulePerformanceId(performanceId); - } - - List bookingList = bookings.stream() - .map(booking -> TicketDetail.of( - booking.getId(), - booking.getBookerName(), - booking.getBookerPhoneNumber(), - booking.getSchedule().getId(), - booking.getPurchaseTicketCount(), - booking.getCreatedAt(), - booking.isPaymentCompleted(), - booking.getSchedule().getScheduleNumber().name() - )) - .collect(Collectors.toList()); - - return TicketRetrieveResponse.of( - performance.getPerformanceTitle(), - performance.getTotalScheduleCount(), - bookingList - ); - } - - @Transactional - public void updateTickets(Long memberId, TicketUpdateRequest request) { - Member member = memberRepository.findById(memberId).orElseThrow( - () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Users user = userRepository.findById(member.getUser().getId()).orElseThrow( - () -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); - - Performance performance = performanceRepository.findById(request.performanceId()) - .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_PERFORMANCE_FOUND)); - - for (TicketUpdateDetail detail : request.bookingList()) { - Booking booking = ticketRepository.findById(detail.bookingId()) - .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND)); - - boolean wasPaymentCompleted = booking.isPaymentCompleted(); - booking.setIsPaymentCompleted(detail.isPaymentCompleted()); - ticketRepository.save(booking); - - if (!wasPaymentCompleted && detail.isPaymentCompleted()) { - String message = String.format("%s님, BEAT에서의 %s의 예매가 확정되었습니다.", detail.bookerName(), request.performanceTitle()); - try { - coolSmsService.sendSms(detail.bookerPhoneNumber(), message); - } catch (CoolsmsException e) { - e.printStackTrace(); - } - } - } - } - - @Transactional - public void deleteTickets(Long memberId, TicketDeleteRequest ticketDeleteRequest) { - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Long userId = member.getUser().getId(); - - Performance performance = performanceRepository.findById(ticketDeleteRequest.performanceId()) - .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_PERFORMANCE_FOUND)); - - if (!performance.getUsers().getId().equals(userId)) { - throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); - } - - for (Long bookingId : ticketDeleteRequest.bookingList()) { - Booking booking = ticketRepository.findById(bookingId) - .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND)); - - ticketRepository.delete(booking); - - Schedule schedule = booking.getSchedule(); - - ticketRepository.delete(booking); - - schedule.decreaseSoldTicketCount(booking.getPurchaseTicketCount()); - scheduleRepository.save(schedule); - } - } + private final TicketRepository ticketRepository; + private final PerformanceRepository performanceRepository; + private final MemberRepository memberRepository; + private final UserRepository userRepository; + private final ScheduleRepository scheduleRepository; + private final CoolSmsService coolSmsService; + + public TicketRetrieveResponse getTickets(Long memberId, Long performanceId, ScheduleNumber scheduleNumber, + BookingStatus bookingStatus) { + Member member = memberRepository.findById(memberId).orElseThrow( + () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Users user = userRepository.findById(member.getUser().getId()).orElseThrow( + () -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); + + Performance performance = performanceRepository.findById(performanceId) + .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); + + List bookings = findBookings(performanceId, scheduleNumber, bookingStatus); + + List bookingList = bookings.stream() + .map(booking -> TicketDetail.of( + booking.getId(), + booking.getBookerName(), + booking.getBookerPhoneNumber(), + booking.getSchedule().getId(), + booking.getPurchaseTicketCount(), + booking.getCreatedAt(), + booking.getBookingStatus(), + booking.getSchedule().getScheduleNumber().name() + )) + .collect(Collectors.toList()); + + return TicketRetrieveResponse.of( + performance.getPerformanceTitle(), + performance.getTotalScheduleCount(), + bookingList + ); + } + + private List findBookings(Long performanceId, ScheduleNumber scheduleNumber, BookingStatus bookingStatus) { + if (scheduleNumber != null && bookingStatus != null) { + return ticketRepository.findBySchedulePerformanceIdAndScheduleScheduleNumberAndBookingStatus(performanceId, + scheduleNumber, bookingStatus); + } else if (scheduleNumber != null) { + return ticketRepository.findBySchedulePerformanceIdAndScheduleScheduleNumber(performanceId, scheduleNumber); + } else if (bookingStatus != null) { + return ticketRepository.findBySchedulePerformanceIdAndBookingStatus(performanceId, bookingStatus); + } else { + return ticketRepository.findBySchedulePerformanceId(performanceId); + } + } + + @Transactional + public void updateTickets(Long memberId, TicketUpdateRequest request) { + Member member = memberRepository.findById(memberId).orElseThrow( + () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Users user = userRepository.findById(member.getUser().getId()).orElseThrow( + () -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); + + Performance performance = performanceRepository.findById(request.performanceId()) + .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_PERFORMANCE_FOUND)); + + for (TicketUpdateDetail detail : request.bookingList()) { + Booking booking = ticketRepository.findById(detail.bookingId()) + .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND)); + + if (booking.getBookingStatus() == BookingStatus.BOOKING_CONFIRMED + && detail.bookingStatus() != BookingStatus.BOOKING_CONFIRMED) { + throw new BadRequestException(TicketErrorCode.PAYMENT_COMPLETED_TICKET_UPDATE_NOT_ALLOWED); + } + + if (booking.getBookingStatus() == BookingStatus.CHECKING_PAYMENT + && detail.bookingStatus() == BookingStatus.BOOKING_CONFIRMED) { + booking.setBookingStatus(BookingStatus.BOOKING_CONFIRMED); + ticketRepository.save(booking); + + String message = String.format("[BEAT] %s님 %s 예매 확정되었습니다.", detail.bookerName(), + request.performanceTitle()); + try { + coolSmsService.sendSms(detail.bookerPhoneNumber(), message); + } catch (CoolsmsException e) { + e.printStackTrace(); + } + } + } + } + + @Transactional + public void cancelTickets(Long memberId, TicketCancelRequest ticketCancelRequest) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Long userId = member.getUser().getId(); + + Performance performance = performanceRepository.findById(ticketCancelRequest.performanceId()) + .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_PERFORMANCE_FOUND)); + + if (!performance.getUsers().getId().equals(userId)) { + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + + for (Long bookingId : ticketCancelRequest.bookingList()) { + Booking booking = ticketRepository.findById(bookingId) + .orElseThrow(() -> new NotFoundException(BookingErrorCode.NO_BOOKING_FOUND)); + + booking.setBookingStatus(BookingStatus.BOOKING_CANCELLED); + ticketRepository.save(booking); + + Schedule schedule = booking.getSchedule(); + schedule.decreaseSoldTicketCount(booking.getPurchaseTicketCount()); + + if (!schedule.isBooking()) { + schedule.updateIsBooking(true); + scheduleRepository.save(schedule); + } + } + } + + @Scheduled(cron = "0 0 4 * * ?") + @Transactional + public void deleteOldCancelledBookings() { + LocalDateTime oneYearAgo = LocalDateTime.now().minusYears(1); + List oldCancelledBookings = ticketRepository.findByBookingStatusAndCancellationDateBefore( + BookingStatus.BOOKING_CANCELLED, oneYearAgo); + ticketRepository.deleteAll(oldCancelledBookings); + } } diff --git a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRequest.java b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRequest.java index 3ea0647d..891ccab3 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRequest.java +++ b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRequest.java @@ -1,5 +1,6 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.schedule.domain.ScheduleNumber; public record GuestBookingRequest( @@ -11,9 +12,9 @@ public record GuestBookingRequest( String birthDate, String password, int totalPaymentAmount, - boolean isPaymentCompleted + BookingStatus bookingStatus ) { - public static GuestBookingRequest of(Long scheduleId, int purchaseTicketCount, ScheduleNumber scheduleNumber, String bookerName, String bookerPhoneNumber, String birthDate, String password, int totalPaymentAmount, boolean isPaymentCompleted) { - return new GuestBookingRequest(scheduleId, purchaseTicketCount, scheduleNumber, bookerName, bookerPhoneNumber, birthDate, password, totalPaymentAmount, isPaymentCompleted); + public static GuestBookingRequest of(Long scheduleId, int purchaseTicketCount, ScheduleNumber scheduleNumber, String bookerName, String bookerPhoneNumber, String birthDate, String password, int totalPaymentAmount, BookingStatus bookingStatus) { + return new GuestBookingRequest(scheduleId, purchaseTicketCount, scheduleNumber, bookerName, bookerPhoneNumber, birthDate, password, totalPaymentAmount, bookingStatus); } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingResponse.java b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingResponse.java index ecf16df1..c9694cd5 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingResponse.java +++ b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingResponse.java @@ -1,5 +1,6 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.performance.domain.BankName; import com.beat.domain.schedule.domain.ScheduleNumber; @@ -13,7 +14,7 @@ public record GuestBookingResponse( ScheduleNumber scheduleNumber, String bookerName, String bookerPhoneNumber, - boolean isPaymentCompleted, + BookingStatus bookingStatus, BankName bankName, String accountNumber, int totalPaymentAmount, @@ -27,7 +28,7 @@ public static GuestBookingResponse of( ScheduleNumber scheduleNumber, String bookerName, String bookerPhoneNumber, - boolean isPaymentCompleted, + BookingStatus bookingStatus, BankName bankName, String accountNumber, int totalPaymentAmount, @@ -40,7 +41,7 @@ public static GuestBookingResponse of( scheduleNumber, bookerName, bookerPhoneNumber, - isPaymentCompleted, + bookingStatus, bankName, accountNumber, totalPaymentAmount, diff --git a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java index 9a490638..65903380 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java +++ b/src/main/java/com/beat/domain/booking/application/dto/GuestBookingRetrieveResponse.java @@ -1,5 +1,6 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.performance.domain.BankName; import com.beat.domain.schedule.domain.ScheduleNumber; @@ -20,7 +21,7 @@ public record GuestBookingRetrieveResponse( String accountNumber, String accountHolder, int dueDate, - boolean isPaymentCompleted, + BookingStatus bookingStatus, LocalDateTime createdAt, String posterImage, int totalPaymentAmount @@ -40,7 +41,7 @@ public static GuestBookingRetrieveResponse of( String accountNumber, String accountHolder, int dueDate, - boolean isPaymentCompleted, + BookingStatus bookingStatus, LocalDateTime createdAt, String posterImage, int totalPaymentAmount @@ -60,7 +61,7 @@ public static GuestBookingRetrieveResponse of( accountNumber, accountHolder, dueDate, - isPaymentCompleted, + bookingStatus, createdAt, posterImage, totalPaymentAmount diff --git a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRequest.java b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRequest.java index d0a84a7d..608acfdd 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRequest.java +++ b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRequest.java @@ -1,5 +1,6 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.schedule.domain.ScheduleNumber; public record MemberBookingRequest( @@ -8,6 +9,6 @@ public record MemberBookingRequest( int purchaseTicketCount, String bookerName, String bookerPhoneNumber, - boolean isPaymentCompleted, + BookingStatus bookingStatus, int totalPaymentAmount ) { } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingResponse.java b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingResponse.java index dce4f10d..9e3342fe 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingResponse.java +++ b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingResponse.java @@ -1,5 +1,6 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.performance.domain.BankName; import com.beat.domain.schedule.domain.ScheduleNumber; @@ -13,7 +14,7 @@ public record MemberBookingResponse( ScheduleNumber scheduleNumber, String bookerName, String bookerPhoneNumber, - boolean isPaymentCompleted, + BookingStatus bookingStatus, BankName bankName, String accountNumber, int totalPaymentAmount, @@ -27,7 +28,7 @@ public static MemberBookingResponse of( ScheduleNumber scheduleNumber, String bookerName, String bookerPhoneNumber, - boolean isPaymentCompleted, + BookingStatus bookingStatus, BankName bankName, String accountNumber, int totalPaymentAmount, @@ -41,7 +42,7 @@ public static MemberBookingResponse of( scheduleNumber, bookerName, bookerPhoneNumber, - isPaymentCompleted, + bookingStatus, bankName, accountNumber, totalPaymentAmount, diff --git a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java index 134767bc..cfc82200 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java +++ b/src/main/java/com/beat/domain/booking/application/dto/MemberBookingRetrieveResponse.java @@ -1,5 +1,6 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.performance.domain.BankName; import com.beat.domain.schedule.domain.ScheduleNumber; @@ -21,7 +22,7 @@ public record MemberBookingRetrieveResponse( String accountNumber, String accountHolder, int dueDate, - boolean isPaymentCompleted, + BookingStatus bookingStatus, LocalDateTime createdAt, String posterImage, int totalPaymentAmount @@ -42,7 +43,7 @@ public static MemberBookingRetrieveResponse of( String accountNumber, String accountHolder, int dueDate, - boolean isPaymentCompleted, + BookingStatus bookingStatus, LocalDateTime createdAt, String posterImage, int totalPaymentAmount @@ -63,7 +64,7 @@ public static MemberBookingRetrieveResponse of( accountNumber, accountHolder, dueDate, - isPaymentCompleted, + bookingStatus, createdAt, posterImage, totalPaymentAmount diff --git a/src/main/java/com/beat/domain/booking/application/dto/TicketDeleteRequest.java b/src/main/java/com/beat/domain/booking/application/dto/TicketCancelRequest.java similarity index 51% rename from src/main/java/com/beat/domain/booking/application/dto/TicketDeleteRequest.java rename to src/main/java/com/beat/domain/booking/application/dto/TicketCancelRequest.java index 57c2e756..65341f8c 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/TicketDeleteRequest.java +++ b/src/main/java/com/beat/domain/booking/application/dto/TicketCancelRequest.java @@ -2,11 +2,11 @@ import java.util.List; -public record TicketDeleteRequest( +public record TicketCancelRequest( Long performanceId, List bookingList ) { - public static TicketDeleteRequest of(Long performanceId, List bookingList) { - return new TicketDeleteRequest(performanceId, bookingList); + public static TicketCancelRequest of(Long performanceId, List bookingList) { + return new TicketCancelRequest(performanceId, bookingList); } } diff --git a/src/main/java/com/beat/domain/booking/application/dto/TicketDetail.java b/src/main/java/com/beat/domain/booking/application/dto/TicketDetail.java index 013eb32c..f72dee2f 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/TicketDetail.java +++ b/src/main/java/com/beat/domain/booking/application/dto/TicketDetail.java @@ -1,5 +1,7 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; + import java.time.LocalDateTime; public record TicketDetail( @@ -9,7 +11,7 @@ public record TicketDetail( Long scheduleId, int purchaseTicketCount, LocalDateTime createdAt, - boolean isPaymentCompleted, + BookingStatus bookingStatus, String scheduleNumber ) { public static TicketDetail of( @@ -19,8 +21,8 @@ public static TicketDetail of( Long scheduleId, int purchaseTicketCount, LocalDateTime createdAt, - boolean isPaymentCompleted, + BookingStatus bookingStatus, String scheduleNumber) { - return new TicketDetail(bookingId, bookerName, bookerPhoneNumber, scheduleId, purchaseTicketCount, createdAt, isPaymentCompleted, scheduleNumber); + return new TicketDetail(bookingId, bookerName, bookerPhoneNumber, scheduleId, purchaseTicketCount, createdAt, bookingStatus, scheduleNumber); } } diff --git a/src/main/java/com/beat/domain/booking/application/dto/TicketUpdateDetail.java b/src/main/java/com/beat/domain/booking/application/dto/TicketUpdateDetail.java index 38e868df..79c2fd29 100644 --- a/src/main/java/com/beat/domain/booking/application/dto/TicketUpdateDetail.java +++ b/src/main/java/com/beat/domain/booking/application/dto/TicketUpdateDetail.java @@ -1,5 +1,7 @@ package com.beat.domain.booking.application.dto; +import com.beat.domain.booking.domain.BookingStatus; + import java.time.LocalDateTime; public record TicketUpdateDetail( @@ -9,7 +11,7 @@ public record TicketUpdateDetail( Long scheduleId, int purchaseTicketCount, LocalDateTime createdAt, - boolean isPaymentCompleted, + BookingStatus bookingStatus, String scheduleNumber ) { public static TicketUpdateDetail of( @@ -19,8 +21,8 @@ public static TicketUpdateDetail of( Long scheduleId, int purchaseTicketCount, LocalDateTime createdAt, - boolean isPaymentCompleted, + BookingStatus bookingStatus, String scheduleNumber) { - return new TicketUpdateDetail(bookingId, bookerName, bookerPhoneNumber, scheduleId, purchaseTicketCount, createdAt, isPaymentCompleted, scheduleNumber); + return new TicketUpdateDetail(bookingId, bookerName, bookerPhoneNumber, scheduleId, purchaseTicketCount, createdAt, bookingStatus, scheduleNumber); } } diff --git a/src/main/java/com/beat/domain/booking/dao/BookingRepository.java b/src/main/java/com/beat/domain/booking/dao/BookingRepository.java index 111be517..cd12d617 100644 --- a/src/main/java/com/beat/domain/booking/dao/BookingRepository.java +++ b/src/main/java/com/beat/domain/booking/dao/BookingRepository.java @@ -1,37 +1,38 @@ package com.beat.domain.booking.dao; -import com.beat.domain.booking.domain.Booking; +import java.util.List; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import java.util.List; -import java.util.Optional; +import com.beat.domain.booking.domain.Booking; public interface BookingRepository extends JpaRepository { - @Query("SELECT b FROM Booking b " + - "JOIN b.schedule s " + - "JOIN s.performance p " + - "WHERE b.bookerName = :bookerName " + - "AND b.bookerPhoneNumber = :bookerPhoneNumber " + - "AND b.password = :password " + - "AND b.birthDate = :birthDate") - Optional> findByBookerNameAndBookerPhoneNumberAndPasswordAndBirthDate( - @Param("bookerName") String bookerName, - @Param("bookerPhoneNumber") String bookerPhoneNumber, - @Param("password") String password, - @Param("birthDate") String birthDate - ); + @Query("SELECT b FROM Booking b " + + "JOIN b.schedule s " + + "JOIN s.performance p " + + "WHERE b.bookerName = :bookerName " + + "AND b.bookerPhoneNumber = :bookerPhoneNumber " + + "AND b.password = :password " + + "AND b.birthDate = :birthDate") + Optional> findByBookerNameAndBookerPhoneNumberAndPasswordAndBirthDate( + @Param("bookerName") String bookerName, + @Param("bookerPhoneNumber") String bookerPhoneNumber, + @Param("password") String password, + @Param("birthDate") String birthDate + ); - Optional findFirstByBookerNameAndBookerPhoneNumberAndBirthDateAndPassword( - String bookerName, - String bookerPhoneNumber, - String birthDate, - String password - ); + Optional findFirstByBookerNameAndBookerPhoneNumberAndBirthDateAndPassword( + String bookerName, + String bookerPhoneNumber, + String birthDate, + String password + ); - List findByUsersId(Long userId); + List findByUsersId(Long userId); - @Query("SELECT COUNT(b) > 0 FROM Booking b WHERE b.schedule.id IN :scheduleIds") - boolean existsByScheduleIdIn(@Param("scheduleIds") List scheduleIds); + @Query("SELECT COUNT(b) > 0 FROM Booking b WHERE b.schedule.id IN :scheduleIds AND b.bookingStatus != 'BOOKING_CANCELLED'") + boolean existsByScheduleIdIn(@Param("scheduleIds") List scheduleIds); } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/dao/TicketRepository.java b/src/main/java/com/beat/domain/booking/dao/TicketRepository.java index aad02e7e..870884e1 100644 --- a/src/main/java/com/beat/domain/booking/dao/TicketRepository.java +++ b/src/main/java/com/beat/domain/booking/dao/TicketRepository.java @@ -1,9 +1,11 @@ package com.beat.domain.booking.dao; import com.beat.domain.booking.domain.Booking; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.schedule.domain.ScheduleNumber; import org.springframework.data.jpa.repository.JpaRepository; +import java.time.LocalDateTime; import java.util.List; public interface TicketRepository extends JpaRepository { @@ -11,7 +13,9 @@ public interface TicketRepository extends JpaRepository { List findBySchedulePerformanceIdAndScheduleScheduleNumber(Long performanceId, ScheduleNumber scheduleNumber); - List findBySchedulePerformanceIdAndIsPaymentCompleted(Long performanceId, boolean isPaymentCompleted); + List findBySchedulePerformanceIdAndBookingStatus(Long performanceId, BookingStatus bookingStatus); - List findBySchedulePerformanceIdAndScheduleScheduleNumberAndIsPaymentCompleted(Long performanceId, ScheduleNumber scheduleNumber, boolean isPaymentCompleted); + List findBySchedulePerformanceIdAndScheduleScheduleNumberAndBookingStatus(Long performanceId, ScheduleNumber scheduleNumber, BookingStatus bookingStatus); + + List findByBookingStatusAndCancellationDateBefore(BookingStatus bookingStatus, LocalDateTime cancellationDate); } diff --git a/src/main/java/com/beat/domain/booking/domain/Booking.java b/src/main/java/com/beat/domain/booking/domain/Booking.java index 39fba2fe..0b3ebfcf 100644 --- a/src/main/java/com/beat/domain/booking/domain/Booking.java +++ b/src/main/java/com/beat/domain/booking/domain/Booking.java @@ -4,6 +4,8 @@ import com.beat.domain.user.domain.Users; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; @@ -38,11 +40,15 @@ public class Booking { private String bookerPhoneNumber; @Column(nullable = false) - private boolean isPaymentCompleted = false; + @Enumerated(EnumType.STRING) + private BookingStatus bookingStatus = BookingStatus.CHECKING_PAYMENT; @Column(nullable = false) private LocalDateTime createdAt = LocalDateTime.now(); + @Column(nullable = true) + private LocalDateTime cancellationDate; + @Column(nullable = true) private String birthDate; @@ -60,23 +66,23 @@ public class Booking { private Users users; @Builder - public Booking(int purchaseTicketCount, String bookerName, String bookerPhoneNumber, boolean isPaymentCompleted, String birthDate, String password, Schedule schedule, Users users) { + public Booking(int purchaseTicketCount, String bookerName, String bookerPhoneNumber, BookingStatus bookingStatus, String birthDate, String password, Schedule schedule, Users users) { this.purchaseTicketCount = purchaseTicketCount; this.bookerName = bookerName; this.bookerPhoneNumber = bookerPhoneNumber; - this.isPaymentCompleted = isPaymentCompleted; + this.bookingStatus = bookingStatus; this.birthDate = birthDate; this.password = password; this.schedule = schedule; this.users = users; } - public static Booking create(int purchaseTicketCount, String bookerName, String bookerPhoneNumber, boolean isPaymentCompleted, String birthDate, String password, Schedule schedule, Users users) { + public static Booking create(int purchaseTicketCount, String bookerName, String bookerPhoneNumber, BookingStatus bookingStatus, String birthDate, String password, Schedule schedule, Users users) { return Booking.builder() .purchaseTicketCount(purchaseTicketCount) .bookerName(bookerName) .bookerPhoneNumber(bookerPhoneNumber) - .isPaymentCompleted(isPaymentCompleted) + .bookingStatus(bookingStatus) .birthDate(birthDate) .password(password) .schedule(schedule) @@ -84,8 +90,10 @@ public static Booking create(int purchaseTicketCount, String bookerName, String .build(); } - public void setIsPaymentCompleted(boolean isPaymentCompleted) { - this.isPaymentCompleted = isPaymentCompleted; + public void setBookingStatus(BookingStatus bookingStatus) { + this.bookingStatus = bookingStatus; + if (bookingStatus == BookingStatus.BOOKING_CANCELLED) { + this.cancellationDate = LocalDateTime.now(); + } } - } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/booking/domain/BookingStatus.java b/src/main/java/com/beat/domain/booking/domain/BookingStatus.java new file mode 100644 index 00000000..74d5a757 --- /dev/null +++ b/src/main/java/com/beat/domain/booking/domain/BookingStatus.java @@ -0,0 +1,14 @@ +package com.beat.domain.booking.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum BookingStatus { + CHECKING_PAYMENT("입금확인중"), + BOOKING_CONFIRMED("예매 확정"), + BOOKING_CANCELLED("예매 취소"); + + private final String displayname; +} diff --git a/src/main/java/com/beat/domain/booking/exception/BookingSuccessCode.java b/src/main/java/com/beat/domain/booking/exception/BookingSuccessCode.java index e77708ff..a24a08ce 100644 --- a/src/main/java/com/beat/domain/booking/exception/BookingSuccessCode.java +++ b/src/main/java/com/beat/domain/booking/exception/BookingSuccessCode.java @@ -13,7 +13,7 @@ public enum BookingSuccessCode implements BaseSuccessCode { GUEST_BOOKING_RETRIEVE_SUCCESS(200, "비회원 예매 조회가 성공적으로 완료되었습니다."), TICKET_RETRIEVE_SUCCESS(200, "예매자 목록 조회가 성공적으로 완료되었습니다."), TICKET_UPDATE_SUCCESS(200, "예매자 입금여부 수정이 성공적으로 완료되었습니다."), - TICKET_DELETE_SUCCESS(200, "예매자 삭제 요청이 성공했습니다.") + TICKET_CANCEL_SUCCESS(200, "예매취소 요청이 성공했습니다.") ; private final int status; diff --git a/src/main/java/com/beat/domain/booking/exception/TicketErrorCode.java b/src/main/java/com/beat/domain/booking/exception/TicketErrorCode.java new file mode 100644 index 00000000..b3376117 --- /dev/null +++ b/src/main/java/com/beat/domain/booking/exception/TicketErrorCode.java @@ -0,0 +1,14 @@ +package com.beat.domain.booking.exception; + +import com.beat.global.common.exception.base.BaseErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum TicketErrorCode implements BaseErrorCode { + PAYMENT_COMPLETED_TICKET_UPDATE_NOT_ALLOWED(400, "이미 결제가 완료된 티켓의 상태는 변경할 수 없습니다."); + + private final int status; + private final String message; +} diff --git a/src/main/java/com/beat/domain/cast/dao/CastRepository.java b/src/main/java/com/beat/domain/cast/dao/CastRepository.java index 37eb520b..98e6214b 100644 --- a/src/main/java/com/beat/domain/cast/dao/CastRepository.java +++ b/src/main/java/com/beat/domain/cast/dao/CastRepository.java @@ -2,6 +2,7 @@ import com.beat.domain.cast.domain.Cast; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.List; @@ -9,4 +10,7 @@ public interface CastRepository extends JpaRepository { List findByPerformanceId(Long performanceId); List findAllByPerformanceId(Long performanceId); + + @Query("SELECT c.id FROM Cast c WHERE c.performance.id = :performanceId") + List findIdsByPerformanceId(Long performanceId); } diff --git a/src/main/java/com/beat/domain/cast/exception/CastErrorCode.java b/src/main/java/com/beat/domain/cast/exception/CastErrorCode.java index 9658d8ab..15189c27 100644 --- a/src/main/java/com/beat/domain/cast/exception/CastErrorCode.java +++ b/src/main/java/com/beat/domain/cast/exception/CastErrorCode.java @@ -7,6 +7,7 @@ @Getter @RequiredArgsConstructor public enum CastErrorCode implements BaseErrorCode { + CAST_NOT_BELONG_TO_PERFORMANCE(403,"해당 등장인물은 해당 공연에 속해 있지 않습니다."), CAST_NOT_FOUND(404, "등장인물이 존재하지 않습니다.") ; diff --git a/src/main/java/com/beat/domain/member/api/MemberController.java b/src/main/java/com/beat/domain/member/api/MemberController.java index 08c06b30..f246a74d 100644 --- a/src/main/java/com/beat/domain/member/api/MemberController.java +++ b/src/main/java/com/beat/domain/member/api/MemberController.java @@ -1,6 +1,8 @@ package com.beat.domain.member.api; +import com.beat.domain.member.application.AuthenticationService; import com.beat.domain.member.application.MemberService; +import com.beat.domain.member.application.SocialLoginService; import com.beat.domain.member.dto.*; import com.beat.domain.member.exception.MemberSuccessCode; import com.beat.global.auth.client.dto.MemberLoginRequest; @@ -20,8 +22,10 @@ @RequestMapping("/api/users") @RequiredArgsConstructor public class MemberController { - private final MemberService memberService; private final TokenService tokenService; + private final AuthenticationService authenticationService; + private final SocialLoginService socialLoginService; + private final static int COOKIE_MAX_AGE = 7 * 24 * 60 * 60; private final static String REFRESH_TOKEN = "refreshToken"; @@ -32,7 +36,7 @@ public ResponseEntity> signUp( @RequestBody final MemberLoginRequest loginRequest, HttpServletResponse response ) { - LoginSuccessResponse loginSuccessResponse = memberService.create(authorizationCode, loginRequest); + LoginSuccessResponse loginSuccessResponse = socialLoginService.handleSocialLogin(authorizationCode, loginRequest); ResponseCookie cookie = ResponseCookie.from(REFRESH_TOKEN, loginSuccessResponse.refreshToken()) .maxAge(COOKIE_MAX_AGE) .path("/") @@ -42,7 +46,7 @@ public ResponseEntity> signUp( .build(); response.setHeader("Set-Cookie", cookie.toString()); return ResponseEntity.status(HttpStatus.OK) - .body(SuccessResponse.of(MemberSuccessCode.SIGN_UP_SUCCESS, LoginSuccessResponse.of(loginSuccessResponse.accessToken(), null, loginSuccessResponse.nickname()))); + .body(SuccessResponse.of(MemberSuccessCode.SIGN_UP_SUCCESS, LoginSuccessResponse.of(loginSuccessResponse.accessToken(), null, loginSuccessResponse.nickname(), loginSuccessResponse.role()))); } @Operation(summary = "access token 재발급 API", description = "refresh token으로 access token을 재발급하는 GET API입니다.") @@ -50,7 +54,7 @@ public ResponseEntity> signUp( public ResponseEntity> refreshToken( @RequestParam final String refreshToken ) { - AccessTokenGetSuccess accessTokenGetSuccess = memberService.refreshToken(refreshToken); + AccessTokenGetSuccess accessTokenGetSuccess = authenticationService.generateAccessTokenFromRefreshToken(refreshToken); return ResponseEntity.status(HttpStatus.OK) .body(SuccessResponse.of(MemberSuccessCode.ISSUE_REFRESH_TOKEN_SUCCESS, accessTokenGetSuccess)); } diff --git a/src/main/java/com/beat/domain/member/application/AuthenticationService.java b/src/main/java/com/beat/domain/member/application/AuthenticationService.java new file mode 100644 index 00000000..49e844c7 --- /dev/null +++ b/src/main/java/com/beat/domain/member/application/AuthenticationService.java @@ -0,0 +1,134 @@ +package com.beat.domain.member.application; + +import com.beat.domain.member.dto.AccessTokenGetSuccess; +import com.beat.domain.member.dto.LoginSuccessResponse; +import com.beat.domain.user.domain.Role; +import com.beat.domain.user.domain.Users; +import com.beat.global.auth.client.dto.MemberInfoResponse; +import com.beat.global.auth.jwt.application.TokenService; +import com.beat.global.auth.jwt.exception.TokenErrorCode; +import com.beat.global.auth.jwt.provider.JwtTokenProvider; +import com.beat.global.auth.jwt.provider.JwtValidationType; +import com.beat.global.auth.security.AdminAuthentication; +import com.beat.global.auth.security.MemberAuthentication; +import com.beat.global.common.exception.BadRequestException; +import com.beat.global.common.exception.BeatException; +import com.beat.global.common.exception.UnauthorizedException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AuthenticationService { + + private final JwtTokenProvider jwtTokenProvider; + private final TokenService tokenService; + + /** + * 사용자의 로그인 성공 시 Access Token과 Refresh Token을 생성하고, + * 로그인 성공 응답 객체(LoginSuccessResponse)를 반환하는 메서드. + * + * @param memberId 회원의 고유 ID + * @param user 로그인한 사용자의 정보가 포함된 Users 객체 + * @param memberInfoResponse 로그인 시 외부로부터 전달된 회원 정보 + * @return 로그인 성공 응답(LoginSuccessResponse) + */ + public LoginSuccessResponse generateLoginSuccessResponse(final Long memberId, final Users user, final MemberInfoResponse memberInfoResponse) { + String nickname = memberInfoResponse.nickname(); + Role role = user.getRole(); + Collection authorities = List.of(role.toGrantedAuthority()); + + log.info("Starting login success response generation for memberId: {}, nickname: {}, role: {}", memberId, nickname, role.getRoleName()); + + UsernamePasswordAuthenticationToken authenticationToken = createAuthenticationToken(memberId, role, authorities); + String refreshToken = issueAndSaveRefreshToken(memberId, authenticationToken); + String accessToken = jwtTokenProvider.issueAccessToken(authenticationToken); + + log.info("Login success for authorities: {}, accessToken: {}, refreshToken: {}", authorities, accessToken, refreshToken); + + return LoginSuccessResponse.of(accessToken, refreshToken, nickname, role.getRoleName()); + } + + /** + * Refresh Token을 사용하여 새로운 Access Token을 생성하는 메서드. + * + * Refresh Token에서 사용자 ID와 Role 정보를 추출한 후, + * Role에 따라 Admin 또는 Member 권한으로 새로운 Access Token을 발급합니다. + * + * @param refreshToken 사용자의 Refresh Token + * @return 새로운 Access Token 정보가 포함된 AccessTokenGetSuccess 객체 + */ + @Transactional + public AccessTokenGetSuccess generateAccessTokenFromRefreshToken(final String refreshToken) { + log.info("Validation result for refresh token: {}", jwtTokenProvider.validateToken(refreshToken)); + + JwtValidationType validationType = jwtTokenProvider.validateToken(refreshToken); + if (!validationType.equals(JwtValidationType.VALID_JWT)) { + log.warn("Invalid refresh token: {}", validationType); + throw switch (validationType) { + case EXPIRED_JWT_TOKEN -> new UnauthorizedException(TokenErrorCode.REFRESH_TOKEN_EXPIRED_ERROR); + case INVALID_JWT_TOKEN -> new BadRequestException(TokenErrorCode.INVALID_REFRESH_TOKEN_ERROR); + case INVALID_JWT_SIGNATURE -> new BadRequestException(TokenErrorCode.REFRESH_TOKEN_SIGNATURE_ERROR); + case UNSUPPORTED_JWT_TOKEN -> new BadRequestException(TokenErrorCode.UNSUPPORTED_REFRESH_TOKEN_ERROR); + case EMPTY_JWT -> new BadRequestException(TokenErrorCode.REFRESH_TOKEN_EMPTY_ERROR); + default -> new BeatException(TokenErrorCode.UNKNOWN_REFRESH_TOKEN_ERROR); + }; + } + + Long memberId = jwtTokenProvider.getMemberIdFromJwt(refreshToken); + + if (!memberId.equals(tokenService.findIdByRefreshToken(refreshToken))) { + log.error("MemberId mismatch: token does not match the stored refresh token"); + throw new BadRequestException(TokenErrorCode.REFRESH_TOKEN_MEMBER_ID_MISMATCH_ERROR); + } + + Role role = jwtTokenProvider.getRoleFromJwt(refreshToken); + Collection authorities = List.of(role.toGrantedAuthority()); + + UsernamePasswordAuthenticationToken authenticationToken = createAuthenticationToken(memberId, role, authorities); + log.info("Generated new access token for memberId: {}, role: {}, authorities: {}", + memberId, role.getRoleName(), authorities); + return AccessTokenGetSuccess.of(jwtTokenProvider.issueAccessToken(authenticationToken)); + } + + /** + * Refresh Token을 발급하고 저장하는 메서드. + * 발급된 Refresh Token을 TokenService에 저장 + * + * @param memberId 회원의 고유 ID + * @param authenticationToken 사용자 인증 정보 + * @return 발급된 Refresh Token + */ + private String issueAndSaveRefreshToken(Long memberId, UsernamePasswordAuthenticationToken authenticationToken) { + String refreshToken = jwtTokenProvider.issueRefreshToken(authenticationToken); + log.info("Issued new refresh token for memberId: {}", memberId); + tokenService.saveRefreshToken(memberId, refreshToken); + return refreshToken; + } + + /** + * 사용자 Role에 따라 적절한 Authentication 객체(Admin 또는 Member)를 생성하는 메서드. + * + * @param memberId 회원의 고유 ID + * @param role 사용자 Role (ADMIN 또는 MEMBER) + * @param authorities 사용자에게 부여된 권한 목록 + * @return 생성된 Admin 또는 Member Authentication 객체 + */ + private UsernamePasswordAuthenticationToken createAuthenticationToken(Long memberId, Role role, Collection authorities) { + if (role == Role.ADMIN) { + log.info("Creating AdminAuthentication for memberId: {}", memberId); + return new AdminAuthentication(memberId, null, authorities); + } else { + log.info("Creating MemberAuthentication for memberId: {}", memberId); + return new MemberAuthentication(memberId, null, authorities); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/member/application/MemberRegistrationService.java b/src/main/java/com/beat/domain/member/application/MemberRegistrationService.java new file mode 100644 index 00000000..5f19fc65 --- /dev/null +++ b/src/main/java/com/beat/domain/member/application/MemberRegistrationService.java @@ -0,0 +1,49 @@ +package com.beat.domain.member.application; + +import com.beat.domain.member.dao.MemberRepository; +import com.beat.domain.member.domain.Member; +import com.beat.domain.user.dao.UserRepository; +import com.beat.domain.user.domain.Role; +import com.beat.domain.user.domain.Users; +import com.beat.global.auth.client.dto.MemberInfoResponse; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@RequiredArgsConstructor +public class MemberRegistrationService { + + private final UserRepository userRepository; + private final MemberRepository memberRepository; + + @Transactional + public Long registerMemberWithUserInfo(final MemberInfoResponse memberInfoResponse) { + Users users = Users.createWithRole(Role.MEMBER); + + log.info("Granting MEMBER role to new user with role: {}", users.getRole()); + + users = userRepository.save(users); + userRepository.flush(); + + log.info("Registering new user with role: {}", users.getRole()); + + Member member = Member.create( + memberInfoResponse.nickname(), + memberInfoResponse.email(), + users, + memberInfoResponse.socialId(), + memberInfoResponse.socialType() + ); + + memberRepository.save(member); + + log.info("Member registered with memberId: {}, role: {}", member.getId(), users.getRole()); + + return member.getId(); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/member/application/MemberService.java b/src/main/java/com/beat/domain/member/application/MemberService.java index d0c68a6f..5fdb3a4b 100644 --- a/src/main/java/com/beat/domain/member/application/MemberService.java +++ b/src/main/java/com/beat/domain/member/application/MemberService.java @@ -3,20 +3,15 @@ import com.beat.domain.member.dao.MemberRepository; import com.beat.domain.member.domain.Member; import com.beat.domain.member.domain.SocialType; -import com.beat.domain.member.dto.*; import com.beat.domain.member.exception.MemberErrorCode; +import com.beat.domain.member.port.in.MemberUseCase; import com.beat.domain.user.dao.UserRepository; import com.beat.domain.user.domain.Users; -import com.beat.global.auth.client.dto.MemberInfoResponse; -import com.beat.global.auth.client.dto.MemberLoginRequest; -import com.beat.global.auth.client.service.KakaoSocialService; -import com.beat.global.auth.jwt.application.TokenService; -import com.beat.global.auth.jwt.exception.TokenErrorCode; -import com.beat.global.auth.jwt.provider.JwtTokenProvider; -import com.beat.global.auth.security.MemberAuthentication; import com.beat.global.common.exception.*; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,114 +19,35 @@ @RequiredArgsConstructor @Transactional(readOnly = true) @Service -public class MemberService { - private final UserRepository userRepository; - private final MemberRepository memberRepository; - private final JwtTokenProvider jwtTokenProvider; - private final TokenService tokenService; - private final KakaoSocialService kakaoSocialService; - - @Transactional - public LoginSuccessResponse create( - final String authorizationCode, - final MemberLoginRequest loginRequest - ) { - return getTokenDto(getUserInfoResponse(authorizationCode, loginRequest)); - } - - public MemberInfoResponse getUserInfoResponse( - final String authorizationCode, - final MemberLoginRequest loginRequest - ) { - switch (loginRequest.socialType()) { - case KAKAO: - return kakaoSocialService.login(authorizationCode, loginRequest); - default: - throw new BadRequestException(MemberErrorCode.SOCIAL_TYPE_BAD_REQUEST); - } - } - - @Transactional - public Long createUser(final MemberInfoResponse userResponse) { - Users users = Users.create(); - users = userRepository.save(users); - - Member member = Member.create( - userResponse.nickname(), - userResponse.email(), - users, - userResponse.socialId(), - userResponse.socialType() - ); - - memberRepository.save(member); - - return member.getId(); - } - - public Member getBySocialId( - final Long socialId, - final SocialType socialType) { - Member member = memberRepository.findBySocialTypeAndSocialId(socialId, socialType).orElseThrow( - () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND) - ); - return member; - } - - @Transactional - public AccessTokenGetSuccess refreshToken( - final String refreshToken - ) { - Long memberId = jwtTokenProvider.getUserFromJwt(refreshToken); - if (!memberId.equals(tokenService.findIdByRefreshToken(refreshToken))) { - throw new BadRequestException(TokenErrorCode.TOKEN_INCORRECT_ERROR); - } - MemberAuthentication memberAuthentication = new MemberAuthentication(memberId, null, null); - return AccessTokenGetSuccess.of( - jwtTokenProvider.issueAccessToken(memberAuthentication) - ); - } - - public boolean isExistingMember( - final Long socialId, - final SocialType socialType - ) { - return memberRepository.findBySocialTypeAndSocialId(socialId, socialType).isPresent(); - } - - public LoginSuccessResponse getTokenByMemberId( - final Long id, - final MemberInfoResponse memberInfoResponse - ) { - MemberAuthentication memberAuthentication = new MemberAuthentication(id, null, null); - String refreshToken = jwtTokenProvider.issueRefreshToken(memberAuthentication); - tokenService.saveRefreshToken(id, refreshToken); - String nickname = memberInfoResponse.nickname(); - return LoginSuccessResponse.of( - jwtTokenProvider.issueAccessToken(memberAuthentication), - refreshToken, nickname - ); - } - - @Transactional - public void deleteUser( - final Long id - ) { - Users users = userRepository.findById(id) - .orElseThrow( - () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND) - ); - userRepository.delete(users); - } - - private LoginSuccessResponse getTokenDto( - final MemberInfoResponse userResponse - ) { - if (isExistingMember(userResponse.socialId(), userResponse.socialType())) { - return getTokenByMemberId(getBySocialId(userResponse.socialId(), userResponse.socialType()).getId(), userResponse); - } else { - Long id = createUser(userResponse); - return getTokenByMemberId(id, userResponse); - } - } +public class MemberService implements MemberUseCase { + private final UserRepository userRepository; + private final MemberRepository memberRepository; + + @Override + @Transactional(readOnly = true) + public Member findMemberByMemberId(Long memberId) { + return memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + } + + @Override + @Transactional(readOnly = true) + public boolean checkMemberExistsBySocialIdAndSocialType(final Long socialId, final SocialType socialType) { + return memberRepository.findBySocialTypeAndSocialId(socialId, socialType).isPresent(); + } + + @Override + @Transactional(readOnly = true) + public Member findMemberBySocialIdAndSocialType(final Long socialId, final SocialType socialType) { + return memberRepository.findBySocialTypeAndSocialId(socialId, socialType) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + } + + @Transactional + public void deleteUser(final Long id) { + Users users = userRepository.findById(id) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + userRepository.delete(users); + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/member/application/SocialLoginService.java b/src/main/java/com/beat/domain/member/application/SocialLoginService.java new file mode 100644 index 00000000..36b304c9 --- /dev/null +++ b/src/main/java/com/beat/domain/member/application/SocialLoginService.java @@ -0,0 +1,119 @@ +package com.beat.domain.member.application; + +import com.beat.domain.member.domain.Member; +import com.beat.domain.member.domain.SocialType; +import com.beat.domain.member.dto.LoginSuccessResponse; +import com.beat.domain.member.exception.MemberErrorCode; +import com.beat.domain.member.port.in.MemberUseCase; +import com.beat.domain.user.domain.Users; +import com.beat.domain.user.port.in.UserUseCase; +import com.beat.global.auth.client.application.KakaoSocialService; +import com.beat.global.auth.client.application.SocialService; +import com.beat.global.auth.client.dto.MemberInfoResponse; +import com.beat.global.auth.client.dto.MemberLoginRequest; +import com.beat.global.common.exception.BadRequestException; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class SocialLoginService { + + private final MemberRegistrationService memberRegistrationService; + private final AuthenticationService authenticationService; + private final KakaoSocialService kakaoSocialService; + private final MemberUseCase memberUseCase; + + /** + * 소셜 로그인 또는 회원가입을 처리하는 메서드. + * 소셜 서비스에서 받은 authorizationCode와 로그인 요청 정보를 기반으로 + * 사용자 정보를 조회하고, 로그인 또는 회원가입 후 성공 응답을 반환. + * + * @param authorizationCode 소셜 인증 코드 + * @param loginRequest 로그인 요청 정보 + * @return 로그인 성공 응답(LoginSuccessResponse) + */ + @Transactional + public LoginSuccessResponse handleSocialLogin(final String authorizationCode, + final MemberLoginRequest loginRequest) { + MemberInfoResponse memberInfoResponse = findMemberInfoFromSocialService(authorizationCode, loginRequest); + return generateLoginResponseFromMemberInfo(memberInfoResponse); + } + + /** + * 소셜 서비스에서 사용자 정보를 조회하는 메서드. + * 소셜 타입에 따라 적절한 소셜 서비스를 사용하여 로그인 정보를 가져옴. + * + * @param authorizationCode 소셜 인증 코드 + * @param loginRequest 로그인 요청 정보 + * @return 소셜 서비스에서 가져온 사용자 정보(MemberInfoResponse) + */ + private MemberInfoResponse findMemberInfoFromSocialService(final String authorizationCode, + final MemberLoginRequest loginRequest) { + SocialService socialService = findSocialService(loginRequest.socialType()); + return socialService.login(authorizationCode, loginRequest); + } + + /** + * 소셜 타입에 맞는 SocialService를 반환하는 메서드. + * 소셜 로그인 타입이 KAKAO인지, GOOGLE인지 등에 따라 적절한 서비스를 반환. + * + * @param socialType 소셜 타입(KAKAO, GOOGLE 등) + * @return 적절한 SocialService 구현체 + */ + private SocialService findSocialService(SocialType socialType) { + return switch (socialType) { + case KAKAO -> kakaoSocialService; + // case GOOGLE -> googleSocialService; + default -> throw new BadRequestException(MemberErrorCode.SOCIAL_TYPE_BAD_REQUEST); + }; + } + + /** + * 사용자 정보를 기반으로 로그인 또는 회원가입을 처리한 후 로그인 성공 응답을 생성하는 메서드. + * 사용자가 존재하면 로그인 처리를, 존재하지 않으면 회원가입 후 로그인 처리를 수행. + * + * @param memberInfoResponse 소셜 서비스에서 가져온 사용자 정보 + * @return 로그인 성공 응답(LoginSuccessResponse) + */ + private LoginSuccessResponse generateLoginResponseFromMemberInfo(final MemberInfoResponse memberInfoResponse) { + log.info("Attempting to find or register member for socialId: {}, socialType: {}", + memberInfoResponse.socialId(), memberInfoResponse.socialType()); + + Long memberId = findOrRegisterMember(memberInfoResponse); + log.info("Found or registered member with memberId: {}", memberId); + + Member member = memberUseCase.findMemberByMemberId(memberId); + Users user = member.getUser(); + + log.info("User role before generating token: {}", user.getRole()); + + return authenticationService.generateLoginSuccessResponse(memberId, user, memberInfoResponse); + } + + /** + * 사용자 정보(Social ID와 Social Type)를 통해 기존 회원을 찾거나, + * 없으면 새로운 회원을 등록하는 메서드. + * + * @param memberInfoResponse 소셜 서비스에서 가져온 사용자 정보 + * @return 등록된 회원 또는 기존 회원의 ID + */ + private Long findOrRegisterMember(final MemberInfoResponse memberInfoResponse) { + boolean memberExists = memberUseCase.checkMemberExistsBySocialIdAndSocialType(memberInfoResponse.socialId(), + memberInfoResponse.socialType()); + + if (memberExists) { + Member existingMember = memberUseCase.findMemberBySocialIdAndSocialType(memberInfoResponse.socialId(), + memberInfoResponse.socialType()); + log.info("Existing member role: {}", existingMember.getUser().getRole()); + return existingMember.getId(); + } + + return memberRegistrationService.registerMemberWithUserInfo(memberInfoResponse); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/member/domain/Member.java b/src/main/java/com/beat/domain/member/domain/Member.java index 90951b30..02a67ac7 100644 --- a/src/main/java/com/beat/domain/member/domain/Member.java +++ b/src/main/java/com/beat/domain/member/domain/Member.java @@ -2,7 +2,17 @@ import com.beat.domain.BaseTimeEntity; import com.beat.domain.user.domain.Users; -import jakarta.persistence.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,7 +23,7 @@ @Entity @Getter -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member extends BaseTimeEntity { @Id @@ -29,7 +39,7 @@ public class Member extends BaseTimeEntity { @Column(nullable = true) private LocalDateTime deletedAt; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = true) @OnDelete(action = OnDeleteAction.CASCADE) private Users user; diff --git a/src/main/java/com/beat/domain/member/dto/LoginSuccessResponse.java b/src/main/java/com/beat/domain/member/dto/LoginSuccessResponse.java index 57b0576e..026bd3d1 100644 --- a/src/main/java/com/beat/domain/member/dto/LoginSuccessResponse.java +++ b/src/main/java/com/beat/domain/member/dto/LoginSuccessResponse.java @@ -3,13 +3,15 @@ public record LoginSuccessResponse( String accessToken, String refreshToken, - String nickname + String nickname, + String role ) { public static LoginSuccessResponse of( final String accessToken, final String refreshToken, - final String nickname + final String nickname, + final String role ) { - return new LoginSuccessResponse(accessToken, refreshToken, nickname); + return new LoginSuccessResponse(accessToken, refreshToken, nickname, role); } } diff --git a/src/main/java/com/beat/domain/member/port/in/MemberUseCase.java b/src/main/java/com/beat/domain/member/port/in/MemberUseCase.java new file mode 100644 index 00000000..d6a194b1 --- /dev/null +++ b/src/main/java/com/beat/domain/member/port/in/MemberUseCase.java @@ -0,0 +1,14 @@ +package com.beat.domain.member.port.in; + +import com.beat.domain.member.domain.Member; +import com.beat.domain.member.domain.SocialType; + +public interface MemberUseCase { + Member findMemberByMemberId(Long memberId); + + boolean checkMemberExistsBySocialIdAndSocialType(Long socialId, SocialType socialType); + + Member findMemberBySocialIdAndSocialType(Long socialId, SocialType socialType); + + void deleteUser(Long id); +} diff --git a/src/main/java/com/beat/domain/performance/api/HomeApi.java b/src/main/java/com/beat/domain/performance/api/HomeApi.java new file mode 100644 index 00000000..0b6e9e58 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/api/HomeApi.java @@ -0,0 +1,33 @@ +package com.beat.domain.performance.api; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestParam; + +import com.beat.domain.performance.application.dto.home.HomeFindAllResponse; +import com.beat.domain.performance.domain.Genre; +import com.beat.global.common.dto.ErrorResponse; +import com.beat.global.common.dto.SuccessResponse; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "Home", description = "홈 화면에서 공연 및 홍보목록 조회 API") +public interface HomeApi { + + @Operation(summary = "전체 공연 및 홍보 목록 조회", description = "홈 화면에서 전체 공연 목록 및 홍보 목록을 조회하는 GET API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "홈 화면 공연 목록 조회가 성공적으로 완료되었습니다.", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ) + } + ) + ResponseEntity> getHomePerformanceList( + @RequestParam(required = false) Genre genre); +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/api/HomeController.java b/src/main/java/com/beat/domain/performance/api/HomeController.java index 7a7a7159..8ebd44b2 100644 --- a/src/main/java/com/beat/domain/performance/api/HomeController.java +++ b/src/main/java/com/beat/domain/performance/api/HomeController.java @@ -1,13 +1,14 @@ package com.beat.domain.performance.api; -import com.beat.domain.performance.application.PerformanceService; -import com.beat.domain.performance.application.dto.home.HomeRequest; -import com.beat.domain.performance.application.dto.home.HomeResponse; +import com.beat.domain.performance.application.HomeService; +import com.beat.domain.performance.application.dto.home.HomeFindRequest; +import com.beat.domain.performance.application.dto.home.HomeFindAllResponse; import com.beat.domain.performance.domain.Genre; import com.beat.domain.performance.exception.PerformanceSuccessCode; import com.beat.global.common.dto.SuccessResponse; -import io.swagger.v3.oas.annotations.Operation; + import lombok.RequiredArgsConstructor; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -17,19 +18,19 @@ @RestController @RequestMapping("/api/main") @RequiredArgsConstructor -public class HomeController { - - private final PerformanceService performanceService; - - @Operation(summary = "전체공연목록, 홍보목록 조회 API", description = "홈화면에서 전체공연목록, 홍보목록을 조회하는 GET API입니다.") - @GetMapping - public ResponseEntity> getHomePerformanceList(@RequestParam(required = false) String genre) { - HomeRequest homeRequest; - if (genre != null) { - homeRequest = new HomeRequest(Genre.valueOf(genre)); - } else { - homeRequest = new HomeRequest(null); - } HomeResponse homeResponse = performanceService.getHomePerformanceList(homeRequest); - return ResponseEntity.ok(SuccessResponse.of(PerformanceSuccessCode.HOME_PERFORMANCE_RETRIEVE_SUCCESS, homeResponse)); - } +public class HomeController implements HomeApi { + + private final HomeService homeService; + + @Override + @GetMapping + public ResponseEntity> getHomePerformanceList( + @RequestParam(required = false) Genre genre) { + + HomeFindRequest request = new HomeFindRequest(genre); + + HomeFindAllResponse response = homeService.findHomePerformanceList(request); + return ResponseEntity.ok( + SuccessResponse.of(PerformanceSuccessCode.HOME_PERFORMANCE_RETRIEVE_SUCCESS, response)); + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/api/PerformanceController.java b/src/main/java/com/beat/domain/performance/api/PerformanceController.java index adf3a9a4..6cc25c77 100644 --- a/src/main/java/com/beat/domain/performance/api/PerformanceController.java +++ b/src/main/java/com/beat/domain/performance/api/PerformanceController.java @@ -1,20 +1,22 @@ package com.beat.domain.performance.api; import com.beat.domain.performance.application.PerformanceManagementService; -import com.beat.domain.performance.application.PerformanceUpdateService; -import com.beat.domain.performance.application.dto.BookingPerformanceDetailResponse; -import com.beat.domain.performance.application.dto.MakerPerformanceResponse; -import com.beat.domain.performance.application.dto.PerformanceDetailResponse; -import com.beat.domain.performance.application.dto.PerformanceEditResponse; +import com.beat.domain.performance.application.PerformanceModifyService; +import com.beat.domain.performance.application.dto.bookingPerformanceDetail.BookingPerformanceDetailResponse; +import com.beat.domain.performance.application.dto.makerPerformance.MakerPerformanceResponse; +import com.beat.domain.performance.application.dto.performanceDetail.PerformanceDetailResponse; +import com.beat.domain.performance.application.dto.modify.PerformanceModifyDetailResponse; import com.beat.domain.performance.application.dto.create.PerformanceRequest; import com.beat.domain.performance.application.dto.create.PerformanceResponse; -import com.beat.domain.performance.application.dto.update.PerformanceUpdateRequest; -import com.beat.domain.performance.application.dto.update.PerformanceUpdateResponse; +import com.beat.domain.performance.application.dto.modify.PerformanceModifyRequest; +import com.beat.domain.performance.application.dto.modify.PerformanceModifyResponse; import com.beat.domain.performance.exception.PerformanceSuccessCode; import com.beat.domain.performance.application.PerformanceService; import com.beat.global.auth.annotation.CurrentMember; import com.beat.global.common.dto.SuccessResponse; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -34,7 +36,7 @@ public class PerformanceController { private final PerformanceService performanceService; private final PerformanceManagementService performanceManagementService; - private final PerformanceUpdateService performanceUpdateService; + private final PerformanceModifyService performanceModifyService; @Operation(summary = "공연 생성 API", description = "공연을 생성하는 POST API입니다.") @PostMapping @@ -47,21 +49,35 @@ public ResponseEntity> createPerformance( } @Operation(summary = "공연 정보 수정 API", description = "공연 정보를 수정하는 PUT API입니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "공연 정보 수정 성공"), + @ApiResponse(responseCode = "400", description = "잘못된 요청 - 회차 최대 개수 초과"), + @ApiResponse(responseCode = "400", description = "잘못된 요청 - 티켓 가격은 음수일 수 없습니다."), + @ApiResponse(responseCode = "400", description = "잘못된 요청 - 예매자가 존재하여 가격을 수정할 수 없습니다."), + @ApiResponse(responseCode = "403", description = "권한 없음 - 해당 공연의 소유자가 아닙니다."), + @ApiResponse(responseCode = "404", description = "존재하지 않는 공연 ID로 수정 요청을 보낼 수 없습니다."), + @ApiResponse(responseCode = "404", description = "존재하지 않는 회원 ID로 수정 요청을 보낼 수 없습니다."), + @ApiResponse(responseCode = "404", description = "존재하지 않는 회차 ID로 수정 요청을 보낼 수 없습니다."), + @ApiResponse(responseCode = "404", description = "존재하지 않는 등장인물 ID로 수정 요청을 보낼 수 없습니다."), + @ApiResponse(responseCode = "404", description = "존재하지 않는 스태프 ID로 수정 요청을 보낼 수 없습니다."), + @ApiResponse(responseCode = "404", description = "존재하지 않는 상세이미지 ID로 수정 요청을 보낼 수 없습니다."), + @ApiResponse(responseCode = "500", description = "서버 내부 오류") + }) @PutMapping - public ResponseEntity> updatePerformance( + public ResponseEntity> updatePerformance( @CurrentMember Long memberId, - @RequestBody PerformanceUpdateRequest performanceUpdateRequest) { - PerformanceUpdateResponse response = performanceUpdateService.updatePerformance(memberId, performanceUpdateRequest); + @RequestBody PerformanceModifyRequest performanceModifyRequest) { + PerformanceModifyResponse response = performanceModifyService.modifyPerformance(memberId, performanceModifyRequest); return ResponseEntity.status(HttpStatus.OK) .body(SuccessResponse.of(PerformanceSuccessCode.PERFORMANCE_UPDATE_SUCCESS, response)); } @Operation(summary = "공연 수정 페이지 정보 조회 API", description = "공연 정보를 조회하는 GET API입니다.") @GetMapping("/{performanceId}") - public ResponseEntity> getPerformanceForEdit( + public ResponseEntity> getPerformanceForEdit( @CurrentMember Long memberId, @PathVariable Long performanceId) { - PerformanceEditResponse response = performanceService.getPerformanceEdit(memberId, performanceId); + PerformanceModifyDetailResponse response = performanceService.getPerformanceEdit(memberId, performanceId); return ResponseEntity.ok(SuccessResponse.of(PerformanceSuccessCode.PERFORMANCE_MODIFY_PAGE_SUCCESS, response)); } diff --git a/src/main/java/com/beat/domain/performance/application/HomeService.java b/src/main/java/com/beat/domain/performance/application/HomeService.java new file mode 100644 index 00000000..6ac6887c --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/HomeService.java @@ -0,0 +1,71 @@ +package com.beat.domain.performance.application; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.beat.domain.performance.application.dto.home.HomeFindAllResponse; +import com.beat.domain.performance.application.dto.home.HomeFindRequest; +import com.beat.domain.performance.application.dto.home.HomePerformanceDetail; +import com.beat.domain.performance.application.dto.home.HomePromotionDetail; +import com.beat.domain.performance.dao.PerformanceRepository; +import com.beat.domain.performance.domain.Genre; +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.promotion.port.in.PromotionUseCase; +import com.beat.domain.schedule.application.ScheduleService; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class HomeService { + + private final ScheduleService scheduleService; + private final PromotionUseCase promotionUseCase; + + private final PerformanceRepository performanceRepository; + + @Transactional(readOnly = true) + public HomeFindAllResponse findHomePerformanceList(HomeFindRequest homeFindRequest) { + + List performances = findPerformancesByGenre(homeFindRequest); + List promotions = findAllPromotionsSortedByCarouselNumber(); + + if (performances.isEmpty()) { + return HomeFindAllResponse.of(promotions, new ArrayList<>()); + } + + List sortedPerformances = performances.stream() + .map(performance -> { + int minDueDate = scheduleService.getMinDueDateForPerformance(performance.getId()); + return HomePerformanceDetail.of(performance, minDueDate); + }) + .sorted(Comparator.comparingInt(detail -> detail.dueDate() < 0 ? 1 : 0) + .thenComparingInt(detail -> Math.abs(detail.dueDate()))) + .toList(); + + return HomeFindAllResponse.of(promotions, sortedPerformances); + } + + private List findPerformancesByGenre(HomeFindRequest homeFindRequest) { + Genre genre = homeFindRequest.genre(); + + if (genre != null) { + return performanceRepository.findByGenre(genre); + } + + return performanceRepository.findAll(); + } + + private List findAllPromotionsSortedByCarouselNumber() { + return promotionUseCase.findAllPromotions() + .stream() + .sorted(Comparator.comparing(Promotion::getCarouselNumber, Comparator.comparingInt(Enum::ordinal))) + .map(HomePromotionDetail::from) + .toList(); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java b/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java index 0e3efa88..289a77ac 100644 --- a/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java +++ b/src/main/java/com/beat/domain/performance/application/PerformanceManagementService.java @@ -1,5 +1,14 @@ package com.beat.domain.performance.application; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import com.beat.domain.booking.dao.BookingRepository; import com.beat.domain.cast.dao.CastRepository; import com.beat.domain.cast.domain.Cast; @@ -7,181 +16,220 @@ import com.beat.domain.member.domain.Member; import com.beat.domain.member.exception.MemberErrorCode; import com.beat.domain.performance.application.dto.create.CastResponse; +import com.beat.domain.performance.application.dto.create.PerformanceImageResponse; import com.beat.domain.performance.application.dto.create.PerformanceRequest; import com.beat.domain.performance.application.dto.create.PerformanceResponse; import com.beat.domain.performance.application.dto.create.ScheduleResponse; import com.beat.domain.performance.application.dto.create.StaffResponse; +import com.beat.domain.performance.dao.PerformanceImageRepository; import com.beat.domain.performance.dao.PerformanceRepository; import com.beat.domain.performance.domain.Performance; +import com.beat.domain.performance.domain.PerformanceImage; import com.beat.domain.performance.exception.PerformanceErrorCode; import com.beat.domain.schedule.dao.ScheduleRepository; import com.beat.domain.schedule.domain.Schedule; import com.beat.domain.staff.dao.StaffRepository; import com.beat.domain.staff.domain.Staff; import com.beat.domain.user.domain.Users; +import com.beat.global.common.exception.BadRequestException; import com.beat.global.common.exception.ForbiddenException; import com.beat.global.common.exception.NotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; +import com.beat.global.common.scheduler.application.JobSchedulerService; -import java.time.LocalDate; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; @Service @RequiredArgsConstructor public class PerformanceManagementService { - private final PerformanceRepository performanceRepository; - private final ScheduleRepository scheduleRepository; - private final CastRepository castRepository; - private final StaffRepository staffRepository; - private final BookingRepository bookingRepository; - private final MemberRepository memberRepository; - - @Transactional - public PerformanceResponse createPerformance(Long memberId, PerformanceRequest request) { - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Users user = member.getUser(); - - Performance performance = Performance.create( - request.performanceTitle(), - request.genre(), - request.runningTime(), - request.performanceDescription(), - request.performanceAttentionNote(), - request.bankName(), - request.accountNumber(), - request.accountHolder(), - request.posterImage(), - request.performanceTeamName(), - request.performanceVenue(), - request.performanceContact(), - request.performancePeriod(), - request.ticketPrice(), - request.totalScheduleCount(), - user - ); - performanceRepository.save(performance); - - List schedules = request.scheduleList().stream() - .map(scheduleRequest -> Schedule.create( - scheduleRequest.performanceDate(), - scheduleRequest.totalTicketCount(), - 0, - true, - scheduleRequest.scheduleNumber(), - performance - )) - .collect(Collectors.toList()); - scheduleRepository.saveAll(schedules); - - List casts = request.castList().stream() - .map(castRequest -> Cast.create( - castRequest.castName(), - castRequest.castRole(), - castRequest.castPhoto(), - performance - )) - .collect(Collectors.toList()); - castRepository.saveAll(casts); - - List staffs = request.staffList().stream() - .map(staffRequest -> Staff.create( - staffRequest.staffName(), - staffRequest.staffRole(), - staffRequest.staffPhoto(), - performance - )) - .collect(Collectors.toList()); - staffRepository.saveAll(staffs); - - return mapToPerformanceResponse(performance, schedules, casts, staffs); - } - - private PerformanceResponse mapToPerformanceResponse(Performance performance, List schedules, List casts, List staffs) { - List scheduleResponses = schedules.stream() - .map(schedule -> ScheduleResponse.of( - schedule.getId(), - schedule.getPerformanceDate(), - schedule.getTotalTicketCount(), - calculateDueDate(schedule.getPerformanceDate().toLocalDate()), - schedule.getScheduleNumber() - )) - .collect(Collectors.toList()); - - List castResponses = casts.stream() - .map(cast -> CastResponse.of( - cast.getId(), - cast.getCastName(), - cast.getCastRole(), - cast.getCastPhoto() - )) - .collect(Collectors.toList()); - - List staffResponses = staffs.stream() - .map(staff -> StaffResponse.of( - staff.getId(), - staff.getStaffName(), - staff.getStaffRole(), - staff.getStaffPhoto() - )) - .collect(Collectors.toList()); - - return PerformanceResponse.of( - performance.getUsers().getId(), - performance.getId(), - performance.getPerformanceTitle(), - performance.getGenre(), - performance.getRunningTime(), - performance.getPerformanceDescription(), - performance.getPerformanceAttentionNote(), - performance.getBankName(), - performance.getAccountNumber(), - performance.getAccountHolder(), - performance.getPosterImage(), - performance.getPerformanceTeamName(), - performance.getPerformanceVenue(), - performance.getPerformanceContact(), - performance.getPerformancePeriod(), - performance.getTicketPrice(), - performance.getTotalScheduleCount(), - scheduleResponses, - castResponses, - staffResponses - ); - } - - private int calculateDueDate(LocalDate performanceDate) { - return (int) ChronoUnit.DAYS.between(LocalDate.now(), performanceDate); - } - - @Transactional - public void deletePerformance(Long memberId, Long performanceId) { - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Long userId = member.getUser().getId(); - - Performance performance = performanceRepository.findById(performanceId) - .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - - if (!performance.getUsers().getId().equals(userId)) { - throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); - } - - List scheduleIds = scheduleRepository.findIdsByPerformanceId(performanceId); - - boolean hasBookings = bookingRepository.existsByScheduleIdIn(scheduleIds); - - if (hasBookings) { - throw new ForbiddenException(PerformanceErrorCode.PERFORMANCE_DELETE_FAILED); - } - - performanceRepository.delete(performance); - } + private final PerformanceRepository performanceRepository; + private final ScheduleRepository scheduleRepository; + private final CastRepository castRepository; + private final StaffRepository staffRepository; + private final BookingRepository bookingRepository; + private final MemberRepository memberRepository; + private final PerformanceImageRepository performanceImageRepository; + private final JobSchedulerService jobSchedulerService; + + @Transactional + public PerformanceResponse createPerformance(Long memberId, PerformanceRequest request) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Users user = member.getUser(); + + if (request.performanceDescription().length() > 500) { + throw new BadRequestException(PerformanceErrorCode.INVALID_PERFORMANCE_DESCRIPTION_LENGTH); + } + + if (request.performanceAttentionNote().length() > 500) { + throw new BadRequestException(PerformanceErrorCode.INVALID_ATTENTION_NOTE_LENGTH); + } + + Performance performance = Performance.create( + request.performanceTitle(), + request.genre(), + request.runningTime(), + request.performanceDescription(), + request.performanceAttentionNote(), + request.bankName(), + request.accountNumber(), + request.accountHolder(), + request.posterImage(), + request.performanceTeamName(), + request.performanceVenue(), + request.performanceContact(), + request.performancePeriod(), + request.ticketPrice(), + request.totalScheduleCount(), + user + ); + performanceRepository.save(performance); + + List schedules = request.scheduleList().stream() + .map(scheduleRequest -> { + if (scheduleRequest.performanceDate().isBefore(LocalDateTime.now())) { + throw new BadRequestException(PerformanceErrorCode.PAST_SCHEDULE_NOT_ALLOWED); + } + return Schedule.create( + scheduleRequest.performanceDate(), + scheduleRequest.totalTicketCount(), + 0, + true, + scheduleRequest.scheduleNumber(), + performance + ); + }) + .collect(Collectors.toList()); + scheduleRepository.saveAll(schedules); + + schedules.forEach(jobSchedulerService::addScheduleIfNotExists); + + List casts = request.castList().stream() + .map(castRequest -> Cast.create( + castRequest.castName(), + castRequest.castRole(), + castRequest.castPhoto(), + performance + )) + .collect(Collectors.toList()); + castRepository.saveAll(casts); + + List staffs = request.staffList().stream() + .map(staffRequest -> Staff.create( + staffRequest.staffName(), + staffRequest.staffRole(), + staffRequest.staffPhoto(), + performance + )) + .collect(Collectors.toList()); + staffRepository.saveAll(staffs); + + List performanceImageList = request.performanceImageList().stream() + .map(performanceImageRequest -> PerformanceImage.create( + performanceImageRequest.performanceImage(), + performance + )) + .collect(Collectors.toList()); + performanceImageRepository.saveAll(performanceImageList); + + return mapToPerformanceResponse(performance, schedules, casts, staffs, performanceImageList); + } + + private PerformanceResponse mapToPerformanceResponse(Performance performance, List schedules, + List casts, List staffs, List performanceImages) { + List scheduleResponses = schedules.stream() + .map(schedule -> ScheduleResponse.of( + schedule.getId(), + schedule.getPerformanceDate(), + schedule.getTotalTicketCount(), + calculateDueDate(schedule.getPerformanceDate().toLocalDate()), + schedule.getScheduleNumber() + )) + .collect(Collectors.toList()); + + List castResponses = casts.stream() + .map(cast -> CastResponse.of( + cast.getId(), + cast.getCastName(), + cast.getCastRole(), + cast.getCastPhoto() + )) + .collect(Collectors.toList()); + + List staffResponses = staffs.stream() + .map(staff -> StaffResponse.of( + staff.getId(), + staff.getStaffName(), + staff.getStaffRole(), + staff.getStaffPhoto() + )) + .collect(Collectors.toList()); + + List performanceImageResponses = performanceImages.stream() + .map(image -> PerformanceImageResponse.of( + image.getId(), + image.getPerformanceImage() + )) + .collect(Collectors.toList()); + + return PerformanceResponse.of( + performance.getUsers().getId(), + performance.getId(), + performance.getPerformanceTitle(), + performance.getGenre(), + performance.getRunningTime(), + performance.getPerformanceDescription(), + performance.getPerformanceAttentionNote(), + performance.getBankName(), + performance.getAccountNumber(), + performance.getAccountHolder(), + performance.getPosterImage(), + performance.getPerformanceTeamName(), + performance.getPerformanceVenue(), + performance.getPerformanceContact(), + performance.getPerformancePeriod(), + performance.getTicketPrice(), + performance.getTotalScheduleCount(), + scheduleResponses, + castResponses, + staffResponses, + performanceImageResponses + ); + } + + private int calculateDueDate(LocalDate performanceDate) { + return (int)ChronoUnit.DAYS.between(LocalDate.now(), performanceDate); + } + + @Transactional + public void deletePerformance(Long memberId, Long performanceId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Long userId = member.getUser().getId(); + + Performance performance = performanceRepository.findById(performanceId) + .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); + + if (!performance.getUsers().getId().equals(userId)) { + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + + List scheduleIds = scheduleRepository.findIdsByPerformanceId(performanceId); + + boolean hasBookings = bookingRepository.existsByScheduleIdIn(scheduleIds); + + if (hasBookings) { + throw new ForbiddenException(PerformanceErrorCode.PERFORMANCE_DELETE_FAILED); + } + + // 모든 스케줄에 대해 등록된 TaskScheduler 작업을 취소 + List schedules = scheduleRepository.findByPerformanceId(performanceId); + for (Schedule schedule : schedules) { + jobSchedulerService.cancelScheduledTaskForPerformance(schedule); + } + + performanceRepository.delete(performance); + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceModifyService.java b/src/main/java/com/beat/domain/performance/application/PerformanceModifyService.java new file mode 100644 index 00000000..48db2f41 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/PerformanceModifyService.java @@ -0,0 +1,603 @@ +package com.beat.domain.performance.application; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.beat.domain.booking.dao.BookingRepository; +import com.beat.domain.cast.dao.CastRepository; +import com.beat.domain.cast.domain.Cast; +import com.beat.domain.cast.exception.CastErrorCode; +import com.beat.domain.member.dao.MemberRepository; +import com.beat.domain.member.domain.Member; +import com.beat.domain.member.exception.MemberErrorCode; +import com.beat.domain.performance.application.dto.modify.PerformanceModifyRequest; +import com.beat.domain.performance.application.dto.modify.PerformanceModifyResponse; +import com.beat.domain.performance.application.dto.modify.cast.CastModifyRequest; +import com.beat.domain.performance.application.dto.modify.cast.CastModifyResponse; +import com.beat.domain.performance.application.dto.modify.performanceImage.PerformanceImageModifyRequest; +import com.beat.domain.performance.application.dto.modify.performanceImage.PerformanceImageModifyResponse; +import com.beat.domain.performance.application.dto.modify.schedule.ScheduleModifyRequest; +import com.beat.domain.performance.application.dto.modify.schedule.ScheduleModifyResponse; +import com.beat.domain.performance.application.dto.modify.staff.StaffModifyRequest; +import com.beat.domain.performance.application.dto.modify.staff.StaffModifyResponse; +import com.beat.domain.performance.dao.PerformanceImageRepository; +import com.beat.domain.performance.dao.PerformanceRepository; +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.performance.domain.PerformanceImage; +import com.beat.domain.performance.exception.PerformanceErrorCode; +import com.beat.domain.performance.exception.PerformanceImageErrorCode; +import com.beat.domain.schedule.dao.ScheduleRepository; +import com.beat.domain.schedule.domain.Schedule; +import com.beat.domain.schedule.domain.ScheduleNumber; +import com.beat.domain.schedule.exception.ScheduleErrorCode; +import com.beat.domain.staff.dao.StaffRepository; +import com.beat.domain.staff.domain.Staff; +import com.beat.domain.staff.exception.StaffErrorCode; +import com.beat.global.common.exception.BadRequestException; +import com.beat.global.common.exception.ForbiddenException; +import com.beat.global.common.exception.NotFoundException; +import com.beat.global.common.scheduler.application.JobSchedulerService; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +public class PerformanceModifyService { + + private final PerformanceRepository performanceRepository; + private final ScheduleRepository scheduleRepository; + private final MemberRepository memberRepository; + private final CastRepository castRepository; + private final StaffRepository staffRepository; + private final BookingRepository bookingRepository; + private final PerformanceImageRepository performanceImageRepository; + private final JobSchedulerService jobSchedulerService; + + @Transactional + public PerformanceModifyResponse modifyPerformance(Long memberId, PerformanceModifyRequest request) { + log.info("Starting updatePerformance for memberId: {}, performanceId: {}", memberId, request.performanceId()); + + Member member = validateMember(memberId); + Long userId = member.getUser().getId(); + + Performance performance = findPerformance(request.performanceId()); + + validateOwnership(userId, performance); + + List scheduleIds = scheduleRepository.findIdsByPerformanceId(request.performanceId()); + boolean isBookerExist = bookingRepository.existsByScheduleIdIn(scheduleIds); + + if (isBookerExist && request.ticketPrice() != performance.getTicketPrice()) { + log.error("Ticket price update failed due to existing bookings for performanceId: {}", performance.getId()); + throw new BadRequestException(PerformanceErrorCode.PRICE_UPDATE_NOT_ALLOWED); + } + + updatePerformanceDetails(performance, request, isBookerExist); + + List modifiedSchedules = processSchedules(request.scheduleModifyRequests(), + performance); + List modifiedCasts = processCasts(request.castModifyRequests(), performance); + List modifiedStaffs = processStaffs(request.staffModifyRequests(), performance); + List modifiedPerformanceImages = processPerformanceImages( + request.performanceImageModifyRequests(), performance); + + PerformanceModifyResponse response = completeModifyResponse(performance, modifiedSchedules, modifiedCasts, + modifiedStaffs, modifiedPerformanceImages); + + log.info("Successfully completed updatePerformance for performanceId: {}", request.performanceId()); + return response; + } + + private Member validateMember(Long memberId) { + log.debug("Validating memberId: {}", memberId); + return memberRepository.findById(memberId) + .orElseThrow(() -> { + log.error("Member not found: memberId: {}", memberId); + return new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND); + }); + } + + private Performance findPerformance(Long performanceId) { + log.debug("Finding performance with performanceId: {}", performanceId); + return performanceRepository.findById(performanceId) + .orElseThrow(() -> { + log.error("Performance not found: performanceId: {}", performanceId); + return new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND); + }); + } + + private void validateOwnership(Long userId, Performance performance) { + if (!performance.getUsers().getId().equals(userId)) { + log.error("User ID {} does not own performance ID {}", userId, performance.getId()); + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + } + + private void updatePerformanceDetails(Performance performance, PerformanceModifyRequest request, + boolean isBookerExist) { + log.debug("Updating performance details for performanceId: {}", performance.getId()); + + performance.update( + request.performanceTitle(), + request.genre(), + request.runningTime(), + request.performanceDescription(), + request.performanceAttentionNote(), + request.bankName(), + request.accountNumber(), + request.accountHolder(), + request.posterImage(), + request.performanceTeamName(), + request.performanceVenue(), + request.performanceContact(), + request.performancePeriod(), + request.totalScheduleCount() + ); + + if (!isBookerExist) { + log.debug("Updating ticket price to {}", request.ticketPrice()); + performance.updateTicketPrice(request.ticketPrice()); + } + + performanceRepository.save(performance); + log.debug("Performance details updated for performanceId: {}", performance.getId()); + } + + private List processSchedules(List scheduleRequests, + Performance performance) { + List existingScheduleIds = scheduleRepository.findIdsByPerformanceId(performance.getId()); + + List requestScheduleIds = scheduleRequests.stream() + .map(ScheduleModifyRequest::scheduleId) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + List schedulesToDelete = existingScheduleIds.stream() + .filter(id -> !requestScheduleIds.contains(id)) + .collect(Collectors.toList()); + + deleteRemainingSchedules(schedulesToDelete); + + List schedules = scheduleRequests.stream() + .map(request -> { + Schedule schedule; + if (request.scheduleId() == null) { + schedule = addSchedule(request, performance); + } else { + schedule = updateSchedule(request, performance); + } + + // isBooking이 true인 경우만 스케줄러에 등록 + if (schedule.isBooking()) { + jobSchedulerService.addScheduleIfNotExists(schedule); + } + + return schedule; + }) + .collect(Collectors.toList()); + + assignScheduleNumbers(schedules); + + return schedules.stream() + .map(schedule -> ScheduleModifyResponse.of( + schedule.getId(), + schedule.getPerformanceDate(), + schedule.getTotalTicketCount(), + calculateDueDate(schedule.getPerformanceDate()), + schedule.getScheduleNumber() + )) + .collect(Collectors.toList()); + } + + private void assignScheduleNumbers(List schedules) { + schedules.sort(Comparator.comparing(Schedule::getPerformanceDate)); + + for (int i = 0; i < schedules.size(); i++) { + ScheduleNumber scheduleNumber = ScheduleNumber.values()[i]; + schedules.get(i).updateScheduleNumber(scheduleNumber); + } + } + + private Schedule addSchedule(ScheduleModifyRequest request, Performance performance) { + log.debug("Adding schedules for performanceId: {}", performance.getId()); + + if (request.performanceDate().isBefore(LocalDateTime.now())) { + throw new BadRequestException(PerformanceErrorCode.PAST_SCHEDULE_NOT_ALLOWED); + } + + long existingSchedulesCount = scheduleRepository.countByPerformanceId(performance.getId()); + + if ((existingSchedulesCount + 1) > 10) { + throw new BadRequestException(PerformanceErrorCode.MAX_SCHEDULE_LIMIT_EXCEEDED); + } + + Schedule schedule = Schedule.create( + request.performanceDate(), + request.totalTicketCount(), + 0, + true, + ScheduleNumber.FIRST, // 임시로 1회차 + performance + ); + + Schedule savedSchedule = scheduleRepository.save(schedule); + log.debug("Added schedule with scheduleId: {} for performanceId: {}", savedSchedule.getId(), + performance.getId()); + return savedSchedule; + } + + private Schedule updateSchedule(ScheduleModifyRequest request, Performance performance) { + log.debug("Updating schedules for scheduleId: {}", request.scheduleId()); + + Schedule schedule = scheduleRepository.findById(request.scheduleId()) + .orElseThrow(() -> { + log.error("Schedule not found: scheduleId: {}", request.scheduleId()); + return new NotFoundException(ScheduleErrorCode.NO_SCHEDULE_FOUND); + }); + + if (!schedule.getPerformance().equals(performance)) { + throw new ForbiddenException(ScheduleErrorCode.SCHEDULE_NOT_BELONG_TO_PERFORMANCE); + } + + // 종료된 스케줄(기존 스케쥴 날짜가 과거인 경우)은 날짜 변경 불가 + if (schedule.getPerformanceDate().isBefore(LocalDateTime.now())) { + if (!schedule.getPerformanceDate().isEqual(request.performanceDate())) { + throw new BadRequestException( + PerformanceErrorCode.SCHEDULE_MODIFICATION_NOT_ALLOWED_FOR_ENDED_SCHEDULE); + } + // 날짜 변경이 없으면 그대로 반환 + return schedule; + } + + // 종료되지 않은 스케줄을 과거 날짜로 수정 시 에러 발생 + if (request.performanceDate().isBefore(LocalDateTime.now())) { + throw new BadRequestException(PerformanceErrorCode.PAST_SCHEDULE_NOT_ALLOWED); + } + + // 티켓 수 관련 검증 + if (request.totalTicketCount() != schedule.getTotalTicketCount()) { + // 판매된 티켓 수보다 적은 totalTicketCount로 변경하려는 경우 예외 처리 + if (request.totalTicketCount() < schedule.getSoldTicketCount()) { + throw new BadRequestException(PerformanceErrorCode.INVALID_TICKET_COUNT); + } + + // 매진 상태로 변경 (soldTicketCount와 totalTicketCount가 동일하고, 기존 isBooking이 true인 경우) + if (request.totalTicketCount() == schedule.getSoldTicketCount() && schedule.isBooking()) { + schedule.updateIsBooking(false); // 매진 처리 (isBooking = false) + } + + // 매진이 풀리는 경우 (totalTicketCount 증가, 기존 isBooking이 false인 경우) + else if (request.totalTicketCount() > schedule.getTotalTicketCount() && !schedule.isBooking()) { + schedule.updateIsBooking(true); // 매진 풀림 처리 (isBooking = true) + } + } + + jobSchedulerService.cancelScheduledTaskForPerformance(schedule); + + schedule.update( + request.performanceDate(), + request.totalTicketCount(), + schedule.getScheduleNumber() // 기존 scheduleNumber 유지 + ); + return scheduleRepository.save(schedule); + } + + private void deleteRemainingSchedules(List scheduleIds) { + if (scheduleIds == null || scheduleIds.isEmpty()) { + log.debug("No schedules to delete"); + return; + } + + scheduleIds.forEach(scheduleId -> { + Schedule schedule = scheduleRepository.findById(scheduleId) + .orElseThrow(() -> { + log.error("Schedule not found: scheduleId: {}", scheduleId); + return new NotFoundException(ScheduleErrorCode.NO_SCHEDULE_FOUND); + }); + + jobSchedulerService.cancelScheduledTaskForPerformance(schedule); + + scheduleRepository.delete(schedule); + log.debug("Deleted schedule with scheduleId: {}", scheduleId); + }); + } + + private List processCasts(List castRequests, Performance performance) { + log.debug("Processing casts for performanceId: {}", performance.getId()); + + List existingCastIds = castRepository.findIdsByPerformanceId(performance.getId()); + + List responses = castRequests.stream() + .map(request -> { + if (request.castId() == null) { + return addCast(request, performance); + } else { + existingCastIds.remove(request.castId()); + return updateCast(request, performance); + } + }) + .toList(); + + deleteRemainingCasts(existingCastIds); + + return responses; + } + + private CastModifyResponse addCast(CastModifyRequest request, Performance performance) { + log.debug("Adding casts for performanceId: {}", performance.getId()); + + Cast cast = Cast.create( + request.castName(), + request.castRole(), + request.castPhoto(), + performance + ); + Cast savedCast = castRepository.save(cast); + log.debug("Added cast with castId: {} for performanceId: {}", savedCast.getId(), performance.getId()); + return CastModifyResponse.of( + savedCast.getId(), + savedCast.getCastName(), + savedCast.getCastRole(), + savedCast.getCastPhoto() + ); + } + + private CastModifyResponse updateCast(CastModifyRequest request, Performance performance) { + log.debug("Updating casts for castId: {}", request.castId()); + + Cast cast = castRepository.findById(request.castId()) + .orElseThrow(() -> { + log.error("Cast not found: castId: {}", request.castId()); + return new NotFoundException(CastErrorCode.CAST_NOT_FOUND); + }); + + if (!cast.getPerformance().equals(performance)) { + throw new ForbiddenException(CastErrorCode.CAST_NOT_BELONG_TO_PERFORMANCE); + } + + cast.update( + request.castName(), + request.castRole(), + request.castPhoto() + ); + castRepository.save(cast); + log.debug("Updated cast with castId: {}", cast.getId()); + return CastModifyResponse.of( + cast.getId(), + cast.getCastName(), + cast.getCastRole(), + cast.getCastPhoto() + ); + } + + private void deleteRemainingCasts(List castIds) { + if (castIds == null || castIds.isEmpty()) { + log.debug("No casts to delete"); + return; + } + + castIds.forEach(castId -> { + Cast cast = castRepository.findById(castId) + .orElseThrow(() -> { + log.error("Cast not found: castId: {}", castId); + return new NotFoundException(CastErrorCode.CAST_NOT_FOUND); + }); + castRepository.delete(cast); + log.debug("Deleted cast with castId: {}", castId); + }); + } + + private List processStaffs(List staffRequests, Performance performance) { + log.debug("Processing staffs for performanceId: {}", performance.getId()); + + List existingStaffIds = staffRepository.findIdsByPerformanceId(performance.getId()); + + List responses = staffRequests.stream() + .map(request -> { + if (request.staffId() == null) { + return addStaff(request, performance); + } else { + existingStaffIds.remove(request.staffId()); // 요청에 포함된 ID는 삭제 후보에서 제거 + return updateStaff(request, performance); + } + }) + .collect(Collectors.toList()); + + deleteRemainingStaffs(existingStaffIds); + + return responses; + } + + private StaffModifyResponse addStaff(StaffModifyRequest request, Performance performance) { + log.debug("Adding staffs for performanceId: {}", performance.getId()); + + Staff staff = Staff.create( + request.staffName(), + request.staffRole(), + request.staffPhoto(), + performance + ); + Staff savedStaff = staffRepository.save(staff); + log.debug("Added staff with staffId: {} for performanceId: {}", savedStaff.getId(), performance.getId()); + return StaffModifyResponse.of( + savedStaff.getId(), + savedStaff.getStaffName(), + savedStaff.getStaffRole(), + savedStaff.getStaffPhoto() + ); + } + + private StaffModifyResponse updateStaff(StaffModifyRequest request, Performance performance) { + log.debug("Updating staffs for staffId: {}", request.staffId()); + + Staff staff = staffRepository.findById(request.staffId()) + .orElseThrow(() -> { + log.error("Staff not found: staffId: {}", request.staffId()); + return new NotFoundException(StaffErrorCode.STAFF_NOT_FOUND); + }); + + if (!staff.getPerformance().equals(performance)) { + throw new ForbiddenException(StaffErrorCode.STAFF_NOT_BELONG_TO_PERFORMANCE); + } + + staff.update( + request.staffName(), + request.staffRole(), + request.staffPhoto() + ); + staffRepository.save(staff); + log.debug("Updated staff with staffId: {}", staff.getId()); + return StaffModifyResponse.of( + staff.getId(), + staff.getStaffName(), + staff.getStaffRole(), + staff.getStaffPhoto() + ); + } + + private void deleteRemainingStaffs(List staffIds) { + if (staffIds == null || staffIds.isEmpty()) { + log.debug("No staffs to delete"); + return; + } + + staffIds.forEach(staffId -> { + Staff staff = staffRepository.findById(staffId) + .orElseThrow(() -> { + log.error("Staff not found: staffId: {}", staffId); + return new NotFoundException(StaffErrorCode.STAFF_NOT_FOUND); + }); + staffRepository.delete(staff); + log.debug("Deleted staff with staffId: {}", staffId); + }); + } + + private int calculateDueDate(LocalDateTime performanceDate) { + return (int)ChronoUnit.DAYS.between(LocalDate.now(), performanceDate.toLocalDate()); + } + + private List processPerformanceImages( + List performanceImageRequests, Performance performance) { + log.debug("Processing performanceImages for performanceId: {}", performance.getId()); + + List existingPerformanceImageIds = performanceImageRepository.findIdsByPerformanceId(performance.getId()); + + List responses = performanceImageRequests.stream() + .map(request -> { + if (request.performanceImageId() == null) { + return addPerformanceImage(request, performance); + } else { + existingPerformanceImageIds.remove(request.performanceImageId()); + return updatePerformanceImage(request, performance); + } + }) + .toList(); + + deleteRemainingPerformanceImages(existingPerformanceImageIds); + + return responses; + } + + private PerformanceImageModifyResponse addPerformanceImage(PerformanceImageModifyRequest request, + Performance performance) { + log.debug("Adding performanceImages for performanceId: {}", performance.getId()); + + PerformanceImage performanceImage = PerformanceImage.create( + request.performanceImage(), + performance + ); + PerformanceImage savedPerformanceImage = performanceImageRepository.save(performanceImage); + log.debug("Added performanceImage: {}", savedPerformanceImage.getId()); + return PerformanceImageModifyResponse.of( + savedPerformanceImage.getId(), + savedPerformanceImage.getPerformanceImage() + ); + } + + private PerformanceImageModifyResponse updatePerformanceImage(PerformanceImageModifyRequest request, + Performance performance) { + log.debug("Updating performanceImages for performanceId: {}", performance.getId()); + + PerformanceImage performanceImage = performanceImageRepository.findById(request.performanceImageId()) + .orElseThrow(() -> { + log.error("PerformanceImage not found: performanceId: {}", request.performanceImageId()); + return new NotFoundException(PerformanceImageErrorCode.PERFORMANCE_IMAGE_NOT_FOUND); + }); + + if (!performanceImage.getPerformance().equals(performance)) { + throw new ForbiddenException(PerformanceImageErrorCode.PERFORMANCE_IMAGE_NOT_BELONG_TO_PERFORMANCE); + } + + performanceImage.update( + request.performanceImage() + ); + performanceImageRepository.save(performanceImage); + log.debug("Updated performanceImage: {}", performanceImage.getId()); + return PerformanceImageModifyResponse.of( + performanceImage.getId(), + performanceImage.getPerformanceImage() + ); + } + + private void deleteRemainingPerformanceImages(List performanceImageIds) { + if (performanceImageIds == null || performanceImageIds.isEmpty()) { + log.debug("No performanceImages to delete"); + return; + } + + performanceImageIds.forEach(performanceImageId -> { + PerformanceImage performanceImage = performanceImageRepository.findById(performanceImageId) + .orElseThrow(() -> { + log.error("PerformanceImage not found: performanceImageId: {}", performanceImageId); + return new NotFoundException(PerformanceImageErrorCode.PERFORMANCE_IMAGE_NOT_FOUND); + }); + performanceImageRepository.delete(performanceImage); + log.debug("Deleted performanceImage: {}", performanceImageId); + }); + } + + private PerformanceModifyResponse completeModifyResponse( + Performance performance, + List scheduleModifyResponses, + List castModifyResponses, + List staffModifyResponses, + List performanceImageModifyResponses + ) { + log.debug("Creating PerformanceModifyResponse for performanceId: {}", performance.getId()); + PerformanceModifyResponse response = PerformanceModifyResponse.of( + performance.getUsers().getId(), + performance.getId(), + performance.getPerformanceTitle(), + performance.getGenre(), + performance.getRunningTime(), + performance.getPerformanceDescription(), + performance.getPerformanceAttentionNote(), + performance.getBankName(), + performance.getAccountNumber(), + performance.getAccountHolder(), + performance.getPosterImage(), + performance.getPerformanceTeamName(), + performance.getPerformanceVenue(), + performance.getPerformanceContact(), + performance.getPerformancePeriod(), + performance.getTicketPrice(), + performance.getTotalScheduleCount(), + scheduleModifyResponses, + castModifyResponses, + staffModifyResponses, + performanceImageModifyResponses + ); + log.info("PerformanceModifyResponse created successfully for performanceId: {}", performance.getId()); + return response; + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceService.java b/src/main/java/com/beat/domain/performance/application/PerformanceService.java index 1907a176..e1352dda 100644 --- a/src/main/java/com/beat/domain/performance/application/PerformanceService.java +++ b/src/main/java/com/beat/domain/performance/application/PerformanceService.java @@ -1,25 +1,43 @@ package com.beat.domain.performance.application; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import com.beat.domain.booking.dao.BookingRepository; +import com.beat.domain.cast.dao.CastRepository; import com.beat.domain.cast.domain.Cast; import com.beat.domain.member.dao.MemberRepository; import com.beat.domain.member.domain.Member; import com.beat.domain.member.exception.MemberErrorCode; -import com.beat.domain.performance.application.dto.*; +import com.beat.domain.performance.application.dto.bookingPerformanceDetail.BookingPerformanceDetailResponse; +import com.beat.domain.performance.application.dto.bookingPerformanceDetail.BookingPerformanceDetailScheduleResponse; import com.beat.domain.performance.application.dto.create.CastResponse; +import com.beat.domain.performance.application.dto.create.PerformanceImageResponse; import com.beat.domain.performance.application.dto.create.ScheduleResponse; import com.beat.domain.performance.application.dto.create.StaffResponse; -import com.beat.domain.performance.application.dto.home.HomePerformanceDetail; -import com.beat.domain.performance.application.dto.home.HomePromotionDetail; -import com.beat.domain.performance.application.dto.home.HomeRequest; -import com.beat.domain.performance.application.dto.home.HomeResponse; +import com.beat.domain.performance.application.dto.makerPerformance.MakerPerformanceDetailResponse; +import com.beat.domain.performance.application.dto.makerPerformance.MakerPerformanceResponse; +import com.beat.domain.performance.application.dto.modify.PerformanceModifyDetailResponse; +import com.beat.domain.performance.application.dto.performanceDetail.PerformanceDetailCastResponse; +import com.beat.domain.performance.application.dto.performanceDetail.PerformanceDetailImageResponse; +import com.beat.domain.performance.application.dto.performanceDetail.PerformanceDetailResponse; +import com.beat.domain.performance.application.dto.performanceDetail.PerformanceDetailScheduleResponse; +import com.beat.domain.performance.application.dto.performanceDetail.PerformanceDetailStaffResponse; +import com.beat.domain.performance.dao.PerformanceImageRepository; import com.beat.domain.performance.dao.PerformanceRepository; import com.beat.domain.performance.domain.Performance; +import com.beat.domain.performance.domain.PerformanceImage; import com.beat.domain.performance.exception.PerformanceErrorCode; -import com.beat.domain.promotion.dao.PromotionRepository; -import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.performance.port.in.PerformanceUseCase; import com.beat.domain.schedule.application.ScheduleService; import com.beat.domain.schedule.dao.ScheduleRepository; -import com.beat.domain.cast.dao.CastRepository; import com.beat.domain.schedule.domain.Schedule; import com.beat.domain.staff.dao.StaffRepository; import com.beat.domain.staff.domain.Staff; @@ -28,276 +46,189 @@ import com.beat.domain.user.exception.UserErrorCode; import com.beat.global.common.exception.ForbiddenException; import com.beat.global.common.exception.NotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Service @RequiredArgsConstructor -public class PerformanceService { - private final PerformanceRepository performanceRepository; - private final ScheduleRepository scheduleRepository; - private final CastRepository castRepository; - private final StaffRepository staffRepository; - private final ScheduleService scheduleService; - private final PromotionRepository promotionRepository; - private final MemberRepository memberRepository; - private final UserRepository userRepository; - private final BookingRepository bookingRepository; - - @Transactional(readOnly = true) - public PerformanceDetailResponse getPerformanceDetail(Long performanceId) { - Performance performance = performanceRepository.findById(performanceId) - .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - - List scheduleList = scheduleRepository.findByPerformanceId(performanceId).stream() - .map(schedule -> PerformanceDetailSchedule.of( - schedule.getId(), - schedule.getPerformanceDate(), - schedule.getScheduleNumber().name() - )).collect(Collectors.toList()); - - List castList = castRepository.findByPerformanceId(performanceId).stream() - .map(cast -> PerformanceDetailCast.of( - cast.getId(), - cast.getCastName(), - cast.getCastRole(), - cast.getCastPhoto() - )).collect(Collectors.toList()); - - List staffList = staffRepository.findByPerformanceId(performanceId).stream() - .map(staff -> PerformanceDetailStaff.of( - staff.getId(), - staff.getStaffName(), - staff.getStaffRole(), - staff.getStaffPhoto() - )).collect(Collectors.toList()); - - return PerformanceDetailResponse.of( - performance.getId(), - performance.getPerformanceTitle(), - performance.getPerformancePeriod(), - scheduleList, - performance.getTicketPrice(), - performance.getGenre().name(), - performance.getPosterImage(), - performance.getRunningTime(), - performance.getPerformanceVenue(), - performance.getPerformanceDescription(), - performance.getPerformanceAttentionNote(), - performance.getPerformanceContact(), - performance.getPerformanceTeamName(), - castList, - staffList - ); - } - - @Transactional - public BookingPerformanceDetailResponse getBookingPerformanceDetail(Long performanceId) { - Performance performance = performanceRepository.findById(performanceId) - .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - - List scheduleList = scheduleRepository.findByPerformanceId(performanceId).stream() - .map(schedule -> { - scheduleService.updateBookingStatus(schedule); - return BookingPerformanceDetailSchedule.of( - schedule.getId(), - schedule.getPerformanceDate(), - schedule.getScheduleNumber().name(), - scheduleService.getAvailableTicketCount(schedule), - schedule.isBooking() - ); - }).collect(Collectors.toList()); - - return BookingPerformanceDetailResponse.of( - performance.getId(), - performance.getPerformanceTitle(), - performance.getPerformancePeriod(), - scheduleList, - performance.getTicketPrice(), - performance.getGenre().name(), - performance.getPosterImage(), - performance.getPerformanceVenue(), - performance.getPerformanceTeamName(), - performance.getBankName() != null ? performance.getBankName().name() : null, - performance.getAccountNumber(), - performance.getAccountHolder() - ); - } - - @Transactional(readOnly = true) - public HomeResponse getHomePerformanceList(HomeRequest homeRequest) { - List performances; - - if (homeRequest.genre() != null) { - performances = performanceRepository.findByGenre(homeRequest.genre()); - } else { - performances = performanceRepository.findAll(); - } - - if (performances.isEmpty()) { - List promotions = getPromotions(); - return HomeResponse.of(promotions, new ArrayList<>()); - } - - List performanceDetails = performances.stream() - .map(performance -> { - List schedules = scheduleRepository.findByPerformanceId(performance.getId()); - int minDueDate = scheduleService.getMinDueDate(schedules); - - return HomePerformanceDetail.of( - performance.getId(), - performance.getPerformanceTitle(), - performance.getPerformancePeriod(), - performance.getTicketPrice(), - minDueDate, - performance.getGenre().name(), - performance.getPosterImage(), - performance.getPerformanceVenue() - ); - }) - .collect(Collectors.toList()); - - // 두 개의 스트림을 각각 처리하여 병합 - List positiveDueDates = performanceDetails.stream() - .filter(detail -> detail.dueDate() >= 0) - .sorted((p1, p2) -> Integer.compare(p1.dueDate(), p2.dueDate())) - .collect(Collectors.toList()); - - List negativeDueDates = performanceDetails.stream() - .filter(detail -> detail.dueDate() < 0) - .sorted((p1, p2) -> Integer.compare(p2.dueDate(), p1.dueDate())) - .collect(Collectors.toList()); - - // 병합된 리스트 - positiveDueDates.addAll(negativeDueDates); - - List promotions = getPromotions(); - - return HomeResponse.of(promotions, positiveDueDates); - } - - private List getPromotions() { - List promotionList = promotionRepository.findAll(); - return promotionList.stream() - .map(promotion -> HomePromotionDetail.of( - promotion.getId(), - promotion.getPromotionPhoto(), - promotion.getPerformance().getId() - )) - .collect(Collectors.toList()); - } - - @Transactional(readOnly = true) - public MakerPerformanceResponse getMemberPerformances(Long memberId) { - Member member = memberRepository.findById(memberId).orElseThrow( - () -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Users user = userRepository.findById(member.getUser().getId()).orElseThrow( - () -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); - - List performances = performanceRepository.findByUsersId(user.getId()); - - List performanceDetails = performances.stream() - .map(performance -> MakerPerformanceDetail.of( - performance.getId(), - performance.getGenre().name(), - performance.getPerformanceTitle(), - performance.getPosterImage(), - performance.getPerformancePeriod() - )) - .collect(Collectors.toList()); - - return MakerPerformanceResponse.of(user.getId(), performanceDetails); - } - - @Transactional - public PerformanceEditResponse getPerformanceEdit(Long memberId, Long performanceId) { - Member member = memberRepository.findById(memberId) - .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Long userId = member.getUser().getId(); - - Performance performance = performanceRepository.findById(performanceId) - .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - - if (!performance.getUsers().getId().equals(userId)) { - throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); - } - - List scheduleIds = scheduleRepository.findIdsByPerformanceId(performanceId); - - boolean isBookerExist = bookingRepository.existsByScheduleIdIn(scheduleIds); - - List schedules = scheduleRepository.findAllByPerformanceId(performanceId); - List casts = castRepository.findAllByPerformanceId(performanceId); - List staffs = staffRepository.findAllByPerformanceId(performanceId); - - return mapToPerformanceEditResponse(performance, schedules, casts, staffs, isBookerExist); - } - - private PerformanceEditResponse mapToPerformanceEditResponse(Performance performance, List schedules, List casts, List staffs, boolean isBookerExist) { - List scheduleResponses = schedules.stream() - .map(schedule -> ScheduleResponse.of( - schedule.getId(), - schedule.getPerformanceDate(), - schedule.getTotalTicketCount(), - calculateDueDate(schedule.getPerformanceDate()), - schedule.getScheduleNumber() - )) - .collect(Collectors.toList()); - - List castResponses = casts.stream() - .map(cast -> CastResponse.of( - cast.getId(), - cast.getCastName(), - cast.getCastRole(), - cast.getCastPhoto() - )) - .collect(Collectors.toList()); - - List staffResponses = staffs.stream() - .map(staff -> StaffResponse.of( - staff.getId(), - staff.getStaffName(), - staff.getStaffRole(), - staff.getStaffPhoto() - )) - .collect(Collectors.toList()); - - return PerformanceEditResponse.of( - performance.getUsers().getId(), - performance.getId(), - performance.getPerformanceTitle(), - performance.getGenre(), - performance.getRunningTime(), - performance.getPerformanceDescription(), - performance.getPerformanceAttentionNote(), - performance.getBankName(), - performance.getAccountNumber(), - performance.getAccountHolder(), - performance.getPosterImage(), - performance.getPerformanceTeamName(), - performance.getPerformanceVenue(), - performance.getPerformanceContact(), - performance.getPerformancePeriod(), - performance.getTicketPrice(), - performance.getTotalScheduleCount(), - isBookerExist, - scheduleResponses, - castResponses, - staffResponses - ); - } - - private int calculateDueDate(LocalDateTime performanceDate) { - return (int) ChronoUnit.DAYS.between(LocalDate.now(), performanceDate.toLocalDate()); - } +public class PerformanceService implements PerformanceUseCase { + private final PerformanceRepository performanceRepository; + private final ScheduleRepository scheduleRepository; + private final CastRepository castRepository; + private final StaffRepository staffRepository; + private final ScheduleService scheduleService; + private final MemberRepository memberRepository; + private final UserRepository userRepository; + private final BookingRepository bookingRepository; + private final PerformanceImageRepository performanceImageRepository; + + @Transactional(readOnly = true) + public PerformanceDetailResponse getPerformanceDetail(Long performanceId) { + Performance performance = performanceRepository.findById(performanceId) + .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); + + List scheduleList = scheduleRepository.findByPerformanceId(performanceId) + .stream() + .map(schedule -> { + int dueDate = scheduleService.calculateDueDate(schedule); + return PerformanceDetailScheduleResponse.of(schedule.getId(), schedule.getPerformanceDate(), + schedule.getScheduleNumber().name(), dueDate, schedule.isBooking()); + }) + .collect(Collectors.toList()); + + int minDueDate = scheduleService.getMinDueDate(scheduleRepository.findAllByPerformanceId(performanceId)); + + List castList = castRepository.findByPerformanceId(performanceId) + .stream() + .map(cast -> PerformanceDetailCastResponse.of(cast.getId(), cast.getCastName(), cast.getCastRole(), + cast.getCastPhoto())) + .collect(Collectors.toList()); + + List staffList = staffRepository.findByPerformanceId(performanceId) + .stream() + .map(staff -> PerformanceDetailStaffResponse.of(staff.getId(), staff.getStaffName(), staff.getStaffRole(), + staff.getStaffPhoto())) + .collect(Collectors.toList()); + + List performanceImageList = performanceImageRepository.findAllByPerformanceId( + performanceId) + .stream() + .map(image -> PerformanceDetailImageResponse.of(image.getId(), image.getPerformanceImage())) + .collect(Collectors.toList()); + + log.info("Successfully completed getPerformanceDetail for performanceId: {}", performanceId); + return PerformanceDetailResponse.of(performance.getId(), performance.getPerformanceTitle(), + performance.getPerformancePeriod(), scheduleList, performance.getTicketPrice(), + performance.getGenre().name(), performance.getPosterImage(), performance.getRunningTime(), + performance.getPerformanceVenue(), performance.getPerformanceDescription(), + performance.getPerformanceAttentionNote(), performance.getPerformanceContact(), + performance.getPerformanceTeamName(), castList, staffList, minDueDate, performanceImageList); + } + + @Transactional(readOnly = true) + public BookingPerformanceDetailResponse getBookingPerformanceDetail(Long performanceId) { + Performance performance = performanceRepository.findById(performanceId) + .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); + + List scheduleList = scheduleRepository.findByPerformanceId( + performanceId).stream().map(schedule -> { + int dueDate = scheduleService.calculateDueDate(schedule); + return BookingPerformanceDetailScheduleResponse.of(schedule.getId(), schedule.getPerformanceDate(), + schedule.getScheduleNumber().name(), scheduleService.getAvailableTicketCount(schedule), + schedule.isBooking(), dueDate); + }).collect(Collectors.toList()); + + return BookingPerformanceDetailResponse.of(performance.getId(), performance.getPerformanceTitle(), + performance.getPerformancePeriod(), scheduleList, performance.getTicketPrice(), + performance.getGenre().name(), performance.getPosterImage(), performance.getPerformanceVenue(), + performance.getPerformanceTeamName(), + performance.getBankName() != null ? performance.getBankName().name() : null, performance.getAccountNumber(), + performance.getAccountHolder()); + } + + @Transactional(readOnly = true) + public MakerPerformanceResponse getMemberPerformances(Long memberId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Users user = userRepository.findById(member.getUser().getId()) + .orElseThrow(() -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); + + List performances = performanceRepository.findByUsersId(user.getId()); + + List performanceDetails = performances.stream().map(performance -> { + List schedules = scheduleRepository.findByPerformanceId(performance.getId()); + int minDueDate = scheduleService.getMinDueDate(schedules); + + return MakerPerformanceDetailResponse.of(performance.getId(), performance.getGenre().name(), + performance.getPerformanceTitle(), performance.getPosterImage(), performance.getPerformancePeriod(), + minDueDate); + }).collect(Collectors.toList()); + + List positiveDueDates = performanceDetails.stream() + .filter(detail -> detail.minDueDate() >= 0) + .sorted(Comparator.comparingInt(MakerPerformanceDetailResponse::minDueDate)) + .collect(Collectors.toList()); + + List negativeDueDates = performanceDetails.stream() + .filter(detail -> detail.minDueDate() < 0) + .sorted(Comparator.comparingInt(MakerPerformanceDetailResponse::minDueDate).reversed()) + .collect(Collectors.toList()); + + positiveDueDates.addAll(negativeDueDates); + + return MakerPerformanceResponse.of(user.getId(), positiveDueDates); + } + + @Override + @Transactional(readOnly = true) + public Performance findById(Long performanceId) { + return performanceRepository.findById(performanceId) + .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); + } + + @Transactional + public PerformanceModifyDetailResponse getPerformanceEdit(Long memberId, Long performanceId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); + + Long userId = member.getUser().getId(); + + Performance performance = performanceRepository.findById(performanceId) + .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); + + if (!performance.getUsers().getId().equals(userId)) { + throw new ForbiddenException(PerformanceErrorCode.NOT_PERFORMANCE_OWNER); + } + + List scheduleIds = scheduleRepository.findIdsByPerformanceId(performanceId); + + boolean isBookerExist = bookingRepository.existsByScheduleIdIn(scheduleIds); + + List schedules = scheduleRepository.findAllByPerformanceId(performanceId); + List casts = castRepository.findAllByPerformanceId(performanceId); + List staffs = staffRepository.findAllByPerformanceId(performanceId); + List performanceImages = performanceImageRepository.findAllByPerformanceId(performanceId); + + return mapToPerformanceEditResponse(performance, schedules, casts, staffs, performanceImages, isBookerExist); + } + + private PerformanceModifyDetailResponse mapToPerformanceEditResponse(Performance performance, + List schedules, List casts, List staffs, List performanceImages, + boolean isBookerExist) { + List scheduleResponses = schedules.stream() + .map(schedule -> ScheduleResponse.of(schedule.getId(), schedule.getPerformanceDate(), + schedule.getTotalTicketCount(), calculateDueDate(schedule.getPerformanceDate()), + schedule.getScheduleNumber())) + .collect(Collectors.toList()); + + List castResponses = casts.stream() + .map(cast -> CastResponse.of(cast.getId(), cast.getCastName(), cast.getCastRole(), cast.getCastPhoto())) + .collect(Collectors.toList()); + + List staffResponses = staffs.stream() + .map(staff -> StaffResponse.of(staff.getId(), staff.getStaffName(), staff.getStaffRole(), + staff.getStaffPhoto())) + .collect(Collectors.toList()); + + List performanceImageResponses = performanceImages.stream() + .map(performanceImage -> PerformanceImageResponse.of(performanceImage.getId(), + performanceImage.getPerformanceImage())) + .collect(Collectors.toList()); + + return PerformanceModifyDetailResponse.of(performance.getUsers().getId(), performance.getId(), + performance.getPerformanceTitle(), performance.getGenre(), performance.getRunningTime(), + performance.getPerformanceDescription(), performance.getPerformanceAttentionNote(), + performance.getBankName(), performance.getAccountNumber(), performance.getAccountHolder(), + performance.getPosterImage(), performance.getPerformanceTeamName(), performance.getPerformanceVenue(), + performance.getPerformanceContact(), performance.getPerformancePeriod(), performance.getTicketPrice(), + performance.getTotalScheduleCount(), isBookerExist, scheduleResponses, castResponses, staffResponses, + performanceImageResponses); + } + + private int calculateDueDate(LocalDateTime performanceDate) { + return (int)ChronoUnit.DAYS.between(LocalDate.now(), performanceDate.toLocalDate()); + } } diff --git a/src/main/java/com/beat/domain/performance/application/PerformanceUpdateService.java b/src/main/java/com/beat/domain/performance/application/PerformanceUpdateService.java deleted file mode 100644 index 70a4c993..00000000 --- a/src/main/java/com/beat/domain/performance/application/PerformanceUpdateService.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.beat.domain.performance.application; - -import com.beat.domain.cast.dao.CastRepository; -import com.beat.domain.cast.domain.Cast; -import com.beat.domain.cast.exception.CastErrorCode; -import com.beat.domain.member.dao.MemberRepository; -import com.beat.domain.member.exception.MemberErrorCode; -import com.beat.domain.performance.application.dto.update.*; -import com.beat.domain.performance.dao.PerformanceRepository; -import com.beat.domain.performance.domain.Performance; -import com.beat.domain.performance.exception.PerformanceErrorCode; -import com.beat.domain.schedule.dao.ScheduleRepository; -import com.beat.domain.schedule.domain.Schedule; -import com.beat.domain.schedule.domain.ScheduleNumber; -import com.beat.domain.schedule.exception.ScheduleErrorCode; -import com.beat.domain.staff.dao.StaffRepository; -import com.beat.domain.staff.domain.Staff; -import com.beat.domain.staff.exception.StaffErrorCode; -import com.beat.global.common.exception.NotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@RequiredArgsConstructor -public class PerformanceUpdateService { - private final PerformanceRepository performanceRepository; - private final ScheduleRepository scheduleRepository; - private final MemberRepository memberRepository; - private final CastRepository castRepository; - private final StaffRepository staffRepository; - - @Transactional - public PerformanceUpdateResponse updatePerformance(Long memberId, PerformanceUpdateRequest request) { - memberRepository.findById(memberId).orElseThrow(() -> new NotFoundException(MemberErrorCode.MEMBER_NOT_FOUND)); - - Performance performance = performanceRepository.findById(request.performanceId()) - .orElseThrow(() -> new NotFoundException(PerformanceErrorCode.PERFORMANCE_NOT_FOUND)); - - performance.update( - request.performanceTitle(), - request.genre(), - request.runningTime(), - request.performanceDescription(), - request.performanceAttentionNote(), - request.bankName(), - request.accountNumber(), - request.accountHolder(), - request.posterImage(), - request.performanceTeamName(), - request.performanceVenue(), - request.performanceContact(), - request.performancePeriod(), - request.totalScheduleCount() - ); - performanceRepository.save(performance); - - List schedules = request.scheduleList().stream() - .map(scheduleRequest -> { - Schedule schedule = scheduleRepository.findById(scheduleRequest.scheduleId()) - .orElseThrow(() -> new NotFoundException(ScheduleErrorCode.NO_SCHEDULE_FOUND)); - schedule.update( - scheduleRequest.performanceDate(), - scheduleRequest.totalTicketCount(), - ScheduleNumber.valueOf(scheduleRequest.scheduleNumber()) - ); - return schedule; - }) - .collect(Collectors.toList()); - scheduleRepository.saveAll(schedules); - - List casts = request.castList().stream() - .map(castRequest -> { - Cast cast = castRepository.findById(castRequest.castId()) - .orElseThrow(() -> new NotFoundException(CastErrorCode.CAST_NOT_FOUND)); - cast.update( - castRequest.castName(), - castRequest.castRole(), - castRequest.castPhoto() - ); - return cast; - }) - .collect(Collectors.toList()); - castRepository.saveAll(casts); - - List staffs = request.staffList().stream() - .map(staffRequest -> { - Staff staff = staffRepository.findById(staffRequest.staffId()) - .orElseThrow(() -> new NotFoundException(StaffErrorCode.STAFF_NOT_FOUND)); - staff.update( - staffRequest.staffName(), - staffRequest.staffRole(), - staffRequest.staffPhoto() - ); - return staff; - }) - .collect(Collectors.toList()); - staffRepository.saveAll(staffs); - - return mapToPerformanceResponse(performance, schedules, casts, staffs); - } - - private PerformanceUpdateResponse mapToPerformanceResponse(Performance performance, List schedules, List casts, List staffs) { - List scheduleResponses = schedules.stream() - .map(schedule -> ScheduleUpdateResponse.of( - schedule.getId(), - schedule.getPerformanceDate(), - schedule.getTotalTicketCount(), - calculateDueDate(schedule.getPerformanceDate()), - schedule.getScheduleNumber() - )) - .collect(Collectors.toList()); - - List castResponses = casts.stream() - .map(cast -> CastUpdateResponse.of( - cast.getId(), - cast.getCastName(), - cast.getCastRole(), - cast.getCastPhoto() - )) - .collect(Collectors.toList()); - - List staffResponses = staffs.stream() - .map(staff -> StaffUpdateResponse.of( - staff.getId(), - staff.getStaffName(), - staff.getStaffRole(), - staff.getStaffPhoto() - )) - .collect(Collectors.toList()); - - return PerformanceUpdateResponse.of( - performance.getUsers().getId(), - performance.getId(), - performance.getPerformanceTitle(), - performance.getGenre(), - performance.getRunningTime(), - performance.getPerformanceDescription(), - performance.getPerformanceAttentionNote(), - performance.getBankName(), - performance.getAccountNumber(), - performance.getAccountHolder(), - performance.getPosterImage(), - performance.getPerformanceTeamName(), - performance.getPerformanceVenue(), - performance.getPerformanceContact(), - performance.getPerformancePeriod(), - performance.getTicketPrice(), - performance.getTotalScheduleCount(), - scheduleResponses, - castResponses, - staffResponses - ); - } - - private int calculateDueDate(LocalDateTime performanceDate) { - return (int) ChronoUnit.DAYS.between(LocalDate.now(), performanceDate.toLocalDate()); - } -} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java b/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java deleted file mode 100644 index 0cbe3616..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailSchedule.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.beat.domain.performance.application.dto; - -import java.time.LocalDateTime; - -public record BookingPerformanceDetailSchedule( - Long scheduleId, - LocalDateTime performanceDate, - String scheduleNumber, - int availableTicketCount, - boolean isBooking -) { - public static BookingPerformanceDetailSchedule of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber, int availableTicketCount, boolean isBooking) { - return new BookingPerformanceDetailSchedule(scheduleId, performanceDate, scheduleNumber, availableTicketCount, isBooking); - } - -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java b/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java deleted file mode 100644 index 21dcaa61..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceDetail.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.beat.domain.performance.application.dto; - -public record MakerPerformanceDetail( - Long performanceId, - String genre, - String performanceTitle, - String posterImage, - String performancePeriod -) { - public static MakerPerformanceDetail of( - Long performanceId, - String genre, - String performanceTitle, - String posterImage, - String performancePeriod) { - return new MakerPerformanceDetail(performanceId, genre, performanceTitle, posterImage, performancePeriod); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailCast.java b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailCast.java deleted file mode 100644 index 2ce813eb..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailCast.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beat.domain.performance.application.dto; - -public record PerformanceDetailCast( - Long castId, - String castName, - String castRole, - String castPhoto -) { - public static PerformanceDetailCast of(Long castId, String castName, String castRole, String castPhoto) { - return new PerformanceDetailCast(castId, castName, castRole, castPhoto); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java deleted file mode 100644 index a8f48a30..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailResponse.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.beat.domain.performance.application.dto; - -import java.util.List; - -public record PerformanceDetailResponse( - Long performanceId, - String performanceTitle, - String performancePeriod, - List scheduleList, - int ticketPrice, - String genre, - String posterImage, - int runningTime, - String performanceVenue, - String performanceDescription, - String performanceAttentionNote, - String performanceContact, - String performanceTeamName, - List castList, - List staffList -) { - public static PerformanceDetailResponse of( - Long performanceId, - String performanceTitle, - String performancePeriod, - List scheduleList, - int ticketPrice, - String genre, - String posterImage, - int runningTime, - String performanceVenue, - String performanceDescription, - String performanceAttentionNote, - String performanceContact, - String performanceTeamName, - List castList, - List staffList - ) { - return new PerformanceDetailResponse(performanceId, performanceTitle, performancePeriod, scheduleList, ticketPrice, genre, posterImage, runningTime, performanceVenue, performanceDescription, performanceAttentionNote, performanceContact, performanceTeamName, castList, staffList); - } - - -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java deleted file mode 100644 index dcfe54c7..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailSchedule.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.beat.domain.performance.application.dto; - -import java.time.LocalDateTime; - -public record PerformanceDetailSchedule( - Long scheduleId, - LocalDateTime performanceDate, - String scheduleNumber -) { - public static PerformanceDetailSchedule of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber) { - return new PerformanceDetailSchedule(scheduleId, performanceDate, scheduleNumber); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailStaff.java b/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailStaff.java deleted file mode 100644 index cf088eaf..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceDetailStaff.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beat.domain.performance.application.dto; - -public record PerformanceDetailStaff( - Long staffId, - String staffName, - String staffRole, - String staffPhoto -) { - public static PerformanceDetailStaff of(Long staffId, String staffName, String staffRole, String staffPhoto) { - return new PerformanceDetailStaff(staffId, staffName, staffRole, staffPhoto); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailResponse.java b/src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailResponse.java similarity index 82% rename from src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailResponse.java rename to src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailResponse.java index 24dcf02c..d42afafa 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/BookingPerformanceDetailResponse.java +++ b/src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailResponse.java @@ -1,4 +1,4 @@ -package com.beat.domain.performance.application.dto; +package com.beat.domain.performance.application.dto.bookingPerformanceDetail; import java.util.List; @@ -6,7 +6,7 @@ public record BookingPerformanceDetailResponse( Long performanceId, String performanceTitle, String performancePeriod, - List scheduleList, + List scheduleList, int ticketPrice, String genre, String posterImage, @@ -20,7 +20,7 @@ public static BookingPerformanceDetailResponse of( Long performanceId, String performanceTitle, String performancePeriod, - List scheduleList, + List scheduleList, int ticketPrice, String genre, String posterImage, diff --git a/src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailScheduleResponse.java b/src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailScheduleResponse.java new file mode 100644 index 00000000..4181e1bb --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/bookingPerformanceDetail/BookingPerformanceDetailScheduleResponse.java @@ -0,0 +1,17 @@ +package com.beat.domain.performance.application.dto.bookingPerformanceDetail; + +import java.time.LocalDateTime; + +public record BookingPerformanceDetailScheduleResponse( + Long scheduleId, + LocalDateTime performanceDate, + String scheduleNumber, + int availableTicketCount, + boolean isBooking, + int dueDate +) { + public static BookingPerformanceDetailScheduleResponse of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber, int availableTicketCount, boolean isBooking, int dueDate) { + return new BookingPerformanceDetailScheduleResponse(scheduleId, performanceDate, scheduleNumber, availableTicketCount, isBooking, dueDate); + } + +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageRequest.java b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageRequest.java new file mode 100644 index 00000000..6081829a --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageRequest.java @@ -0,0 +1,6 @@ +package com.beat.domain.performance.application.dto.create; + +public record PerformanceImageRequest( + String performanceImage +) { +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageResponse.java b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageResponse.java new file mode 100644 index 00000000..abf14ff3 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceImageResponse.java @@ -0,0 +1,16 @@ +package com.beat.domain.performance.application.dto.create; + +public record PerformanceImageResponse( + Long imageId, + String imageUrl +) { + public static PerformanceImageResponse of( + Long imageId, + String imageUrl + ) { + return new PerformanceImageResponse( + imageId, + imageUrl + ); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceRequest.java b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceRequest.java index 1ae592f9..2663abf6 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceRequest.java +++ b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceRequest.java @@ -23,5 +23,6 @@ public record PerformanceRequest( int totalScheduleCount, List scheduleList, List castList, - List staffList + List staffList, + List performanceImageList ) {} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceResponse.java b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceResponse.java index 9d34b8da..4fbbbf0b 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceResponse.java +++ b/src/main/java/com/beat/domain/performance/application/dto/create/PerformanceResponse.java @@ -25,7 +25,8 @@ public record PerformanceResponse( int totalScheduleCount, List scheduleList, List castList, - List staffList + List staffList, + List performanceImageList ) { public static PerformanceResponse of( Long userId, @@ -47,7 +48,8 @@ public static PerformanceResponse of( int totalScheduleCount, List scheduleList, List castList, - List staffList + List staffList, + List performanceImageList ) { return new PerformanceResponse( userId, @@ -69,7 +71,8 @@ public static PerformanceResponse of( totalScheduleCount, scheduleList, castList, - staffList + staffList, + performanceImageList ); } } diff --git a/src/main/java/com/beat/domain/performance/application/dto/home/HomeFindAllResponse.java b/src/main/java/com/beat/domain/performance/application/dto/home/HomeFindAllResponse.java new file mode 100644 index 00000000..1117fd4b --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/home/HomeFindAllResponse.java @@ -0,0 +1,12 @@ +package com.beat.domain.performance.application.dto.home; + +import java.util.List; + +public record HomeFindAllResponse( + List promotionList, + List performanceList +) { + public static HomeFindAllResponse of(List promotionList, List performanceList) { + return new HomeFindAllResponse(promotionList, performanceList); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/home/HomeRequest.java b/src/main/java/com/beat/domain/performance/application/dto/home/HomeFindRequest.java similarity index 70% rename from src/main/java/com/beat/domain/performance/application/dto/home/HomeRequest.java rename to src/main/java/com/beat/domain/performance/application/dto/home/HomeFindRequest.java index 841c8f08..3431ad80 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/home/HomeRequest.java +++ b/src/main/java/com/beat/domain/performance/application/dto/home/HomeFindRequest.java @@ -2,5 +2,5 @@ import com.beat.domain.performance.domain.Genre; -public record HomeRequest(Genre genre) { -} +public record HomeFindRequest(Genre genre) { +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/home/HomePerformanceDetail.java b/src/main/java/com/beat/domain/performance/application/dto/home/HomePerformanceDetail.java index 1417cfb4..71dbefc4 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/home/HomePerformanceDetail.java +++ b/src/main/java/com/beat/domain/performance/application/dto/home/HomePerformanceDetail.java @@ -1,16 +1,28 @@ package com.beat.domain.performance.application.dto.home; +import com.beat.domain.performance.domain.Performance; + public record HomePerformanceDetail( - Long performanceId, - String performanceTitle, - String performancePeriod, - int ticketPrice, - int dueDate, - String genre, - String posterImage, - String performanceVenue + Long performanceId, + String performanceTitle, + String performancePeriod, + int ticketPrice, + int dueDate, + String genre, + String posterImage, + String performanceVenue ) { - public static HomePerformanceDetail of(Long performanceId, String performanceTitle, String performancePeriod, int ticketPrice, int dueDate, String genre, String posterImage, String performanceVenue) { - return new HomePerformanceDetail(performanceId, performanceTitle, performancePeriod, ticketPrice, dueDate, genre, posterImage, performanceVenue); - } -} + + public static HomePerformanceDetail of(Performance performance, int minDueDate) { + return new HomePerformanceDetail( + performance.getId(), + performance.getPerformanceTitle(), + performance.getPerformancePeriod(), + performance.getTicketPrice(), + minDueDate, + performance.getGenre().name(), + performance.getPosterImage(), + performance.getPerformanceVenue() + ); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/home/HomePromotionDetail.java b/src/main/java/com/beat/domain/performance/application/dto/home/HomePromotionDetail.java index 9bd9e35f..cf49a643 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/home/HomePromotionDetail.java +++ b/src/main/java/com/beat/domain/performance/application/dto/home/HomePromotionDetail.java @@ -1,11 +1,19 @@ package com.beat.domain.performance.application.dto.home; -public record HomePromotionDetail( - Long promotionId, - String promotionPhoto, - Long performanceId -) { - public static HomePromotionDetail of(Long promotionId, String promotionPhoto, Long performanceId) { - return new HomePromotionDetail(promotionId, promotionPhoto, performanceId); - } +import com.beat.domain.promotion.domain.CarouselNumber; +import com.beat.domain.promotion.domain.Promotion; + +public record HomePromotionDetail(Long promotionId, String promotionPhoto, Long performanceId, String redirectUrl, + boolean isExternal, CarouselNumber carouselNumber) { + + public static HomePromotionDetail from(Promotion promotion) { + Long performanceId = null; + + if (promotion.getPerformance() != null) { + performanceId = promotion.getPerformance().getId(); + } + + return new HomePromotionDetail(promotion.getId(), promotion.getPromotionPhoto(), performanceId, + promotion.getRedirectUrl(), promotion.isExternal(), promotion.getCarouselNumber()); + } } diff --git a/src/main/java/com/beat/domain/performance/application/dto/home/HomeResponse.java b/src/main/java/com/beat/domain/performance/application/dto/home/HomeResponse.java deleted file mode 100644 index c3d963b4..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/home/HomeResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beat.domain.performance.application.dto.home; - -import java.util.List; - -public record HomeResponse( - List promotionList, - List performanceList -) { - public static HomeResponse of(List promotionList, List performanceList) { - return new HomeResponse(promotionList, performanceList); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceDetailResponse.java b/src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceDetailResponse.java new file mode 100644 index 00000000..f34501ad --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceDetailResponse.java @@ -0,0 +1,20 @@ +package com.beat.domain.performance.application.dto.makerPerformance; + +public record MakerPerformanceDetailResponse( + Long performanceId, + String genre, + String performanceTitle, + String posterImage, + String performancePeriod, + int minDueDate +) { + public static MakerPerformanceDetailResponse of( + Long performanceId, + String genre, + String performanceTitle, + String posterImage, + String performancePeriod, + int minDueDate) { // minDueDate 매개변수 추가 + return new MakerPerformanceDetailResponse(performanceId, genre, performanceTitle, posterImage, performancePeriod, minDueDate); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceResponse.java b/src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceResponse.java similarity index 55% rename from src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceResponse.java rename to src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceResponse.java index 6a36683d..ef0f0ffd 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/MakerPerformanceResponse.java +++ b/src/main/java/com/beat/domain/performance/application/dto/makerPerformance/MakerPerformanceResponse.java @@ -1,14 +1,14 @@ -package com.beat.domain.performance.application.dto; +package com.beat.domain.performance.application.dto.makerPerformance; import java.util.List; public record MakerPerformanceResponse( Long userId, - List performances + List performances ) { public static MakerPerformanceResponse of( Long userId, - List performances) { + List performances) { return new MakerPerformanceResponse(userId, performances); } } diff --git a/src/main/java/com/beat/domain/performance/application/dto/PerformanceEditResponse.java b/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyDetailResponse.java similarity index 80% rename from src/main/java/com/beat/domain/performance/application/dto/PerformanceEditResponse.java rename to src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyDetailResponse.java index e2341753..eb58f23c 100644 --- a/src/main/java/com/beat/domain/performance/application/dto/PerformanceEditResponse.java +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyDetailResponse.java @@ -1,6 +1,7 @@ -package com.beat.domain.performance.application.dto; +package com.beat.domain.performance.application.dto.modify; import com.beat.domain.performance.application.dto.create.CastResponse; +import com.beat.domain.performance.application.dto.create.PerformanceImageResponse; import com.beat.domain.performance.application.dto.create.ScheduleResponse; import com.beat.domain.performance.application.dto.create.StaffResponse; import com.beat.domain.performance.domain.BankName; @@ -8,7 +9,7 @@ import java.util.List; -public record PerformanceEditResponse( +public record PerformanceModifyDetailResponse( Long userId, Long performanceId, String performanceTitle, @@ -29,9 +30,10 @@ public record PerformanceEditResponse( boolean isBookerExist, List scheduleList, List castList, - List staffList + List staffList, + List performanceImageList ) { - public static PerformanceEditResponse of( + public static PerformanceModifyDetailResponse of( Long userId, Long performanceId, String performanceTitle, @@ -52,9 +54,10 @@ public static PerformanceEditResponse of( boolean isBookerExist, List scheduleList, List castList, - List staffList + List staffList, + List performanceImageList ) { - return new PerformanceEditResponse( + return new PerformanceModifyDetailResponse( userId, performanceId, performanceTitle, @@ -75,7 +78,8 @@ public static PerformanceEditResponse of( isBookerExist, scheduleList, castList, - staffList + staffList, + performanceImageList ); } } diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyRequest.java b/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyRequest.java new file mode 100644 index 00000000..cd8b966a --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyRequest.java @@ -0,0 +1,33 @@ +package com.beat.domain.performance.application.dto.modify; + +import com.beat.domain.performance.application.dto.modify.cast.CastModifyRequest; +import com.beat.domain.performance.application.dto.modify.performanceImage.PerformanceImageModifyRequest; +import com.beat.domain.performance.application.dto.modify.schedule.ScheduleModifyRequest; +import com.beat.domain.performance.application.dto.modify.staff.StaffModifyRequest; +import com.beat.domain.performance.domain.BankName; +import com.beat.domain.performance.domain.Genre; + +import java.util.List; + +public record PerformanceModifyRequest( + Long performanceId, + String performanceTitle, + Genre genre, + int runningTime, + String performanceDescription, + String performanceAttentionNote, + BankName bankName, + String accountNumber, + String accountHolder, + String posterImage, + String performanceTeamName, + String performanceVenue, + String performanceContact, + String performancePeriod, + int totalScheduleCount, + int ticketPrice, + List scheduleModifyRequests, + List castModifyRequests, + List staffModifyRequests, + List performanceImageModifyRequests +) {} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyResponse.java b/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyResponse.java new file mode 100644 index 00000000..cd6dfdf2 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/PerformanceModifyResponse.java @@ -0,0 +1,83 @@ +package com.beat.domain.performance.application.dto.modify; + +import com.beat.domain.performance.application.dto.modify.cast.CastModifyResponse; +import com.beat.domain.performance.application.dto.modify.performanceImage.PerformanceImageModifyResponse; +import com.beat.domain.performance.application.dto.modify.schedule.ScheduleModifyResponse; +import com.beat.domain.performance.application.dto.modify.staff.StaffModifyResponse; +import com.beat.domain.performance.domain.BankName; +import com.beat.domain.performance.domain.Genre; + +import java.util.List; + +public record PerformanceModifyResponse( + Long userId, + Long performanceId, + String performanceTitle, + Genre genre, + int runningTime, + String performanceDescription, + String performanceAttentionNote, + BankName bankName, + String accountNumber, + String accountHolder, + String posterImage, + String performanceTeamName, + String performanceVenue, + String performanceContact, + String performancePeriod, + int ticketPrice, + int totalScheduleCount, + List scheduleModifyResponses, + List castModifyResponses, + List staffModifyResponses, + List performanceImageModifyResponses +) { + public static PerformanceModifyResponse of( + Long userId, + Long performanceId, + String performanceTitle, + Genre genre, + int runningTime, + String performanceDescription, + String performanceAttentionNote, + BankName bankName, + String accountNumber, + String accountHolder, + String posterImage, + String performanceTeamName, + String performanceVenue, + String performanceContact, + String performancePeriod, + int ticketPrice, + int totalScheduleCount, + List scheduleModifyResponses, + List castModifyResponses, + List staffModifyResponses, + List performanceImageModifyResponses) + { + + return new PerformanceModifyResponse( + userId, + performanceId, + performanceTitle, + genre, + runningTime, + performanceDescription, + performanceAttentionNote, + bankName, + accountNumber, + accountHolder, + posterImage, + performanceTeamName, + performanceVenue, + performanceContact, + performancePeriod, + ticketPrice, + totalScheduleCount, + scheduleModifyResponses, + castModifyResponses, + staffModifyResponses, + performanceImageModifyResponses + ); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyRequest.java b/src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyRequest.java new file mode 100644 index 00000000..3f3b56d2 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyRequest.java @@ -0,0 +1,12 @@ +package com.beat.domain.performance.application.dto.modify.cast; + +import org.jetbrains.annotations.Nullable; + +public record CastModifyRequest( + @Nullable + Long castId, + String castName, + String castRole, + String castPhoto +) { +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyResponse.java b/src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyResponse.java new file mode 100644 index 00000000..bfed8151 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/cast/CastModifyResponse.java @@ -0,0 +1,11 @@ +package com.beat.domain.performance.application.dto.modify.cast; + +public record CastModifyResponse(Long castId, + String castName, + String castRole, + String castPhoto) { + + public static CastModifyResponse of(Long castId, String castName, String castRole, String castPhoto) { + return new CastModifyResponse(castId, castName, castRole, castPhoto); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyRequest.java b/src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyRequest.java new file mode 100644 index 00000000..4e05250c --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyRequest.java @@ -0,0 +1,10 @@ +package com.beat.domain.performance.application.dto.modify.performanceImage; + +import javax.annotation.Nullable; + +public record PerformanceImageModifyRequest( + @Nullable + Long performanceImageId, + String performanceImage +) { +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyResponse.java b/src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyResponse.java new file mode 100644 index 00000000..18d93f89 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/performanceImage/PerformanceImageModifyResponse.java @@ -0,0 +1,11 @@ +package com.beat.domain.performance.application.dto.modify.performanceImage; + +public record PerformanceImageModifyResponse( + Long performanceImageId, + String performanceImage +) { + + public static PerformanceImageModifyResponse of(Long performanceImageId, String performanceImage) { + return new PerformanceImageModifyResponse(performanceImageId, performanceImage); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyRequest.java b/src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyRequest.java new file mode 100644 index 00000000..fcda2a5f --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyRequest.java @@ -0,0 +1,13 @@ +package com.beat.domain.performance.application.dto.modify.schedule; + +import org.jetbrains.annotations.Nullable; + +import java.time.LocalDateTime; + +public record ScheduleModifyRequest( + @Nullable + Long scheduleId, + LocalDateTime performanceDate, + int totalTicketCount +) { +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyResponse.java b/src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyResponse.java new file mode 100644 index 00000000..fadf4dc9 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/schedule/ScheduleModifyResponse.java @@ -0,0 +1,16 @@ +package com.beat.domain.performance.application.dto.modify.schedule; + +import com.beat.domain.schedule.domain.ScheduleNumber; + +import java.time.LocalDateTime; + +public record ScheduleModifyResponse(Long scheduleId, + LocalDateTime performanceDate, + int totalTicketCount, + int dueDate, + ScheduleNumber scheduleNumber) { + + public static ScheduleModifyResponse of(Long scheduleId, LocalDateTime performanceDate, int totalTicketCount, int dueDate, ScheduleNumber scheduleNumber) { + return new ScheduleModifyResponse(scheduleId, performanceDate, totalTicketCount, dueDate, scheduleNumber); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyRequest.java b/src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyRequest.java new file mode 100644 index 00000000..67020ed1 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyRequest.java @@ -0,0 +1,12 @@ +package com.beat.domain.performance.application.dto.modify.staff; + +import org.jetbrains.annotations.Nullable; + +public record StaffModifyRequest( + @Nullable + Long staffId, + String staffName, + String staffRole, + String staffPhoto +) { +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyResponse.java b/src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyResponse.java new file mode 100644 index 00000000..afe97f49 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/modify/staff/StaffModifyResponse.java @@ -0,0 +1,11 @@ +package com.beat.domain.performance.application.dto.modify.staff; + +public record StaffModifyResponse(Long staffId, + String staffName, + String staffRole, + String staffPhoto) { + + public static StaffModifyResponse of(Long staffId, String staffName, String staffRole, String staffPhoto) { + return new StaffModifyResponse(staffId, staffName, staffRole, staffPhoto); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailCastResponse.java b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailCastResponse.java new file mode 100644 index 00000000..ede5b7bc --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailCastResponse.java @@ -0,0 +1,12 @@ +package com.beat.domain.performance.application.dto.performanceDetail; + +public record PerformanceDetailCastResponse( + Long castId, + String castName, + String castRole, + String castPhoto +) { + public static PerformanceDetailCastResponse of(Long castId, String castName, String castRole, String castPhoto) { + return new PerformanceDetailCastResponse(castId, castName, castRole, castPhoto); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailImageResponse.java b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailImageResponse.java new file mode 100644 index 00000000..05def70f --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailImageResponse.java @@ -0,0 +1,10 @@ +package com.beat.domain.performance.application.dto.performanceDetail; + +public record PerformanceDetailImageResponse( + Long performanceImageId, + String performanceImage +) { + public static PerformanceDetailImageResponse of(Long performanceImageId, String performanceImage) { + return new PerformanceDetailImageResponse(performanceImageId, performanceImage); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailResponse.java b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailResponse.java new file mode 100644 index 00000000..2047176d --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailResponse.java @@ -0,0 +1,63 @@ +package com.beat.domain.performance.application.dto.performanceDetail; + +import java.util.List; + +public record PerformanceDetailResponse( + Long performanceId, + String performanceTitle, + String performancePeriod, + List scheduleList, + int ticketPrice, + String genre, + String posterImage, + int runningTime, + String performanceVenue, + String performanceDescription, + String performanceAttentionNote, + String performanceContact, + String performanceTeamName, + List castList, + List staffList, + int minDueDate, + List performanceImageList +) { + public static PerformanceDetailResponse of( + Long performanceId, + String performanceTitle, + String performancePeriod, + List scheduleList, + int ticketPrice, + String genre, + String posterImage, + int runningTime, + String performanceVenue, + String performanceDescription, + String performanceAttentionNote, + String performanceContact, + String performanceTeamName, + List castList, + List staffList, + int minDueDate, + List performanceImageList + ) { + return new PerformanceDetailResponse( + performanceId, + performanceTitle, + performancePeriod, + scheduleList, + ticketPrice, + genre, + posterImage, + runningTime, + performanceVenue, + performanceDescription, + performanceAttentionNote, + performanceContact, + performanceTeamName, + castList, + staffList, + minDueDate, + performanceImageList + ); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailScheduleResponse.java b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailScheduleResponse.java new file mode 100644 index 00000000..4adbddd7 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailScheduleResponse.java @@ -0,0 +1,15 @@ +package com.beat.domain.performance.application.dto.performanceDetail; + +import java.time.LocalDateTime; + +public record PerformanceDetailScheduleResponse( + Long scheduleId, + LocalDateTime performanceDate, + String scheduleNumber, + int dueDate, + boolean isBooking +) { + public static PerformanceDetailScheduleResponse of(Long scheduleId, LocalDateTime performanceDate, String scheduleNumber, int dueDate, boolean isBooking) { + return new PerformanceDetailScheduleResponse(scheduleId, performanceDate, scheduleNumber, dueDate, isBooking); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailStaffResponse.java b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailStaffResponse.java new file mode 100644 index 00000000..8a24c9fc --- /dev/null +++ b/src/main/java/com/beat/domain/performance/application/dto/performanceDetail/PerformanceDetailStaffResponse.java @@ -0,0 +1,12 @@ +package com.beat.domain.performance.application.dto.performanceDetail; + +public record PerformanceDetailStaffResponse( + Long staffId, + String staffName, + String staffRole, + String staffPhoto +) { + public static PerformanceDetailStaffResponse of(Long staffId, String staffName, String staffRole, String staffPhoto) { + return new PerformanceDetailStaffResponse(staffId, staffName, staffRole, staffPhoto); + } +} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateRequest.java b/src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateRequest.java deleted file mode 100644 index cb178956..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateRequest.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -public record CastUpdateRequest( - Long castId, - String castName, - String castRole, - String castPhoto -) {} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateResponse.java b/src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateResponse.java deleted file mode 100644 index 39d8d97a..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/CastUpdateResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -public record CastUpdateResponse( - Long castId, - String castName, - String castRole, - String castPhoto -) { - public static CastUpdateResponse of(Long castId, String castName, String castRole, String castPhoto) { - return new CastUpdateResponse(castId, castName, castRole, castPhoto); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateRequest.java b/src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateRequest.java deleted file mode 100644 index 255883c7..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -import com.beat.domain.performance.domain.BankName; -import com.beat.domain.performance.domain.Genre; - -import java.util.List; - -public record PerformanceUpdateRequest( - Long performanceId, - String performanceTitle, - Genre genre, - int runningTime, - String performanceDescription, - String performanceAttentionNote, - BankName bankName, - String accountNumber, - String accountHolder, - String posterImage, - String performanceTeamName, - String performanceVenue, - String performanceContact, - String performancePeriod, - int totalScheduleCount, - List scheduleList, - List castList, - List staffList -) {} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateResponse.java b/src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateResponse.java deleted file mode 100644 index fc2bc6dc..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/PerformanceUpdateResponse.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -import com.beat.domain.performance.domain.BankName; -import com.beat.domain.performance.domain.Genre; - -import java.util.List; - -public record PerformanceUpdateResponse( - Long userId, - Long performanceId, - String performanceTitle, - Genre genre, - int runningTime, - String performanceDescription, - String performanceAttentionNote, - BankName bankName, - String accountNumber, - String accountHolder, - String posterImage, - String performanceTeamName, - String performanceVenue, - String performanceContact, - String performancePeriod, - int ticketPrice, - int totalScheduleCount, - List scheduleList, - List castList, - List staffList -) { - public static PerformanceUpdateResponse of(Long userId, Long performanceId, String performanceTitle, Genre genre, int runningTime, - String performanceDescription, String performanceAttentionNote, BankName bankName, String accountNumber, String accountHolder, - String posterImage, String performanceTeamName, String performanceVenue, String performanceContact, String performancePeriod, - int ticketPrice, int totalScheduleCount, List scheduleList, List castList, List staffList) { - return new PerformanceUpdateResponse(userId, performanceId, performanceTitle, genre, runningTime, performanceDescription, performanceAttentionNote, bankName, accountNumber, - accountHolder, posterImage, performanceTeamName, performanceVenue, performanceContact, performancePeriod, ticketPrice, totalScheduleCount, scheduleList, castList, staffList); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateRequest.java b/src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateRequest.java deleted file mode 100644 index bdaf8728..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -import java.time.LocalDateTime; - -public record ScheduleUpdateRequest( - Long scheduleId, - LocalDateTime performanceDate, - int totalTicketCount, - String scheduleNumber -) {} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateResponse.java b/src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateResponse.java deleted file mode 100644 index 2ef82613..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/ScheduleUpdateResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -import com.beat.domain.schedule.domain.ScheduleNumber; - -import java.time.LocalDateTime; - -public record ScheduleUpdateResponse( - Long scheduleId, - LocalDateTime performanceDate, - int totalTicketCount, - int dueDate, - ScheduleNumber scheduleNumber -) { - public static ScheduleUpdateResponse of(Long scheduleId, LocalDateTime performanceDate, int totalTicketCount, int dueDate, ScheduleNumber scheduleNumber) { - return new ScheduleUpdateResponse(scheduleId, performanceDate, totalTicketCount, dueDate, scheduleNumber); - } -} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateRequest.java b/src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateRequest.java deleted file mode 100644 index 00a49735..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateRequest.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -public record StaffUpdateRequest( - Long staffId, - String staffName, - String staffRole, - String staffPhoto -) {} diff --git a/src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateResponse.java b/src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateResponse.java deleted file mode 100644 index 68bba8d9..00000000 --- a/src/main/java/com/beat/domain/performance/application/dto/update/StaffUpdateResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.beat.domain.performance.application.dto.update; - -public record StaffUpdateResponse( - Long staffId, - String staffName, - String staffRole, - String staffPhoto -) { - public static StaffUpdateResponse of(Long staffId, String staffName, String staffRole, String staffPhoto) { - return new StaffUpdateResponse(staffId, staffName, staffRole, staffPhoto); - } -} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/dao/PerformanceImageRepository.java b/src/main/java/com/beat/domain/performance/dao/PerformanceImageRepository.java new file mode 100644 index 00000000..9f7d74ca --- /dev/null +++ b/src/main/java/com/beat/domain/performance/dao/PerformanceImageRepository.java @@ -0,0 +1,14 @@ +package com.beat.domain.performance.dao; + +import com.beat.domain.performance.domain.PerformanceImage; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface PerformanceImageRepository extends JpaRepository { + List findAllByPerformanceId(Long performanceId); + + @Query("SELECT s.id FROM PerformanceImage s WHERE s.performance.id = :performanceId") + List findIdsByPerformanceId(Long performanceId); +} diff --git a/src/main/java/com/beat/domain/performance/domain/Performance.java b/src/main/java/com/beat/domain/performance/domain/Performance.java index 78cc146e..8ba1af31 100644 --- a/src/main/java/com/beat/domain/performance/domain/Performance.java +++ b/src/main/java/com/beat/domain/performance/domain/Performance.java @@ -1,8 +1,10 @@ package com.beat.domain.performance.domain; import com.beat.domain.BaseTimeEntity; +import com.beat.domain.performance.exception.PerformanceErrorCode; import com.beat.domain.promotion.domain.Promotion; import com.beat.domain.user.domain.Users; +import com.beat.global.common.exception.BadRequestException; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -33,10 +35,10 @@ public class Performance extends BaseTimeEntity { @Column(nullable = false) private int runningTime; - @Column(nullable = false) + @Column(nullable = false, length = 500) private String performanceDescription; - @Column(nullable = false) + @Column(nullable = false, length = 500) private String performanceAttentionNote; @Enumerated(EnumType.STRING) @@ -78,6 +80,9 @@ public class Performance extends BaseTimeEntity { @OnDelete(action = OnDeleteAction.CASCADE) private Users users; + @OneToMany(mappedBy = "performance", cascade = CascadeType.ALL, orphanRemoval = true) + private List performanceImageList = new ArrayList<>(); + @Builder public Performance(String performanceTitle, Genre genre, int runningTime, String performanceDescription, String performanceAttentionNote, BankName bankName, String accountNumber, String accountHolder, String posterImage, String performanceTeamName, String performanceVenue, String performanceContact, @@ -143,4 +148,11 @@ public void update( this.performancePeriod = performancePeriod; this.totalScheduleCount = totalScheduleCount; } + + public void updateTicketPrice(int newTicketPrice) { + if (newTicketPrice < 0) { + throw new BadRequestException(PerformanceErrorCode.NEGATIVE_TICKET_PRICE); + } + this.ticketPrice = newTicketPrice; + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/domain/PerformanceImage.java b/src/main/java/com/beat/domain/performance/domain/PerformanceImage.java new file mode 100644 index 00000000..33bbfb02 --- /dev/null +++ b/src/main/java/com/beat/domain/performance/domain/PerformanceImage.java @@ -0,0 +1,41 @@ +package com.beat.domain.performance.domain; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class PerformanceImage { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String performanceImage; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "performance_id", nullable = false) + private Performance performance; + + @Builder + public PerformanceImage(String performanceImage, Performance performance) { + this.performanceImage = performanceImage; + this.performance = performance; + } + + public static PerformanceImage create(String perforemanceImage, Performance performance) { + return PerformanceImage.builder() + .performanceImage(perforemanceImage) + .performance(performance) + .build(); + } + + public void update(String performanceImage) { + this.performanceImage = performanceImage; + } +} diff --git a/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java b/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java index 5b1ab3ea..8e4f3a0b 100644 --- a/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java +++ b/src/main/java/com/beat/domain/performance/exception/PerformanceErrorCode.java @@ -1,22 +1,30 @@ package com.beat.domain.performance.exception; import com.beat.global.common.exception.base.BaseErrorCode; + import lombok.Getter; import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor public enum PerformanceErrorCode implements BaseErrorCode { - PERFORMANCE_NOT_FOUND(404, "해당 공연 정보를 찾을 수 없습니다."), - REQUIRED_DATA_MISSING(400, "필수 데이터가 누락되었습니다."), - INVALID_DATA_FORMAT(400, "잘못된 데이터 형식입니다."), - INVALID_REQUEST_FORMAT(400, "잘못된 요청 형식입니다."), - NO_PERFORMANCE_FOUND(404, "공연을 찾을 수 없습니다."), - PERFORMANCE_DELETE_FAILED(403, "예매자가 1명 이상 있을 경우, 공연을 삭제할 수 없습니다."), - NOT_PERFORMANCE_OWNER(403, "해당 공연의 메이커가 아닙니다."), - INTERNAL_SERVER_ERROR(500, "서버 내부 오류입니다.") - ; + PERFORMANCE_NOT_FOUND(404, "해당 공연 정보를 찾을 수 없습니다."), + REQUIRED_DATA_MISSING(400, "필수 데이터가 누락되었습니다."), + INVALID_DATA_FORMAT(400, "잘못된 데이터 형식입니다."), + INVALID_REQUEST_FORMAT(400, "잘못된 요청 형식입니다."), + PRICE_UPDATE_NOT_ALLOWED(400, "예매자가 존재하여 가격을 수정할 수 없습니다."), + NEGATIVE_TICKET_PRICE(400, "티켓 가격은 음수일 수 없습니다."), + NO_PERFORMANCE_FOUND(404, "공연을 찾을 수 없습니다."), + PERFORMANCE_DELETE_FAILED(403, "예매자가 1명 이상 있을 경우, 공연을 삭제할 수 없습니다."), + NOT_PERFORMANCE_OWNER(403, "해당 공연의 메이커가 아닙니다."), + MAX_SCHEDULE_LIMIT_EXCEEDED(400, "공연 회차는 최대 10개까지 추가할 수 있습니다."), + INVALID_PERFORMANCE_DESCRIPTION_LENGTH(400, "공연 소개 글자수가 500자를 초과했습니다."), + INVALID_ATTENTION_NOTE_LENGTH(400, "공연 유의사항 글자수가 500자를 초과했습니다."), + INTERNAL_SERVER_ERROR(500, "서버 내부 오류입니다."), + PAST_SCHEDULE_NOT_ALLOWED(400, "과거 날짜 회차를 포함한 공연을 생성할 수 없습니다."), + SCHEDULE_MODIFICATION_NOT_ALLOWED_FOR_ENDED_SCHEDULE(400, "종료된 회차를 수정할 수 없습니다."), + INVALID_TICKET_COUNT(400, "판매된 티켓 수보다 적은 수로 판매할 티켓 매수를 수정할 수 없습니다."); - private final int status; - private final String message; + private final int status; + private final String message; } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/performance/exception/PerformanceImageErrorCode.java b/src/main/java/com/beat/domain/performance/exception/PerformanceImageErrorCode.java new file mode 100644 index 00000000..f043a71a --- /dev/null +++ b/src/main/java/com/beat/domain/performance/exception/PerformanceImageErrorCode.java @@ -0,0 +1,16 @@ +package com.beat.domain.performance.exception; + +import com.beat.global.common.exception.base.BaseErrorCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum PerformanceImageErrorCode implements BaseErrorCode { + PERFORMANCE_IMAGE_NOT_FOUND(404, "해당 공연 상세이미지를 찾을 수 없습니다."), + PERFORMANCE_IMAGE_NOT_BELONG_TO_PERFORMANCE(403, "해당 싱세이미지는 해당 공연에 속해 있지 않습니다.") + ; + + private final int status; + private final String message; +} diff --git a/src/main/java/com/beat/domain/performance/port/in/PerformanceUseCase.java b/src/main/java/com/beat/domain/performance/port/in/PerformanceUseCase.java new file mode 100644 index 00000000..ea77f90d --- /dev/null +++ b/src/main/java/com/beat/domain/performance/port/in/PerformanceUseCase.java @@ -0,0 +1,7 @@ +package com.beat.domain.performance.port.in; + +import com.beat.domain.performance.domain.Performance; + +public interface PerformanceUseCase { + Performance findById(Long performanceId); +} diff --git a/src/main/java/com/beat/domain/promotion/application/PromotionSchedulerService.java b/src/main/java/com/beat/domain/promotion/application/PromotionSchedulerService.java new file mode 100644 index 00000000..db3e7a24 --- /dev/null +++ b/src/main/java/com/beat/domain/promotion/application/PromotionSchedulerService.java @@ -0,0 +1,44 @@ +package com.beat.domain.promotion.application; + +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.promotion.dao.PromotionRepository; +import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.schedule.application.ScheduleService; +import com.beat.domain.schedule.dao.ScheduleRepository; +import com.beat.domain.schedule.domain.Schedule; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class PromotionSchedulerService { + + private final PromotionRepository promotionRepository; + private final ScheduleRepository scheduleRepository; + private final ScheduleService scheduleService; + + @Scheduled(cron = "1 0 0 * * ?") + @Transactional + public void checkAndDeleteInvalidPromotions() { + List promotions = promotionRepository.findAll(); + + for (Promotion promotion : promotions) { + Performance performance = promotion.getPerformance(); + + if (performance == null) { + return; + } + + List schedules = scheduleRepository.findByPerformanceId(performance.getId()); + int minDueDate = scheduleService.getMinDueDate(schedules); + + if (minDueDate < 0) { + promotionRepository.delete(promotion); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/application/PromotionService.java b/src/main/java/com/beat/domain/promotion/application/PromotionService.java new file mode 100644 index 00000000..dd0c8f05 --- /dev/null +++ b/src/main/java/com/beat/domain/promotion/application/PromotionService.java @@ -0,0 +1,57 @@ +package com.beat.domain.promotion.application; + +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionModifyRequest; +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.promotion.dao.PromotionRepository; +import com.beat.domain.promotion.domain.CarouselNumber; +import com.beat.domain.promotion.domain.Promotion; +import com.beat.domain.promotion.exception.PromotionErrorCode; +import com.beat.domain.promotion.port.in.PromotionUseCase; +import com.beat.global.common.exception.NotFoundException; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@Transactional +@RequiredArgsConstructor +public class PromotionService implements PromotionUseCase { + + private final PromotionRepository promotionRepository; + + @Override + @Transactional(readOnly = true) + public Promotion findById(Long promotionId) { + return promotionRepository.findById(promotionId) + .orElseThrow(() -> new NotFoundException(PromotionErrorCode.PROMOTION_NOT_FOUND)); + } + + @Override + @Transactional(readOnly = true) + public List findAllPromotions() { + return promotionRepository.findAll(); + } + + @Override + public Promotion createPromotion(String newImageUrl, Performance performance, String redirectUrl, + boolean isExternal, CarouselNumber carouselNumber) { + Promotion newPromotion = Promotion.create(newImageUrl, performance, redirectUrl, isExternal, carouselNumber); + return promotionRepository.save(newPromotion); + } + + @Override + public Promotion modifyPromotion(Promotion promotion, Performance performance, PromotionModifyRequest request) { + promotion.updatePromotionDetails(request.carouselNumber(), request.newImageUrl(), request.isExternal(), + request.redirectUrl(), performance); + return promotionRepository.save(promotion); + } + + @Override + public void deletePromotionsByPromotionIds(List promotionIds) { + promotionRepository.deleteByPromotionIds(promotionIds); + } +} diff --git a/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java b/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java index 95a64b0b..077515fc 100644 --- a/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java +++ b/src/main/java/com/beat/domain/promotion/dao/PromotionRepository.java @@ -1,7 +1,24 @@ package com.beat.domain.promotion.dao; +import com.beat.domain.promotion.domain.CarouselNumber; import com.beat.domain.promotion.domain.Promotion; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; public interface PromotionRepository extends JpaRepository { -} + List findAll(); + + @Modifying(clearAutomatically = true) + @Transactional + @Query("DELETE FROM Promotion p WHERE p.id IN :promotionIds") + void deleteByPromotionIds(@Param("promotionIds") List promotionIds); + + @Query("SELECT p FROM Promotion p WHERE p.carouselNumber = :carouselNumber") + Optional findByCarouselNumber(@Param("carouselNumber") CarouselNumber carouselNumber); +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/domain/CarouselNumber.java b/src/main/java/com/beat/domain/promotion/domain/CarouselNumber.java new file mode 100644 index 00000000..6a8dbe2a --- /dev/null +++ b/src/main/java/com/beat/domain/promotion/domain/CarouselNumber.java @@ -0,0 +1,18 @@ +package com.beat.domain.promotion.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum CarouselNumber { + ONE(1), + TWO(2), + THREE(3), + FOUR(4), + FIVE(5), + SIX(6), + SEVEN(7); + + private final int number; +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/domain/Promotion.java b/src/main/java/com/beat/domain/promotion/domain/Promotion.java index 445469ef..fa0240a3 100644 --- a/src/main/java/com/beat/domain/promotion/domain/Promotion.java +++ b/src/main/java/com/beat/domain/promotion/domain/Promotion.java @@ -1,7 +1,17 @@ package com.beat.domain.promotion.domain; import com.beat.domain.performance.domain.Performance; -import jakarta.persistence.*; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -12,27 +22,57 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Promotion { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column(nullable = false) - private String promotionPhoto; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "performance_id", nullable = false) - private Performance performance; - - @Builder - public Promotion(String promotionPhoto, Performance performance) { - this.promotionPhoto = promotionPhoto; - this.performance = performance; - } - - public static Promotion create(String promotionPhoto, Performance performance) { - return Promotion.builder() - .promotionPhoto(promotionPhoto) - .performance(performance) - .build(); - } -} + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String promotionPhoto; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "performance_id", nullable = true) + private Performance performance; + + @Column(nullable = false) + private String redirectUrl; + + @Column(nullable = false) + private boolean isExternal; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private CarouselNumber carouselNumber; + + @Builder + public Promotion(String promotionPhoto, Performance performance, String redirectUrl, boolean isExternal, + CarouselNumber carouselNumber) { + this.promotionPhoto = promotionPhoto; + this.performance = performance; + this.redirectUrl = redirectUrl; + this.isExternal = isExternal; + this.carouselNumber = carouselNumber; + } + + public static Promotion create(String promotionPhoto, Performance performance, String redirectUrl, + boolean isExternal, CarouselNumber carouselNumber) { + return Promotion.builder() + .promotionPhoto(promotionPhoto) + .performance(performance) + .redirectUrl(redirectUrl) + .isExternal(isExternal) + .carouselNumber(carouselNumber) + .build(); + } + + /** + * Promotion 정보를 업데이트하는 도메인 메서드 + */ + public void updatePromotionDetails(CarouselNumber carouselNumber, String newImageUrl, boolean isExternal, + String redirectUrl, Performance performance) { + this.carouselNumber = carouselNumber; + this.promotionPhoto = newImageUrl; + this.isExternal = isExternal; + this.redirectUrl = redirectUrl; + this.performance = performance; + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/exception/PromotionErrorCode.java b/src/main/java/com/beat/domain/promotion/exception/PromotionErrorCode.java new file mode 100644 index 00000000..f7df85e6 --- /dev/null +++ b/src/main/java/com/beat/domain/promotion/exception/PromotionErrorCode.java @@ -0,0 +1,15 @@ +package com.beat.domain.promotion.exception; + +import com.beat.global.common.exception.base.BaseErrorCode; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum PromotionErrorCode implements BaseErrorCode { + PROMOTION_NOT_FOUND(404,"해당 홍보 정보를 찾을 수 없습니다.") + ; + private final int status; + private final String message; +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java b/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java new file mode 100644 index 00000000..de360656 --- /dev/null +++ b/src/main/java/com/beat/domain/promotion/port/in/PromotionUseCase.java @@ -0,0 +1,21 @@ +package com.beat.domain.promotion.port.in; + +import com.beat.admin.application.dto.request.CarouselHandleRequest.PromotionModifyRequest; +import com.beat.domain.performance.domain.Performance; +import com.beat.domain.promotion.domain.CarouselNumber; +import com.beat.domain.promotion.domain.Promotion; + +import java.util.List; + +public interface PromotionUseCase { + Promotion findById(Long promotionId); + + List findAllPromotions(); + + Promotion createPromotion(String newImageUrl, Performance performance, String redirectUrl, boolean isExternal, + CarouselNumber carouselNumber); + + Promotion modifyPromotion(Promotion promotion, Performance performance, PromotionModifyRequest request); + + void deletePromotionsByPromotionIds(List promotionIds); +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/schedule/application/ScheduleService.java b/src/main/java/com/beat/domain/schedule/application/ScheduleService.java index a8162ce6..838a17b0 100644 --- a/src/main/java/com/beat/domain/schedule/application/ScheduleService.java +++ b/src/main/java/com/beat/domain/schedule/application/ScheduleService.java @@ -9,10 +9,8 @@ import com.beat.global.common.exception.NotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.OptionalInt; @@ -48,36 +46,20 @@ public TicketAvailabilityResponse findTicketAvailability(Long scheduleId, Ticket ); } - private void validateRequest(Long scheduleId, TicketAvailabilityRequest ticketAvailabilityRequest) { - if (ticketAvailabilityRequest.purchaseTicketCount() <= 0 || scheduleId <= 0) { - throw new BadRequestException(ScheduleErrorCode.INVALID_DATA_FORMAT); - } - } - public int getAvailableTicketCount(Schedule schedule) { return schedule.getTotalTicketCount() - schedule.getSoldTicketCount(); } - public boolean isBookingAvailable(Schedule schedule) { - int availableTicketCount = getAvailableTicketCount(schedule); - return schedule.isBooking() && availableTicketCount > 0 && schedule.getPerformanceDate().isAfter(LocalDateTime.now()); - } - - @Transactional - public void updateBookingStatus(Schedule schedule) { - boolean isBookingAvailable = isBookingAvailable(schedule); - if (schedule.isBooking() != isBookingAvailable) { - schedule.setBooking(isBookingAvailable); - scheduleRepository.save(schedule); - } - } - public int calculateDueDate(Schedule schedule) { - // LocalDate 객체를 사용하여 날짜 차이만 계산 int dueDate = (int) ChronoUnit.DAYS.between(LocalDate.now(), schedule.getPerformanceDate().toLocalDate()); return dueDate; } + public int getMinDueDateForPerformance(Long performanceId) { + List schedules = scheduleRepository.findByPerformanceId(performanceId); + return getMinDueDate(schedules); + } + public int getMinDueDate(List schedules) { OptionalInt minPositiveDueDate = schedules.stream() .mapToInt(this::calculateDueDate) @@ -94,4 +76,9 @@ public int getMinDueDate(List schedules) { } } + private void validateRequest(Long scheduleId, TicketAvailabilityRequest ticketAvailabilityRequest) { + if (ticketAvailabilityRequest.purchaseTicketCount() <= 0 || scheduleId <= 0) { + throw new BadRequestException(ScheduleErrorCode.INVALID_DATA_FORMAT); + } + } } diff --git a/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java b/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java index a67b18b6..3a471b8e 100644 --- a/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java +++ b/src/main/java/com/beat/domain/schedule/dao/ScheduleRepository.java @@ -21,4 +21,11 @@ public interface ScheduleRepository extends JpaRepository { List findAllByPerformanceId(Long performanceId); @Query("SELECT s.id FROM Schedule s WHERE s.performance.id = :performanceId") - List findIdsByPerformanceId(@Param("performanceId") Long performanceId);} \ No newline at end of file + List findIdsByPerformanceId(@Param("performanceId") Long performanceId); + + int countByPerformanceId(Long performanceId); + + // 기존의 PENDING 상태인 스케줄들을 조회하는 메소드 + @Query("SELECT s FROM Schedule s WHERE s.isBooking = true") + List findPendingSchedules(); +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/schedule/domain/Schedule.java b/src/main/java/com/beat/domain/schedule/domain/Schedule.java index d3e33df4..f9a8e05f 100644 --- a/src/main/java/com/beat/domain/schedule/domain/Schedule.java +++ b/src/main/java/com/beat/domain/schedule/domain/Schedule.java @@ -89,4 +89,11 @@ public void decreaseSoldTicketCount(int count) { } } + public void updateScheduleNumber(ScheduleNumber scheduleNumber) { + this.scheduleNumber = scheduleNumber; + } + + public void updateIsBooking(boolean isBooking) { + this.isBooking = isBooking; + } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/schedule/domain/ScheduleNumber.java b/src/main/java/com/beat/domain/schedule/domain/ScheduleNumber.java index 89d3dc73..60b93aa6 100644 --- a/src/main/java/com/beat/domain/schedule/domain/ScheduleNumber.java +++ b/src/main/java/com/beat/domain/schedule/domain/ScheduleNumber.java @@ -8,7 +8,14 @@ public enum ScheduleNumber { FIRST("1회차"), SECOND("2회차"), - THIRD("3회차"); + THIRD("3회차"), + FOURTH("4회차"), + FIFTH("5회차"), + SIXTH("6회차"), + SEVENTH("7회차"), + EIGHTH("8회차"), + NINTH("9회차"), + TENTH("10회차"); private final String displayName; } diff --git a/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java b/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java index e9af170a..98e02ad1 100644 --- a/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java +++ b/src/main/java/com/beat/domain/schedule/exception/ScheduleErrorCode.java @@ -8,6 +8,7 @@ @RequiredArgsConstructor public enum ScheduleErrorCode implements BaseErrorCode { INVALID_DATA_FORMAT(400, "잘못된 데이터 형식입니다."), + SCHEDULE_NOT_BELONG_TO_PERFORMANCE(403,"해당 스케줄은 해당 공연에 속해 있지 않습니다."), NO_SCHEDULE_FOUND(404, "해당 회차를 찾을 수 없습니다."), INSUFFICIENT_TICKETS(409, "요청한 티켓 수량이 잔여 티켓 수를 초과했습니다. 다른 수량을 선택해 주세요."), EXCESS_TICKET_DELETE(409, "예매된 티켓 수 이상을 삭제할 수 없습니다.") diff --git a/src/main/java/com/beat/domain/staff/dao/StaffRepository.java b/src/main/java/com/beat/domain/staff/dao/StaffRepository.java index d3af9518..f32801ea 100644 --- a/src/main/java/com/beat/domain/staff/dao/StaffRepository.java +++ b/src/main/java/com/beat/domain/staff/dao/StaffRepository.java @@ -2,6 +2,7 @@ import com.beat.domain.staff.domain.Staff; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import java.util.List; @@ -9,4 +10,7 @@ public interface StaffRepository extends JpaRepository { List findByPerformanceId(Long performanceId); List findAllByPerformanceId(Long performanceId); + + @Query("SELECT s.id FROM Staff s WHERE s.performance.id = :performanceId") + List findIdsByPerformanceId(Long performanceId); } diff --git a/src/main/java/com/beat/domain/staff/exception/StaffErrorCode.java b/src/main/java/com/beat/domain/staff/exception/StaffErrorCode.java index 706e50d8..495ee148 100644 --- a/src/main/java/com/beat/domain/staff/exception/StaffErrorCode.java +++ b/src/main/java/com/beat/domain/staff/exception/StaffErrorCode.java @@ -7,6 +7,7 @@ @Getter @RequiredArgsConstructor public enum StaffErrorCode implements BaseErrorCode { + STAFF_NOT_BELONG_TO_PERFORMANCE(403, "해당 스태프는 해당 공연에 속해있지 않습니다."), STAFF_NOT_FOUND(404, "스태프가 존재하지 않습니다.") ; diff --git a/src/main/java/com/beat/domain/user/application/UserService.java b/src/main/java/com/beat/domain/user/application/UserService.java index 5c8a1ace..f485c0fc 100644 --- a/src/main/java/com/beat/domain/user/application/UserService.java +++ b/src/main/java/com/beat/domain/user/application/UserService.java @@ -1,4 +1,33 @@ package com.beat.domain.user.application; -public class UserService { -} +import com.beat.domain.user.dao.UserRepository; +import com.beat.domain.user.domain.Users; +import com.beat.domain.user.exception.UserErrorCode; +import com.beat.domain.user.port.in.UserUseCase; +import com.beat.global.common.exception.NotFoundException; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class UserService implements UserUseCase { + private final UserRepository userRepository; + + @Override + @Transactional(readOnly = true) + public List findAllUsers() { + return userRepository.findAll(); + } + + @Override + @Transactional(readOnly = true) + public Users findUserByUserId(final Long userId) { + return userRepository.findById(userId) + .orElseThrow(() -> new NotFoundException(UserErrorCode.USER_NOT_FOUND)); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/user/application/dto/UserResponse.java b/src/main/java/com/beat/domain/user/application/dto/UserResponse.java deleted file mode 100644 index 61df11c4..00000000 --- a/src/main/java/com/beat/domain/user/application/dto/UserResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.beat.domain.user.application.dto; - -public record UserResponse( - -) { - -} diff --git a/src/main/java/com/beat/domain/user/domain/Role.java b/src/main/java/com/beat/domain/user/domain/Role.java new file mode 100644 index 00000000..1854d454 --- /dev/null +++ b/src/main/java/com/beat/domain/user/domain/Role.java @@ -0,0 +1,33 @@ +package com.beat.domain.user.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +@RequiredArgsConstructor +@Getter +public enum Role { + + USER("ROLE_USER"), + MEMBER("ROLE_MEMBER"), + ADMIN("ROLE_ADMIN"); + + private final String roleName; + + /** + * GrantedAuthority로 변환하는 메서드. + * Spring Security에서 사용자 권한을 처리할 때 사용. + */ + public GrantedAuthority toGrantedAuthority() { + return new SimpleGrantedAuthority(roleName); + } + + /** + * 역할 이름을 반환하는 메서드. + * 예: "ROLE_USER", "ROLE_MEMBER", "ROLE_ADMIN". + */ + public String getRoleName() { + return this.roleName; + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/domain/user/domain/Users.java b/src/main/java/com/beat/domain/user/domain/Users.java index b2fc9059..6b017cba 100644 --- a/src/main/java/com/beat/domain/user/domain/Users.java +++ b/src/main/java/com/beat/domain/user/domain/Users.java @@ -1,28 +1,46 @@ package com.beat.domain.user.domain; +import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import lombok.Setter; @Entity @Getter @Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Users { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Enumerated(EnumType.STRING) + @Column(nullable = false, columnDefinition = "varchar(10) default 'USER'") + private Role role; + @Builder - public Users() { + public Users(Role role) { + this.role = role; } public static Users create() { return Users.builder() + .role(Role.USER) + .build(); + } + + public static Users createWithRole(Role role) { + return Users.builder() + .role(role) .build(); } } \ No newline at end of file diff --git a/src/main/java/com/beat/domain/user/port/in/UserUseCase.java b/src/main/java/com/beat/domain/user/port/in/UserUseCase.java new file mode 100644 index 00000000..4ef38873 --- /dev/null +++ b/src/main/java/com/beat/domain/user/port/in/UserUseCase.java @@ -0,0 +1,11 @@ +package com.beat.domain.user.port.in; + +import com.beat.domain.user.domain.Users; + +import java.util.List; + +public interface UserUseCase { + List findAllUsers(); + + Users findUserByUserId(final Long userId); +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/auth/annotation/CurrentMember.java b/src/main/java/com/beat/global/auth/annotation/CurrentMember.java index 8651ab1c..d3327b83 100644 --- a/src/main/java/com/beat/global/auth/annotation/CurrentMember.java +++ b/src/main/java/com/beat/global/auth/annotation/CurrentMember.java @@ -6,8 +6,11 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import io.swagger.v3.oas.annotations.Parameter; + @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented +@Parameter(hidden = true) public @interface CurrentMember { } \ No newline at end of file diff --git a/src/main/java/com/beat/global/auth/client/service/KakaoSocialService.java b/src/main/java/com/beat/global/auth/client/application/KakaoSocialService.java similarity index 96% rename from src/main/java/com/beat/global/auth/client/service/KakaoSocialService.java rename to src/main/java/com/beat/global/auth/client/application/KakaoSocialService.java index 36471454..367e077a 100644 --- a/src/main/java/com/beat/global/auth/client/service/KakaoSocialService.java +++ b/src/main/java/com/beat/global/auth/client/application/KakaoSocialService.java @@ -1,4 +1,4 @@ -package com.beat.global.auth.client.service; +package com.beat.global.auth.client.application; import com.beat.domain.member.domain.SocialType; import com.beat.global.auth.client.dto.MemberInfoResponse; @@ -24,10 +24,11 @@ public class KakaoSocialService implements SocialService { private static final String AUTH_CODE = "authorization_code"; @Value("${spring.security.oauth2.client.registration.kakao.redirect-uri}") - private String REDIRECT_URI; + private String redirectUri; @Value("${spring.security.oauth2.client.registration.kakao.client-id}") private String clientId; + private final KakaoApiClient kakaoApiClient; private final KakaoAuthApiClient kakaoAuthApiClient; @@ -55,7 +56,7 @@ private String getOAuth2Authentication( KakaoAccessTokenResponse response = kakaoAuthApiClient.getOAuth2AccessToken( AUTH_CODE, clientId, - REDIRECT_URI, + redirectUri, authorizationCode ); log.info("Received OAuth2 authentication response: {}", response); diff --git a/src/main/java/com/beat/global/auth/client/service/SocialService.java b/src/main/java/com/beat/global/auth/client/application/SocialService.java similarity index 83% rename from src/main/java/com/beat/global/auth/client/service/SocialService.java rename to src/main/java/com/beat/global/auth/client/application/SocialService.java index 3934d2ef..5900d7cc 100644 --- a/src/main/java/com/beat/global/auth/client/service/SocialService.java +++ b/src/main/java/com/beat/global/auth/client/application/SocialService.java @@ -1,4 +1,4 @@ -package com.beat.global.auth.client.service; +package com.beat.global.auth.client.application; import com.beat.global.auth.client.dto.MemberInfoResponse; import com.beat.global.auth.client.dto.MemberLoginRequest; diff --git a/src/main/java/com/beat/global/auth/jwt/application/TokenService.java b/src/main/java/com/beat/global/auth/jwt/application/TokenService.java index 6097bfeb..ba41fd5c 100644 --- a/src/main/java/com/beat/global/auth/jwt/application/TokenService.java +++ b/src/main/java/com/beat/global/auth/jwt/application/TokenService.java @@ -6,8 +6,10 @@ import com.beat.global.common.exception.NotFoundException; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +@Slf4j @RequiredArgsConstructor @Service public class TokenService { @@ -16,25 +18,22 @@ public class TokenService { @Transactional public void saveRefreshToken(final Long memberId, final String refreshToken) { - tokenRepository.save( - Token.of(memberId, refreshToken) - ); + tokenRepository.save(Token.of(memberId, refreshToken)); } public Long findIdByRefreshToken(final String refreshToken) { Token token = tokenRepository.findByRefreshToken(refreshToken) - .orElseThrow( - () -> new NotFoundException(TokenErrorCode.REFRESH_TOKEN_NOT_FOUND) - ); + .orElseThrow(() -> new NotFoundException(TokenErrorCode.REFRESH_TOKEN_NOT_FOUND)); + return token.getId(); } @Transactional public void deleteRefreshToken(final Long memberId) { Token token = tokenRepository.findById(memberId) - .orElseThrow( - () -> new NotFoundException(TokenErrorCode.REFRESH_TOKEN_NOT_FOUND) - ); + .orElseThrow(() -> new NotFoundException(TokenErrorCode.REFRESH_TOKEN_NOT_FOUND)); + tokenRepository.delete(token); + log.info("Deleted refresh token: {}", token); } } \ No newline at end of file diff --git a/src/main/java/com/beat/global/auth/jwt/exception/TokenErrorCode.java b/src/main/java/com/beat/global/auth/jwt/exception/TokenErrorCode.java index c8ab889a..87a87eb0 100644 --- a/src/main/java/com/beat/global/auth/jwt/exception/TokenErrorCode.java +++ b/src/main/java/com/beat/global/auth/jwt/exception/TokenErrorCode.java @@ -8,9 +8,16 @@ @RequiredArgsConstructor public enum TokenErrorCode implements BaseErrorCode { - AUTHENTICATION_CODE_EXPIRED(403, "토큰이 만료되었습니다"), - REFRESH_TOKEN_NOT_FOUND(404, "리프레쉬토큰이 없습니다"), - TOKEN_INCORRECT_ERROR(400, "잘못된 토큰입니다"); + AUTHENTICATION_CODE_EXPIRED(401, "인가코드가 만료되었습니다"), + REFRESH_TOKEN_NOT_FOUND(404, "리프레쉬 토큰이 존재하지 않습니다"), + INVALID_REFRESH_TOKEN_ERROR(400, "잘못된 리프레쉬 토큰입니다"), + REFRESH_TOKEN_MEMBER_ID_MISMATCH_ERROR(400, "리프레쉬 토큰의 사용자 정보가 일치하지 않습니다"), + REFRESH_TOKEN_EXPIRED_ERROR(401, "리프레쉬 토큰이 만료되었습니다"), + REFRESH_TOKEN_SIGNATURE_ERROR(400, "리프레쉬 토큰의 서명의 잘못 되었습니다"), + UNSUPPORTED_REFRESH_TOKEN_ERROR(400, "지원하지 않는 리프레쉬 토큰입니다"), + REFRESH_TOKEN_EMPTY_ERROR(400, "리프레쉬 토큰이 비어있습니다"), + UNKNOWN_REFRESH_TOKEN_ERROR(500, "알 수 없는 리프레쉬 토큰 오류가 발생했습니다") + ; private final int status; private final String message; diff --git a/src/main/java/com/beat/global/auth/jwt/filter/JwtAuthenticationFilter.java b/src/main/java/com/beat/global/auth/jwt/filter/JwtAuthenticationFilter.java index 7e3365e3..9177cca6 100644 --- a/src/main/java/com/beat/global/auth/jwt/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/beat/global/auth/jwt/filter/JwtAuthenticationFilter.java @@ -1,56 +1,112 @@ package com.beat.global.auth.jwt.filter; - +import com.beat.domain.user.domain.Role; import com.beat.global.auth.jwt.provider.JwtTokenProvider; +import com.beat.global.auth.jwt.provider.JwtValidationType; +import com.beat.global.auth.security.AdminAuthentication; import com.beat.global.auth.security.MemberAuthentication; + import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; + import java.io.IOException; +import java.util.Collection; +import java.util.List; + import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; -import static com.beat.global.auth.jwt.provider.JwtValidationType.VALID_JWT; - @Slf4j @Component @RequiredArgsConstructor public class JwtAuthenticationFilter extends OncePerRequestFilter { - private final JwtTokenProvider jwtTokenProvider; - - @Override - protected void doFilterInternal(@NonNull HttpServletRequest request, - @NonNull HttpServletResponse response, - @NonNull FilterChain filterChain) throws ServletException, IOException { - try { - final String token = getJwtFromRequest(request); - if (StringUtils.hasText(token) && jwtTokenProvider.validateToken(token) == VALID_JWT) { - Long memberId = jwtTokenProvider.getUserFromJwt(token); - // authentication 객체 생성 -> principal에 유저 정보를 담는다. - MemberAuthentication authentication = new MemberAuthentication(memberId.toString(), null, null); - authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - } catch (Exception e) { - log.error("JwtAuthentication Authentication Exception Occurs! - {}", e.getClass(), e); - - } - // 다음 필터로 요청 전달 - filterChain.doFilter(request, response); - } - private String getJwtFromRequest(HttpServletRequest request) { - String bearerToken = request.getHeader("Authorization"); - if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { - return bearerToken.substring("Bearer ".length()); - } - return null; - } + private final JwtTokenProvider jwtTokenProvider; + + @Override + protected void doFilterInternal(@NonNull HttpServletRequest request, + @NonNull HttpServletResponse response, + @NonNull FilterChain filterChain) throws ServletException, IOException { + + final String token = getJwtFromRequest(request); + + if (!StringUtils.hasText(token)) { + log.info("JWT Token not found in request header. Assuming guest access or public API request."); + filterChain.doFilter(request, response); + return; + } + + try { + JwtValidationType validationType = jwtTokenProvider.validateToken(token); + + if (validationType == JwtValidationType.VALID_JWT) { + setAuthentication(token, request); + filterChain.doFilter(request, response); + } else { + handleInvalidToken(validationType, response); + } + } catch (Exception e) { + log.error("JWT Authentication Exception: ", e); + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 응답 + } + } + + private void setAuthentication(String token, HttpServletRequest request) { + Long memberId = jwtTokenProvider.getMemberIdFromJwt(token); + Role role = jwtTokenProvider.getRoleFromJwt(token); + + log.info("Setting authentication for memberId: {} with role: {}", memberId, role); + + Collection authorities = List.of(role.toGrantedAuthority()); + UsernamePasswordAuthenticationToken authentication = createAuthentication(memberId, authorities, role); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + + log.info("Authentication set: memberId: {}, role: {}", memberId, role); + + SecurityContextHolder.getContext().setAuthentication(authentication); + } + + private void handleInvalidToken(JwtValidationType validationType, HttpServletResponse response) { + if (validationType == JwtValidationType.EXPIRED_JWT_TOKEN) { + log.warn("JWT Token is expired"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 응답 + } else { + log.warn("JWT Token is invalid"); + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 400 응답 + } + } + + private UsernamePasswordAuthenticationToken createAuthentication(Long memberId, + Collection authorities, Role role) { + log.info("Creating authentication for memberId: {} with role: {}", memberId, role); + + if (role == Role.ADMIN) { + log.info("Creating AdminAuthentication for memberId: {}", memberId); + return new AdminAuthentication(memberId.toString(), null, authorities); + } else if (role == Role.MEMBER) { + log.info("Creating MemberAuthentication for memberId: {}", memberId); + return new MemberAuthentication(memberId.toString(), null, authorities); + } + log.error("Unknown role: {}", role); + throw new IllegalArgumentException("Unknown role: " + role); + } + + private String getJwtFromRequest(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { + return bearerToken.substring("Bearer ".length()); + } + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/beat/global/auth/jwt/provider/JwtTokenProvider.java b/src/main/java/com/beat/global/auth/jwt/provider/JwtTokenProvider.java index 1aac0d78..1ac5d6ea 100644 --- a/src/main/java/com/beat/global/auth/jwt/provider/JwtTokenProvider.java +++ b/src/main/java/com/beat/global/auth/jwt/provider/JwtTokenProvider.java @@ -1,5 +1,7 @@ package com.beat.global.auth.jwt.provider; +import com.beat.domain.user.domain.Role; + import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Header; @@ -7,86 +9,129 @@ import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import jakarta.annotation.PostConstruct; + import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Date; + import javax.crypto.SecretKey; + +import lombok.extern.slf4j.Slf4j; + import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; +@Slf4j @Service public class JwtTokenProvider { - @Value("${jwt.secret}") - private String JWT_SECRET; - @Value("${jwt.access-token-expire-time}") - private long ACCESS_TOKEN_EXPIRE_TIME; - @Value("${jwt.refresh-token-expire-time}") - private long REFRESH_TOKEN_EXPIRE_TIME; - - private static final String MEMBER_ID = "memberId"; - - @PostConstruct - protected void init() { - JWT_SECRET = Base64.getEncoder().encodeToString(JWT_SECRET.getBytes(StandardCharsets.UTF_8)); - } - - public String issueAccessToken(final Authentication authentication) { - return issueToken(authentication, ACCESS_TOKEN_EXPIRE_TIME); - } - - public String issueRefreshToken(final Authentication authentication) { - return issueToken(authentication, REFRESH_TOKEN_EXPIRE_TIME); - } - - private String issueToken(final Authentication authentication, final long expiredTime) { - final Date now = new Date(); - - final Claims claims = Jwts.claims() - .setIssuedAt(now) - .setExpiration(new Date(now.getTime() + expiredTime)); - - claims.put(MEMBER_ID, authentication.getPrincipal()); - return Jwts.builder() - .setHeaderParam(Header.TYPE, Header.JWT_TYPE) - .setClaims(claims) - .signWith(getSigningKey()) - .compact(); - } - - private SecretKey getSigningKey() { - String encodedKey = Base64.getEncoder().encodeToString(JWT_SECRET.getBytes()); //SecretKey 통해 서명 생성 - return Keys.hmacShaKeyFor(encodedKey.getBytes()); //일반적으로 HMAC (Hash-based Message Authentication Code) 알고리즘 사용 - } - - public JwtValidationType validateToken(String token) { - try { - Claims claims = getBody(token); - - return JwtValidationType.VALID_JWT; - } catch (MalformedJwtException ex) { - return JwtValidationType.INVALID_JWT_TOKEN; - } catch (ExpiredJwtException ex) { - return JwtValidationType.EXPIRED_JWT_TOKEN; - } catch (UnsupportedJwtException ex) { - return JwtValidationType.UNSUPPORTED_JWT_TOKEN; - } catch (IllegalArgumentException ex) { - return JwtValidationType.EMPTY_JWT; - } - } - - private Claims getBody(final String token) { - return Jwts.parserBuilder() - .setSigningKey(getSigningKey()) - .build() - .parseClaimsJws(token) - .getBody(); - } - - public Long getUserFromJwt(String token) { - Claims claims = getBody(token); - return Long.valueOf(claims.get(MEMBER_ID).toString()); - } + @Value("${jwt.secret}") + private String jwtSecret; + + @Value("${jwt.access-token-expire-time}") + private long accessTokenExpireTime; + + @Value("${jwt.refresh-token-expire-time}") + private long refreshTokenExpireTime; + + private static final String MEMBER_ID = "memberId"; + private static final String ROLE_KEY = "role"; + + @PostConstruct + protected void init() { + jwtSecret = Base64.getEncoder().encodeToString(jwtSecret.getBytes(StandardCharsets.UTF_8)); + } + + public String issueAccessToken(final Authentication authentication) { + return issueToken(authentication, accessTokenExpireTime); + } + + public String issueRefreshToken(final Authentication authentication) { + return issueToken(authentication, refreshTokenExpireTime); + } + + private String issueToken(final Authentication authentication, final long expiredTime) { + final Date now = new Date(); + + final Claims claims = Jwts.claims().setIssuedAt(now).setExpiration(new Date(now.getTime() + expiredTime)); + + claims.put(MEMBER_ID, authentication.getPrincipal()); + log.info("Added member ID to claims: {}", authentication.getPrincipal()); + log.info("Authorities before token generation: {}", authentication.getAuthorities()); + + String role = authentication.getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("No authorities found for user")); + + log.info("Selected role for token: {}", role); + + claims.put(ROLE_KEY, role); + log.info("Added role to claims: {}", role); + + return Jwts.builder() + .setHeaderParam(Header.TYPE, Header.JWT_TYPE) + .setClaims(claims) + .signWith(getSigningKey()) + .compact(); + } + + private SecretKey getSigningKey() { + String encodedKey = Base64.getEncoder().encodeToString(jwtSecret.getBytes()); + return Keys.hmacShaKeyFor(encodedKey.getBytes()); + } + + public JwtValidationType validateToken(String token) { + try { + Claims claims = getBody(token); + return JwtValidationType.VALID_JWT; + } catch (MalformedJwtException ex) { + log.error("Invalid JWT Token: {}", ex.getMessage()); + return JwtValidationType.INVALID_JWT_TOKEN; + } catch (ExpiredJwtException ex) { + log.error("Expired JWT Token: {}", ex.getMessage()); + return JwtValidationType.EXPIRED_JWT_TOKEN; + } catch (UnsupportedJwtException ex) { + log.error("Unsupported JWT Token: {}", ex.getMessage()); + return JwtValidationType.UNSUPPORTED_JWT_TOKEN; + } catch (IllegalArgumentException ex) { + log.error("Empty JWT Token or Illegal Argument: {}", ex.getMessage()); + return JwtValidationType.EMPTY_JWT; + } catch (SignatureException ex) { + log.error("Invalid JWT Signature: {}", ex.getMessage()); + return JwtValidationType.INVALID_JWT_SIGNATURE; + } + } + + private Claims getBody(final String token) { + return Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody(); + } + + public Long getMemberIdFromJwt(String token) { + Claims claims = getBody(token); + Long memberId = Long.valueOf(claims.get(MEMBER_ID).toString()); + + // 로그 추가: memberId 확인 + log.info("Extracted memberId from JWT: {}", memberId); + + return memberId; + } + + public Role getRoleFromJwt(String token) { + Claims claims = getBody(token); + String roleName = claims.get(ROLE_KEY, String.class); + + log.info("Extracted role from JWT: {}", roleName); + + // "ROLE_" 접두사 제거 + String enumValue = roleName.replace("ROLE_", ""); + log.info("Final role after processing: {}", enumValue); + + return Role.valueOf(enumValue.toUpperCase()); + } } \ No newline at end of file diff --git a/src/main/java/com/beat/global/auth/redis/Token.java b/src/main/java/com/beat/global/auth/redis/Token.java index 6eab8fce..69bed8e7 100644 --- a/src/main/java/com/beat/global/auth/redis/Token.java +++ b/src/main/java/com/beat/global/auth/redis/Token.java @@ -7,7 +7,7 @@ import org.springframework.data.redis.core.RedisHash; import org.springframework.data.redis.core.index.Indexed; -@RedisHash(value = "refreshToken", timeToLive = 60 * 60 * 24 * 1000L * 14) +@RedisHash(value = "refreshToken", timeToLive = 1209600) @Getter @Builder public class Token { diff --git a/src/main/java/com/beat/global/auth/resolver/CurrentUserArgumentResolver.java b/src/main/java/com/beat/global/auth/resolver/CurrentMemberArgumentResolver.java similarity index 94% rename from src/main/java/com/beat/global/auth/resolver/CurrentUserArgumentResolver.java rename to src/main/java/com/beat/global/auth/resolver/CurrentMemberArgumentResolver.java index e14e4f37..2290cc94 100644 --- a/src/main/java/com/beat/global/auth/resolver/CurrentUserArgumentResolver.java +++ b/src/main/java/com/beat/global/auth/resolver/CurrentMemberArgumentResolver.java @@ -13,7 +13,7 @@ @Component @RequiredArgsConstructor -public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver { +public class CurrentMemberArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { diff --git a/src/main/java/com/beat/global/auth/security/AdminAuthentication.java b/src/main/java/com/beat/global/auth/security/AdminAuthentication.java new file mode 100644 index 00000000..d1efbfae --- /dev/null +++ b/src/main/java/com/beat/global/auth/security/AdminAuthentication.java @@ -0,0 +1,18 @@ +package com.beat.global.auth.security; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; + +import java.util.Collection; + +public class AdminAuthentication extends UsernamePasswordAuthenticationToken { + + public AdminAuthentication(Object principal, Object credentials, + Collection authorities) { + super(principal, credentials, authorities); + } + + public Long getAdminId() { + return (Long) getPrincipal(); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/auth/security/CustomAccessDeniedHandler.java b/src/main/java/com/beat/global/auth/security/CustomAccessDeniedHandler.java index 65b67724..6855ac4d 100644 --- a/src/main/java/com/beat/global/auth/security/CustomAccessDeniedHandler.java +++ b/src/main/java/com/beat/global/auth/security/CustomAccessDeniedHandler.java @@ -4,15 +4,21 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component; +@Slf4j @Component public class CustomAccessDeniedHandler implements AccessDeniedHandler { @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { + String path = request.getRequestURI(); + String method = request.getMethod(); + log.warn("Access Denied: Method: {}, Path: {}, Message: {}", method, path, accessDeniedException.getMessage()); + setResponse(response); } diff --git a/src/main/java/com/beat/global/auth/security/CustomJwtAuthenticationEntryPoint.java b/src/main/java/com/beat/global/auth/security/CustomJwtAuthenticationEntryPoint.java index 55f6ef33..2591e943 100644 --- a/src/main/java/com/beat/global/auth/security/CustomJwtAuthenticationEntryPoint.java +++ b/src/main/java/com/beat/global/auth/security/CustomJwtAuthenticationEntryPoint.java @@ -3,20 +3,24 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; - +import lombok.extern.slf4j.Slf4j; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +@Slf4j @Component public class CustomJwtAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) { + String path = request.getRequestURI(); + String method = request.getMethod(); + log.warn("Unauthorized access attempt: Method: {}, Path: {}, Message: {}", method, path, authException.getMessage()); + setResponse(response); } private void setResponse(HttpServletResponse response) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); } - -} +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/common/config/SecurityConfig.java b/src/main/java/com/beat/global/common/config/SecurityConfig.java index dd99398e..7ab26c3d 100644 --- a/src/main/java/com/beat/global/common/config/SecurityConfig.java +++ b/src/main/java/com/beat/global/common/config/SecurityConfig.java @@ -1,5 +1,6 @@ package com.beat.global.common.config; +import com.beat.domain.user.domain.Role; import com.beat.global.auth.jwt.filter.JwtAuthenticationFilter; import com.beat.global.auth.security.CustomAccessDeniedHandler; import com.beat.global.auth.security.CustomJwtAuthenticationEntryPoint; @@ -8,7 +9,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; @@ -22,6 +22,7 @@ public class SecurityConfig { private final JwtAuthenticationFilter jwtAuthenticationFilter; private final CustomJwtAuthenticationEntryPoint customJwtAuthenticationEntryPoint; private final CustomAccessDeniedHandler customAccessDeniedHandler; + private static final String[] AUTH_WHITELIST = { "/api/users/sign-up", "/api/users/refresh-token", @@ -36,7 +37,12 @@ public class SecurityConfig { "/v3/api-docs/**", "/swagger-ui/**", "/swagger-resources/**", - "/api/files/**" + "/api/files/**", + "/error" + }; + + private static final String[] AUTH_ADMIN_ONLY = { + "/api/admin/**" }; @Bean @@ -44,19 +50,16 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti http.csrf(AbstractHttpConfigurer::disable) .formLogin(AbstractHttpConfigurer::disable) .httpBasic(AbstractHttpConfigurer::disable) - .sessionManagement(session -> { - session.sessionCreationPolicy(SessionCreationPolicy.STATELESS); - }) + .sessionManagement(session -> + session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .exceptionHandling(exception -> - { - exception.authenticationEntryPoint(customJwtAuthenticationEntryPoint); - exception.accessDeniedHandler(customAccessDeniedHandler); - }); + exception.authenticationEntryPoint(customJwtAuthenticationEntryPoint) + .accessDeniedHandler(customAccessDeniedHandler)); - http.authorizeHttpRequests(auth -> { - auth.requestMatchers(AUTH_WHITELIST).permitAll(); - auth.anyRequest().authenticated(); - }) + http.authorizeHttpRequests(auth -> + auth.requestMatchers(AUTH_WHITELIST).permitAll() + .requestMatchers(AUTH_ADMIN_ONLY).hasAuthority(Role.ADMIN.getRoleName()) + .anyRequest().authenticated()) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); diff --git a/src/main/java/com/beat/global/common/config/WebConfig.java b/src/main/java/com/beat/global/common/config/WebConfig.java index ce53c953..341035ab 100644 --- a/src/main/java/com/beat/global/common/config/WebConfig.java +++ b/src/main/java/com/beat/global/common/config/WebConfig.java @@ -1,7 +1,10 @@ package com.beat.global.common.config; -import com.beat.global.auth.resolver.CurrentUserArgumentResolver; +import com.beat.global.auth.resolver.CurrentMemberArgumentResolver; + import lombok.RequiredArgsConstructor; + +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.CorsRegistry; @@ -13,19 +16,22 @@ @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { - private final CurrentUserArgumentResolver currentUserArgumentResolver; - - @Override - public void addArgumentResolvers(List resolvers) { - resolvers.add(currentUserArgumentResolver); - } - - @Override - public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**") - .allowedOriginPatterns("*") // 모든 도메인 허용 - .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") - .allowedHeaders("*") - .allowCredentials(true); - } + private final CurrentMemberArgumentResolver currentMemberArgumentResolver; + + @Value("${cors.allowed-origins}") + private String[] allowedOrigins; + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(currentMemberArgumentResolver); + } + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins(allowedOrigins) + .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS") + .allowedHeaders("*") + .allowCredentials(true); + } } \ No newline at end of file diff --git a/src/main/java/com/beat/global/common/dto/SuccessResponse.java b/src/main/java/com/beat/global/common/dto/SuccessResponse.java index ccc83c7d..7a7db761 100644 --- a/src/main/java/com/beat/global/common/dto/SuccessResponse.java +++ b/src/main/java/com/beat/global/common/dto/SuccessResponse.java @@ -7,11 +7,11 @@ public record SuccessResponse( String message, T data ) { - public static SuccessResponse of(final BaseSuccessCode baseSuccessCode, final T data) { - return new SuccessResponse(baseSuccessCode.getStatus(), baseSuccessCode.getMessage(), data); + public static SuccessResponse of(final BaseSuccessCode baseSuccessCode, final T data) { + return new SuccessResponse<>(baseSuccessCode.getStatus(), baseSuccessCode.getMessage(), data); } - public static SuccessResponse from(final BaseSuccessCode baseSuccessCode) { - return new SuccessResponse(baseSuccessCode.getStatus(), baseSuccessCode.getMessage(), null); + public static SuccessResponse from(final BaseSuccessCode baseSuccessCode) { + return new SuccessResponse<>(baseSuccessCode.getStatus(), baseSuccessCode.getMessage(), null); } } \ No newline at end of file diff --git a/src/main/java/com/beat/global/common/handler/GlobalExceptionHandler.java b/src/main/java/com/beat/global/common/handler/GlobalExceptionHandler.java index 34c38c70..d234b07c 100644 --- a/src/main/java/com/beat/global/common/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/beat/global/common/handler/GlobalExceptionHandler.java @@ -2,53 +2,96 @@ import com.beat.global.common.dto.ErrorResponse; import com.beat.global.common.exception.BadRequestException; +import com.beat.global.common.exception.BeatException; import com.beat.global.common.exception.ConflictException; import com.beat.global.common.exception.ForbiddenException; import com.beat.global.common.exception.NotFoundException; import com.beat.global.common.exception.UnauthorizedException; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import java.util.Objects; +import java.util.Optional; +@Slf4j @RestControllerAdvice public class GlobalExceptionHandler { + /** + * 400 BAD_REQUEST + */ @ExceptionHandler(BadRequestException.class) public ResponseEntity handleBadRequestException(final BadRequestException e) { + log.error("BadRequestException: {}", e.getMessage()); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.from(e.getBaseErrorCode())); } + + @ExceptionHandler(MethodArgumentNotValidException.class) + protected ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + String errorMessage = Optional.ofNullable(e.getBindingResult().getFieldError()) + .map(FieldError::getDefaultMessage) // 메서드 참조 사용 + .orElse("Validation error"); + + log.warn("MethodArgumentNotValidException: {}", errorMessage); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), errorMessage)); + } + + /** + * 401 UNAUTHORIZED + */ @ExceptionHandler(UnauthorizedException.class) public ResponseEntity handleUnauthorizedException(final UnauthorizedException e) { + log.error("UnauthorizedException: {}", e.getMessage()); return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ErrorResponse.from(e.getBaseErrorCode())); } + /** + * 403 FORBIDDEN + */ @ExceptionHandler(ForbiddenException.class) public ResponseEntity handleForbiddenException(final ForbiddenException e) { + log.error("ForbiddenException: {}", e.getMessage()); return ResponseEntity.status(HttpStatus.FORBIDDEN).body(ErrorResponse.from(e.getBaseErrorCode())); } + /** + * 404 NOT_FOUND + */ @ExceptionHandler(NotFoundException.class) protected ResponseEntity handleNotFoundException(final NotFoundException e) { + log.error("NotFoundException: {}", e.getMessage()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ErrorResponse.from(e.getBaseErrorCode())); } - @ExceptionHandler(MethodArgumentNotValidException.class) - protected ResponseEntity handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorResponse.of(HttpStatus.BAD_REQUEST.value(), Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage())); - } - + /** + * 409 CONFLICT + */ @ExceptionHandler(ConflictException.class) protected ResponseEntity handleConflictException(final ConflictException e) { + log.error("ConflictException: {}", e.getMessage()); return ResponseEntity.status(HttpStatus.CONFLICT).body(ErrorResponse.from(e.getBaseErrorCode())); } + /** + * 500 INTERNEL_SERVER + */ @ExceptionHandler(Exception.class) protected ResponseEntity handleException(final Exception e) { + log.error("Unexpected server error: ", e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ErrorResponse.of(HttpStatus.INTERNAL_SERVER_ERROR.value(), "서버 내부 오류입니다.")); } -} + + /** + * CUSTOM_ERROR + */ + @ExceptionHandler(BeatException.class) + public ResponseEntity handleBeatException(final BeatException e) { + log.error("BeatException occurred: ", e); + return ResponseEntity.status(e.getBaseErrorCode().getStatus()).body(ErrorResponse.from(e.getBaseErrorCode())); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/common/scheduler/application/JobSchedulerService.java b/src/main/java/com/beat/global/common/scheduler/application/JobSchedulerService.java new file mode 100644 index 00000000..622c45c4 --- /dev/null +++ b/src/main/java/com/beat/global/common/scheduler/application/JobSchedulerService.java @@ -0,0 +1,120 @@ +package com.beat.global.common.scheduler.application; + +import com.beat.domain.schedule.dao.ScheduleRepository; +import com.beat.domain.schedule.domain.Schedule; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.Hibernate; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; +import org.springframework.scheduling.TaskScheduler; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ScheduledFuture; + +@Slf4j +@Service +@RequiredArgsConstructor +public class JobSchedulerService { + + private final ScheduleRepository scheduleRepository; + private final TaskScheduler taskScheduler; + + // 스케줄 ID와 관련된 작업을 관리하기 위한 ConcurrentHashMap 선언 + private final Map> scheduledTasks = new ConcurrentHashMap<>(); + + // ApplicationReadyEvent는 애플리케이션이 완전히 시작된 후에 한 번만 실행됩니다. + @EventListener(ApplicationReadyEvent.class) + @Transactional + public void onApplicationReady(ApplicationReadyEvent event) { + // 서버 시작 시점에만 실행되도록 트랜잭션 관리가 필요한 부분을 다른 메서드로 분리 + log.info("onApplicationReady() method triggered."); + schedulePendingPerformances(); + } + + @Transactional(readOnly = true) + public void schedulePendingPerformances() { + // PENDING 상태의 스케줄들을 조회하여 트랜잭션 내에서 처리 + List schedules = scheduleRepository.findPendingSchedules(); + + // 각각의 스케줄에 대해 지연 로딩 처리 및 스케줄링 작업 수행 + schedules.forEach(schedule -> { + // Performance 초기화 시점은 트랜잭션 경계 내에서 이루어져야 함 + Hibernate.initialize(schedule.getPerformance()); + addScheduleIfNotExists(schedule); + }); + } + + // 스케줄 종료 시점에 맞춰 isBooking 업데이트 + @Transactional + public void addScheduleIfNotExists(Schedule schedule) { + if (scheduledTasks.containsKey(schedule.getId())) { + log.debug("Schedule ID {} is already scheduled. Skipping duplicate registration.", schedule.getId()); + return; + } + + // 여기서 데이터베이스 X-Lock을 걸어 중복 실행 방지 + scheduleRepository.lockById(schedule.getId()) + .ifPresentOrElse( + lockedSchedule -> { + log.info("Lock acquired for Schedule ID: {}", lockedSchedule.getId()); + LocalDateTime performanceEndTime = lockedSchedule.getPerformanceDate() + .plusMinutes(lockedSchedule.getPerformance().getRunningTime()); + + log.info("Scheduling task for Schedule ID: {} at {}", lockedSchedule.getId(), performanceEndTime); + + ScheduledFuture scheduledTask = taskScheduler.schedule( + () -> updateIsBookingFalse(lockedSchedule.getId()), + Date.from(performanceEndTime.atZone(ZoneId.systemDefault()).toInstant()) + ); + + scheduledTasks.put(lockedSchedule.getId(), scheduledTask); + log.debug("Task added for Schedule ID: {}", lockedSchedule.getId()); + + logScheduledTasks(); + }, + () -> log.warn("Failed to acquire lock for Schedule ID: {}", schedule.getId()) + ); + } + + // 스케줄 종료 시 isBooking을 false로 업데이트 + @Transactional + public void updateIsBookingFalse(Long scheduleId) { + Schedule schedule = scheduleRepository.findById(scheduleId) + .orElseThrow(() -> new IllegalStateException("Schedule not found: " + scheduleId)); + + log.info("Updating isBooking to false for schedule ID: {}", scheduleId); + schedule.updateIsBooking(false); + scheduleRepository.save(schedule); + + // 스케줄 작업 완료 후 Map에서 삭제 + scheduledTasks.remove(scheduleId); + log.debug("Completed Task removed for Schedule ID: {}", scheduleId); + logScheduledTasks(); + } + + public void cancelScheduledTaskForPerformance(Schedule schedule) { + ScheduledFuture scheduledTask = scheduledTasks.get(schedule.getId()); + if (scheduledTask != null && !scheduledTask.isDone()) { + scheduledTask.cancel(true); // 작업이 완료되지 않았다면 취소 + scheduledTasks.remove(schedule.getId()); + log.info("Cancelled Task removed for Schedule ID: {}", schedule.getId()); + logScheduledTasks(); + } + } + + // 현재 등록된 스케줄 로그 출력 + public void logScheduledTasks() { + scheduledTasks.forEach((scheduleId, future) -> { + log.debug("Scheduled task for Schedule ID: {} is currently {}.", + scheduleId, (future.isCancelled() ? "Cancelled" : "Scheduled")); + }); + } +} diff --git a/src/main/java/com/beat/global/external/s3/api/FileApi.java b/src/main/java/com/beat/global/external/s3/api/FileApi.java new file mode 100644 index 00000000..0557f2dc --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/api/FileApi.java @@ -0,0 +1,41 @@ +package com.beat.global.external.s3.api; + +import com.beat.global.common.dto.ErrorResponse; +import com.beat.global.common.dto.SuccessResponse; +import com.beat.global.external.s3.application.dto.PerformanceMakerPresignedUrlFindAllResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.List; + +@Tag(name = "Image - Performance PreSigned Url", description = "Performance PreSigned Url 발급 API") +public interface FileApi { + + @Operation(summary = "공연 이미지 업로드 Presigned URL 발급", description = "공연 등록 시 업로드할 이미지에 대한 presigned URL을 발급 받는 GET API") + @ApiResponses( + value = { + @ApiResponse( + responseCode = "200", + description = "공연 메이커를 위한 Presigned URL 발급 성공.", + content = @Content(schema = @Schema(implementation = SuccessResponse.class)) + ), + @ApiResponse( + responseCode = "500", + description = "S3 PreSigned url을 받아오기에 실패했습니다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + } + ) + ResponseEntity> generateAllPresignedUrls( + @RequestParam String posterImage, + @RequestParam(required = false) List castImages, + @RequestParam(required = false) List staffImages, + @RequestParam(required = false) List performanceImages + ); +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/api/FileController.java b/src/main/java/com/beat/global/external/s3/api/FileController.java new file mode 100644 index 00000000..5c72455e --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/api/FileController.java @@ -0,0 +1,44 @@ +package com.beat.global.external.s3.api; + +import com.beat.global.common.dto.SuccessResponse; +import com.beat.global.external.s3.exception.FileSuccessCode; +import com.beat.global.external.s3.application.dto.PerformanceMakerPresignedUrlFindAllResponse; +import com.beat.global.external.s3.port.in.FileUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/api/files") +@RequiredArgsConstructor +public class FileController implements FileApi { + + private final FileUseCase fileUseCase; + + @GetMapping("/presigned-url") + @Override + public ResponseEntity> generateAllPresignedUrls( + @RequestParam String posterImage, + @RequestParam(required = false) List castImages, + @RequestParam(required = false) List staffImages, + @RequestParam(required = false) List performanceImages) { + // 토큰 주도록 변경이 필요 + if (castImages == null) { + castImages = List.of(); + } + if (staffImages == null) { + staffImages = List.of(); + } + if (performanceImages == null) { + performanceImages = List.of(); + } + + PerformanceMakerPresignedUrlFindAllResponse response = fileUseCase.issueAllPresignedUrlsForPerformanceMaker(posterImage, castImages, staffImages, performanceImages); + return ResponseEntity.ok(SuccessResponse.of(FileSuccessCode.PERFORMANCE_MAKER_PRESIGNED_URL_ISSUED, response)); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/application/FileService.java b/src/main/java/com/beat/global/external/s3/application/FileService.java new file mode 100644 index 00000000..0b3ffb75 --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/application/FileService.java @@ -0,0 +1,115 @@ +package com.beat.global.external.s3.application; + +import com.amazonaws.HttpMethod; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; +import com.beat.global.external.s3.application.dto.PerformanceMakerPresignedUrlFindAllResponse; +import com.beat.global.external.s3.port.in.FileUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class FileService implements FileUseCase { + + @Value("${cloud.s3.bucket}") + private String bucket; + + private final AmazonS3 amazonS3; + + @Override + public PerformanceMakerPresignedUrlFindAllResponse issueAllPresignedUrlsForPerformanceMaker(String posterImage, List castImages, List staffImages, List performanceImages) { + Map> performanceMakerPresignedUrls = new HashMap<>(); + + // Poster Image URL + Map posterUrl = new HashMap<>(); + String posterFilePath = generatePath("poster", posterImage); + URL posterPresignedUrl = amazonS3.generatePresignedUrl(buildPresignedUrlRequest(bucket, posterFilePath)); + posterUrl.put(posterImage, posterPresignedUrl.toString()); + performanceMakerPresignedUrls.put("poster", posterUrl); + + // Cast Images URLs + Map castUrls = new HashMap<>(); + for (String castImage : castImages) { + String castFilePath = generatePath("cast", castImage); + URL castPresignedUrl = amazonS3.generatePresignedUrl(buildPresignedUrlRequest(bucket, castFilePath)); + castUrls.put(castImage, castPresignedUrl.toString()); + } + performanceMakerPresignedUrls.put("cast", castUrls); + + // Staff Images URLs + Map staffUrls = new HashMap<>(); + for (String staffImage : staffImages) { + String staffFilePath = generatePath("staff", staffImage); + URL staffPresignedUrl = amazonS3.generatePresignedUrl(buildPresignedUrlRequest(bucket, staffFilePath)); + staffUrls.put(staffImage, staffPresignedUrl.toString()); + } + performanceMakerPresignedUrls.put("staff", staffUrls); + + // Performance Images URLs + Map performanceImageUrls = new HashMap<>(); + for (String performanceImage : performanceImages) { + String performanceImageFilePath = generatePath("performance", performanceImage); + URL performanceImagePresignedUrl = amazonS3.generatePresignedUrl(buildPresignedUrlRequest(bucket, performanceImageFilePath)); + performanceImageUrls.put(performanceImage, performanceImagePresignedUrl.toString()); + } + performanceMakerPresignedUrls.put("performance", performanceImageUrls); + + return PerformanceMakerPresignedUrlFindAllResponse.from(performanceMakerPresignedUrls); + } + + // Carousel Images URLs + @Override + public Map issueAllPresignedUrlsForCarousel(List carouselImages) { + Map carouselPresignedUrls = new HashMap<>(); + + for (String carouselImage : carouselImages) { + String carouselFilePath = generatePath("carousel", carouselImage); + URL carouselPresignedUrl = amazonS3.generatePresignedUrl(buildPresignedUrlRequest(bucket, carouselFilePath)); + carouselPresignedUrls.put(carouselImage, carouselPresignedUrl.toString()); + } + + return carouselPresignedUrls; + } + + // Banner Image URL + @Override + public String issuePresignedUrlForBanner(String bannerImage) { + String bannerFilePath = generatePath("banner", bannerImage); + URL bannerPresignedUrl = amazonS3.generatePresignedUrl(buildPresignedUrlRequest(bucket, bannerFilePath)); + + return bannerPresignedUrl.toString(); + } + + private GeneratePresignedUrlRequest buildPresignedUrlRequest(String bucket, String fileName) { + return new GeneratePresignedUrlRequest(bucket, fileName) + .withMethod(HttpMethod.PUT) + .withExpiration(generatePresignedUrlExpiration()); + } + + private Date generatePresignedUrlExpiration() { + Date expiration = new Date(); + long expTimeMillis = expiration.getTime(); + expTimeMillis += 1000 * 60 * 60 * 2; + expiration.setTime(expTimeMillis); + + return expiration; + } + + private String generateFileId() { + return UUID.randomUUID().toString(); + } + + private String generatePath(String prefix, String fileName) { + String fileId = generateFileId(); + return String.format("%s/%s", prefix, fileId + "-" + fileName); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/application/dto/BannerPresignedUrlFindResponse.java b/src/main/java/com/beat/global/external/s3/application/dto/BannerPresignedUrlFindResponse.java new file mode 100644 index 00000000..db79b0b9 --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/application/dto/BannerPresignedUrlFindResponse.java @@ -0,0 +1,9 @@ +package com.beat.global.external.s3.application.dto; + +public record BannerPresignedUrlFindResponse( + String bannerPresignedUrl +) { + public static BannerPresignedUrlFindResponse from(String bannerPresignedUrl) { + return new BannerPresignedUrlFindResponse(bannerPresignedUrl); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/application/dto/CarouselPresignedUrlFindAllResponse.java b/src/main/java/com/beat/global/external/s3/application/dto/CarouselPresignedUrlFindAllResponse.java new file mode 100644 index 00000000..133be7f2 --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/application/dto/CarouselPresignedUrlFindAllResponse.java @@ -0,0 +1,11 @@ +package com.beat.global.external.s3.application.dto; + +import java.util.Map; + +public record CarouselPresignedUrlFindAllResponse( + Map carouselPresignedUrls +) { + public static CarouselPresignedUrlFindAllResponse from(Map carouselPresignedUrls) { + return new CarouselPresignedUrlFindAllResponse(carouselPresignedUrls); + } +} diff --git a/src/main/java/com/beat/global/external/s3/application/dto/PerformanceMakerPresignedUrlFindAllResponse.java b/src/main/java/com/beat/global/external/s3/application/dto/PerformanceMakerPresignedUrlFindAllResponse.java new file mode 100644 index 00000000..6fca8735 --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/application/dto/PerformanceMakerPresignedUrlFindAllResponse.java @@ -0,0 +1,11 @@ +package com.beat.global.external.s3.application.dto; + +import java.util.Map; + +public record PerformanceMakerPresignedUrlFindAllResponse( + Map> performanceMakerPresignedUrls +) { + public static PerformanceMakerPresignedUrlFindAllResponse from(Map> performanceMakerPresignedUrls) { + return new PerformanceMakerPresignedUrlFindAllResponse(performanceMakerPresignedUrls); + } +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/S3Config.java b/src/main/java/com/beat/global/external/s3/config/S3Config.java similarity index 96% rename from src/main/java/com/beat/global/external/s3/S3Config.java rename to src/main/java/com/beat/global/external/s3/config/S3Config.java index 73eca54e..ce079891 100644 --- a/src/main/java/com/beat/global/external/s3/S3Config.java +++ b/src/main/java/com/beat/global/external/s3/config/S3Config.java @@ -1,4 +1,4 @@ -package com.beat.global.external.s3; +package com.beat.global.external.s3.config; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; diff --git a/src/main/java/com/beat/global/external/s3/controller/FileController.java b/src/main/java/com/beat/global/external/s3/controller/FileController.java index eec8614e..e69de29b 100644 --- a/src/main/java/com/beat/global/external/s3/controller/FileController.java +++ b/src/main/java/com/beat/global/external/s3/controller/FileController.java @@ -1,37 +0,0 @@ -package com.beat.global.external.s3.controller; - -import com.beat.global.external.s3.service.FileService; -import io.swagger.v3.oas.annotations.Operation; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import java.util.List; -import java.util.Map; - -@RestController -@RequestMapping("/api/files") -@RequiredArgsConstructor -public class FileController { - - private final FileService fileService; - - @Operation(summary = "presigned-url API", description = "S3에 업로드 할 수 있는 유효한 url을 주는 GET API입니다.") - @GetMapping("/presigned-url") - public ResponseEntity>> getPresignedUrls( - @RequestParam String posterImage, - @RequestParam(required = false) List castImages, - @RequestParam(required = false) List staffImages) { - if (castImages == null) { - castImages = List.of(); - } - if (staffImages == null) { - staffImages = List.of(); - } - Map> response = fileService.getPresignedUrls(posterImage, castImages, staffImages); - return ResponseEntity.ok(response); - } -} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/exception/FileSuccessCode.java b/src/main/java/com/beat/global/external/s3/exception/FileSuccessCode.java new file mode 100644 index 00000000..fef7e359 --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/exception/FileSuccessCode.java @@ -0,0 +1,13 @@ +package com.beat.global.external.s3.exception; + +import com.beat.global.common.exception.base.BaseSuccessCode; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum FileSuccessCode implements BaseSuccessCode { + PERFORMANCE_MAKER_PRESIGNED_URL_ISSUED(200, "공연 메이커를 위한 Presigned URL 발급 성공"); + private final int status; + private final String message; +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/port/in/FileUseCase.java b/src/main/java/com/beat/global/external/s3/port/in/FileUseCase.java new file mode 100644 index 00000000..28adfec4 --- /dev/null +++ b/src/main/java/com/beat/global/external/s3/port/in/FileUseCase.java @@ -0,0 +1,17 @@ +package com.beat.global.external.s3.port.in; + +import com.beat.global.external.s3.application.dto.BannerPresignedUrlFindResponse; +import com.beat.global.external.s3.application.dto.CarouselPresignedUrlFindAllResponse; +import com.beat.global.external.s3.application.dto.PerformanceMakerPresignedUrlFindAllResponse; + +import java.util.List; +import java.util.Map; + +public interface FileUseCase { + + PerformanceMakerPresignedUrlFindAllResponse issueAllPresignedUrlsForPerformanceMaker(String posterImage, List castImages, List staffImages, List performanceImages); + + Map issueAllPresignedUrlsForCarousel(List carouselImages); + + String issuePresignedUrlForBanner(String bannerImage); +} \ No newline at end of file diff --git a/src/main/java/com/beat/global/external/s3/service/FileService.java b/src/main/java/com/beat/global/external/s3/service/FileService.java deleted file mode 100644 index fd544080..00000000 --- a/src/main/java/com/beat/global/external/s3/service/FileService.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.beat.global.external.s3.service; - -import com.amazonaws.HttpMethod; -import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -import java.net.URL; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -@Service -@RequiredArgsConstructor -public class FileService { - - @Value("${cloud.s3.bucket}") - private String bucket; - - private final AmazonS3 amazonS3; - - public Map> getPresignedUrls(String posterImage, List castImages, List staffImages) { - Map> presignedUrls = new HashMap<>(); - - // Poster Image URL - Map posterUrl = new HashMap<>(); - String posterFilePath = createPath("poster", posterImage); - URL posterPresignedUrl = amazonS3.generatePresignedUrl(getGeneratePresignedUrlRequest(bucket, posterFilePath)); - posterUrl.put(posterImage, posterPresignedUrl.toString()); - presignedUrls.put("poster", posterUrl); - - // Cast Images URLs - Map castUrls = new HashMap<>(); - for (String castImage : castImages) { - String castFilePath = createPath("cast", castImage); - URL castPresignedUrl = amazonS3.generatePresignedUrl(getGeneratePresignedUrlRequest(bucket, castFilePath)); - castUrls.put(castImage, castPresignedUrl.toString()); - } - presignedUrls.put("cast", castUrls); - - // Staff Images URLs - Map staffUrls = new HashMap<>(); - for (String staffImage : staffImages) { - String staffFilePath = createPath("staff", staffImage); - URL staffPresignedUrl = amazonS3.generatePresignedUrl(getGeneratePresignedUrlRequest(bucket, staffFilePath)); - staffUrls.put(staffImage, staffPresignedUrl.toString()); - } - presignedUrls.put("staff", staffUrls); - - return presignedUrls; - } - - private GeneratePresignedUrlRequest getGeneratePresignedUrlRequest(String bucket, String fileName) { - return new GeneratePresignedUrlRequest(bucket, fileName) - .withMethod(HttpMethod.PUT) - .withExpiration(getPresignedUrlExpiration()); - } - - private Date getPresignedUrlExpiration() { - Date expiration = new Date(); - long expTimeMillis = expiration.getTime(); - expTimeMillis += 1000 * 60 * 60 * 2; - expiration.setTime(expTimeMillis); - - return expiration; - } - - private String createFileId() { - return UUID.randomUUID().toString(); - } - - private String createPath(String prefix, String fileName) { - String fileId = createFileId(); - return String.format("%s/%s", prefix, fileId + "-" + fileName); - } -} \ No newline at end of file diff --git a/src/main/java/com/beat/global/swagger/SwaggerConfig.java b/src/main/java/com/beat/global/swagger/SwaggerConfig.java index fa4e1bb6..f3ffc34b 100644 --- a/src/main/java/com/beat/global/swagger/SwaggerConfig.java +++ b/src/main/java/com/beat/global/swagger/SwaggerConfig.java @@ -6,11 +6,17 @@ import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.oas.models.servers.Server; + +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class SwaggerConfig { + + @Value("${app.server.url}") + private String serverUrl; + @Bean public OpenAPI openAPI() { String jwt = "JWT"; @@ -21,7 +27,7 @@ public OpenAPI openAPI() { .scheme("bearer") .bearerFormat("JWT") ); - return new OpenAPI().addServersItem(new Server().url("/")) + return new OpenAPI().addServersItem(new Server().url(serverUrl)) .components(new Components()) .info(apiInfo()) .addSecurityItem(securityRequirement) @@ -31,6 +37,6 @@ private Info apiInfo() { return new Info() .title("BEAT Project API") .description("간편하게 소규모 공연을 등록하고 관리할 수 있는 티켓 예매 플랫폼") - .version("1.0.0"); + .version("1.1.0"); } } \ No newline at end of file diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index c2309f23..e9d0c438 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -57,8 +57,8 @@ spring: jwt: secret: ${DEV_JWT_SECRET} - access-token-expire-time: 31536000000 # 365일 (1년) 밀리초 - refresh-token-expire-time: 1209600000 # 14일 밀리초 + access-token-expire-time: ${DEV_ACCESS_TOKEN_EXPIRE_TIME} + refresh-token-expire-time: ${DEV_REFRESH_TOKEN_EXPIRE_TIME} cloud: aws: @@ -71,3 +71,13 @@ cloud: stack: auto: false +logging: + level: + root: info # 추후 debug로 변경 + +cors: + allowed-origins: ${DEV_ALLOWED_ORIGINS} + +app: + server: + url: ${DEV_SERVER_URL} \ No newline at end of file diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml deleted file mode 100644 index c923e123..00000000 --- a/src/main/resources/application-local.yml +++ /dev/null @@ -1,21 +0,0 @@ -server: - port: 8080 - -spring: - config: - activate: - on-profile: local - - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/beat - username: root - password: - jpa: - hibernate: - ddl-auto: create - show-sql: true - properties: - hibernate: - dialect: org.hibernate.dialect.MySQLDialect - format_sql: true \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index e21062b0..c9689bd2 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -57,8 +57,8 @@ spring: jwt: secret: ${PROD_JWT_SECRET} - access-token-expire-time: 31536000000 # 365일 (1년) 밀리초 - refresh-token-expire-time: 1209600000 # 14일 밀리초 + access-token-expire-time: ${PROD_ACCESS_TOKEN_EXPIRE_TIME} + refresh-token-expire-time: ${PROD_REFRESH_TOKEN_EXPIRE_TIME} cloud: aws: @@ -70,3 +70,14 @@ cloud: bucket: beat-prod-bucket stack: auto: false + +logging: + level: + root: info + +cors: + allowed-origins: ${PROD_ALLOWED_ORIGINS} + +app: + server: + url: ${PROD_SERVER_URL} \ No newline at end of file diff --git a/src/test/java/com/beat/domain/booking/GuestBookingServiceConcurrencyTest.java b/src/test/java/com/beat/domain/booking/GuestBookingServiceConcurrencyTest.java index 032ed530..ca1a66c5 100644 --- a/src/test/java/com/beat/domain/booking/GuestBookingServiceConcurrencyTest.java +++ b/src/test/java/com/beat/domain/booking/GuestBookingServiceConcurrencyTest.java @@ -3,6 +3,7 @@ import com.beat.domain.booking.application.GuestBookingService; import com.beat.domain.booking.application.dto.GuestBookingRequest; import com.beat.domain.booking.application.dto.GuestBookingResponse; +import com.beat.domain.booking.domain.BookingStatus; import com.beat.domain.performance.dao.PerformanceRepository; import com.beat.domain.performance.domain.BankName; import com.beat.domain.performance.domain.Genre; @@ -129,7 +130,7 @@ public void testConcurrentGuestBooking() { "1990-01-01", generateRandomPassword(), 35000, - false + BookingStatus.CHECKING_PAYMENT ); GuestBookingResponse response = guestBookingService.createGuestBooking(request); assertNotNull(response); @@ -152,7 +153,7 @@ public void testConcurrentGuestBooking() { "1990-01-01", generateRandomPassword(), 35000, - false + BookingStatus.CHECKING_PAYMENT ); GuestBookingResponse response = guestBookingService.createGuestBooking(request); assertNotNull(response);