Skip to content

Commit 6d7ce83

Browse files
gunwoong1630HwuanPagejohnhuh619garusitellCopilot
authored
release (#148)
* git initialize * feature/swagger-03-gunwoong (#5) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feat: swagger 추가 * feat: swagger 추가 * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/OpenAPI Test/02-HwuanPage * feature/OpenAPI Test/02-HwuanPage * Update SurfingForecastApiClient.java * feature/APICallTest-02-HwuanPage * feature/EntityInit-13-HwuanPage * feature/EntityInit-13-HwuanPage * feature/JellyfishEntityInit-13-HwuanPage * Update FishingType.java * feature/EntityInitialize-13-HwuanPage * feat: entity, repositor 구현 * feat: 예상 dto 구현 * chore: 의존성 추가 * feat: 로그인 구현 & 이후 토큰 발급 로직 구현 * fix: AuthCotnroller 수정 * fix: 클라이언트에서 카카오에서 코드를 받아 서버로 post 하게 수정 * feat: 토큰 검증 * feat: refresh token 블랙리스트 처리 로직 구현 * feat: refresh 토큰 블랙리스트 처리 & 재발급 로직 구현 * feat: SecurityFilterChain 엔드 포인트 허용 * feat: refresh 토큰 블랙리스트 검증 로직 구현 * feat: redis에서 refreshToken 블랙리스트 검증 * refactor: controller에 강하게 결합 되어 있던 로직들 분리 * test: member 관련 테스트 * chore: 하드코딩한 중요 값 Intellij IDEA 환경변수로 설정 * refactor: state 관리를 위해 세션 추가 * feat: member 정보 조회하는 서비스 로직 구현 * feat: member 정보 조회하는 서비스 로직 구현 * format: naver formatter로 포매팅 * chore: application-dev * fix: customException 처리 * Feat/meeting interface (#19) * feat : MeetingService 인터페이스 구현 * feat : ParticipantResponse * feat : MeetingListResponse 구현 * feat : MeetingDetailResponse구현 * feat : MeetingDetailAndMemberResponse 구현 * feat : ListSpot 구현 * feat : DetailSpot 구현 * feat : CreateMeetingRequest 구현 * feat : Tag 구현 * feat : Long -> long 변경 서비스와 Entity내에서 null값이 절대 나오지 않는다고 판단하는 값을 long으로 변경하였습니다. * feat : MeetingService.java -> 무한페이지로딩형식으로 바꾸었습니다. * Update src/main/java/sevenstar/marineleisure/meeting/Dto/Response/MeetingDetailResponse.java Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]> * Feature/FavoritesAndAlertInterface-16-HwuanPage * feature/FavoritesAndAlertInterface-16-HwuanPage * Update AlertMapper.java * Update JellyfishRegionDensityRepository.java * Update AlertController.java * Update FavoriteController.java * Update FavoriteRepository.java * Update AlertController.java * Update JellyfishSpieces.java * Update JellyfishRegion.java * Update JellyfishRegion.java * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * Feature/api scheduler 15 gunwoong (#28) * feat: api * feat: api 스케줄링 * feat: spot service inteface * test: remove legacy test * feat: apply open meteo * test: apply api test * feat: spot service (#34) * feat: spot service * feat: spot service 고도화 및 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * hotfix: duplicated controller method * feature/FavoriteCRUD-33-HwuanPage * DELETE COMPLETE * UPDATE COMPLETE * search COMPLETE * Before gunwoong * FavoriteCRUD create * feat/domain test * FavoriteSpotServiceTest * FavoriteSpotServiceTest * feature/FavoriteCURD-33-HwuanPage * add some description on service * Update FavoriteServiceImpl.java * Feature/spot preview 40 gunwoong (#41) * feat: spot preview & 리팩토링 * feat: spot preview & 리팩토링 * hotfix: jpa metamodel fix * fix: error fix * fix: 소셜 로그인 재시도 시 닉네임 UNIQUE 제약 위반 오류 발생 (#42) * fix: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 하던 버그 수정 * refactor: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 수정 사항 리팩토링 * test: 변경사항에 따른 테스트 코드 수정 * hofix: bug fix * Feature/Alert-22-HwuanPage * Create Pdf Parser * Web crawler run perpectly,but pdfparser do not work well * PDF parse to stack DB complete with OPENAI * CallAlert Complete * JellyFish PDF parsing work well * feature/ControllerTest Complete * feature/JellyfishAlert-26-HwuanPage * feat: 즐겨찾기 추가 및 리팩토링 (#49) * feat: 즐겨찾기 추가 및 리팩토링 * refactor: 리팩토링 * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 코드 적용이 필요합니다. * `createMeeting(Long memberId, CreateMeetingRequest request)`: * 목적: 새로운 모임을 생성합니다. 호스트를 참여자로 자동 등록하고 태그 정보를 저장합니다. * `updateMeeting(Long meetingId, Long memberId, UpdateMeetingRequest request)`: * 목적: 기존 모임의 정보를 수정합니다. 호스트만 수정할 수 있도록 검증합니다. * `deleteMeeting(Member member, Long meetingId)`: * 목적: 모임을 삭제합니다. * 개선 예정: 물리적 삭제 대신 논리적 삭제(Soft Delete) 방식 도입을 고려 중입니다. * feat : MeetingValidate.java,MemberValidate.java,ParticipantValidate,SpotValidate,TagValidate.java 검증로직을 추가하였습니다. * feat : MemberError.java , ParticipantRepository 기능을 추가하였습니다. --------- Co-authored-by: Hwang Seong Cheol a.k.a Hwuan Page <[email protected]> * Feature/integration init (#54) * feature/IntegrationSet(test&Build)-52-HwuanPage * data.sql unique update * image build needs * ignore dev.yml * remove dev.yml tracking and ignore it * prod * proded * Feature/activities 17 audwls239 (#56) * feature: 컨트롤러, 서비스 생성 * feature: 활동별 지수 조회(위치 기반) * feature: DTO 추가 * feature: 활동별 지수 조회(글로벌) 추가, 컨트롤러 수정 * feature: 활동별 지수 상세 조회(미완성) * feature: 해양 정보 조회 * feature: 활동 상세 조회 --------- Co-authored-by: Gunwoong cho <[email protected]> * feat : ParticipantError 입니다. * hotfix: error fix * fix : Directory 수정사항입니다. (#57) * hotfix: error fix * feat: member delete (#58) * fix: 멤버 삭제 구현 * feat: 멤버 삭제, 위/경도 수정 구현 * test: 테스트 수정 * Delete src/main/java/sevenstar/marineleisure/meeting/repository/MemberRepository.java * Delete src/main/java/sevenstar/marineleisure/meeting/repository/OutdoorSpotSpotRepository.java * Delete src/main/resources/test.http --------- Co-authored-by: LEESUNBIN <[email protected]> Co-authored-by: Gunwoong cho <[email protected]> * fix : ParticipantRepository (#59) existsByMeetingIdAndUserId 로 수정하였습니다. * fix : ParticipantRepository (#60) memberId -> userId로 수정하였습니다. * fix: token (#61) * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 # Conflicts: # src/main/java/sevenstar/marineleisure/global/exception/enums/CommonErrorCode.java # src/main/java/sevenstar/marineleisure/global/swagger/SwaggerController.java * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 코드 적용이 필요합니다. * `createMeeting(Long memberId, CreateMeetingRequest request)`: * 목적: 새로운 모임을 생성합니다. 호스트를 참여자로 자동 등록하고 태그 정보를 저장합니다. * `updateMeeting(Long meetingId, Long memberId, UpdateMeetingRequest request)`: * 목적: 기존 모임의 정보를 수정합니다. 호스트만 수정할 수 있도록 검증합니다. * `deleteMeeting(Member member, Long meetingId)`: * 목적: 모임을 삭제합니다. * 개선 예정: 물리적 삭제 대신 논리적 삭제(Soft Delete) 방식 도입을 고려 중입니다. * feat : MeetingValidate.java,MemberValidate.java,ParticipantValidate,SpotValidate,TagValidate.java 검증로직을 추가하였습니다. * feat : MemberError.java , ParticipantRepository 기능을 추가하였습니다. --------- Co-authored-by: Hwang Seong Cheol a.k.a Hwuan Page <[email protected]> * feat: 테스트용 액세스 토큰 생성 * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * Feature/api scheduler 15 gunwoong (#28) * feat: api * feat: api 스케줄링 * feat: spot service inteface * test: remove legacy test * feat: apply open meteo * test: apply api test * feature/FavoriteCRUD-33-HwuanPage * DELETE COMPLETE * UPDATE COMPLETE * search COMPLETE * Before gunwoong * FavoriteCRUD create * feat/domain test * FavoriteSpotServiceTest * FavoriteSpotServiceTest * feature/FavoriteCURD-33-HwuanPage * add some description on service * Update FavoriteServiceImpl.java * fix: error fix * fix: 소셜 로그인 재시도 시 닉네임 UNIQUE 제약 위반 오류 발생 (#42) * fix: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 하던 버그 수정 * refactor: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 수정 사항 리팩토링 * test: 변경사항에 따른 테스트 코드 수정 * hofix: bug fix * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 # Conflicts: # src/main/java/sevenstar/marineleisure/global/exception/enums/CommonErrorCode.java # src/main/java/sevenstar/marineleisure/global/swagger/SwaggerController.java * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 코드 적용이 필요합니다. * `createMeeting(Long memberId, CreateMeetingRequest request)`: * 목적: 새로운 모임을 생성합니다. 호스트를 참여자로 자동 등록하고 태그 정보를 저장합니다. * `updateMeeting(Long meetingId, Long memberId, UpdateMeetingRequest request)`: * 목적: 기존 모임의 정보를 수정합니다. 호스트만 수정할 수 있도록 검증합니다. * `deleteMeeting(Member member, Long meetingId)`: * 목적: 모임을 삭제합니다. * 개선 예정: 물리적 삭제 대신 논리적 삭제(Soft Delete) 방식 도입을 고려 중입니다. * feat : MeetingValidate.java,MemberValidate.java,ParticipantValidate,SpotValidate,TagValidate.java 검증로직을 추가하였습니다. * feat : MemberError.java , ParticipantRepository 기능을 추가하였습니다. --------- Co-authored-by: Hwang Seong Cheol a.k.a Hwuan Page <[email protected]> * fix : jellyfish 부분 * fix: activity 부분 * fix: member 부분 * fix: member 부분 * fix: spot 부분 * fix: forecast 부분 * fix: favorite 부분 * fix: alert 부분 * fix: meeting 부분 --------- Co-authored-by: Gunwoong cho <[email protected]> Co-authored-by: Hwang Seong Cheol a.k.a Hwuan Page <[email protected]> Co-authored-by: MyungJin <[email protected]> Co-authored-by: LEESUNBIN <[email protected]> Co-authored-by: gunwoong <[email protected]> * hotfix/fix-alert&favorites-62-HwuanPage * fix(hotfix/Meeting) : rebase로 인한 코드 누락 수정 (#65) * hotfix: 코드 누락 해결 (#67) * Fix/fix 70 gunwoong (#71) * hotfix: fix * hotfix: fix * hotfix: fix * fix: application-prod.yml에서 쿠키를 쓸지 말지 결정할 수 있게 수정 (#69) * fix: application-prod.yml에서 쿠키를 쓸지 말지 결정할 수 있게 수정 * test: 테스트 코드 작성 * fix: activities 시큐리티 엔드포인트 허용. redirecturi 수정 * Chore/docker set andvariable-68-hwuanPage * chore/ReadytoDeployv1.0.0-68-HuwanPage * chore/ReadytoDeploymentv1.0.0-68-HuwanPage * remove etc * prod * refactor: blacklist 엔티티의 jti에 인덱스를 건다. (#74) * Feat/meeting test 75 (#77) * feat : Meetingtest 를 위한 Util 파일입니니다. * feat : Meetingtest 를 위한 Util 파일입니니다. * feat : MeetingServiceImplTest 단위테스트입니다. * feat : MeetingControllerTest 통합테스트입니다. * feat : Build Lombok을 테스트를 위한 수정입니다. * feat : Tag 엔티티 Tag List<String> content 를 변환하기 위한 파일입니다. * feat : MeetingServiceImpl * feat : MeetingServiceImpl에서 수정하는 응답을 수정 , 매퍼를 수정하였습니다. * feat : Meeting에서 필요한 url을 열어뒀습니다. * space prob solve * stack-trace-DEBUG * hotfix/data.sql deprecate-HwuanPage (#79) * hotfix/data.sql deprecate-HwuanPage * portnum fix * Xtest * test X * workflow fix * add id * fix docker-compose-image-root * release/v1-marineleisure * fix: blacklist 엔티티의 jti에 인덱스를 건다. (#83) * fix: cors 프론트엔드 배포 도메인 추가 (#84) * fix: blacklist 엔티티의 jti에 인덱스를 건다. * fix: cors 프로트엔드 도메인 추가 * hotfix/method_allowed_patch-HwuanPage (#86) * Refactor/exception hwuan page (#87) * refacotr/favorite-Exception-update * fix kakao_redirect_uri * Feature/map service refactoring 76 gunwoong (#85) * feat: mapServiceRefactoring * refactoring: spot detail refactoring * refactoring: GeoUtils refactoring * test: repository test disable for prod * fix: apply flyway to yml * fix: disable test * refactor: khoa refactoring * fix: bug * fix: sql * fix: yml 환경변수 추가 * fix: detail field name 수정 * feature: 스케줄링 비동기 구현 (#91) * refactor: cacheable (#103) * Fix/meeting urland role (#100) * fix : MeetingServiceImpl getStatusMeetings -> getStatusMeeting_role : Guest 인지 host 인지 판단하는 로직을 추가 * fix : MeetingRepository getStatusMeetings -> getStatusMeeting_role : Guest 인지 host 인지 판단하는 로직을 추가 * fix : MeetingError MEETING_MEMBER_NOT_FOUND 에러를 추가하였습니다. 미팅에서 맴버를 확인할 수 없는 에러입니다. * fix : MeetingController MeetingController 에서 role 을 확인하여 추가 확인할 수 있도록 하였습니다. * fix : MeetingServiceImplTest, MeetingControllerTest.java URL 개선에 의한 새로운 테스트 입니다. * fix : MeetingServiceImplTest, MeetingControllerTest.java @disabled 추가 하였습니다. * feat: 회원 탈퇴 시 카카오 연결 끊기도 수행하게 구현한다. (#98) * feat: member 삭제 시 kakao 연결 끊기 로직도 수행하게 구현 * test: 변경 사항 test * feat : Meeting의 커서방식에서 매핑을 하였습니다. (#94) * feat: 카카오 로그인 과정에서 pkce를 통해 보안 관점에서 개선 (#106) * feat: 보안 인증 과정에서 PKCE 추가하여 구현 * test: 변경 사항 test 추가 * feat: PKCE 기반 보안 기능 코드 구조 변경 * test: PKCE 기반 보안 기능 test * refactor: PKCE 생성을 클라이언트 에게 넘긴다. * test: pkce test 플로우 변경에 따라 변경 * fix: member entity의 nickname 중복을 허용한다 * fix: 테스트를 위해 SchedulerService.java 의 @RequiredArgsConstrucor 지운 부분 복구 * fix: 테스트를 위해 SchedulerService.java 의 @RequiredArgsConstrucor 지운 부분 복구 * refactor: open-meteo 서비스 관련 리팩토링 (#95) * refactor: RichDomain으로 변경 내역입니다. (#105) * Fix: login redirect (#107) * fix: 로그인 요청때의 리다이렉트 uri를 토큰 교환시에도 사용 * test: test * fix: fallback 상황에서 리다이렉트 uri 찾는 로직 추가 * Refactor/meeting rich domain (#110) * refactor: RichDomain으로 변경 내역입니다. * refactor: 누락 프로젝트 파일이 있어 첨부합니다. * build: caffenine 적용 * relase (#111) (#112) * git initialize * feature/swagger-03-gunwoong (#5) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feat: swagger 추가 * feat: swagger 추가 * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/OpenAPI Test/02-HwuanPage * feature/OpenAPI Test/02-HwuanPage * Update SurfingForecastApiClient.java * feature/APICallTest-02-HwuanPage * feature/EntityInit-13-HwuanPage * feature/EntityInit-13-HwuanPage * feature/JellyfishEntityInit-13-HwuanPage * Update FishingType.java * feature/EntityInitialize-13-HwuanPage * feat: entity, repositor 구현 * feat: 예상 dto 구현 * chore: 의존성 추가 * feat: 로그인 구현 & 이후 토큰 발급 로직 구현 * fix: AuthCotnroller 수정 * fix: 클라이언트에서 카카오에서 코드를 받아 서버로 post 하게 수정 * feat: 토큰 검증 * feat: refresh token 블랙리스트 처리 로직 구현 * feat: refresh 토큰 블랙리스트 처리 & 재발급 로직 구현 * feat: SecurityFilterChain 엔드 포인트 허용 * feat: refresh 토큰 블랙리스트 검증 로직 구현 * feat: redis에서 refreshToken 블랙리스트 검증 * refactor: controller에 강하게 결합 되어 있던 로직들 분리 * test: member 관련 테스트 * chore: 하드코딩한 중요 값 Intellij IDEA 환경변수로 설정 * refactor: state 관리를 위해 세션 추가 * feat: member 정보 조회하는 서비스 로직 구현 * feat: member 정보 조회하는 서비스 로직 구현 * format: naver formatter로 포매팅 * chore: application-dev * fix: customException 처리 * Feat/meeting interface (#19) * feat : MeetingService 인터페이스 구현 * feat : ParticipantResponse * feat : MeetingListResponse 구현 * feat : MeetingDetailResponse구현 * feat : MeetingDetailAndMemberResponse 구현 * feat : ListSpot 구현 * feat : DetailSpot 구현 * feat : CreateMeetingRequest 구현 * feat : Tag 구현 * feat : Long -> long 변경 서비스와 Entity내에서 null값이 절대 나오지 않는다고 판단하는 값을 long으로 변경하였습니다. * feat : MeetingService.java -> 무한페이지로딩형식으로 바꾸었습니다. * Update src/main/java/sevenstar/marineleisure/meeting/Dto/Response/MeetingDetailResponse.java --------- * Feature/FavoritesAndAlertInterface-16-HwuanPage * feature/FavoritesAndAlertInterface-16-HwuanPage * Update AlertMapper.java * Update JellyfishRegionDensityRepository.java * Update AlertController.java * Update FavoriteController.java * Update FavoriteRepository.java * Update AlertController.java * Update JellyfishSpieces.java * Update JellyfishRegion.java * Update JellyfishRegion.java * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * Feature/api scheduler 15 gunwoong (#28) * feat: api * feat: api 스케줄링 * feat: spot service inteface * test: remove legacy test * feat: apply open meteo * test: apply api test * feat: spot service (#34) * feat: spot service * feat: spot service 고도화 및 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * hotfix: duplicated controller method * feature/FavoriteCRUD-33-HwuanPage * DELETE COMPLETE * UPDATE COMPLETE * search COMPLETE * Before gunwoong * FavoriteCRUD create * feat/domain test * FavoriteSpotServiceTest * FavoriteSpotServiceTest * feature/FavoriteCURD-33-HwuanPage * add some description on service * Update FavoriteServiceImpl.java * Feature/spot preview 40 gunwoong (#41) * feat: spot preview & 리팩토링 * feat: spot preview & 리팩토링 * hotfix: jpa metamodel fix * fix: error fix * fix: 소셜 로그인 재시도 시 닉네임 UNIQUE 제약 위반 오류 발생 (#42) * fix: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 하던 버그 수정 * refactor: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 수정 사항 리팩토링 * test: 변경사항에 따른 테스트 코드 수정 * hofix: bug fix * Feature/Alert-22-HwuanPage * Create Pdf Parser * Web crawler run perpectly,but pdfparser do not work well * PDF parse to stack DB complete with OPENAI * CallAlert Complete * JellyFish PDF parsing work well * feature/ControllerTest Complete * feature/JellyfishAlert-26-HwuanPage * feat: 즐겨찾기 추가 및 리팩토링 (#49) * feat: 즐겨찾기 추가 및 리팩토링 * refactor: 리팩토링 * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 코드 적용이 필요합니다. * `createMeeting(Long memberId, CreateMeetingRequest request)`: * 목적: 새로운 모임을 생성합니다. 호스트를 참여자로 자동 등록하고 태그 정보를 저장합니다. * `updateMeeting(Long meetingId, Long memberId, UpdateMeetingRequest request)`: * 목적: 기존 모임의 정보를 수정합니다. 호스트만 수정할 수 있도록 검증합니다. * `deleteMeeting(Member member, Long meetingId)`: * 목적: 모임을 삭제합니다. * 개선 예정: 물리적 삭제 대신 논리적 삭제(Soft Delete) 방식 도입을 고려 중입니다. * feat : MeetingValidate.java,MemberValidate.java,ParticipantValidate,SpotValidate,TagValidate.java 검증로직을 추가하였습니다. * feat : MemberError.java , ParticipantRepository 기능을 추가하였습니다. --------- * Feature/integration init (#54) * feature/IntegrationSet(test&Build)-52-HwuanPage * data.sql unique update * image build needs * ignore dev.yml * remove dev.yml tracking and ignore it * prod * proded * Feature/activities 17 audwls239 (#56) * feature: 컨트롤러, 서비스 생성 * feature: 활동별 지수 조회(위치 기반) * feature: DTO 추가 * feature: 활동별 지수 조회(글로벌) 추가, 컨트롤러 수정 * feature: 활동별 지수 상세 조회(미완성) * feature: 해양 정보 조회 * feature: 활동 상세 조회 --------- * feat : ParticipantError 입니다. * hotfix: error fix * fix : Directory 수정사항입니다. (#57) * hotfix: error fix * feat: member delete (#58) * fix: 멤버 삭제 구현 * feat: 멤버 삭제, 위/경도 수정 구현 * test: 테스트 수정 * Delete src/main/java/sevenstar/marineleisure/meeting/repository/MemberRepository.java * Delete src/main/java/sevenstar/marineleisure/meeting/repository/OutdoorSpotSpotRepository.java * Delete src/main/resources/test.http --------- * fix : ParticipantRepository (#59) existsByMeetingIdAndUserId 로 수정하였습니다. * fix : ParticipantRepository (#60) memberId -> userId로 수정하였습니다. * fix: token (#61) * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 # Conflicts: # src/main/java/sevenstar/marineleisure/global/exception/enums/CommonErrorCode.java # src/main/java/sevenstar/marineleisure/global/swagger/SwaggerController.java * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 코드 적용이 필요합니다. * `createMeeting(Long memberId, CreateMeetingRequest request)`: * 목적: 새로운 모임을 생성합니다. 호스트를 참여자로 자동 등록하고 태그 정보를 저장합니다. * `updateMeeting(Long meetingId, Long memberId, UpdateMeetingRequest request)`: * 목적: 기존 모임의 정보를 수정합니다. 호스트만 수정할 수 있도록 검증합니다. * `deleteMeeting(Member member, Long meetingId)`: * 목적: 모임을 삭제합니다. * 개선 예정: 물리적 삭제 대신 논리적 삭제(Soft Delete) 방식 도입을 고려 중입니다. * feat : MeetingValidate.java,MemberValidate.java,ParticipantValidate,SpotValidate,TagValidate.java 검증로직을 추가하였습니다. * feat : MemberError.java , ParticipantRepository 기능을 추가하였습니다. --------- * feat: 테스트용 액세스 토큰 생성 * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * Feature/api scheduler 15 gunwoong (#28) * feat: api * feat: api 스케줄링 * feat: spot service inteface * test: remove legacy test * feat: apply open meteo * test: apply api test * feature/FavoriteCRUD-33-HwuanPage * DELETE COMPLETE * UPDATE COMPLETE * search COMPLETE * Before gunwoong * FavoriteCRUD create * feat/domain test * FavoriteSpotServiceTest * FavoriteSpotServiceTest * feature/FavoriteCURD-33-HwuanPage * add some description on service * Update FavoriteServiceImpl.java * fix: error fix * fix: 소셜 로그인 재시도 시 닉네임 UNIQUE 제약 위반 오류 발생 (#42) * fix: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 하던 버그 수정 * refactor: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 수정 사항 리팩토링 * test: 변경사항에 따른 테스트 코드 수정 * hofix: bug fix * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 # Conflicts: # src/main/java/sevenstar/marineleisure/global/exception/enums/CommonErrorCode.java # src/main/java/sevenstar/marineleisure/global/swagger/SwaggerController.java * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 코드 적용이 필요합니다. * `createMeeting(Long memberId, CreateMeetingRequest request)`: * 목적: 새로운 모임을 생성합니다. 호스트를 참여자로 자동 등록하고 태그 정보를 저장합니다. * `updateMeeting(Long meetingId, Long memberId, UpdateMeetingRequest request)`: * 목적: 기존 모임의 정보를 수정합니다. 호스트만 수정할 수 있도록 검증합니다. * `deleteMeeting(Member member, Long meetingId)`: * 목적: 모임을 삭제합니다. * 개선 예정: 물리적 삭제 대신 논리적 삭제(Soft Delete) 방식 도입을 고려 중입니다. * feat : MeetingValidate.java,MemberValidate.java,ParticipantValidate,SpotValidate,TagValidate.java 검증로직을 추가하였습니다. * feat : MemberError.java , ParticipantRepository 기능을 추가하였습니다. --------- * fix : jellyfish 부분 * fix: activity 부분 * fix: member 부분 * fix: member 부분 * fix: spot 부분 * fix: forecast 부분 * fix: favorite 부분 * fix: alert 부분 * fix: meeting 부분 --------- * hotfix/fix-alert&favorites-62-HwuanPage * fix(hotfix/Meeting) : rebase로 인한 코드 누락 수정 (#65) * hotfix: 코드 누락 해결 (#67) * Fix/fix 70 gunwoong (#71) * hotfix: fix * hotfix: fix * hotfix: fix * fix: application-prod.yml에서 쿠키를 쓸지 말지 결정할 수 있게 수정 (#69) * fix: application-prod.yml에서 쿠키를 쓸지 말지 결정할 수 있게 수정 * test: 테스트 코드 작성 * fix: activities 시큐리티 엔드포인트 허용. redirecturi 수정 * Chore/docker set andvariable-68-hwuanPage * chore/ReadytoDeployv1.0.0-68-HuwanPage * chore/ReadytoDeploymentv1.0.0-68-HuwanPage * remove etc * prod * refactor: blacklist 엔티티의 jti에 인덱스를 건다. (#74) * Feat/meeting test 75 (#77) * feat : Meetingtest 를 위한 Util 파일입니니다. * feat : Meetingtest 를 위한 Util 파일입니니다. * feat : MeetingServiceImplTest 단위테스트입니다. * feat : MeetingControllerTest 통합테스트입니다. * feat : Build Lombok을 테스트를 위한 수정입니다. * feat : Tag 엔티티 Tag List<String> content 를 변환하기 위한 파일입니다. * feat : MeetingServiceImpl * feat : MeetingServiceImpl에서 수정하는 응답을 수정 , 매퍼를 수정하였습니다. * feat : Meeting에서 필요한 url을 열어뒀습니다. * space prob solve * stack-trace-DEBUG * hotfix/data.sql deprecate-HwuanPage (#79) * hotfix/data.sql deprecate-HwuanPage * portnum fix * Xtest * test X * workflow fix * add id * fix docker-compose-image-root * release/v1-marineleisure * fix: blacklist 엔티티의 jti에 인덱스를 건다. (#83) * fix: cors 프론트엔드 배포 도메인 추가 (#84) * fix: blacklist 엔티티의 jti에 인덱스를 건다. * fix: cors 프로트엔드 도메인 추가 * hotfix/method_allowed_patch-HwuanPage (#86) * Refactor/exception hwuan page (#87) * refacotr/favorite-Exception-update * fix kakao_redirect_uri * Feature/map service refactoring 76 gunwoong (#85) * feat: mapServiceRefactoring * refactoring: spot detail refactoring * refactoring: GeoUtils refactoring * test: repository test disable for prod * fix: apply flyway to yml * fix: disable test * refactor: khoa refactoring * fix: bug * fix: sql * fix: yml 환경변수 추가 * fix: detail field name 수정 * feature: 스케줄링 비동기 구현 (#91) * refactor: cacheable (#103) * Fix/meeting urland role (#100) * fix : MeetingServiceImpl getStatusMeetings -> getStatusMeeting_role : Guest 인지 host 인지 판단하는 로직을 추가 * fix : MeetingRepository getStatusMeetings -> getStatusMeeting_role : Guest 인지 host 인지 판단하는 로직을 추가 * fix : MeetingError MEETING_MEMBER_NOT_FOUND 에러를 추가하였습니다. 미팅에서 맴버를 확인할 수 없는 에러입니다. * fix : MeetingController MeetingController 에서 role 을 확인하여 추가 확인할 수 있도록 하였습니다. * fix : MeetingServiceImplTest, MeetingControllerTest.java URL 개선에 의한 새로운 테스트 입니다. * fix : MeetingServiceImplTest, MeetingControllerTest.java @disabled 추가 하였습니다. * feat: 회원 탈퇴 시 카카오 연결 끊기도 수행하게 구현한다. (#98) * feat: member 삭제 시 kakao 연결 끊기 로직도 수행하게 구현 * test: 변경 사항 test * feat : Meeting의 커서방식에서 매핑을 하였습니다. (#94) * feat: 카카오 로그인 과정에서 pkce를 통해 보안 관점에서 개선 (#106) * feat: 보안 인증 과정에서 PKCE 추가하여 구현 * test: 변경 사항 test 추가 * feat: PKCE 기반 보안 기능 코드 구조 변경 * test: PKCE 기반 보안 기능 test * refactor: PKCE 생성을 클라이언트 에게 넘긴다. * test: pkce test 플로우 변경에 따라 변경 * fix: member entity의 nickname 중복을 허용한다 * fix: 테스트를 위해 SchedulerService.java 의 @RequiredArgsConstrucor 지운 부분 복구 * fix: 테스트를 위해 SchedulerService.java 의 @RequiredArgsConstrucor 지운 부분 복구 * refactor: open-meteo 서비스 관련 리팩토링 (#95) * refactor: RichDomain으로 변경 내역입니다. (#105) * Fix: login redirect (#107) * fix: 로그인 요청때의 리다이렉트 uri를 토큰 교환시에도 사용 * test: test * fix: fallback 상황에서 리다이렉트 uri 찾는 로직 추가 * Refactor/meeting rich domain (#110) * refactor: RichDomain으로 변경 내역입니다. * refactor: 누락 프로젝트 파일이 있어 첨부합니다. * build: caffenine 적용 --------- Co-authored-by: HwuanPage <[email protected]> Co-authored-by: JaeoneHeo <[email protected]> Co-authored-by: LEESUNBIN <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: MyungJin <[email protected]> Co-authored-by: iseonbin <[email protected]> * fix: fallback 상황에서 리다이렉트 uri 찾는 로직 추가 (#113) * release (#114) (#115) * git initialize * feature/swagger-03-gunwoong (#5) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feat: swagger 추가 * feat: swagger 추가 * feature/base domain 04 gunwoong (#6) * feat: 공통 도메인 구현 * feat: 메인 어플리케이션에 추가 * feature/OpenAPI Test/02-HwuanPage * feature/OpenAPI Test/02-HwuanPage * Update SurfingForecastApiClient.java * feature/APICallTest-02-HwuanPage * feature/EntityInit-13-HwuanPage * feature/EntityInit-13-HwuanPage * feature/JellyfishEntityInit-13-HwuanPage * Update FishingType.java * feature/EntityInitialize-13-HwuanPage * feat: entity, repositor 구현 * feat: 예상 dto 구현 * chore: 의존성 추가 * feat: 로그인 구현 & 이후 토큰 발급 로직 구현 * fix: AuthCotnroller 수정 * fix: 클라이언트에서 카카오에서 코드를 받아 서버로 post 하게 수정 * feat: 토큰 검증 * feat: refresh token 블랙리스트 처리 로직 구현 * feat: refresh 토큰 블랙리스트 처리 & 재발급 로직 구현 * feat: SecurityFilterChain 엔드 포인트 허용 * feat: refresh 토큰 블랙리스트 검증 로직 구현 * feat: redis에서 refreshToken 블랙리스트 검증 * refactor: controller에 강하게 결합 되어 있던 로직들 분리 * test: member 관련 테스트 * chore: 하드코딩한 중요 값 Intellij IDEA 환경변수로 설정 * refactor: state 관리를 위해 세션 추가 * feat: member 정보 조회하는 서비스 로직 구현 * feat: member 정보 조회하는 서비스 로직 구현 * format: naver formatter로 포매팅 * chore: application-dev * fix: customException 처리 * Feat/meeting interface (#19) * feat : MeetingService 인터페이스 구현 * feat : ParticipantResponse * feat : MeetingListResponse 구현 * feat : MeetingDetailResponse구현 * feat : MeetingDetailAndMemberResponse 구현 * feat : ListSpot 구현 * feat : DetailSpot 구현 * feat : CreateMeetingRequest 구현 * feat : Tag 구현 * feat : Long -> long 변경 서비스와 Entity내에서 null값이 절대 나오지 않는다고 판단하는 값을 long으로 변경하였습니다. * feat : MeetingService.java -> 무한페이지로딩형식으로 바꾸었습니다. * Update src/main/java/sevenstar/marineleisure/meeting/Dto/Response/MeetingDetailResponse.java --------- * Feature/FavoritesAndAlertInterface-16-HwuanPage * feature/FavoritesAndAlertInterface-16-HwuanPage * Update AlertMapper.java * Update JellyfishRegionDensityRepository.java * Update AlertController.java * Update FavoriteController.java * Update FavoriteRepository.java * Update AlertController.java * Update JellyfishSpieces.java * Update JellyfishRegion.java * Update JellyfishRegion.java * feature/CustomExceptionInit-22-HwuanPage * feature/CustomExceptionInit-22-HwuanPage * Errorcode interface Change * Refactor application.yml 환경변수 설정 (#25) * refactor: application.yml 환경변수 설정 * Rename: 오타 수정 * Feature/spot service interface 29 gunwoong (#30) * feat: api * feat: api 스케줄링 * feat: spot service inteface * Feature/api scheduler 15 gunwoong (#28) * feat: api * feat: api 스케줄링 * feat: spot service inteface * test: remove legacy test * feat: apply open meteo * test: apply api test * feat: spot service (#34) * feat: spot service * feat: spot service 고도화 및 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * feat: 조회도 관련 서비스 추가 * hotfix: duplicated controller method * feature/FavoriteCRUD-33-HwuanPage * DELETE COMPLETE * UPDATE COMPLETE * search COMPLETE * Before gunwoong * FavoriteCRUD create * feat/domain test * FavoriteSpotServiceTest * FavoriteSpotServiceTest * feature/FavoriteCURD-33-HwuanPage * add some description on service * Update FavoriteServiceImpl.java * Feature/spot preview 40 gunwoong (#41) * feat: spot preview & 리팩토링 * feat: spot preview & 리팩토링 * hotfix: jpa metamodel fix * fix: error fix * fix: 소셜 로그인 재시도 시 닉네임 UNIQUE 제약 위반 오류 발생 (#42) * fix: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 하던 버그 수정 * refactor: 로그아웃 후 재로그인 시 동일 정보로 db에 insert 수정 사항 리팩토링 * test: 변경사항에 따른 테스트 코드 수정 * hofix: bug fix * Feature/Alert-22-HwuanPage * Create Pdf Parser * Web crawler run perpectly,but pdfparser do not work well * PDF parse to stack DB complete with OPENAI * CallAlert Complete * JellyFish PDF parsing work well * feature/ControllerTest Complete * feature/JellyfishAlert-26-HwuanPage * feat: 즐겨찾기 추가 및 리팩토링 (#49) * feat: 즐겨찾기 추가 및 리팩토링 * refactor: 리팩토링 * feat: 카카오 로그인을 stateless 하게 변경한다 (#51) * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경 * refactor: 기존 state 사용 방식 -> stateless 방식으로 변경으로 인해 필요 없는 엔드 포인트 삭제 * test: 변경사항 test 수정 * feat: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 코드 구현 * test: 카카오 측에서 인증 실패시에 반환 하는 에러 처리하는 테스트 추가 * fix: 주석 제거 * fix: exception 변경 * Feat/meeting service (#46) * WIP: Rebase를 위한 임시 저장 * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * feat : Meeting.java -> Meeting 엔터티 @builder 를 상위 어노테이션에 일단 추가시켰습니다. * Delete MeetingServiceImplReview.md * Delete MeetingServiceUserFlow.md * feat : 패키지명 변경 이슈 -> 패키지 명을 컨벤션에 따른 이름으로 변경했습니다. * feat : MeetingController.java long participantCount = participantRepository.countMeetingIdMember -> long participantCount = participantRepository.countMeetingId로 수정하였습니다. * feat : MeetingError.java MeetingError.java 를 추가하였습니다. * feat : MeetingMapper MeetingServiceImpl에서 사용중이었던 Mapper를 분리하였습니다. * feat : MeetingService.java 패키지 명 수정으로 인해서 수정사항이 있었습니다. * feat : MeetingServiceImpl.java 트랜잭션 관리 명확화 하였습니다. validate 패키지를 개선하였습니다. joinMeeting 중복 참여 제한 로직을 강화하였습니다. * `getAllMeetings(Long cursorId, int size)`: * 목적: 모든 모임 목록을 페이징 처리하여 조회합니다. cursorId를 사용하여 무한 스크롤과 같은 커서 기반 페이징을 지원합니다. * 특징: @transactional(readOnly = true)를 통해 읽기 전용 트랜잭션으로 최적화되었습니다. * `getMeetingDetails(Long meetingId)`: * 목적: 특정 모임의 상세 정보를 조회합니다. 호스트, 장소, 태그 등 연관된 정보를 함께 가져옵니다. * 개선 예정: 현재 N+1 문제가 발생할 수 있어, 향후 Fetch Join을 통한 성능 최적화가 필요합니다. * `getStatusMyMeetings(Long memberId, Long cursorId, int size, MeetingStatus meetingStatus)`: * 목적: 특정 회원의 상태별(예: 모집 중, 완료) 모임 목록을 페이징 처리하여 조회합니다. * `getMeetingDetailAndMember(Long memberId, Long meetingId)`: * 목적: 호스트가 자신의 모임 상세 정보와 참여자 목록을 조회합니다. 참여자들의 닉네임을 함께 제공합니다. * `countMeetings(Long memberId)`: * 목적: 특정 회원이 참여한 모임의 총 개수를 반환합니다. * `joinMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 특정 모임에 참여합니다. * 주요 개선: 모임 상태 검증(verifyRecruiting), 중복 참여 검증(`verifyNotAlreadyParticipant`), 모임 정원 초과 검증(verifyMeetingCount) 로직이 강화되었습니다. * 개선 예정: 동시성 문제(Race Condition) 해결을 위한 비관적 락(Pessimistic Lock) 적용이 필요합니다. * `leaveMeeting(Long meetingId, Long memberId)`: * 목적: 회원이 모임에서 탈퇴합니다. * 주요 개선: 호스트 탈퇴 방지(verifyNotHost), 모임 상태에 따른 탈퇴 가능 여부 검증(verifyLeave) 로직이 추가되었습니다. * 개선 예정: MEETING_NOT_FOUND 대신 CANNOT_LEAVE_COMPLETED_MEETING과 같은 더 구체적인 에러 …
1 parent 5f0b079 commit 6d7ce83

File tree

6 files changed

+210
-18
lines changed

6 files changed

+210
-18
lines changed

README.md

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,167 @@
1-
# WEB5_7_7STARBALL_BE
1+
# 🌊 MarineLeisure - 수상레저 특화 해양 정보 서비스
2+
3+
> **7성구 팀**의 레저 활동자를 위한 위치 기반 맞춤형 해양 정보 제공 플랫폼
4+
5+
---
6+
7+
## 📌 프로젝트 소개
8+
9+
**MarineLeisure**는 낚시, 스쿠버다이빙, 해루질, 서핑 등 수상레저 활동을 즐기는 사용자를 위해 설계된 웹 기반 정보 서비스입니다. 실시간 기상 및 해양 생물 정보를 통해 **안전하고 효율적인 레저 활동**을 가능하게 합니다.
10+
11+
> 수온, 조류, 파도, 시야 등 다양한 해양 데이터를 기반으로 레저 최적 장소를 추천하고, 위험 생물 정보를 제공하여 사용자 경험을 향상시킵니다.
12+
13+
---
14+
15+
## 👥 팀원 소개
16+
17+
| 이름 | 역할 | 담당 | 이메일 | GitHub | 한마디 |
18+
|------|------|------|--------|--------|--------|
19+
| 👨‍💻 조건웅 | 백엔드 팀장 | 외부 API 연계 및 지도, 알림 관련 서비스| [email protected] | [gunwoong1630](https://github.com/gunwoong1630?tab=repositories) | Hi |
20+
| 👨‍💻 김명진 | 백엔드 개발 | 활동 관련 서비스 | [email protected] | [audwls239](https://github.com/audwls239?tab=repositories) | 잘 부탁드려요! |
21+
| 👨‍💻 허재원 | 백엔드 개발 | 인증 서비스 개발 | [email protected] | [johnhuh619](https://github.com/johnhuh619) | 안녕하세요~~ |
22+
| 👩‍💻 이선빈 | 백엔드 개발 | 모임 관련 서비스 | [email protected] | [twinkey0201](https://github.com/](https://github.com/garusitell)) | 안녕하십니까 |
23+
24+
---
25+
26+
## 💡 기획 의도
27+
28+
- 기존 기상·해양 정보는 **학술 목적**이거나 **파편화**되어 있어 접근이 어려움
29+
- 수상레저 활동은 **활동별 필요한 정보가 상이**
30+
- **사용자의 위치, 활동 유형에 따라 맞춤 정보 제공**이 필요
31+
32+
> MarineLeisure는 활동별 맞춤형 지수, 위치 기반 추천, 즐겨찾기, 모임 개설, 위험 생물 알림 등을 통해 보다 **개인화된 레저 서비스**를 제공합니다.
33+
34+
---
35+
36+
## 🎯 주요 기능
37+
38+
| 기능 | 설명 |
39+
|------|------|
40+
| 📍 위치 기반 추천 | 현재 위치 기반 가까운 최적의 레저 장소 추천 |
41+
| 🌊 활동별 정보 제공 | 낚시, 해루질, 다이빙, 서핑에 맞춘 기상 및 해양 데이터 제공 |
42+
| 🐟 해양 위험 생물 알림 | 국립수산과학원 데이터 기반 위험 생물 출몰 경고 |
43+
| ⭐ 즐겨찾기 & 알림 | 자주 가는 포인트를 등록하고 조건 만족 시 알림 전송 |
44+
| 👥 모임 생성 | 레저 포인트 기반 모임 개설 및 참여 (선착순 모집) |
45+
46+
---
47+
48+
## 🛠️ Troubleshooting (문제 해결 사례)
49+
50+
### 🔸 1. 위치 기반 지점 추천 성능 병목
51+
- **문제**: 사용자의 현재 위치로 주변 지점을 추천할 때, 비회원 포함 전 사용자 요청으로 트래픽 집중. DB 조회가 복잡해 병목 발생.
52+
- **해결 방법**:
53+
- 행정구역 단위로 프리셋 지점을 미리 정의 및 캐싱
54+
- 사용자는 좌표만 보내고, 서버는 해당 위치에 맞는 사전 정의 지점 목록을 즉시 반환
55+
-**효과**: 실시간 DB 조회 횟수 감소, 성능 안정성 확보
56+
57+
### 🔸 2. 카카오 API 사용 중 429 Too Many Requests 발생
58+
- **문제**: 역지오코딩 요청이 많아져 카카오 API의 호출 한도를 초과 → 요청 실패율 증가
59+
- **해결 방법**:
60+
- Resilience4j 서킷브레이커 적용
61+
- 일정 실패율 이상일 때 외부 API 호출 차단 + fallback 응답 처리
62+
-**효과**: API 안정성 향상, 시스템 다운 위험 방지
63+
64+
### 🔸 3. 외부 API 의존 → 자체 역지오코딩 시스템 구축
65+
- **문제**: Kakao Maps API 의존으로 429 에러 지속 발생, 트래픽 증가 시 불안정
66+
- **해결 방법**:
67+
- 공공 OpenAPI에서 제공하는 시/도 경계 SHP 파일 확보
68+
- GeoTools 라이브러리를 사용해 좌표 → 행정구역 자체 변환 시스템 구현
69+
-**효과**: 외부 API 의존 제거, 트래픽 급증 시에도 안정적 응답 가능
70+
71+
### 🔸 4. 위험생물 PDF → JSON 자동화 오류
72+
- **문제**: 국립수산과학원 PDF 양식이 유동적이라 기존 좌표 기반 파싱 방식 실패
73+
- **해결 방법**:
74+
- OpenAI를 활용해 PDF 내 텍스트 패턴 분석 → JSON으로 직접 변환
75+
- 불규칙한 표에서도 문맥 기반으로 정보 추출 가능
76+
-**효과**: 자동화 정확도 향상, 비용/속도 최적화 (1,000토큰 ≒ 0.0002달러)
77+
78+
### 🔸 5. Native Query의 과도한 조인으로 인한 성능 저하
79+
- **문제**: 복잡한 LEFT JOIN으로 인해 불필요한 중복 로우 발생, 결과셋 비대 → 응답 시간 지연
80+
- **해결 방법**:
81+
- 네이티브 SQL 단순화 및 조회 최적화
82+
- 필요 데이터만 분리 조회하고 애플리케이션 단에서 가공
83+
-**효과**: p95 응답 시간 개선 (7초 → 1.79초 → 20ms까지)
84+
85+
### 🔸 6. Hikari 커넥션 풀 과부하 문제
86+
- **문제**: 고트래픽 환경에서 커넥션 풀 병목으로 인해 처리량 제한
87+
- **해결 방법**:
88+
- `maximumPoolSize`를 10 → 20 → 30 → 50으로 단계적 조정 후 최적값 도출
89+
- 최종 권장 설정: **maximumPoolSize = 30**
90+
-**효과**: 커넥션 안정화, 응답 시간 p95 ≈ 15ms
91+
92+
### 🔸 7. OAuth2 로그인 보안 취약점
93+
- **문제**: state/code 탈취 공격에 취약 가능성
94+
- **해결 방법**:
95+
- **PKCE(Proof Key for Code Exchange)** 적용
96+
- code_verifier를 클라이언트에 저장, 탈취 시에도 인증 불가
97+
-**효과**: OAuth 보안 강화, 안전한 로그인 플로우 확보
98+
99+
---
100+
101+
## 🛠 기술 스택
102+
103+
| 구분 | 기술 |
104+
|------|------|
105+
| **Frontend** | React, Next.js, TailwindCSS |
106+
| **Backend** | Spring Boot, JWT, REST API |
107+
| **DB** | MySQL, H2 (테스트) |
108+
| **Infra** | AWS EC2, Docker, GitHub Actions (CI/CD) |
109+
| **API** | 바다누리 OpenAPI, Open-Meteo, Kakao API, 국립수산과학원 |
110+
| **기타** | Redis , Geo tools, Apache PDFBox (보고서), GitHub |
111+
112+
---
113+
114+
## 🧭 사용 흐름 예시
115+
116+
### 🎣 낚시 유저 A
117+
- 현재 위치 기준 **낚시 포인트 추천**
118+
- → 추천 포인트 3곳 + 해양 정보 제공
119+
120+
### 🤿 다이버 B
121+
- 특정 반경 내 **다이빙 장소 조회**
122+
- → 추천 포인트 3곳 + 해양 정보 제공
123+
124+
---
125+
126+
## 🔗 API 목록
127+
128+
| 항목 | 출처 | 설명 |
129+
|------|------|------|
130+
| 기상/해양 정보 | [Open-Meteo Marine API](https://open-meteo.com/) | 수온, 조류, 파도, 바람 등 |
131+
| 해파리 속보 | [국립수산과학원](https://www.nifs.go.kr/) | 해양 위험 생물 정보 |
132+
| 위치 서비스 | Kakao Map API | 위경도 ↔ 행정구역 변환 |
133+
| 주소정보 | Kakao Geocoding | 위치 기반 주소 추정 |
134+
| 로그인/OAuth | Kakao Oauth 2.0 | 사용자 로그인 연동 |
135+
136+
---
137+
138+
## 📸 개발 결과물
139+
140+
- ✅ Postman 테스트 완료 (모든 API 정상 응답)
141+
- ✅ ERD 및 스키마 설계 완료
142+
- ✅ GitHub Actions 통한 Docker 빌드 및 배포 자동화
143+
- ✅ 이메일 알림 연동 완료
144+
- ✅ 위치 기반 레저 포인트 추천 기능 정상 작동
145+
146+
---
147+
148+
## 📅 일정 (WBS 요약)
149+
150+
| 주차 | 주요 내용 |
151+
|------|----------|
152+
| 1주차 | 기획/요구사항 도출, 외부 API 분석, 공통 코드 작성 |
153+
| 2주차 | 백엔드 API 개발 및 DB 설계 |
154+
| 3주차 | 프론트-백 통합 및 리팩토링, 기능 추가 |
155+
| 4주차 | 배포 및 발표 자료 준비 |
156+
157+
📎 전체 일정 보기: [WBS Notion 링크](https://www.notion.so/WBS-21e15a01205481a59984c28195e49260?pvs=21)
158+
159+
---
160+
161+
## 🧪 설치 및 실행 방법
162+
163+
1. `.env` 파일 작성
164+
2. Docker 기반 배포
165+
```bash
166+
# 빌드 및 실행
167+
docker-compose up --build

src/main/java/sevenstar/marineleisure/activity/controller/ActivityController.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@
22

33
import static sevenstar.marineleisure.global.exception.enums.ActivityErrorCode.*;
44

5-
import java.math.BigDecimal;
65
import java.util.Map;
76

87
import org.springframework.http.ResponseEntity;
9-
import org.springframework.web.bind.annotation.ModelAttribute;
108
import org.springframework.web.bind.annotation.GetMapping;
9+
import org.springframework.web.bind.annotation.ModelAttribute;
1110
import org.springframework.web.bind.annotation.PathVariable;
1211
import org.springframework.web.bind.annotation.RequestMapping;
1312
import org.springframework.web.bind.annotation.RestController;
1413

1514
import lombok.RequiredArgsConstructor;
16-
import sevenstar.marineleisure.activity.dto.reponse.ActivityDetailResponse;
1715
import sevenstar.marineleisure.activity.dto.reponse.ActivitySummaryResponse;
1816
import sevenstar.marineleisure.activity.dto.reponse.ActivityWeatherResponse;
1917
import sevenstar.marineleisure.activity.dto.request.ActivityDetailRequest;
@@ -22,13 +20,16 @@
2220
import sevenstar.marineleisure.activity.service.ActivityService;
2321
import sevenstar.marineleisure.global.domain.BaseResponse;
2422
import sevenstar.marineleisure.global.enums.ActivityCategory;
23+
import sevenstar.marineleisure.spot.dto.detail.SpotDetailReadResponse;
24+
import sevenstar.marineleisure.spot.service.SpotService;
2525

2626
@RestController
2727
@RequiredArgsConstructor
2828
@RequestMapping("/activities")
2929
public class ActivityController {
3030

3131
private final ActivityService activityService;
32+
private final SpotService spotService;
3233

3334
@GetMapping("/index")
3435
public ResponseEntity<BaseResponse<Map<String, ActivitySummaryResponse>>> getActivityIndex(@ModelAttribute ActivityIndexRequest activityIndexRequest) {
@@ -39,13 +40,20 @@ public ResponseEntity<BaseResponse<Map<String, ActivitySummaryResponse>>> getAct
3940
));
4041
}
4142

43+
// @GetMapping("/{activity}/detail")
44+
// public ResponseEntity<BaseResponse<ActivityDetailResponse>> getActivityDetail(@PathVariable ActivityCategory activity, @ModelAttribute ActivityDetailRequest activityDetailRequest) {
45+
// try {
46+
// return BaseResponse.success(activityService.getActivityDetail(activity, new BigDecimal(activityDetailRequest.latitude()), new BigDecimal(activityDetailRequest.longitude())));
47+
// } catch (RuntimeException e) {
48+
// return BaseResponse.error(INVALID_ACTIVITY);
49+
// }
50+
// }
51+
4252
@GetMapping("/{activity}/detail")
43-
public ResponseEntity<BaseResponse<ActivityDetailResponse>> getActivityDetail(@PathVariable ActivityCategory activity, @ModelAttribute ActivityDetailRequest activityDetailRequest) {
44-
try {
45-
return BaseResponse.success(activityService.getActivityDetail(activity, new BigDecimal(activityDetailRequest.latitude()), new BigDecimal(activityDetailRequest.longitude())));
46-
} catch (RuntimeException e) {
47-
return BaseResponse.error(INVALID_ACTIVITY);
48-
}
53+
ResponseEntity<BaseResponse<SpotDetailReadResponse>> getSpotDetail(@PathVariable ActivityCategory activity, @ModelAttribute ActivityDetailRequest activityDetailRequest) {
54+
Long id = spotService.nearSpotId(activityDetailRequest.latitude(), activityDetailRequest.longitude(),
55+
activity);
56+
return BaseResponse.success(spotService.searchSpotDetail(id));
4957
}
5058

5159
@GetMapping("/weather")

src/main/java/sevenstar/marineleisure/global/enums/TimePeriod.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public static TimePeriod from(String value) {
1818
return timePeriod;
1919
}
2020
}
21-
throw new IllegalArgumentException("Invalid TimePeriod value: " + value);
21+
return TimePeriod.AM;
22+
// throw new IllegalArgumentException("Invalid TimePeriod value: " + value);
2223
}
2324

2425
}

src/main/java/sevenstar/marineleisure/spot/dto/detail/items/SurfingSpotDetail.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,30 @@
1111
public class SurfingSpotDetail implements ActivitySpotDetail {
1212
private final LocalDate forecastDate;
1313
private final TimePeriod timePeriod;
14-
private final float waveHeight;
14+
// private final float waveHeight;
1515
private final int wavePeriod;
16-
private final float windSpeed;
17-
private final float seaTemp;
16+
// private final float windSpeed;
17+
// private final float seaTemp;
1818
private final TotalIndex totalIndex;
1919
private final int uvIndex;
2020

21+
private RangeDetail waveHeight;
22+
private RangeDetail seaTemp;
23+
private RangeDetail windSpeed;
24+
2125
public SurfingSpotDetail(LocalDate forecastDate, TimePeriod timePeriod, float waveHeight, int wavePeriod,
2226
float windSpeed, float seaTemp, TotalIndex totalIndex, int uvIndex) {
2327
this.forecastDate = forecastDate;
2428
this.timePeriod = timePeriod;
25-
this.waveHeight = waveHeight;
29+
// this.waveHeight = waveHeight;
30+
this.waveHeight = new RangeDetail(waveHeight, waveHeight + 0.1f);
2631
this.wavePeriod = wavePeriod;
27-
this.windSpeed = windSpeed;
28-
this.seaTemp = seaTemp;
32+
// this.windSpeed = windSpeed;
33+
this.windSpeed = new RangeDetail(windSpeed, windSpeed + 0.1f);
34+
// this.seaTemp = seaTemp;
35+
this.seaTemp = new RangeDetail(seaTemp, seaTemp + 0.1f);
2936
this.totalIndex = totalIndex;
3037
this.uvIndex = uvIndex;
3138
}
3239

33-
3440
}

src/main/java/sevenstar/marineleisure/spot/service/SpotService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ public interface SpotService {
1414
SpotPreviewReadResponse preview(float latitude, float longitude);
1515

1616
void upsertSpotViewStats(Long spotId);
17+
18+
Long nearSpotId(float latitude, float longitude, ActivityCategory category);
1719
}

src/main/java/sevenstar/marineleisure/spot/service/SpotServiceImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.time.LocalDate;
77
import java.util.ArrayList;
88
import java.util.List;
9+
import java.util.Optional;
910

1011
import org.springframework.cache.annotation.Cacheable;
1112
import org.springframework.data.domain.Pageable;
@@ -143,4 +144,12 @@ public void upsertSpotViewStats(Long spotId) {
143144
spotViewStatsRepository.upsertViewStats(spotId, LocalDate.now());
144145
}
145146

147+
@Override
148+
public Long nearSpotId(float latitude, float longitude, ActivityCategory category) {
149+
return outdoorSpotRepository.findNearSpot(latitude, longitude, category.name())
150+
.map(OutdoorSpot::getId)
151+
.orElse(0L);
152+
}
153+
154+
146155
}

0 commit comments

Comments
 (0)