Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
49b41e2
git initialize
HwuanPage Jun 30, 2025
537c984
feature/swagger-03-gunwoong (#5)
gunwoong1630 Jul 4, 2025
94cd99e
feature/base domain 04 gunwoong (#6)
gunwoong1630 Jul 4, 2025
a0ada69
feature/OpenAPI Test/02-HwuanPage
HwuanPage Jul 4, 2025
7694e75
feature/EntityInit-13-HwuanPage
HwuanPage Jul 7, 2025
34a65bf
feat: entity, repositor 구현
johnhuh619 Jul 8, 2025
eebd4ac
feat: 예상 dto 구현
johnhuh619 Jul 8, 2025
36fd789
chore: 의존성 추가
johnhuh619 Jul 8, 2025
175200c
feat: 로그인 구현 & 이후 토큰 발급 로직 구현
johnhuh619 Jul 8, 2025
0adafb8
fix: AuthCotnroller 수정
johnhuh619 Jul 8, 2025
b72262b
fix: 클라이언트에서 카카오에서 코드를 받아 서버로 post 하게 수정
johnhuh619 Jul 8, 2025
306d47a
feat: 토큰 검증
johnhuh619 Jul 8, 2025
d6e9a8f
feat: refresh token 블랙리스트 처리 로직 구현
johnhuh619 Jul 8, 2025
2afab70
feat: refresh 토큰 블랙리스트 처리 & 재발급 로직 구현
johnhuh619 Jul 8, 2025
5e29204
feat: SecurityFilterChain 엔드 포인트 허용
johnhuh619 Jul 9, 2025
911358b
feat: refresh 토큰 블랙리스트 검증 로직 구현
johnhuh619 Jul 9, 2025
4e94e82
feat: redis에서 refreshToken 블랙리스트 검증
johnhuh619 Jul 9, 2025
a8c95cb
refactor: controller에 강하게 결합 되어 있던 로직들 분리
johnhuh619 Jul 9, 2025
36efc22
test: member 관련 테스트
johnhuh619 Jul 9, 2025
7a5b753
chore: 하드코딩한 중요 값 Intellij IDEA 환경변수로 설정
johnhuh619 Jul 9, 2025
c968016
refactor: state 관리를 위해 세션 추가
johnhuh619 Jul 9, 2025
cb4d897
feat: member 정보 조회하는 서비스 로직 구현
johnhuh619 Jul 10, 2025
3d0c45a
feat: member 정보 조회하는 서비스 로직 구현
johnhuh619 Jul 10, 2025
9c4e3b2
format: naver formatter로 포매팅
johnhuh619 Jul 10, 2025
9a3057b
chore: application-dev
johnhuh619 Jul 10, 2025
07b1b3d
fix: customException 처리
johnhuh619 Jul 10, 2025
df194fb
Feat/meeting interface (#19)
garusitell Jul 7, 2025
2214b68
Feature/FavoritesAndAlertInterface-16-HwuanPage
HwuanPage Jul 7, 2025
d8bdb16
feature/CustomExceptionInit-22-HwuanPage
HwuanPage Jul 7, 2025
8ad8409
Refactor application.yml 환경변수 설정 (#25)
audwls239 Jul 8, 2025
28b9b51
Feature/spot service interface 29 gunwoong (#30)
gunwoong1630 Jul 8, 2025
c81e4ad
Feature/api scheduler 15 gunwoong (#28)
gunwoong1630 Jul 8, 2025
2214a36
feat: spot service (#34)
gunwoong1630 Jul 10, 2025
991bba3
hotfix: duplicated controller method
gunwoong1630 Jul 10, 2025
d0874a6
feature/FavoriteCRUD-33-HwuanPage
HwuanPage Jul 11, 2025
832541e
Feature/spot preview 40 gunwoong (#41)
gunwoong1630 Jul 11, 2025
6e82141
hotfix: jpa metamodel fix
gunwoong1630 Jul 11, 2025
757c6fb
fix: error fix
gunwoong1630 Jul 11, 2025
496de94
fix: 소셜 로그인 재시도 시 닉네임 UNIQUE 제약 위반 오류 발생 (#42)
johnhuh619 Jul 11, 2025
12db47a
hofix: bug fix
gunwoong1630 Jul 11, 2025
e818cdd
Feature/Alert-22-HwuanPage
HwuanPage Jul 14, 2025
9af7855
feat: 즐겨찾기 추가 및 리팩토링 (#49)
gunwoong1630 Jul 14, 2025
2eb0453
feat: 카카오 로그인을 stateless 하게 변경한다 (#51)
johnhuh619 Jul 14, 2025
3121616
Feat/meeting service (#46)
garusitell Jul 14, 2025
9ba172b
Feature/integration init (#54)
HwuanPage Jul 14, 2025
008272a
Feature/activities 17 audwls239 (#56)
audwls239 Jul 14, 2025
b45b2e7
feat : ParticipantError 입니다.
garusitell Jul 14, 2025
d556d53
hotfix: error fix
gunwoong1630 Jul 14, 2025
2cbdc8c
fix : Directory 수정사항입니다. (#57)
garusitell Jul 14, 2025
afd564a
hotfix: error fix
gunwoong1630 Jul 14, 2025
bd2923e
feat: member delete (#58)
johnhuh619 Jul 14, 2025
b101278
fix : ParticipantRepository (#59)
garusitell Jul 14, 2025
944b62f
fix : ParticipantRepository (#60)
garusitell Jul 14, 2025
db23ae1
fix: token (#61)
johnhuh619 Jul 15, 2025
4aa55cc
hotfix/fix-alert&favorites-62-HwuanPage
HwuanPage Jul 15, 2025
1f70995
fix(hotfix/Meeting) : rebase로 인한 코드 누락 수정 (#65)
garusitell Jul 15, 2025
73ae7c2
hotfix: 코드 누락 해결 (#67)
audwls239 Jul 15, 2025
a052e1e
Fix/fix 70 gunwoong (#71)
gunwoong1630 Jul 15, 2025
abaaca0
fix: application-prod.yml에서 쿠키를 쓸지 말지 결정할 수 있게 수정 (#69)
johnhuh619 Jul 15, 2025
62e120b
fix: activities 시큐리티 엔드포인트 허용. redirecturi 수정
johnhuh619 Jul 16, 2025
9e484d5
Chore/docker set andvariable-68-hwuanPage
HwuanPage Jul 16, 2025
f69afe9
refactor: blacklist 엔티티의 jti에 인덱스를 건다. (#74)
johnhuh619 Jul 16, 2025
76b0998
Feat/meeting test 75 (#77)
garusitell Jul 16, 2025
a1b72fe
space prob solve
HwuanPage Jul 16, 2025
a7c6ab8
stack-trace-DEBUG
HwuanPage Jul 16, 2025
ad018cf
hotfix/data.sql deprecate-HwuanPage (#79)
HwuanPage Jul 16, 2025
16c1f7d
Xtest
HwuanPage Jul 16, 2025
68d92ca
test X
HwuanPage Jul 16, 2025
2f35102
workflow fix
HwuanPage Jul 16, 2025
9913db5
add id
HwuanPage Jul 16, 2025
9c0f685
fix docker-compose-image-root
HwuanPage Jul 16, 2025
e2bd799
release/v1-marineleisure
HwuanPage Jul 16, 2025
ac0506e
fix: blacklist 엔티티의 jti에 인덱스를 건다. (#83)
johnhuh619 Jul 17, 2025
cb66460
fix: cors 프론트엔드 배포 도메인 추가 (#84)
johnhuh619 Jul 17, 2025
2d9cf4e
hotfix/method_allowed_patch-HwuanPage (#86)
HwuanPage Jul 17, 2025
8142760
Refactor/exception hwuan page (#87)
HwuanPage Jul 17, 2025
66a9059
Merge branch 'main' into dev
HwuanPage Jul 17, 2025
9842485
Feature/map service refactoring 76 gunwoong (#85)
gunwoong1630 Jul 17, 2025
dceed44
fix: yml 환경변수 추가
gunwoong1630 Jul 17, 2025
fab78ee
fix: detail field name 수정
gunwoong1630 Jul 18, 2025
9a34704
feature: 스케줄링 비동기 구현 (#91)
gunwoong1630 Jul 18, 2025
fd9ccb8
refactor: cacheable (#103)
gunwoong1630 Jul 22, 2025
0745a27
Fix/meeting urland role (#100)
garusitell Jul 23, 2025
964da7a
feat: 회원 탈퇴 시 카카오 연결 끊기도 수행하게 구현한다. (#98)
johnhuh619 Jul 23, 2025
baac63c
feat : Meeting의 커서방식에서 매핑을 하였습니다. (#94)
garusitell Jul 23, 2025
b9226df
feat: 카카오 로그인 과정에서 pkce를 통해 보안 관점에서 개선 (#106)
johnhuh619 Jul 25, 2025
dcccf3a
refactor: open-meteo 서비스 관련 리팩토링 (#95)
gunwoong1630 Jul 26, 2025
6f2e43a
refactor: RichDomain으로 변경 내역입니다. (#105)
garusitell Jul 26, 2025
0fef118
Fix: login redirect (#107)
johnhuh619 Jul 26, 2025
08ee8e8
Refactor/meeting rich domain (#110)
garusitell Jul 27, 2025
9d3112e
Merge branch 'main-0727' into dev-0727
gunwoong1630 Jul 27, 2025
d027700
build: caffenine 적용
gunwoong1630 Jul 27, 2025
4ee46c2
relase (#111) (#112)
gunwoong1630 Jul 27, 2025
37562d3
fix: fallback 상황에서 리다이렉트 uri 찾는 로직 추가 (#113)
johnhuh619 Jul 28, 2025
70db7d4
Merge branch 'main' into dev
gunwoong1630 Jul 28, 2025
9c3b138
release (#114) (#115)
gunwoong1630 Jul 28, 2025
332ff5f
hotfix: jwt access token 만료 시간 수정
johnhuh619 Jul 28, 2025
9b1b8ed
hotfix: 탈퇴 후 바로 재가입 가능하게 태그 변경하는 로직 추가
johnhuh619 Jul 28, 2025
b4a57de
fix: API 명세에 빠진 부분 추가 (#117)
gunwoong1630 Jul 28, 2025
d1bb05d
fix: 사용하지않는 projeciton 삭제
gunwoong1630 Jul 28, 2025
88cd60a
hotfix: modelattribute
gunwoong1630 Jul 28, 2025
2f10ee3
hotfix: Response ErrorCode
audwls239 Jul 28, 2025
13dd032
hotfix: valid
gunwoong1630 Jul 28, 2025
05ccb39
hotfix: valid
gunwoong1630 Jul 28, 2025
5f55075
hotfix: Fix Wrong Logic
audwls239 Jul 28, 2025
9b7b3ea
hotfix(meeting) :: Meeting상세보기 :: Response 응답부분에 currentParticipant를 …
garusitell Jul 28, 2025
bb5a512
hotfix: weather (#122)
gunwoong1630 Jul 28, 2025
d1a3117
Merge branch 'main' into dev
gunwoong1630 Jul 28, 2025
0c4e207
release (#123) (#124)
gunwoong1630 Jul 28, 2025
fa399ec
Hotfix/activity index gunwoong (#125)
gunwoong1630 Jul 29, 2025
3182015
Merge branch 'main' into dev
gunwoong1630 Jul 29, 2025
eedacee
release (#126) (#127)
gunwoong1630 Jul 29, 2025
7b05831
feature: apply circuit breaker
gunwoong1630 Jul 29, 2025
93dbcf9
hotfix: jellyfish (#128)
gunwoong1630 Jul 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ dependencies {
implementation 'org.flywaydb:flyway-mysql'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'

// circuit breaker dependencies
implementation 'io.github.resilience4j:resilience4j-spring-boot3:2.2.0'
}

dependencyManagement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
import sevenstar.marineleisure.global.enums.ActivityCategory;
import sevenstar.marineleisure.global.enums.TimePeriod;
import sevenstar.marineleisure.spot.domain.OutdoorSpot;
import sevenstar.marineleisure.spot.dto.SpotPreviewReadResponse;
import sevenstar.marineleisure.spot.repository.OutdoorSpotRepository;
import sevenstar.marineleisure.spot.service.SpotService;

@Service
@RequiredArgsConstructor
Expand All @@ -42,6 +44,8 @@ public class ActivityService {
private final ScubaRepository scubaRepository;
private final SurfingRepository surfingRepository;

private final SpotService spotService;

@Transactional(readOnly = true)
public Map<String, ActivitySummaryResponse> getActivitySummary(BigDecimal latitude, BigDecimal longitude,
boolean global) {
Expand All @@ -55,90 +59,92 @@ public Map<String, ActivitySummaryResponse> getActivitySummary(BigDecimal latitu
private Map<String, ActivitySummaryResponse> getLocalActivitySummary(BigDecimal latitude, BigDecimal longitude) {
Map<String, ActivitySummaryResponse> responses = new HashMap<>();

Fishing fishingBySpot = null;
Mudflat mudflatBySpot = null;
Surfing surfingBySpot = null;
Scuba scubaBySpot = null;

LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
LocalDateTime endOfDay = startOfDay.plusDays(1);

List<OutdoorSpot> outdoorSpotList = outdoorSpotRepository.findByCoordinates(latitude, longitude, 10);

while (fishingBySpot == null || mudflatBySpot == null || surfingBySpot == null || scubaBySpot == null) {

OutdoorSpot currentSpot;
Long currentSpotId;

try {
currentSpot = outdoorSpotList.removeFirst();
currentSpotId = currentSpot.getId();
} catch (Exception e) {
break;
}

if (fishingBySpot == null) {
Optional<Fishing> fishingResult = fishingRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
currentSpotId, startOfDay, endOfDay);

if (fishingResult.isPresent()) {
fishingBySpot = fishingResult.get();
responses.put("Fishing",
new ActivitySummaryResponse(currentSpot.getName(), fishingResult.get().getTotalIndex()));
}
}

if (mudflatBySpot == null) {
Optional<Mudflat> mudflatResult = mudflatRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
currentSpotId, startOfDay, endOfDay);

if (mudflatResult.isPresent()) {
mudflatBySpot = mudflatResult.get();
responses.put("Mudflat",
new ActivitySummaryResponse(currentSpot.getName(), mudflatResult.get().getTotalIndex()));
}
}

if (surfingBySpot == null) {
Optional<Surfing> surfingResult = surfingRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
currentSpotId, startOfDay, endOfDay);

if (surfingResult.isPresent()) {
surfingBySpot = surfingResult.get();
responses.put("Surfing",
new ActivitySummaryResponse(currentSpot.getName(), surfingResult.get().getTotalIndex()));
}
}

if (scubaBySpot == null) {
Optional<Scuba> scubaResult = scubaRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
currentSpotId, startOfDay, endOfDay);

if (scubaResult.isPresent()) {
scubaBySpot = scubaResult.get();
responses.put("Scuba",
new ActivitySummaryResponse(currentSpot.getName(), scubaResult.get().getTotalIndex()));
}
}
}
SpotPreviewReadResponse preview = spotService.preview(latitude.floatValue(), longitude.floatValue());
responses.put("Fishing",
new ActivitySummaryResponse(preview.fishing().getName(), preview.fishing().getTotalIndex()));
responses.put("Mudflat",new ActivitySummaryResponse(preview.mudflat().getName(), preview.mudflat().getTotalIndex()));
responses.put("Surfing", new ActivitySummaryResponse(preview.surfing().getName(), preview.surfing().getTotalIndex()));
responses.put("Scuba", new ActivitySummaryResponse(preview.scuba().getName(), preview.scuba().getTotalIndex()));

// Fishing fishingBySpot = null;
// Mudflat mudflatBySpot = null;
// Surfing surfingBySpot = null;
// Scuba scubaBySpot = null;
//
// LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
// LocalDateTime endOfDay = startOfDay.plusDays(1);
//
// List<OutdoorSpot> outdoorSpotList = outdoorSpotRepository.findByCoordinates(latitude, longitude, 10);
//
// while (fishingBySpot == null || mudflatBySpot == null || surfingBySpot == null || scubaBySpot == null) {
//
// OutdoorSpot currentSpot;
// Long currentSpotId;
//
// try {
// currentSpot = outdoorSpotList.removeFirst();
// currentSpotId = currentSpot.getId();
// } catch (Exception e) {
// break;
// }
//
// if (fishingBySpot == null) {
// Optional<Fishing> fishingResult = fishingRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
// currentSpotId, startOfDay, endOfDay);
//
// if (fishingResult.isPresent()) {
// fishingBySpot = fishingResult.get();
// responses.put("Fishing",
// new ActivitySummaryResponse(currentSpot.getName(), fishingResult.get().getTotalIndex()));
// }
// }
//
// if (mudflatBySpot == null) {
// Optional<Mudflat> mudflatResult = mudflatRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
// currentSpotId, startOfDay, endOfDay);
//
// if (mudflatResult.isPresent()) {
// mudflatBySpot = mudflatResult.get();
// responses.put("Mudflat",
// new ActivitySummaryResponse(currentSpot.getName(), mudflatResult.get().getTotalIndex()));
// }
// }
//
// if (surfingBySpot == null) {
// Optional<Surfing> surfingResult = surfingRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
// currentSpotId, startOfDay, endOfDay);
//
// if (surfingResult.isPresent()) {
// surfingBySpot = surfingResult.get();
// responses.put("Surfing",
// new ActivitySummaryResponse(currentSpot.getName(), surfingResult.get().getTotalIndex()));
// }
// }
//
// if (scubaBySpot == null) {
// Optional<Scuba> scubaResult = scubaRepository.findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByCreatedAtDesc(
// currentSpotId, startOfDay, endOfDay);
//
// if (scubaResult.isPresent()) {
// scubaBySpot = scubaResult.get();
// responses.put("Scuba",
// new ActivitySummaryResponse(currentSpot.getName(), scubaResult.get().getTotalIndex()));
// }
// }
// }

return responses;
}

private Map<String, ActivitySummaryResponse> getGlobalActivitySummary() {
Map<String, ActivitySummaryResponse> responses = new HashMap<>();

LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
LocalDateTime endOfDay = startOfDay.plusDays(1);
LocalDate now = LocalDate.now();

Optional<Fishing> fishingResult = fishingRepository.findTopByCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByTotalIndexDesc(
startOfDay, endOfDay);
Optional<Mudflat> mudflatResult = mudflatRepository.findTopByCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByTotalIndexDesc(
startOfDay, endOfDay);
Optional<Surfing> surfingResult = surfingRepository.findTopByCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByTotalIndexDesc(
startOfDay, endOfDay);
Optional<Scuba> scubaResult = scubaRepository.findTopByCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByTotalIndexDesc(
startOfDay, endOfDay);
Optional<Fishing> fishingResult = fishingRepository.findBestTotaIndexFishing(now);
Optional<Mudflat> mudflatResult = mudflatRepository.findBestTotaIndexMudflat(now);
Optional<Surfing> surfingResult = surfingRepository.findBestTotaIndexSurfing(now);
Optional<Scuba> scubaResult = scubaRepository.findBestTotaIndexScuba(now);

if (fishingResult.isPresent()) {
Fishing fishing = fishingResult.get();
Expand Down Expand Up @@ -225,4 +231,6 @@ public ActivityWeatherResponse getWeatherBySpot(Float latitude, Float longitude)
fishing.getSeaTempMax().toString()
);
}


}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package sevenstar.marineleisure.alert.controller;

import java.util.List;
import java.util.Map;
import java.util.Set;

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.RestController;

import lombok.RequiredArgsConstructor;
import sevenstar.marineleisure.alert.dto.response.JellyfishResponse;
import sevenstar.marineleisure.alert.dto.response.JellyfishResponseDto;
import sevenstar.marineleisure.alert.dto.vo.JellyfishDetailVO;
import sevenstar.marineleisure.alert.mapper.AlertMapper;
Expand All @@ -26,9 +29,11 @@ public class AlertController {
* @return 해파리 발생 관련 정보
*/
@GetMapping("/jellyfish")
public ResponseEntity<BaseResponse<JellyfishResponseDto>> getJellyfishList() {
public ResponseEntity<BaseResponse<JellyfishResponse>> getJellyfishList() {
List<JellyfishDetailVO> items = jellyfishService.search();
JellyfishResponseDto result = alertMapper.toResponseDto(items);
Map<String, Set<String>> map = jellyfishService.convert(items);

JellyfishResponse result = alertMapper.toResponseDto(items.getFirst().getReportDate(), map);
return BaseResponse.success(result);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package sevenstar.marineleisure.alert.dto.response;

import java.time.LocalDate;
import java.util.Map;
import java.util.Set;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class JellyfishResponse {
private LocalDate reposrtDate;
private Map<String, Set<String>> jellyfish;
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,19 @@
package sevenstar.marineleisure.alert.mapper;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;
import sevenstar.marineleisure.alert.dto.response.JellyfishResponseDto;
import sevenstar.marineleisure.alert.dto.vo.JellyfishDetailVO;
import sevenstar.marineleisure.alert.dto.vo.JellyfishRegionVO;
import sevenstar.marineleisure.alert.dto.vo.JellyfishSpeciesVO;
import sevenstar.marineleisure.global.enums.DensityLevel;
import sevenstar.marineleisure.global.enums.ToxicityLevel;
import sevenstar.marineleisure.alert.dto.response.JellyfishResponse;

@Component
@RequiredArgsConstructor
public class AlertMapper {

public JellyfishResponseDto toResponseDto(List<JellyfishDetailVO> detailList) {
if (detailList.isEmpty()) {
return null;
}
LocalDate reportDate = detailList.get(0).getReportDate();

List<JellyfishRegionVO> regions = detailList.stream()
.map(detail -> new JellyfishRegionVO(
detail.getRegion(),
new JellyfishSpeciesVO(
detail.getSpecies(),
ToxicityLevel.valueOf(detail.getToxicity()).getDescription(),
DensityLevel.valueOf(detail.getDensityType()).getDescription()
)
))
.toList();

return new JellyfishResponseDto(reportDate, regions);
public JellyfishResponse toResponseDto(LocalDate reportDate, Map<String, Set<String>> map) {
return new JellyfishResponse(reportDate, map);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
Expand Down Expand Up @@ -56,7 +61,7 @@ public JellyfishSpecies searchByName(String name) {
/**
* 웹에서 크롤링 해 Pdf를 DB에 적재합니다.
*/
// @Scheduled(cron = "0 0 0 ? * FRI")
@Scheduled(cron = "0 0 0 ? * FRI")
// 금요일 00시에 동작합니다.
@Transactional
public void updateLatestReport() {
Expand Down Expand Up @@ -104,4 +109,15 @@ public void updateLatestReport() {
}
}

public Map<String, Set<String>> convert(List<JellyfishDetailVO> jellyfish) {
Map<String, Set<String>> map = new HashMap<>();
for (JellyfishDetailVO detail : jellyfish) {
if (map.containsKey(detail.getSpecies())) {
map.get(detail.getSpecies()).add(detail.getRegion());
} else {
map.put(detail.getSpecies(), new HashSet<>(List.of(detail.getRegion())));
}
}
return map;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import sevenstar.marineleisure.alert.dto.vo.ParsedJellyfishVO;
Expand All @@ -21,6 +22,7 @@ public class JellyfishExtractor {
private final OpenAiChatModel chatModel;
private final ObjectMapper objectMapper;

@CircuitBreaker(name = "openai-api", fallbackMethod = "fallbackExtractJellyfishData")
public List<ParsedJellyfishVO> extractJellyfishData(String text) {
try {
String instruction = """
Expand Down Expand Up @@ -71,4 +73,9 @@ public List<ParsedJellyfishVO> extractJellyfishData(String text) {
return List.of();
}
}

public List<ParsedJellyfishVO> fallbackExtractJellyfishData(String text, Throwable t) {
log.error("OpenAI API 호출에 실패하여 fallback 메서드가 실행되었습니다. message: {}", t.getMessage());
return List.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ Optional<Fishing> findFirstBySpotIdAndCreatedAtGreaterThanEqualAndCreatedAtLessT
LocalDateTime endDateTime
);

@Query(value = """
SELECT *
FROM fishing_forecast f
WHERE f.forecast_date = :forecastDate
ORDER BY f.total_index DESC
LIMIT 1
""",nativeQuery = true)
Optional<Fishing> findBestTotaIndexFishing(@Param("forecastDate") LocalDate forecastDate);

Optional<Fishing> findTopByCreatedAtGreaterThanEqualAndCreatedAtLessThanOrderByTotalIndexDesc(LocalDateTime start,
LocalDateTime end);

Expand Down
Loading
Loading