diff --git a/README.md b/README.md
index 9bad4ae0..440264ab 100644
--- a/README.md
+++ b/README.md
@@ -251,7 +251,7 @@ Resolves: #12
- 기록/리포트
+ 기록/리포트/AI피드백
|
diff --git a/src/main/java/com/umc/finly/domain/record/converter/RecordConverter.java b/src/main/java/com/umc/finly/domain/record/converter/RecordConverter.java
index 67de0ebc..ac7d47e3 100644
--- a/src/main/java/com/umc/finly/domain/record/converter/RecordConverter.java
+++ b/src/main/java/com/umc/finly/domain/record/converter/RecordConverter.java
@@ -3,15 +3,25 @@
import com.umc.finly.domain.market.stock.entity.Stock;
import com.umc.finly.domain.record.dto.request.RecordCreateReqDTO;
import com.umc.finly.domain.record.dto.request.RecordUpdateReqDTO;
+import com.umc.finly.domain.record.dto.response.DailyReportResDTO;
+import com.umc.finly.domain.record.dto.response.RecentSearchResDTO;
import com.umc.finly.domain.record.dto.response.RecordCreateResDTO;
import com.umc.finly.domain.record.dto.response.RecordDetailResDTO;
+import com.umc.finly.domain.record.dto.response.RecordSearchResDTO;
import com.umc.finly.domain.record.dto.response.RecordUpdateResDTO;
+import com.umc.finly.domain.record.dto.response.TodayRecordResDTO;
import com.umc.finly.domain.record.entity.RecordEntry;
import com.umc.finly.domain.record.entity.RecordFeedback;
+import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
@Component
@RequiredArgsConstructor
public class RecordConverter {
@@ -51,16 +61,177 @@ public void applyUpdate(RecordEntry entry, RecordUpdateReqDTO req, Stock stockOr
// 생성 응답 DTO로 변환
public RecordCreateResDTO toCreateRes(RecordEntry entry, Stock stock, RecordFeedback feedback) {
- return RecordCreateResDTO.from(entry, stock, feedback);
+ RecordCreateResDTO.FeedbackInfo feedbackInfo = null;
+ if (feedback != null) {
+ feedbackInfo = RecordCreateResDTO.FeedbackInfo.builder()
+ .feedbackId(feedback.getId())
+ .status(feedback.getStatus().name())
+ .build();
+ }
+
+ return RecordCreateResDTO.builder()
+ .recordId(entry.getId())
+ .recordDate(entry.getRecordDate())
+ .recordedAt(entry.getCreatedAt())
+ .session(entry.getSession())
+ .tradeAction(entry.getTradeAction())
+ .symbol(stock.getSymbol())
+ .emotionCode(entry.getEmotionCode())
+ .emotionIntensity(entry.getEmotionIntensity())
+ .memo(entry.getMemo())
+ .feedback(feedbackInfo)
+ .build();
}
// 상세 응답 DTO로 변환
public RecordDetailResDTO toDetailRes(RecordEntry entry, Stock stock) {
- return RecordDetailResDTO.from(entry, stock);
+ return RecordDetailResDTO.builder()
+ .recordId(entry.getId())
+ .recordDate(entry.getRecordDate())
+ .recordedAt(entry.getCreatedAt())
+ .session(entry.getSession())
+ .tradeAction(entry.getTradeAction())
+ .symbol(stock.getSymbol())
+ .unitPrice(entry.getUnitPrice())
+ .quantity(entry.getQuantity())
+ .emotionCode(entry.getEmotionCode())
+ .emotionIntensity(entry.getEmotionIntensity())
+ .memo(entry.getMemo())
+ .build();
}
// 수정 응답 DTO로 변환
public RecordUpdateResDTO toUpdateRes(RecordEntry entry, Stock stock) {
- return RecordUpdateResDTO.from(entry, stock);
+ return RecordUpdateResDTO.builder()
+ .recordId(entry.getId())
+ .recordDate(entry.getRecordDate())
+ .updatedAt(entry.getUpdatedAt())
+ .session(entry.getSession())
+ .tradeAction(entry.getTradeAction())
+ .symbol(stock.getSymbol())
+ .unitPrice(entry.getUnitPrice())
+ .quantity(entry.getQuantity())
+ .emotionCode(entry.getEmotionCode())
+ .emotionIntensity(entry.getEmotionIntensity())
+ .memo(entry.getMemo())
+ .build();
+ }
+
+ // 일일 리포트 응답 DTO로 변환
+ public DailyReportResDTO toDailyReportRes(RecordEntry entry, Stock stock, String content) {
+ return DailyReportResDTO.builder()
+ .recordId(entry.getId())
+ .recordDate(entry.getRecordDate())
+ .recordedAt(entry.getCreatedAt())
+ .session(entry.getSession())
+ .tradeAction(entry.getTradeAction())
+ .unitPrice(entry.getUnitPrice())
+ .quantity(entry.getQuantity())
+ .emotionCode(entry.getEmotionCode())
+ .name(stock.getName())
+ .content(content)
+ .build();
+ }
+
+ // 오늘 기록 응답 DTO로 변환
+ public TodayRecordResDTO toTodayRecordRes(
+ LocalDate date,
+ List entries,
+ Map stockMap
+ ) {
+ // 프리즘 피드백 타이틀 생성
+ String title = generatePrismTitle(entries);
+ TodayRecordResDTO.PrismFeedback prismFeedback = TodayRecordResDTO.PrismFeedback.builder()
+ .title(title)
+ .generatedAt(LocalDateTime.now())
+ .build();
+
+ // 타임라인 엔트리 변환
+ List timelineSummary = entries.stream()
+ .map(entry -> toTimelineEntry(entry, stockMap.get(entry.getStockId())))
+ .toList();
+
+ return TodayRecordResDTO.builder()
+ .date(date)
+ .prismFeedback(prismFeedback)
+ .timelineSummary(timelineSummary)
+ .hasRecords(!entries.isEmpty())
+ .recordCount(entries.size())
+ .build();
+ }
+
+ // 타임라인 엔트리 변환
+ public TodayRecordResDTO.TimelineEntry toTimelineEntry(RecordEntry entry, Stock stock) {
+ String symbol = stock != null ? stock.getSymbol() : "";
+ return TodayRecordResDTO.TimelineEntry.builder()
+ .recordId(entry.getId())
+ .recordDate(entry.getRecordDate())
+ .recordedAt(entry.getCreatedAt())
+ .session(entry.getSession())
+ .tradeAction(entry.getTradeAction())
+ .symbol(symbol)
+ .unitPrice(entry.getUnitPrice())
+ .quantity(entry.getQuantity())
+ .emotionCode(entry.getEmotionCode())
+ .emotionIntensity(entry.getEmotionIntensity())
+ .memo(entry.getMemo())
+ .build();
+ }
+
+ // 프리즘 타이틀 생성 (오늘 기록들의 감정 흐름 요약)
+ public String generatePrismTitle(List entries) {
+ if (entries == null || entries.isEmpty()) {
+ return "괜찮아요. 기록이 없는 날도 있을 수 있죠.";
+ }
+ if (entries.size() == 1) {
+ EmotionCode emotion = entries.get(0).getEmotionCode();
+ if (emotion == null) {
+ return "오늘 하루도 기록을 남겼네요!";
+ }
+ return "{{" + emotion.getLabel() + "}}한 하루네요!";
+ }
+ EmotionCode first = entries.get(0).getEmotionCode();
+ EmotionCode last = entries.get(entries.size() - 1).getEmotionCode();
+ if (first == null || last == null) {
+ return "오늘도 열심히 기록했네요!";
+ }
+ return "{{" + first.getLabel() + "}}하게 시작해 {{" + last.getLabel() + "}}" + last.getParticle() + " 마무리한 날이네요.";
+ }
+
+ // 검색 응답 DTO로 변환
+ public RecordSearchResDTO toSearchRes(List entries, Map stockMap) {
+ List searchEntries = entries.stream()
+ .map(entry -> toSearchEntry(entry, stockMap.get(entry.getStockId())))
+ .toList();
+
+ return RecordSearchResDTO.builder()
+ .records(searchEntries)
+ .totalCount(searchEntries.size())
+ .build();
+ }
+
+ // 검색 엔트리 변환
+ public RecordSearchResDTO.SearchEntry toSearchEntry(RecordEntry entry, Stock stock) {
+ String symbol = stock != null ? stock.getSymbol() : "";
+ return RecordSearchResDTO.SearchEntry.builder()
+ .recordId(entry.getId())
+ .recordDate(entry.getRecordDate())
+ .recordedAt(entry.getCreatedAt())
+ .session(entry.getSession())
+ .tradeAction(entry.getTradeAction())
+ .symbol(symbol)
+ .unitPrice(entry.getUnitPrice())
+ .quantity(entry.getQuantity())
+ .emotionCode(entry.getEmotionCode())
+ .emotionIntensity(entry.getEmotionIntensity())
+ .memo(entry.getMemo())
+ .build();
+ }
+
+ // 최근 검색어 응답 DTO로 변환
+ public RecentSearchResDTO toRecentSearchRes(List keywords) {
+ return RecentSearchResDTO.builder()
+ .recentKeywords(keywords)
+ .build();
}
}
diff --git a/src/main/java/com/umc/finly/domain/record/converter/RecordFeedbackConverter.java b/src/main/java/com/umc/finly/domain/record/converter/RecordFeedbackConverter.java
index cdcb82ea..05065d96 100644
--- a/src/main/java/com/umc/finly/domain/record/converter/RecordFeedbackConverter.java
+++ b/src/main/java/com/umc/finly/domain/record/converter/RecordFeedbackConverter.java
@@ -10,6 +10,14 @@ public class RecordFeedbackConverter {
// RecordFeedback 엔티티를 응답 DTO로 변환
public RecordFeedbackResDTO toResDTO(RecordFeedback feedback) {
- return RecordFeedbackResDTO.from(feedback);
+ return RecordFeedbackResDTO.builder()
+ .feedbackId(feedback.getId())
+ .recordEntryId(feedback.getRecordEntryId())
+ .status(feedback.getStatus())
+ .content(feedback.getContent())
+ .suggestion(feedback.getSuggestion())
+ .createdAt(feedback.getCreatedAt())
+ .updatedAt(feedback.getUpdatedAt())
+ .build();
}
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/DailyReportResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/DailyReportResDTO.java
index 848d10b9..042f6afb 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/DailyReportResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/DailyReportResDTO.java
@@ -1,7 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.market.stock.entity.Stock;
-import com.umc.finly.domain.record.entity.RecordEntry;
import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import com.umc.finly.domain.record.enums.TradeAction;
@@ -28,20 +26,4 @@ public class DailyReportResDTO {
private EmotionCode emotionCode; // 감정 코드
private String name; // 종목명 (symbol 아닌 name)
private String content; // AI 피드백 내용
-
- // Entity → DTO 변환
- public static DailyReportResDTO from(RecordEntry entry, Stock stock, String content) {
- return DailyReportResDTO.builder()
- .recordId(entry.getId())
- .recordDate(entry.getRecordDate())
- .recordedAt(entry.getCreatedAt())
- .session(entry.getSession())
- .tradeAction(entry.getTradeAction())
- .unitPrice(entry.getUnitPrice())
- .quantity(entry.getQuantity())
- .emotionCode(entry.getEmotionCode())
- .name(stock.getName())
- .content(content)
- .build();
- }
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/RecentSearchResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/RecentSearchResDTO.java
index 389b382a..7e495a18 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/RecentSearchResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/RecentSearchResDTO.java
@@ -12,11 +12,4 @@
public class RecentSearchResDTO {
private List recentKeywords; // 최근 검색 키워드 리스트 (최신순)
-
- // 키워드 리스트 → DTO 변환
- public static RecentSearchResDTO from(List keywords) {
- return RecentSearchResDTO.builder()
- .recentKeywords(keywords)
- .build();
- }
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/RecordCreateResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/RecordCreateResDTO.java
index b27718c1..600a45cd 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/RecordCreateResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/RecordCreateResDTO.java
@@ -1,8 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.market.stock.entity.Stock;
-import com.umc.finly.domain.record.entity.RecordEntry;
-import com.umc.finly.domain.record.entity.RecordFeedback;
import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import com.umc.finly.domain.record.enums.TradeAction;
@@ -36,28 +33,4 @@ public static class FeedbackInfo {
private Long feedbackId; // 피드백 ID
private String status; // 피드백 상태 (PENDING, GENERATING, COMPLETED, FAILED)
}
-
- // Entity → DTO 변환 (팩토리 메서드)
- public static RecordCreateResDTO from(RecordEntry entry, Stock stock, RecordFeedback feedback) {
- FeedbackInfo feedbackInfo = null;
- if (feedback != null) {
- feedbackInfo = FeedbackInfo.builder()
- .feedbackId(feedback.getId())
- .status(feedback.getStatus().name())
- .build();
- }
-
- return RecordCreateResDTO.builder()
- .recordId(entry.getId())
- .recordDate(entry.getRecordDate())
- .recordedAt(entry.getCreatedAt())
- .session(entry.getSession())
- .tradeAction(entry.getTradeAction())
- .symbol(stock.getSymbol())
- .emotionCode(entry.getEmotionCode())
- .emotionIntensity(entry.getEmotionIntensity())
- .memo(entry.getMemo())
- .feedback(feedbackInfo)
- .build();
- }
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/RecordDetailResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/RecordDetailResDTO.java
index 9fc71dbb..f13216b6 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/RecordDetailResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/RecordDetailResDTO.java
@@ -1,7 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.market.stock.entity.Stock;
-import com.umc.finly.domain.record.entity.RecordEntry;
import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import com.umc.finly.domain.record.enums.TradeAction;
@@ -29,21 +27,4 @@ public class RecordDetailResDTO {
private EmotionCode emotionCode; // 감정 코드
private Integer emotionIntensity; // 감정 강도
private String memo; // 메모
-
- // Entity → DTO 변환
- public static RecordDetailResDTO from(RecordEntry entry, Stock stock) {
- return RecordDetailResDTO.builder()
- .recordId(entry.getId())
- .recordDate(entry.getRecordDate())
- .recordedAt(entry.getCreatedAt())
- .session(entry.getSession())
- .tradeAction(entry.getTradeAction())
- .symbol(stock.getSymbol())
- .unitPrice(entry.getUnitPrice())
- .quantity(entry.getQuantity())
- .emotionCode(entry.getEmotionCode())
- .emotionIntensity(entry.getEmotionIntensity())
- .memo(entry.getMemo())
- .build();
- }
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/RecordFeedbackResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/RecordFeedbackResDTO.java
index 41f15997..3282b038 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/RecordFeedbackResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/RecordFeedbackResDTO.java
@@ -1,6 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.record.entity.RecordFeedback;
import com.umc.finly.domain.record.enums.FeedbackStatus;
import lombok.Builder;
import lombok.Getter;
@@ -20,17 +19,4 @@ public class RecordFeedbackResDTO {
private String suggestion; // AI 제안 (투자 조언)
private LocalDateTime createdAt; // 생성 시각
private LocalDateTime updatedAt; // 수정 시각 (상태 변경 시 갱신)
-
- // Entity → DTO 변환
- public static RecordFeedbackResDTO from(RecordFeedback feedback) {
- return RecordFeedbackResDTO.builder()
- .feedbackId(feedback.getId())
- .recordEntryId(feedback.getRecordEntryId())
- .status(feedback.getStatus())
- .content(feedback.getContent())
- .suggestion(feedback.getSuggestion())
- .createdAt(feedback.getCreatedAt())
- .updatedAt(feedback.getUpdatedAt())
- .build();
- }
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/RecordSearchResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/RecordSearchResDTO.java
index 65df16b2..9ba22063 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/RecordSearchResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/RecordSearchResDTO.java
@@ -1,6 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.record.entity.RecordEntry;
import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import com.umc.finly.domain.record.enums.TradeAction;
@@ -36,22 +35,5 @@ public static class SearchEntry {
private EmotionCode emotionCode; // 감정 코드
private Integer emotionIntensity; // 감정 강도
private String memo; // 메모
-
- // Entity → DTO 변환
- public static SearchEntry from(RecordEntry entry, String symbol) {
- return SearchEntry.builder()
- .recordId(entry.getId())
- .recordDate(entry.getRecordDate())
- .recordedAt(entry.getCreatedAt())
- .session(entry.getSession())
- .tradeAction(entry.getTradeAction())
- .symbol(symbol)
- .unitPrice(entry.getUnitPrice())
- .quantity(entry.getQuantity())
- .emotionCode(entry.getEmotionCode())
- .emotionIntensity(entry.getEmotionIntensity())
- .memo(entry.getMemo())
- .build();
- }
}
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/RecordUpdateResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/RecordUpdateResDTO.java
index f58b6cb0..748c1c96 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/RecordUpdateResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/RecordUpdateResDTO.java
@@ -1,7 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.market.stock.entity.Stock;
-import com.umc.finly.domain.record.entity.RecordEntry;
import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import com.umc.finly.domain.record.enums.TradeAction;
@@ -29,21 +27,4 @@ public class RecordUpdateResDTO {
private EmotionCode emotionCode; // 감정 코드
private Integer emotionIntensity; // 감정 강도
private String memo; // 메모
-
- // Entity → DTO 변환
- public static RecordUpdateResDTO from(RecordEntry entry, Stock stock) {
- return RecordUpdateResDTO.builder()
- .recordId(entry.getId())
- .recordDate(entry.getRecordDate())
- .updatedAt(entry.getUpdatedAt())
- .session(entry.getSession())
- .tradeAction(entry.getTradeAction())
- .symbol(stock.getSymbol())
- .unitPrice(entry.getUnitPrice())
- .quantity(entry.getQuantity())
- .emotionCode(entry.getEmotionCode())
- .emotionIntensity(entry.getEmotionIntensity())
- .memo(entry.getMemo())
- .build();
- }
}
diff --git a/src/main/java/com/umc/finly/domain/record/dto/response/TodayRecordResDTO.java b/src/main/java/com/umc/finly/domain/record/dto/response/TodayRecordResDTO.java
index 37232dcc..60fe4fcf 100644
--- a/src/main/java/com/umc/finly/domain/record/dto/response/TodayRecordResDTO.java
+++ b/src/main/java/com/umc/finly/domain/record/dto/response/TodayRecordResDTO.java
@@ -1,6 +1,5 @@
package com.umc.finly.domain.record.dto.response;
-import com.umc.finly.domain.record.entity.RecordEntry;
import com.umc.finly.domain.record.enums.EmotionCode;
import com.umc.finly.domain.record.enums.Session;
import com.umc.finly.domain.record.enums.TradeAction;
@@ -47,46 +46,5 @@ public static class TimelineEntry {
private EmotionCode emotionCode; // 감정 코드
private Integer emotionIntensity; // 감정 강도
private String memo; // 메모
-
- // Entity → DTO 변환
- public static TimelineEntry from(RecordEntry entry, String symbol) {
- return TimelineEntry.builder()
- .recordId(entry.getId())
- .recordDate(entry.getRecordDate())
- .recordedAt(entry.getCreatedAt())
- .session(entry.getSession())
- .tradeAction(entry.getTradeAction())
- .symbol(symbol)
- .unitPrice(entry.getUnitPrice())
- .quantity(entry.getQuantity())
- .emotionCode(entry.getEmotionCode())
- .emotionIntensity(entry.getEmotionIntensity())
- .memo(entry.getMemo())
- .build();
- }
- }
-
- // 프리즘 타이틀 생성 (오늘 기록들의 감정 흐름 요약)
- // 기록 0개: 위로 메시지
- // 기록 1개: 해당 감정 강조
- // 기록 2개+: 첫 감정 → 마지막 감정 흐름 표현
- public static String generatePrismTitle(List entries) {
- if (entries == null || entries.isEmpty()) {
- return "괜찮아요. 기록이 없는 날도 있을 수 있죠.";
- }
- if (entries.size() == 1) {
- EmotionCode emotion = entries.get(0).getEmotionCode();
- if (emotion == null) { // null 체크
- return "오늘 하루도 기록을 남겼네요!";
- }
- return "{{" + emotion.getLabel() + "}}한 하루네요!";
- }
- EmotionCode first = entries.get(0).getEmotionCode();
- EmotionCode last = entries.get(entries.size() - 1).getEmotionCode();
- if (first == null || last == null) { // null 체크
- return "오늘도 열심히 기록했네요!";
- }
- // {{감정}}으로/로 조사 처리 (particle 사용)
- return "{{" + first.getLabel() + "}}하게 시작해 {{" + last.getLabel() + "}}" + last.getParticle() + " 마무리한 날이네요.";
}
}
diff --git a/src/main/java/com/umc/finly/domain/record/service/RecordServiceImpl.java b/src/main/java/com/umc/finly/domain/record/service/RecordServiceImpl.java
index b1a36d0b..b22896fc 100644
--- a/src/main/java/com/umc/finly/domain/record/service/RecordServiceImpl.java
+++ b/src/main/java/com/umc/finly/domain/record/service/RecordServiceImpl.java
@@ -33,7 +33,6 @@
import java.math.BigDecimal;
import java.time.LocalDate;
-import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
@@ -193,7 +192,7 @@ public DailyReportResDTO getDailyReport(Long memberId, Long recordId) {
}
}
- return DailyReportResDTO.from(entry, stock, content);
+ return recordConverter.toDailyReportRes(entry, stock, content);
}
@Override
@@ -202,14 +201,7 @@ public TodayRecordResDTO getTodayRecords(Long memberId, LocalDate date) {
List entries = recordEntryRepository
.findByMemberIdAndRecordDateOrderByCreatedAtAsc(memberId, date);
- // 2. 프리즘 피드백 타이틀 자동 생성 (감정 기반 문구)
- String title = TodayRecordResDTO.generatePrismTitle(entries);
- TodayRecordResDTO.PrismFeedback prismFeedback = TodayRecordResDTO.PrismFeedback.builder()
- .title(title)
- .generatedAt(LocalDateTime.now())
- .build();
-
- // 3. N+1 방지: 기록에 포함된 stockId 일괄 조회
+ // 2. N+1 방지: 기록에 포함된 stockId 일괄 조회
List stockIds = entries.stream()
.map(RecordEntry::getStockId)
.distinct()
@@ -217,22 +209,8 @@ public TodayRecordResDTO getTodayRecords(Long memberId, LocalDate date) {
Map stockMap = stockRepository.findAllById(stockIds).stream()
.collect(Collectors.toMap(Stock::getId, Function.identity()));
- // 4. 타임라인 엔트리 변환
- List timelineSummary = entries.stream()
- .map(entry -> {
- Stock stock = stockMap.get(entry.getStockId());
- String symbol = stock != null ? stock.getSymbol() : "";
- return TodayRecordResDTO.TimelineEntry.from(entry, symbol);
- })
- .toList();
-
- return TodayRecordResDTO.builder()
- .date(date)
- .prismFeedback(prismFeedback)
- .timelineSummary(timelineSummary)
- .hasRecords(!entries.isEmpty())
- .recordCount(entries.size())
- .build();
+ // 3. 응답 DTO 변환 (converter에 위임)
+ return recordConverter.toTodayRecordRes(date, entries, stockMap);
}
@Override
@@ -272,19 +250,8 @@ public RecordSearchResDTO searchRecords(Long memberId, String keyword, EmotionCo
Map stockMap = stockRepository.findAllById(resultStockIds).stream()
.collect(Collectors.toMap(Stock::getId, Function.identity()));
- // 6. 응답 DTO 생성
- List searchEntries = entries.stream()
- .map(entry -> {
- Stock stock = stockMap.get(entry.getStockId());
- String symbol = stock != null ? stock.getSymbol() : "";
- return RecordSearchResDTO.SearchEntry.from(entry, symbol);
- })
- .toList();
-
- return RecordSearchResDTO.builder()
- .records(searchEntries)
- .totalCount(searchEntries.size())
- .build();
+ // 6. 응답 DTO 변환 (converter에 위임)
+ return recordConverter.toSearchRes(entries, stockMap);
}
@Override
@@ -292,7 +259,7 @@ public RecentSearchResDTO getRecentSearchKeywords(Long memberId) {
// 최근 검색 키워드 조회 (최신순, 상위 N개)
List recentKeywords = searchHistoryRepository
.findRecentKeywordsByMemberId(memberId, PageRequest.of(0, RECENT_SEARCH_LIMIT));
- return RecentSearchResDTO.from(recentKeywords);
+ return recordConverter.toRecentSearchRes(recentKeywords);
}
@Override
|