Skip to content

Commit 20fd278

Browse files
committed
add feature tier system
1 parent 28a7da5 commit 20fd278

File tree

13 files changed

+363
-65
lines changed

13 files changed

+363
-65
lines changed

src/main/java/grit/stockIt/domain/mission/controller/MissionController.java

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -80,38 +80,6 @@ public ResponseEntity<RewardResponseDto> claimDailyAttendance(
8080
return ResponseEntity.ok(responseDto);
8181
}
8282

83-
/**
84-
* POST /api/missions/view-report
85-
* '종목 리포트 보기' 미션의 진행도를 1 증가시킵니다.
86-
*/
87-
@PostMapping("/view-report")
88-
@ResponseStatus(HttpStatus.OK)
89-
public void trackReportView(
90-
@AuthenticationPrincipal UserDetails userDetails
91-
) {
92-
String email = userDetails.getUsername();
93-
log.info("Request: trackReportView for Email={}", email);
94-
95-
// 서비스 호출
96-
missionService.handleReportView(email);
97-
}
98-
99-
/**
100-
* POST /api/missions/analyze-portfolio
101-
* '포트폴리오 분석' 미션의 진행도를 1 증가시킵니다.
102-
*/
103-
@PostMapping("/analyze-portfolio")
104-
@ResponseStatus(HttpStatus.OK)
105-
public void trackPortfolioAnalysis(
106-
@AuthenticationPrincipal UserDetails userDetails
107-
) {
108-
String email = userDetails.getUsername();
109-
log.info("Request: trackPortfolioAnalysis for Email={}", email);
110-
111-
// 서비스 호출
112-
missionService.handlePortfolioAnalysis(email);
113-
}
114-
11583
/**
11684
* POST /api/missions/bankruptcy
11785
* [신규] 인생 2회차(파산 신청)
@@ -129,4 +97,13 @@ public ResponseEntity<RewardResponseDto> applyForBankruptcy(
12997

13098
return ResponseEntity.ok(new RewardResponseDto(reward));
13199
}
100+
101+
/**
102+
* [신규] 내 티어 및 점수 현황 조회
103+
*/
104+
@GetMapping("/tier")
105+
@Operation(summary = "티어 및 점수 조회", description = "활동 점수와 실력 점수를 합산한 현재 티어 정보를 반환합니다.")
106+
public ResponseEntity<UserTierStatusDto> getMyTierStatus(@AuthenticationPrincipal UserDetails userDetails) {
107+
return ResponseEntity.ok(missionService.getTierInfo(userDetails.getUsername()));
108+
}
132109
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package grit.stockIt.domain.mission.dto;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
6+
@Getter
7+
@Builder
8+
public class UserTierStatusDto {
9+
private String currentTier; // BRONZE, SILVER, GOLD, PLATINUM, LEGEND
10+
private String nextTier; // 다음 티어 (LEGEND면 null 혹은 "MAX")
11+
12+
private int totalScore; // 총점
13+
private int activityScore; // 활동 점수
14+
private int skillScore; // 실력 점수
15+
16+
private int scoreToNextTier; // 다음 티어까지 남은 점수
17+
private double progressPercentage; // 티어 달성 진행도 (%)
18+
}

src/main/java/grit/stockIt/domain/mission/enums/MissionConditionType.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,9 @@ public enum MissionConditionType {
3131
HOLD_FOR_DAYS_AND_SELL_PROFIT, // (905: 존버는 승리한다)
3232
LOGIN_STREAK, // (906, 907, 908: 출석 7/15/30일)
3333
RANKING_TOP_10, // (909: 랭커)
34-
ASSET_UNDER_THRESHOLD // [신규] (911: 인생 2회차 - 잔고 5만원 미만)
34+
ASSET_UNDER_THRESHOLD, // [신규] (911: 인생 2회차 - 잔고 5만원 미만)
35+
36+
ACTIVITY_SCORE, // [신규] 활동 점수 누적용
37+
SKILL_SCORE, // [신규] 실력 점수(수익금) 누적용
38+
REACH_LEGEND // [신규] 레전드 달성 체크용 (Mission 903)
3539
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package grit.stockIt.domain.mission.event;
2+
import lombok.Getter;
3+
import lombok.RequiredArgsConstructor;
4+
/**
5+
* 포트폴리오 분석 완료 이벤트
6+
*/
7+
@Getter
8+
@RequiredArgsConstructor
9+
public class PortfolioAnalyzedEvent {
10+
private final String email; // 미션 수행자
11+
private final Long accountId; // 분석한 계좌
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package grit.stockIt.domain.mission.event;
2+
3+
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
6+
/**
7+
* 종목 분석 완료 이벤트
8+
*/
9+
@Getter
10+
@RequiredArgsConstructor
11+
public class StockAnalyzedEvent {
12+
private final String email; // 미션 수행자
13+
private final String stockCode; // 분석한 종목
14+
}

src/main/java/grit/stockIt/domain/mission/service/MissionEventListener.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package grit.stockIt.domain.mission.service;
22

3+
import grit.stockIt.domain.mission.event.PortfolioAnalyzedEvent;
4+
import grit.stockIt.domain.mission.event.StockAnalyzedEvent;
35
import grit.stockIt.domain.order.event.TradeCompletionEvent;
46
import lombok.RequiredArgsConstructor;
7+
import lombok.extern.slf4j.Slf4j;
58
import org.springframework.context.event.EventListener;
69
import org.springframework.stereotype.Component;
10+
import org.springframework.scheduling.annotation.Async;
711

12+
@Slf4j
813
@Component
914
@RequiredArgsConstructor
1015
public class MissionEventListener {
@@ -19,10 +24,32 @@ public void handleTradeCompletionEvent(TradeCompletionEvent event) { // 2. [수
1924
// 모든 로직을 MissionService에 위임합니다.
2025
missionService.updateMissionProgress(event);
2126
}
27+
/**
28+
* [신규] 종목 분석 완료 이벤트 수신
29+
* @Async를 붙여 WebFlux의 Non-blocking 스레드가 JPA(Blocking) 로직을 기다리지 않게 함
30+
*/
31+
@Async
32+
@EventListener
33+
public void handleStockAnalyzedEvent(StockAnalyzedEvent event) {
34+
log.info("Event Received: Stock Analysis for {}", event.getEmail());
35+
try {
36+
missionService.handleReportView(event.getEmail());
37+
} catch (Exception e) {
38+
log.error("종목 분석 미션 처리 중 오류 발생", e);
39+
}
40+
}
2241

23-
// (향후 출석(LoginEvent) 등 다른 이벤트가 생기면 여기에 리스너 추가)
24-
// @EventListener
25-
// public void handleLoginEvent(LoginEvent event) {
26-
// missionService.updateLoginMission(event.getMemberId());
27-
// }
42+
/**
43+
* [신규] 포트폴리오 분석 완료 이벤트 수신
44+
*/
45+
@Async
46+
@EventListener
47+
public void handlePortfolioAnalyzedEvent(PortfolioAnalyzedEvent event) {
48+
log.info("Event Received: Portfolio Analysis for {}", event.getEmail());
49+
try {
50+
missionService.handlePortfolioAnalysis(event.getEmail());
51+
} catch (Exception e) {
52+
log.error("포트폴리오 분석 미션 처리 중 오류 발생", e);
53+
}
54+
}
2855
}

0 commit comments

Comments
 (0)