Skip to content

Sisc1 20251119 퀀트봇받아오기#120

Merged
Kosw6 merged 7 commits intomainfrom
SISC1-20251119-퀀트봇받아오기
Nov 20, 2025

Hidden character warning

The head ref may contain hidden characters: "SISC1-20251119-\ud000\ud2b8\ubd07\ubc1b\uc544\uc624\uae30"
Merged

Sisc1 20251119 퀀트봇받아오기#120
Kosw6 merged 7 commits intomainfrom
SISC1-20251119-퀀트봇받아오기

Conversation

@daye200
Copy link
Contributor

@daye200 daye200 commented Nov 19, 2025

#119

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • 거래 로그, 보유 자산, AI 리포트 조회 API 추가
  • 보안

    • 특정 엔드포인트의 공개 접근 제한, 인증 요구사항 강화
  • 개선

    • 사용자 포인트 필드 추가
    • 향상된 예외 처리 및 오류 메시지 추가

@coderabbitai
Copy link

coderabbitai bot commented Nov 19, 2025

Walkthrough

보안 설정을 강화하여 여러 엔드포인트의 공개 접근을 제거하고, QuantBot 거래 조회 기능을 위한 새로운 REST 컨트롤러, DTO, JPA 엔티티, 리포지토리 및 서비스를 추가했습니다. 또한 사용자 엔티티에 포인트 필드를 추가하고 새로운 에러 코드를 정의했습니다.

Changes

Cohort / File(s) 변경 요약
보안 설정 강화
backend/src/main/java/org/sejongisc/backend/common/auth/config/SecurityConfig.java
/api/user/id/find, /api/user/password/reset/**, /api/email/**, /swagger-resources/**, /webjars/** 엔드포인트의 공개 접근(permitAll)을 제거하고 인증 필요로 변경
QuantBot API 컨트롤러
backend/src/main/java/org/sejongisc/backend/stock/controller/QuantBotController.java
거래 로그, 보유 자산, XAI 리포트 조회를 위한 3개의 GET 엔드포인트 추가 (/logs, /holdings, /report)
QuantBot API DTO
backend/src/main/java/org/sejongisc/backend/stock/dto/TradeLogDto.java,
backend/src/main/java/org/sejongisc/backend/stock/dto/HoldingDto.java,
backend/src/main/java/org/sejongisc/backend/stock/dto/XaiReportResponse.java
거래 로그, 보유 자산, XAI 리포트 응답 데이터를 위한 3개의 신규 record DTO 정의
거래 관련 JPA 엔티티
backend/src/main/java/org/sejongisc/backend/stock/entity/Execution.java,
backend/src/main/java/org/sejongisc/backend/stock/entity/XaiReport.java
거래 실행 기록과 XAI 리포트 데이터를 저장할 2개의 신규 엔티티, XaiReport와의 다대일 관계 설정
거래 데이터 리포지토리
backend/src/main/java/org/sejongisc/backend/stock/repository/ExecutionRepository.java,
backend/src/main/java/org/sejongisc/backend/stock/repository/XaiReportRepository.java
Execution과 XaiReport 엔티티 조회를 위한 2개의 Spring Data JPA 리포지토리, 거래 로그 및 현재 보유 자산 조회 메서드 포함
QuantBot 비즈니스 로직
backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java
거래 로그, 보유 자산, XAI 리포트 조회 기능을 제공하는 서비스 계층, CustomException 기반 에러 처리
사용자 엔티티 및 서비스 개선
backend/src/main/java/org/sejongisc/backend/user/entity/User.java,
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java
사용자 엔티티에 포인트 필드 추가, 컬럼 제약 조건 설정, 회원가입 시 포인트 초기화
에러 코드 확장
backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java
EMAIL\_CODE\_MISMATCH, EXECUTION\_NOT\_FOUND, XAI\_REPORT\_NOT\_FOUND 에러 코드 추가 및 EMAIL\_INVALID\_EMAIL 메시지 형식 수정

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

추가 검토 필요 사항:

  • SecurityConfig 변경: 보안 정책 변경으로 인한 엔드포인트 접근 제어 검증, 특히 /api/user/id/find와 /api/user/password/reset/** 엔드포인트가 인증 필수로 변경되었는지 확인
  • QuantBotService 에러 처리: ExecutionRepository.findById() 호출 시 Optional 처리 로직 및 CustomException 발생 조건 검증
  • Execution-XaiReport 관계: JPA 다대일 관계 설정 및 lazy loading 동작 확인
  • ExecutionRepository 쿼리: findCurrentHoldings() 메서드의 @Query 구현이 최신 Execution 조회 및 보유 수량 필터링을 올바르게 수행하는지 검증
  • 보안과 API의 상호작용: 새로운 QuantBot 엔드포인트가 보안 설정에서 올바르게 보호되고 있는지 확인

Possibly related PRs

Suggested reviewers

  • discipline24

Poem

🐰 새로운 거래 기록들이 흐르고,
보안의 문은 더 견고해지고,
QuantBot의 손길이 시장을 헤치며,
포인트 카운터 시작 - 0에서 희망으로! ✨
한 발씩 내딛는 피그벳, 앞으로 나아가요!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 '퀀트봇받아오기'(QuantBot 데이터 조회 기능)라는 주요 변경사항을 반영하나, 날짜와 브랜치명이 포함되어 있고 명확하지 못한 표현을 사용하고 있습니다.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SISC1-20251119-퀀트봇받아오기

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@daye200 daye200 linked an issue Nov 19, 2025 that may be closed by this pull request
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (2)

119-122: OAuth 사용자 생성 시 포인트 필드 초기화가 누락되었습니다.

findOrCreateUser 메서드에서 새로운 User를 생성할 때 point(0)이 누락되어 있습니다. User 엔티티의 point 필드는 nullable = false로 설정되어 있어, 명시적으로 초기화하지 않으면 다음과 같은 문제가 발생할 수 있습니다:

  • 데이터베이스 제약 조건 위반 가능성
  • updatePoint() 메서드 호출 시 NPE 발생 위험

다음 diff를 적용하여 OAuth 사용자의 포인트도 초기화하세요:

                 User newUser = User.builder()
                         .name(oauthInfo.getName())
                         .role(Role.TEAM_MEMBER)
+                        .point(0)
                         .build();

339-343: OAuth 사용자 생성 시 포인트 필드 초기화가 누락되었습니다.

upsertOAuthUser 메서드에서도 새로운 User를 생성할 때 point(0) 초기화가 누락되어 있습니다. 이는 findOrCreateUser와 동일한 문제로, nullable = false 제약 조건 위반 및 NPE 위험이 있습니다.

다음 diff를 적용하여 OAuth 사용자의 포인트를 초기화하세요:

                 User newUser = User.builder()
                         .email(email)
                         .name(name)
                         .role(Role.TEAM_MEMBER)
+                        .point(0)
                         .build();
🧹 Nitpick comments (6)
backend/src/main/java/org/sejongisc/backend/stock/dto/XaiReportResponse.java (1)

1-13: 레코드 구조가 적절합니다.

코드가 깔끔하고 Java 레코드 규칙을 잘 따르고 있습니다. 금융 데이터에 BigDecimal을, 날짜에 LocalDate를 사용한 것도 적절한 선택입니다.

선택적 개선 사항:

  • 각 필드의 의미를 명확히 하기 위해 JavaDoc 주석을 추가하는 것을 고려해보세요 (특히 signal 필드가 어떤 값을 가질 수 있는지)
  • 필드의 null 허용 여부를 문서화하면 API 사용자에게 도움이 될 수 있습니다

예시:

/**
 * XAI 리포트 응답 DTO
 * 
 * @param ticker 종목 코드
 * @param signal 매매 신호 (예: "BUY", "SELL", "HOLD")
 * @param price 가격
 * @param date 리포트 날짜
 * @param report XAI 분석 리포트 내용
 */
public record XaiReportResponse(
    String ticker,
    String signal,
    BigDecimal price,
    LocalDate date,
    String report
) {}
backend/src/main/java/org/sejongisc/backend/stock/entity/XaiReport.java (1)

20-30: 컬럼 정의 및 인덱스 추가 권장

엔티티 구조는 적절하나, 다음 개선사항을 고려해주세요:

  1. 컬럼 제약 조건: ticker, signal, date 등 주요 필드에 @Column 어노테이션으로 nullable, length 제약 조건 추가
  2. 인덱스 추가: ticker, date 필드는 조회 쿼리에 자주 사용될 가능성이 높으므로 인덱스 추가 고려
  3. updatedAt 필드: createdAt만 있고 updatedAt이 없는데, 수정 이력 추적이 필요하다면 추가 권장

예시:

 @Entity
 @Getter
 @NoArgsConstructor
 @Builder
 @AllArgsConstructor
 @Table(name = "xai_reports")
 public class XaiReport {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
+  
+  @Column(nullable = false, length = 20)
   private String ticker;
+  
+  @Column(nullable = false, length = 10)
   private String signal;
+  
+  @Column(nullable = false, precision = 19, scale = 4)
   private BigDecimal price;
+  
+  @Column(nullable = false)
   private LocalDate date;

   @Column(columnDefinition = "text")
   private String report;
+  
   private LocalDateTime createdAt;
+  private LocalDateTime updatedAt;

 }
backend/src/main/java/org/sejongisc/backend/stock/entity/Execution.java (1)

20-42: 컬럼 제약 조건 및 인덱스 추가 권장

실행 데이터를 잘 표현하는 포괄적인 엔티티입니다. 다음 개선사항을 고려해주세요:

  1. 컬럼 제약 조건: 주요 필드에 @Column 어노테이션으로 nullable, precision, scale 정의
  2. side 필드 제약: "BUY"/"SELL" 등으로 제한하는 체크 제약 조건 추가
  3. 인덱스: ticker, fillDate는 조회 쿼리에 자주 사용되므로 복합 인덱스 고려

예시:

 @Entity
 @Getter
 @NoArgsConstructor
 @Builder
 @AllArgsConstructor
 @Table(name = "executions")
 public class Execution {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
+  
+  @Column(nullable = false, length = 20)
   private String ticker;
   private LocalDate signalDate;
+  
+  @Column(precision = 19, scale = 4)
   private BigDecimal signalPrice;
   private String signal;
+  
+  @Column(nullable = false)
   private LocalDate fillDate;
+  
+  @Column(nullable = false, precision = 19, scale = 4)
   private BigDecimal fillPrice;
+  
+  @Column(nullable = false)
   private Integer qty;
+  
+  @Column(nullable = false, length = 10)
   private String side; // BUY, SELL
+  
+  @Column(precision = 19, scale = 4)
   private BigDecimal value;
   // ... 나머지 BigDecimal 필드들도 precision, scale 추가
backend/src/main/java/org/sejongisc/backend/stock/repository/XaiReportRepository.java (1)

3-3: 미사용 import 제거

java.util.List import가 사용되지 않습니다.

 package org.sejongisc.backend.stock.repository;

-import java.util.List;
 import org.sejongisc.backend.stock.entity.XaiReport;
 import org.springframework.data.jpa.repository.JpaRepository;
backend/src/main/java/org/sejongisc/backend/stock/controller/QuantBotController.java (1)

15-18: ResponseEntity 사용 권장

모든 엔드포인트가 ResponseEntity를 사용하지 않아 HTTP 상태 코드를 명시적으로 제어할 수 없습니다. 특히 빈 리스트와 에러 상황을 구분하기 어렵습니다.

예시:

 @GetMapping("/logs")
-public List<TradeLogDto> getTradeLogs() {
-  return quantBotService.getTradeLogs();
+public ResponseEntity<List<TradeLogDto>> getTradeLogs() {
+  List<TradeLogDto> logs = quantBotService.getTradeLogs();
+  return ResponseEntity.ok(logs);
 }

 @GetMapping("/holdings")
-public List<HoldingDto> getHoldings() {
-  return quantBotService.getHoldings();
+public ResponseEntity<List<HoldingDto>> getHoldings() {
+  List<HoldingDto> holdings = quantBotService.getHoldings();
+  return ResponseEntity.ok(holdings);
 }
backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (1)

33-44: 비효율적인 데이터 조회

Execution 엔티티에서 이미 XaiReport를 가져왔는데(Line 37), 다시 repository에서 조회하고 있습니다(Lines 42-43). 이는 불필요한 데이터베이스 쿼리를 발생시킵니다.

다음과 같이 리팩토링하는 것을 권장합니다:

   public XaiReport getXaiReportByExecutionId(Long executionId) {
     Execution exec = executionRepository.findById(executionId)
         .orElseThrow(() -> new IllegalArgumentException("Execution not found: " + executionId));
 
-    Long xaiReportId = exec.getXaiReport().getId();
-    if (xaiReportId == null) {
-      throw new IllegalStateException("Execution has no xaiReportId: " + executionId);
+    XaiReport xaiReport = exec.getXaiReport();
+    if (xaiReport == null) {
+      throw new IllegalStateException("Execution has no xaiReport: " + executionId);
     }
 
-    return xaiReportRepository.findById(xaiReportId)
-        .orElseThrow(() -> new IllegalArgumentException("XaiReport not found: " + xaiReportId));
+    return xaiReport;
   }

만약 최신 데이터를 보장하기 위해 재조회가 필요하다면, 엔티티 매니저의 refresh()를 사용하거나 명시적인 주석으로 의도를 표시하세요.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b5d509 and d0e23d1.

📒 Files selected for processing (13)
  • backend/src/main/java/org/sejongisc/backend/common/auth/config/SecurityConfig.java (0 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/controller/QuantBotController.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/dto/HoldingDto.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/dto/TradeLogDto.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/dto/XaiReportResponse.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/entity/Execution.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/entity/XaiReport.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/repository/ExecutionRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/repository/XaiReportRepository.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/entity/User.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (1 hunks)
  • backend/src/main/resources/application.yml (1 hunks)
💤 Files with no reviewable changes (1)
  • backend/src/main/java/org/sejongisc/backend/common/auth/config/SecurityConfig.java
🧰 Additional context used
🧬 Code graph analysis (2)
backend/src/main/java/org/sejongisc/backend/stock/entity/XaiReport.java (1)
backend/src/main/java/org/sejongisc/backend/stock/entity/Execution.java (1)
  • Entity (12-44)
backend/src/main/java/org/sejongisc/backend/stock/entity/Execution.java (1)
backend/src/main/java/org/sejongisc/backend/stock/entity/XaiReport.java (1)
  • Entity (12-32)
🔇 Additional comments (5)
backend/src/main/java/org/sejongisc/backend/stock/dto/HoldingDto.java (1)

5-11: LGTM!

보유 종목 정보를 표현하는 간결하고 명확한 DTO입니다. Record 타입을 사용하여 불변성을 보장하고 있으며, 필드 타입도 적절합니다.

backend/src/main/java/org/sejongisc/backend/stock/dto/TradeLogDto.java (1)

6-19: LGTM!

매매 로그 정보를 잘 표현하는 포괄적인 DTO입니다. Record 타입으로 불변성을 보장하고, 필드 구성도 적절합니다.

backend/src/main/java/org/sejongisc/backend/stock/repository/ExecutionRepository.java (1)

15-31: 보유 종목 조회 쿼리 로직 검증 완료

JPQL 쿼리 로직이 올바릅니다:

  • 서브쿼리로 각 ticker별 최신 execution (MAX id) 조회
  • positionQty > 0 필터링으로 실제 보유 종목만 반환
  • 생성자 표현식을 사용한 DTO 프로젝션이 정확함
backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (2)

21-24: LGTM!

매매 로그 조회 로직이 명확하고 올바르게 구현되었습니다.


27-30: LGTM!

보유 현황 조회 로직이 명확하고 올바르게 구현되었습니다.

Comment on lines +45 to 46
@Column(columnDefinition = "integer default 0",nullable = false)
private Integer point;
Copy link

@coderabbitai coderabbitai bot Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

포인트 필드의 타입과 데이터베이스 제약 조건 불일치

Java 필드 타입은 Integer(nullable)이지만, 데이터베이스 컬럼은 nullable = false로 설정되어 있습니다. 이러한 불일치는 다음과 같은 문제를 야기할 수 있습니다:

  • 포인트가 명시적으로 초기화되지 않으면 null이 될 수 있음
  • Line 64-66의 updatePoint() 메서드에서 NPE 발생 가능
  • 데이터베이스 제약 조건 위반 위험

다음 중 한 가지 방법으로 해결하는 것을 권장합니다:

방법 1 (권장): primitive int 타입 사용

-@Column(columnDefinition = "integer default 0",nullable = false)
-private Integer point;
+@Column(columnDefinition = "integer default 0", nullable = false)
+private int point;

방법 2: @PrePersist에서 기본값 설정

 @PrePersist
 public void prePersist() {
     if (this.role == null) {
         this.role = Role.TEAM_MEMBER;
     }
+    if (this.point == null) {
+        this.point = 0;
+    }
 }

방법 1이 더 안전하고 명확하므로 권장됩니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Column(columnDefinition = "integer default 0",nullable = false)
private Integer point;
@Column(columnDefinition = "integer default 0", nullable = false)
private int point;
🤖 Prompt for AI Agents
In backend/src/main/java/org/sejongisc/backend/user/entity/User.java around
lines 45-46, the field is declared as "private Integer point" while the column
is marked nullable=false which can lead to NPEs and DB constraint violations;
change the field to the primitive type "private int point" (update its
getter/setter signatures accordingly) and keep the @Column(columnDefinition =
"integer default 0", nullable = false) so the Java type and DB constraint align;
alternatively, if you prefer to keep Integer, add a @PrePersist method to set
point = 0 when null, but prefer the primitive int change as the primary fix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 내가 담당자가 아니라 건들이기 무서운디

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드를 확인해본 결과 현재 point 필드가 Integer 타입이라 생성 시 null 상태가 될 수 있다는 것을 확인했습니다. 그래서 int 타입으로 변경해주시면 감사하겠습니다.

.email(dto.getEmail())
.passwordHash(encodedPw)
.role(role)
.point(0)
Copy link

@coderabbitai coderabbitai bot Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

포인트 초기화가 올바르게 추가되었습니다.

회원가입 시 포인트를 0으로 초기화하는 것은 올바른 구현입니다. 다만, OAuth 사용자 생성 경로에서도 동일한 초기화가 필요한지 확인이 필요합니다.

다음 스크립트를 실행하여 모든 User 생성 경로에서 point 필드가 초기화되는지 확인하세요:


🏁 Script executed:

#!/bin/bash
# User.builder()를 사용하는 모든 위치를 찾아 point 초기화 여부 확인
rg -nP -A 10 'User\.builder\(\)' --type java

Length of output: 80181


OAuth 사용자 생성 경로에서 포인트 초기화 누락 발견

검증 결과, 일반 회원가입은 올바르게 .point(0)을 초기화하고 있으나, OAuth/OIDC 사용자 생성 경로에서는 포인트 필드를 초기화하지 않고 있습니다.

다음 파일들에서 .point(0) 추가 필요:

  • backend/src/main/java/org/sejongisc/backend/user/service/UserServiceImpl.java (줄 119, 339)
  • backend/src/main/java/org/sejongisc/backend/common/auth/config/CustomOidcUserService.java (줄 54)
  • backend/src/main/java/org/sejongisc/backend/common/auth/config/CustomOAuth2UserService.java (줄 85)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 내가 담당자가 아니라 건들이기 무서운디?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daye200, 충분히 이해할 수 있는 우려입니다! 다른 팀원이 담당하는 코드를 수정하는 것은 신중해야 하죠.

다행히 User 엔티티의 point 필드에는 데이터베이스 레벨에서 default 0 설정이 되어 있어서(@Column(columnDefinition = "integer default 0", nullable = false)), OAuth 경로에서 명시적으로 초기화하지 않아도 데이터베이스에는 0으로 저장됩니다. 따라서 기능상 문제는 없습니다.

다만 코드 일관성을 위해서는 모든 User 생성 경로에서 명시적으로 .point(0)을 추가하는 것이 좋습니다.

다음과 같이 처리하시는 것을 추천드립니다:

  1. 현재 PR은 그대로 진행 - 일반 회원가입 경로의 초기화만으로도 충분합니다
  2. 별도 이슈 생성 - OAuth 경로의 포인트 초기화를 담당자가 처리할 수 있도록 follow-up 이슈로 남기기

필요하시면 제가 이슈를 생성해드릴 수 있습니다. 이슈를 만들어드릴까요?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

토끼 리뷰 내용처럼 DB에서는 default 0으로 지정되기 때문에 기능상 문제가 없을 것 같습니다.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

spring:
profiles:
active: prod
active: dev
Copy link

@coderabbitai coderabbitai bot Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

프로덕션 배포 시 위험: dev 프로파일로 변경

Spring 프로파일이 prod에서 dev로 변경되었습니다. 이 설정이 프로덕션 환경에 배포될 경우 개발 모드로 실행되어 보안 취약점이나 의도하지 않은 동작이 발생할 수 있습니다.

다음 사항을 확인해주세요:

  • 이 변경이 의도된 것인지 확인
  • 프로덕션 환경에서는 환경 변수나 별도의 설정 파일로 프로파일을 관리하는 것을 권장

🏁 Script executed:

#!/bin/bash
# 프로젝트에서 프로파일 설정 방법과 배포 설정 확인
echo "=== Checking for profile configuration ==="
fd -t f "application.*\.yml|application.*\.properties" backend/src/main/resources/

echo -e "\n=== Checking for deployment configurations ==="
fd -t f "Dockerfile|docker-compose|deployment" .

echo -e "\n=== Checking for environment-specific configs ==="
rg -n "spring\.profiles\.active" --type yaml --type properties

Length of output: 262


추가 검증이 필요합니다. 다음 정보를 수집하겠습니다:

추가 정보를 수집하겠습니다. 애플리케이션 설정 파일과 Dockerfile을 검토해야 합니다.


---

🏁 Script executed:

```shell
#!/bin/bash
# application.yml 전체 내용 확인
echo "=== Content of application.yml ==="
cat backend/src/main/resources/application.yml

echo -e "\n=== Checking for environment-specific profile files ==="
fd -t f "application-.*" backend/src/main/resources/

echo -e "\n=== Backend Dockerfile content ==="
cat backend/Dockerfile

Length of output: 798


마지막으로 배포 구성(docker-compose, 쿠버네티스, CI/CD)에서 프로파일을 재정의하는지 확인하겠습니다.


---

🏁 Script executed:

```shell
#!/bin/bash
# docker-compose 파일 확인
echo "=== Looking for docker-compose files ==="
fd -t f "docker-compose.*" .

echo -e "\n=== Looking for kubernetes manifests ==="
fd -t f "\.yaml|\.yml" . | grep -iE "k8s|kubernetes|deployment|pod" | head -20

echo -e "\n=== Checking for CI/CD configs ==="
fd -t f "\.github|\.gitlab-ci|\.circleci|Jenkinsfile" .

echo -e "\n=== Checking if any config sets SPRING_PROFILES_ACTIVE ==="
rg -i "SPRING_PROFILES_ACTIVE|spring\.profiles\.active" . --type yaml --type json -n

Length of output: 178


프로덕션 배포 시 dev 프로파일이 활성화됨 — 반드시 수정 필요

검증 결과, 다음이 확인되었습니다:

  • application.ymldev 프로파일이 하드코딩되어 있음
  • 환경별 프로파일 파일 없음 (예: application-prod.yml, application-dev.yml)
  • Dockerfile에서 SPRING_PROFILES_ACTIVE 환경변수나 JVM 인자로 프로파일을 재정의하지 않음
  • Docker Compose, Kubernetes, CI/CD 파이프라인에서도 프로파일 재정의 메커니즘이 없음
  • show_sql: true, format_sql: true 등 디버깅 설정이 프로덕션에서도 활성화됨

해결 방법 (다음 중 하나):

  1. Dockerfile의 ENTRYPOINT-Dspring.profiles.active=prod 추가
  2. Dockerfile에서 ENV SPRING_PROFILES_ACTIVE=prod 설정
  3. 환경별 프로파일 파일 생성 및 활용 (application-prod.yml, application-dev.yml)

수정 위치: backend/src/main/resources/application.yml (기본값 변경) 또는 backend/Dockerfile (프로덕션 배포 시 프로파일 명시)

🤖 Prompt for AI Agents
In backend/src/main/resources/application.yml around lines 3 to 3, the file
hardcodes "active: dev" which causes dev profile and debug settings to run in
production; remove or stop hardcoding the active profile and instead (a) remove
the active property or set it to a neutral default, (b) create
environment-specific files (application-dev.yml and application-prod.yml) with
prod turning off debug settings (show_sql/format_sql=false), and (c) ensure
production runtime sets the profile via Dockerfile/infra—prefer adding ENV
SPRING_PROFILES_ACTIVE=prod to backend/Dockerfile or adding
-Dspring.profiles.active=prod to the ENTRYPOINT so production deploys use the
prod profile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이거 바꾼다는게 깜빡했다

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daye200, 네, 이해했습니다! 프로덕션 배포 전에 prod 프로파일로 변경해 주시면 됩니다. 😊

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0e23d1 and 80eafe9.

📒 Files selected for processing (3)
  • backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/controller/QuantBotController.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • backend/src/main/java/org/sejongisc/backend/stock/controller/QuantBotController.java
  • backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java

Comment on lines 56 to 60
EMAIL_CODE_MISMATCH(HttpStatus.BAD_REQUEST, "인증 코드가 일치하지 않습니다."),

EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다"),

EMAIL_ALREADY_VERIFIED(HttpStatus.BAD_REQUEST, "24시간 이내에 이미 인증된 이메일입니다."),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

메시지 종결부 일관성을 유지하세요.

58번 줄의 에러 메시지가 마침표 없이 종료되어 다른 에러 코드들과 일관성이 맞지 않습니다. 파일 전체에서 대부분의 에러 메시지가 마침표로 끝나므로 동일한 패턴을 따라야 합니다.

다음 diff를 적용하여 일관성을 유지하세요:

-  EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다"),
+  EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다."),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
EMAIL_CODE_MISMATCH(HttpStatus.BAD_REQUEST, "인증 코드가 일치하지 않습니다."),
EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다"),
EMAIL_ALREADY_VERIFIED(HttpStatus.BAD_REQUEST, "24시간 이내에 이미 인증된 이메일입니다."),
EMAIL_CODE_MISMATCH(HttpStatus.BAD_REQUEST, "인증 코드가 일치하지 않습니다."),
EMAIL_INVALID_EMAIL(HttpStatus.BAD_REQUEST, "유효하지 않은 이메일입니다."),
EMAIL_ALREADY_VERIFIED(HttpStatus.BAD_REQUEST, "24시간 이내에 이미 인증된 이메일입니다."),
🤖 Prompt for AI Agents
In backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java
around lines 56 to 60, the error message for EMAIL_INVALID_EMAIL (line 58) lacks
a trailing period and thus breaks consistency with other messages; update that
message to end with a period so it matches the file's punctuation pattern (i.e.,
add a '.' at the end of the string) while leaving surrounding enum entries and
formatting unchanged.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (1)

23-33: 거래 로그/보유 현황 조회에 페이징·필터링 도입을 고려해보세요

getTradeLogs, getHoldings에서 전체 리스트를 한 번에 조회하고 있어, 실운영에서 데이터가 많아지면 메모리 사용량과 응답 시간이 커질 수 있습니다.
향후 트래픽·데이터량을 생각하면 Pageable 기반 조회나 기간/종목 필터 등을 추가해 API 단에서 제어할 수 있게 해두는 것을 추천드립니다.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80eafe9 and 2e38338.

📒 Files selected for processing (2)
  • backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java (1 hunks)
  • backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/src/main/java/org/sejongisc/backend/common/exception/ErrorCode.java
🔇 Additional comments (2)
backend/src/main/java/org/sejongisc/backend/stock/service/QuantBotService.java (2)

1-22: 서비스 레이어 및 의존성 주입 방식은 적절합니다

@Service + @RequiredArgsConstructor 조합과 final 리포지토리 주입, CustomException/ErrorCode 활용이 일관되고 유지보수에 무리가 없어 보입니다. 현재 구조 그대로 사용해도 좋겠습니다.


35-47: getXaiReportByExecutionId의 NPE/지연 로딩 이슈가 잘 해결되었습니다

@Transactional(readOnly = true) 추가와 Execution 조회 후 xaiReport를 로컬 변수로 받아 null 체크하는 방식으로, 이전에 지적되었던 NPE 및 LAZY 로딩 문제를 잘 정리하신 것 같습니다. EXECUTION_NOT_FOUND, XAI_REPORT_NOT_FOUND 에러 코드 매핑도 명확합니다.

@Kosw6 Kosw6 merged commit 84d2797 into main Nov 20, 2025
1 check passed
@Kosw6 Kosw6 deleted the SISC1-20251119-퀀트봇받아오기 branch November 20, 2025 09:09
@daye200 daye200 restored the SISC1-20251119-퀀트봇받아오기 branch January 11, 2026 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

⚙️ [기능추가][퀀트봇] db가져오는 기능 추가

3 participants