Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
5 changes: 3 additions & 2 deletions recruitment-service/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.5'
id 'io.spring.dependency-management' version '1.1.7'
id 'org.springframework.boot' version '3.1.5'
id 'io.spring.dependency-management' version '1.1.3'
}

group = 'com.example'
Expand All @@ -28,6 +28,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.mysql:mysql-connector-j'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.recruitment.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/swagger-test")
public class SwaggerTestController {
@GetMapping
public String test() {
return "Swagger works!";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,7 @@ public class RecruitmentRequestDto {

@NotNull(message = "마감 시간은 필수입니다.")
private LocalDateTime deadlineTime;
}



//원래 dto 코드
/*
* package com.example.recruitment.dto;

import java.time.LocalDateTime;

import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class RecruitmentRequestDto {
private Long userId;
private Long storeId;
private String title;
private String description;
private LocalDateTime deadlineTime;
@NotBlank(message = "카테고리는 비어 있을 수 없습니다.")
private String category;
}
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.recruitment.entity;

import jakarta.persistence.Embeddable;
import lombok.*;

@Embeddable
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class MenuItem {

private String name;
private int price;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.example.recruitment.entity;

import jakarta.persistence.*;
import lombok.*;

import java.util.List;

@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class Order {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

검증 어노테이션과 감사 필드 추가를 고려해주세요.

엔티티에 데이터 검증과 생성/수정 시간 추적을 위한 필드가 없습니다.

+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+import java.time.LocalDateTime;
+
 @Entity
 @Table(name = "orders")
+@EntityListeners(AuditingEntityListener.class)
 @Getter @Setter
 @NoArgsConstructor
 @AllArgsConstructor
 public class Order {
+
+    // 기존 필드들...
+    
+    @CreatedDate
+    private LocalDateTime createdAt;
+    
+    @LastModifiedDate  
+    private LocalDateTime updatedAt;
📝 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
@Entity
@Table(name = "orders")
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class Order {
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@Entity
@Table(name = "orders")
@EntityListeners(AuditingEntityListener.class)
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class Order {
// 기존 필드들...
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
🤖 Prompt for AI Agents
In recruitment-service/src/main/java/com/example/recruitment/entity/Order.java
around lines 8 to 13, the entity lacks validation annotations and audit fields
for tracking creation and modification timestamps. Add appropriate validation
annotations (e.g., @NotNull, @Size) to relevant fields to enforce data
integrity. Also, include audit fields such as createdAt and updatedAt with
annotations like @CreatedDate and @LastModifiedDate, and enable auditing by
adding @EntityListeners(AuditingEntityListener.class) to the entity class.


@Id @GeneratedValue
private Long id;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

ID 생성 전략을 명시적으로 지정해주세요.

@GeneratedValue에 전략을 명시하지 않으면 JPA 구현체에 따라 다른 전략이 사용될 수 있습니다. 명시적으로 전략을 지정하는 것이 좋습니다.

-    @Id @GeneratedValue
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
📝 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
@Id @GeneratedValue
private Long id;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
🤖 Prompt for AI Agents
In recruitment-service/src/main/java/com/example/recruitment/entity/Order.java
around lines 15 to 16, the @GeneratedValue annotation on the id field lacks an
explicit generation strategy. Specify the generation strategy explicitly by
adding the strategy attribute to @GeneratedValue, such as
GenerationType.IDENTITY or GenerationType.AUTO, to ensure consistent ID
generation behavior across different JPA implementations.


@ManyToOne
private Recruitment recruitment; // 어떤 모집글에 대한 주문인지

@ManyToOne
private User user; // 누가 주문했는지
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

관계 매핑에 fetch 타입과 cascade 설정을 추가해주세요.

@ManyToOne 관계에서 fetch 타입과 cascade 옵션을 명시적으로 설정하면 성능과 데이터 일관성을 보장할 수 있습니다.

-    @ManyToOne
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "recruitment_id", nullable = false)
     private Recruitment recruitment; // 어떤 모집글에 대한 주문인지
 
-    @ManyToOne
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "user_id", nullable = false)
     private User user; // 누가 주문했는지

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In recruitment-service/src/main/java/com/example/recruitment/entity/Order.java
around lines 18 to 22, the @ManyToOne annotations for recruitment and user
fields lack explicit fetch type and cascade settings. To improve performance and
data consistency, add fetch=FetchType.LAZY and appropriate cascade options
(e.g., CascadeType.PERSIST or CascadeType.MERGE) to both @ManyToOne annotations.


@ElementCollection
@CollectionTable(name = "order_menu_items", joinColumns = @JoinColumn(name = "order_id"))
private List<MenuItem> menuItems; // 메뉴 리스트 (내장 객체로 구성)

private int totalPrice; // 총 가격
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

통화 처리를 위해 BigDecimal 사용을 고려해주세요.

int 타입은 통화 계산에서 정밀도 문제를 일으킬 수 있습니다. 금융 관련 계산에는 BigDecimal을 사용하는 것이 권장됩니다.

+import java.math.BigDecimal;
+
-    private int totalPrice; // 총 가격
+    private BigDecimal totalPrice; // 총 가격
📝 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
private int totalPrice; // 총 가격
// at the top of the file, alongside the other imports
import java.math.BigDecimal;
// inside the Order entity
- private int totalPrice; // 총 가격
+ private BigDecimal totalPrice; // 총 가격
🤖 Prompt for AI Agents
In recruitment-service/src/main/java/com/example/recruitment/entity/Order.java
at line 28, the totalPrice field is currently an int, which can cause precision
issues in currency calculations. Change the type of totalPrice from int to
BigDecimal to ensure accurate financial computations. Also, update any related
code that sets or gets this field to handle BigDecimal properly.

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ public class Recruitment {
@OneToMany(mappedBy = "recruitment", cascade = CascadeType.ALL, orphanRemoval = true)
private List<RecruitmentParticipant> participants;


private String title;
private String description;

private String status; // RECRUITING, CONFIRMED 등
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

상태 필드에 열거형(Enum) 사용을 권장합니다.

문자열 대신 열거형을 사용하여 타입 안전성을 향상시키고 유효하지 않은 상태 값 입력을 방지할 수 있습니다.

다음과 같이 열거형을 정의하고 사용하는 것을 권장합니다:

+@Enumerated(EnumType.STRING)
+private RecruitmentStatus status;  // RECRUITING, CONFIRMED 등
-private String status;  // RECRUITING, CONFIRMED 등

별도의 enum 클래스를 생성하세요:

public enum RecruitmentStatus {
    RECRUITING, CONFIRMED, CLOSED
}
🤖 Prompt for AI Agents
In
recruitment-service/src/main/java/com/example/recruitment/entity/Recruitment.java
at line 30, replace the String type status field with an enum type to improve
type safety and prevent invalid values. Create a separate enum class named
RecruitmentStatus with constants RECRUITING, CONFIRMED, and CLOSED, then change
the status field's type to RecruitmentStatus and update any related code
accordingly.


private LocalDateTime deadlineTime;

//카테고리 추가가
@Column(nullable = false)
private String category;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.example.recruitment.exception;

import com.example.recruitment.common.ApiResponse;
import com.example.recruitment.common.FieldErrorDetail;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.example.recruitment.common.ApiResponse;
import com.example.recruitment.common.FieldErrorDetail;

import java.util.List;

@RestControllerAdvice
Expand All @@ -21,7 +21,7 @@ public ResponseEntity<ApiResponse<Object>> handleCustomException(CustomException
.body(ApiResponse.fail(ec.getCode(), ec.getMessage(), ec.getStatus()));
}

//유효성 검사 실패
// 유효성 검사 실패
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResponse<Object>> handleValidationException(MethodArgumentNotValidException e) {
List<FieldErrorDetail> errorList = e.getBindingResult().getFieldErrors()
Expand All @@ -34,8 +34,17 @@ public ResponseEntity<ApiResponse<Object>> handleValidationException(MethodArgum
.body(ApiResponse.validationFail(errorList));
}

// 그 외 모든 예외 처리
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResponse<Object>> handleGeneralException(Exception e) {
public ResponseEntity<ApiResponse<Object>> handleGeneralException(Exception e, HttpServletRequest request) throws Exception {
String path = request.getRequestURI();

if (path != null && (path.contains("/v3/api-docs") || path.contains("/swagger"))) {
throw e; // Swagger 요청은 예외 처리하지 않고 Spring에게 맡김
}



return ResponseEntity
.status(ErrorCode.INTERNAL_ERROR.getStatus())
.body(ApiResponse.fail(
Expand All @@ -45,5 +54,3 @@ public ResponseEntity<ApiResponse<Object>> handleGeneralException(Exception e) {
));
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.recruitment.repository;

import com.example.recruitment.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long> {
}
Loading