-
Notifications
You must be signed in to change notification settings - Fork 0
[#22][be][assistant] 일간 피드백 조회 api 추가 #253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| package com.rouby.assistant.feedback.application.dto; | ||
|
|
||
| import com.rouby.assistant.feedback.domain.entity.Feedback; | ||
| import java.time.LocalDateTime; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import lombok.Builder; | ||
|
|
||
| public record GetDailyFeedbacksInfo( | ||
| List<GetFeedbackInfo> feedbacks | ||
| ) { | ||
|
|
||
| public static GetDailyFeedbacksInfo from(List<Feedback> feedbacks) { | ||
|
|
||
| if (feedbacks == null || feedbacks.isEmpty()) { | ||
| return new GetDailyFeedbacksInfo(Collections.emptyList()); | ||
| } | ||
|
|
||
| return new GetDailyFeedbacksInfo(feedbacks.stream().map(GetFeedbackInfo::from).toList()); | ||
| } | ||
|
|
||
| @Builder | ||
| public record GetFeedbackInfo( | ||
| int slot, | ||
| String userInput, | ||
| String userMood, | ||
| String feedbackContent, | ||
| String status, | ||
| LocalDateTime createdAt, | ||
| LocalDateTime updatedAt | ||
| ) { | ||
|
|
||
| public static GetFeedbackInfo from(Feedback feedback) { | ||
|
|
||
| return GetFeedbackInfo.builder() | ||
| .slot(feedback.getSlot()) | ||
| .userInput(feedback.getUserInput()) | ||
| .userMood(feedback.getMood().toString()) | ||
| .feedbackContent(feedback.getFeedbackContent().getContent()) | ||
| .status(feedback.getStatus().toString()) | ||
| .createdAt(feedback.getCreatedAt()) | ||
| .updatedAt(feedback.getUpdatedAt()) | ||
| .build(); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| package com.rouby.assistant.feedback.infrastructure.persistence.jpa; | ||
|
|
||
| import com.rouby.assistant.feedback.domain.entity.Feedback; | ||
| import com.rouby.assistant.feedback.domain.entity.enums.Status; | ||
| import com.rouby.assistant.feedback.domain.repository.FeedbackRepository; | ||
| import java.time.LocalDate; | ||
| import java.time.LocalDateTime; | ||
| import java.util.List; | ||
| import java.util.Optional; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.data.jpa.repository.Modifying; | ||
|
|
@@ -17,6 +19,8 @@ public interface FeedbackJpaRepository extends | |
| Optional<Feedback> findTop1ByUserIdAndCreatedAtBetweenOrderByCreatedAtDesc( | ||
| Long userId, LocalDateTime fromAt, LocalDateTime toAt); | ||
|
|
||
| List<Feedback> findByUserIdAndFeedbackDateAndStatusAndDeletedAtIsNull(Long userId, LocalDate date, Status status); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 🧩 Analysis chain쿼리 메서드가 올바르게 추가되었습니다. 성능 최적화를 고려하세요. Spring Data JPA 메서드 네이밍 컨벤션을 따른 명확한 쿼리 메서드입니다. 성능 최적화를 위해 데이터베이스 인덱스 존재 여부를 확인하세요: 복합 인덱스 🏁 Script executed: #!/bin/bash
# Description: Check for database index on feedback table for the new query
# Search for index definitions or migration files related to feedback table
fd -e sql -e xml | xargs rg -l "feedback" | xargs rg -i "index.*feedback.*(user_id|feedback_date|status|deleted_at)"
# Also check JPA entity for index annotations
rg -A5 "@Table|@Index" back/src/main/java/com/rouby/assistant/feedback/domain/entity/Feedback.javaLength of output: 0 더 정확한 검증을 위해 추가 스크립트를 실행하겠습니다. 더 정확한 검증을 위해 추가 스크립트를 실행하겠습니다. 🏁 Script executed: #!/bin/bash
# Find and examine the Feedback entity file
echo "=== Searching for Feedback entity ==="
find . -name "Feedback.java" -type f 2>/dev/null | head -5
# Check the entity file for index annotations
echo -e "\n=== Checking Feedback entity for @Index annotations ==="
rg -A20 "@Entity|@Table" back/src/main/java/com/rouby/assistant/feedback/domain/entity/Feedback.java 2>/dev/null || echo "Entity file not found or no matches"
# Look for database migration files
echo -e "\n=== Searching for database migration files ==="
fd -e sql -e yml -e yaml | grep -iE "(migration|flyway|liquibase|db)" | head -10
# Search for any index definitions in the entire codebase
echo -e "\n=== Searching for @Index annotations anywhere ==="
rg -n "@Index" --type java 2>/dev/null | head -10 || echo "No @Index annotations found"Length of output: 1274 🏁 Script executed: #!/bin/bash
# Find and examine the Feedback entity file
echo "=== Searching for Feedback entity ==="
find . -name "Feedback.java" -type f 2>/dev/null | grep -v target
# Check the entity file for index annotations
echo -e "\n=== Checking Feedback entity for @Index annotations ==="
rg -A20 "@Entity|@Table" --type java 2>/dev/null | grep -A20 "Feedback"
# Look for database migration files
echo -e "\n=== Searching for database migration files ==="
fd -e sql -e yml -e yaml 2>/dev/null | grep -iE "(migration|flyway|liquibase|db|ddl|schema)" | head -20
# Search for any index definitions in the entire codebase
echo -e "\n=== Searching for @Index annotations ==="
rg -B2 -A2 "@Index" --type java 2>/dev/nullLength of output: 5783 스키마 파일을 확인하여 데이터베이스 레벨에서 인덱스가 정의되어 있는지 검증하겠습니다. 🏁 Script executed: #!/bin/bash
# Check schema.sql for feedback table and indexes
echo "=== Checking schema.sql for feedback table ==="
rg -A20 -i "create.*table.*feedback|feedback" back/src/main/resources/db/schema.sql
# Check if there are any index definitions for feedback table
echo -e "\n=== Searching for indexes on feedback table ==="
rg -i "create.*index.*feedback|feedback.*index" back/src/main/resources/db/schema.sql
# Display entire schema.sql if it's not too large
echo -e "\n=== Full schema.sql content ==="
cat back/src/main/resources/db/schema.sql | head -100Length of output: 1290 복합 인덱스 추가 권장 - 현재 인덱스가 새 쿼리를 커버하지 않습니다 Spring Data JPA 쿼리 메서드 이름 규칙은 올바르게 작성되었습니다. 그러나 검증 결과, 데이터베이스 스키마에는 코드베이스의 다른 엔티티들( @Entity
@Table(name = "feedback", indexes = {
@Index(name = "idx_feedback_user_date_status_deleted",
columnList = "user_id, feedback_date, status, deleted_at")
})🤖 Prompt for AI Agents |
||
|
|
||
| @Query(""" | ||
| SELECT MAX(fb.slot) FROM Feedback fb | ||
| WHERE fb.userId = :userId AND fb.feedbackDate = :today AND fb.status != 'FAILED' | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,19 @@ | ||
| package com.rouby.assistant.feedback.presentation; | ||
|
|
||
| import com.rouby.assistant.feedback.application.service.FeedbackReadService; | ||
| import com.rouby.assistant.feedback.application.usecase.CreateFeedbackUsecase; | ||
| import com.rouby.assistant.feedback.presentation.dto.CreateFeedbackRequest; | ||
| import com.rouby.assistant.feedback.presentation.dto.GetDailyFeedbacksResponse; | ||
| import com.rouby.user.user.infrastructure.security.dto.SecurityUser; | ||
| import jakarta.validation.constraints.PastOrPresent; | ||
| import java.time.LocalDate; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.security.access.prepost.PreAuthorize; | ||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
| import org.springframework.validation.annotation.Validated; | ||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.PathVariable; | ||
| import org.springframework.web.bind.annotation.PostMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
|
|
@@ -19,6 +25,7 @@ | |
| public class FeedbackController { | ||
|
|
||
| private final CreateFeedbackUsecase createFeedbackUsecase; | ||
| private final FeedbackReadService feedbackReadService; | ||
|
|
||
| @PreAuthorize("hasAnyRole('USER')") | ||
| @PostMapping | ||
|
|
@@ -29,4 +36,15 @@ public ResponseEntity<Void> createDailyFeedback( | |
| createFeedbackUsecase.requestFeedback(request.toCommand(user.getId())); | ||
| return ResponseEntity.accepted().build(); | ||
| } | ||
|
|
||
| @PreAuthorize("hasAnyRole('USER')") | ||
| @GetMapping("/daily/{date}") | ||
| public ResponseEntity<GetDailyFeedbacksResponse> getDailyFeedback( | ||
| @AuthenticationPrincipal SecurityUser user, | ||
| @PathVariable @PastOrPresent LocalDate date) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 수고하셨습니다! @PastOrPresent는 잘 동작하는지 궁금합니다!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 잘 동작합니다. 관련 테스트 코드가 있습니다. |
||
|
|
||
| GetDailyFeedbacksResponse res = GetDailyFeedbacksResponse.from( | ||
| feedbackReadService.getDailyFeedbacks(user.getId(), date)); | ||
| return ResponseEntity.ok(res); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package com.rouby.assistant.feedback.presentation.dto; | ||
|
|
||
| import com.rouby.assistant.feedback.application.dto.GetDailyFeedbacksInfo; | ||
| import com.rouby.assistant.feedback.application.dto.GetDailyFeedbacksInfo.GetFeedbackInfo; | ||
| import java.time.LocalDateTime; | ||
| import java.util.List; | ||
| import lombok.Builder; | ||
|
|
||
| public record GetDailyFeedbacksResponse( | ||
| List<GetDailyFeedbackResponse> feedbacks | ||
| ) { | ||
|
|
||
| public static GetDailyFeedbacksResponse from(GetDailyFeedbacksInfo feedbacksInfo) { | ||
| return new GetDailyFeedbacksResponse( | ||
| feedbacksInfo.feedbacks().stream().map(GetDailyFeedbackResponse::from).toList()); | ||
| } | ||
|
HanaHww2 marked this conversation as resolved.
|
||
|
|
||
| @Builder | ||
| record GetDailyFeedbackResponse( | ||
| int slot, | ||
| String userMood, | ||
| String userInput, | ||
| String feedbackContent, | ||
| LocalDateTime createdAt, | ||
| LocalDateTime updatedAt | ||
| ) { | ||
|
|
||
| public static GetDailyFeedbackResponse from(GetFeedbackInfo info) { | ||
|
|
||
| return GetDailyFeedbackResponse.builder() | ||
| .slot(info.slot()) | ||
| .userMood(info.userMood()) | ||
| .userInput(info.userInput()) | ||
| .feedbackContent(info.feedbackContent()) | ||
| .createdAt(info.createdAt()) | ||
| .updatedAt(info.updatedAt()) | ||
| .build(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,11 @@ | ||
| ### 피드백 생성 요청 | ||
| POST {{url}}/api/v1/assistants/feedbacks | ||
| content-type: application/json | ||
|
|
||
| { | ||
| "userInput": "오늘은 집중이 잘 안 되는 하루였던 거 같아. 빨리 집중해서 취업해야 되는데...!", | ||
| "userMood": "SOSO" | ||
| } | ||
| } | ||
|
|
||
| ### 일간 피드백 리스트 요청 | ||
| GET {{url}}/api/v1/assistants/feedbacks/daily/2025-10-22 |
Uh oh!
There was an error while loading. Please reload this page.