Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 12 additions & 0 deletions src/main/java/life/mosu/mosuserver/domain/application/Lunch.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package life.mosu.mosuserver.domain.application;

import java.util.Arrays;
import life.mosu.mosuserver.global.exception.CustomRuntimeException;
import life.mosu.mosuserver.global.exception.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

Expand All @@ -15,4 +18,13 @@ public enum Lunch {
OPTION6("중식 도시락");

private final String lunchName;

public static Lunch from(String lunchName) {
return Arrays.stream(values())
.filter(e -> e.getLunchName().equals(lunchName))
.findFirst()
.orElseThrow(
() -> new CustomRuntimeException(ErrorCode.NOT_FOUND_LUNCH)
);
}
Comment on lines +22 to +29

Choose a reason for hiding this comment

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

medium

For improved performance, use a static Map for looking up enum values from a string. The current implementation iterates through all enum values for every call, which has a time complexity of O(n). Using a pre-populated static Map provides a constant time complexity O(1) lookup.

private static final java.util.Map<String, Lunch> LUNCH_BY_NAME =
    java.util.Arrays.stream(values()).collect(
        java.util.stream.Collectors.toUnmodifiableMap(Lunch::getLunchName, e -> e));

public static Lunch from(String lunchName) {
    Lunch lunch = LUNCH_BY_NAME.get(lunchName);
    if (lunch == null) {
        throw new CustomRuntimeException(ErrorCode.NOT_FOUND_LUNCH);
    }
    return lunch;
}

}
15 changes: 12 additions & 3 deletions src/main/java/life/mosu/mosuserver/domain/school/Area.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package life.mosu.mosuserver.domain.school;

import java.util.Arrays;
import life.mosu.mosuserver.global.exception.CustomRuntimeException;
import life.mosu.mosuserver.global.exception.ErrorCode;
import lombok.Getter;

@Getter
public enum Area {
DAECHI("대치"),
MOKDONG("목동"),
NOWON("노원");
private final String areaName;

Area(String areaName) {
private Area(String areaName) {
this.areaName = areaName;
}

public String getAreaName() {
return areaName;
public static Area from(String areaName) {
return Arrays.stream(Area.values())
.filter(area -> area.getAreaName().equals(areaName))
.findFirst()
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.NOT_FOUND_AREA));
}
Comment on lines +19 to 24

Choose a reason for hiding this comment

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

medium

Using a static Map for lookups in the from method would be more efficient. While the performance impact is negligible with only three enum constants, it's a good practice for consistency and scalability.

private static final java.util.Map<String, Area> AREA_BY_NAME =
    java.util.Arrays.stream(values()).collect(
        java.util.stream.Collectors.toUnmodifiableMap(Area::getAreaName, e -> e));

public static Area from(String areaName) {
    Area area = AREA_BY_NAME.get(areaName);
    if (area == null) {
        throw new CustomRuntimeException(ErrorCode.NOT_FOUND_AREA);
    }
    return area;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.LocalDate;
import java.time.LocalDateTime;
import life.mosu.mosuserver.domain.application.Lunch;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -30,11 +32,20 @@ public class SchoolJpaEntity {
@Column(name = "school_name")
private String schoolName;

@Embedded
private AddressJpaVO address;
Comment on lines +35 to +36
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Address field not included in constructor.

The address field is still present in the entity but removed from the constructor parameters. This could lead to entities being created with null addresses. Verify if this is intentional or if the address should be included in the constructor.


🏁 Script executed:

#!/bin/bash
# Check if AddressJpaVO is used elsewhere in the codebase and how it's typically initialized
rg -A 5 "AddressJpaVO" --type java

Length of output: 10540


🏁 Script executed:

#!/bin/bash
# Display class declaration, annotations, constructor, and builder for SchoolJpaEntity
sed -n '1,200p' src/main/java/life/mosu/mosuserver/domain/school/SchoolJpaEntity.java

Length of output: 1865


Include address in the SchoolJpaEntity @builder constructor

The address field is declared but omitted from the builder constructor, which prevents calls like SchoolJpaEntity.builder().address(...) (used in DatabaseInitializer) and leaves address uninitialized.

• File: src/main/java/life/mosu/mosuserver/domain/school/SchoolJpaEntity.java
– The @Builder constructor (around line Thirty-nine) only takes (String schoolName, Area area, Lunch lunch, LocalDate examDate, Long capacity, LocalDateTime deadlineTime, Integer lunchPrice).

Please update the constructor to include AddressJpaVO address and assign it:

 @Builder
-public SchoolJpaEntity(String schoolName,
-        Area area,
-        Lunch lunch,
-        LocalDate examDate,
-        Long capacity,
-        LocalDateTime deadlineTime,
-        Integer lunchPrice) {
-    this.schoolName = schoolName;
-    this.area = area;
-    this.lunch = lunch;
-    this.examDate = examDate;
-    this.capacity = capacity;
-    this.deadlineTime = deadlineTime;
-    this.lunchPrice = lunchPrice;
-}
+public SchoolJpaEntity(String schoolName,
+        AddressJpaVO address,
+        Area area,
+        Lunch lunch,
+        LocalDate examDate,
+        Long capacity,
+        LocalDateTime deadlineTime,
+        Integer lunchPrice) {
+    this.schoolName = schoolName;
+    this.address = address;
+    this.area = area;
+    this.lunch = lunch;
+    this.examDate = examDate;
+    this.capacity = capacity;
+    this.deadlineTime = deadlineTime;
+    this.lunchPrice = lunchPrice;
+}
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/domain/school/SchoolJpaEntity.java around
lines 35 to 39, the address field is declared but missing from the @Builder
constructor parameters and assignment. Update the @Builder constructor to
include AddressJpaVO address as a parameter and assign it to this.address to
enable builder calls like SchoolJpaEntity.builder().address(...).


@Enumerated(EnumType.STRING)
private Area area;

@Embedded
private AddressJpaVO address;
@Enumerated(EnumType.STRING)
private Lunch lunch;

@Column(name = "lunch_price")
private Integer lunchPrice;

@Column(name = "deadline_time")
private LocalDateTime deadlineTime;

@Column(name = "exam_date")
private LocalDate examDate;
Expand All @@ -43,12 +54,16 @@ public class SchoolJpaEntity {
private Long capacity;

@Builder
public SchoolJpaEntity(String schoolName, Area area, AddressJpaVO address, LocalDate examDate,
Long capacity) {
public SchoolJpaEntity(String schoolName, Area area, Lunch lunch, LocalDate examDate,
Long capacity,
LocalDateTime deadlineTime, Integer lunchPrice, AddressJpaVO address) {
this.schoolName = schoolName;
this.area = area;
this.address = address;
this.lunch = lunch;
this.examDate = examDate;
this.capacity = capacity;
this.deadlineTime = deadlineTime;
this.lunchPrice = lunchPrice;
this.address = address;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public enum ErrorCode {
// 이벤트 관련 에러
EVENT_NOT_FOUND(HttpStatus.NOT_FOUND, "이벤트를 찾을 수 없습니다."),

// Enum 관련 에러
NOT_FOUND_AREA(HttpStatus.NOT_FOUND, "해당 지역을 찾을 수 없습니다."),
NOT_FOUND_LUNCH(HttpStatus.NOT_FOUND, "해당 도시락을 찾을 수 없습니다."),

// FAQ 관련 에러
FAQ_NOT_FOUND(HttpStatus.NOT_FOUND, "FAQ를 찾을 수 없습니다."),
FAQ_CREATION_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "FAQ 등록에 실패했습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,59 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import java.time.LocalDate;
import life.mosu.mosuserver.domain.school.AddressJpaVO;
import java.time.LocalDateTime;
import life.mosu.mosuserver.domain.application.Lunch;
import life.mosu.mosuserver.domain.school.Area;
import life.mosu.mosuserver.domain.school.SchoolJpaEntity;
import life.mosu.mosuserver.presentation.application.dto.AddressRequest;


@Schema(description = "학교 생성/등록 요청 DTO")
public record SchoolRegistrationRequest(
@Schema(description = "학교 이름", example = "모수고등학교")
@NotBlank(message = "학교 이름은 필수 입니다.")
String schoolName,

@Schema(description = "지역 (예: DAECHI, MOKDONG, NOWON)", example = "DAECHI")
@NotNull(message = "지역은 필수 입니다.")
String area,

@Schema(description = "학교 주소 정보")
@NotNull(message = "주소 정보는 필수 입니다.")
AddressRequest address,
AddressRequest schoolAddress,

@Schema(description = "시험/입학 시험 날짜 (YYYY-MM-DD)", example = "2025-11-20")
@Schema(description = "날짜 (YYYY-MM-DD)", example = "2025-11-20")
@NotNull(message = "시험 날짜는 필수입니다.")
LocalDate examDate,

@Schema(description = "학교명", example = "모수고등학교")
@NotBlank(message = "학교 이름은 필수 입니다.")
String schoolName,

@Schema(description = "도시락 메뉴")
@NotNull
String lunch,

@Schema(description = "도시락 가격")
@NotNull
Integer lunchPrice,

@NotNull
@Schema(description = "신청 마감 일시", example = "2025-05-30T10:00:00")
LocalDateTime deadlineTime,
Comment on lines +34 to +44

Choose a reason for hiding this comment

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

medium

The new fields lunch, lunchPrice, and deadlineTime are annotated with @NotNull, but they are missing the message attribute. Providing a descriptive error message is important for client-side error handling and provides a better user experience.

Additionally, lunchPrice should probably be a positive number. Consider adding a @Positive annotation.

Suggested change
@Schema(description = "도시락 메뉴")
@NotNull
String lunch,
@Schema(description = "도시락 가격")
@NotNull
Integer lunchPrice,
@NotNull
@Schema(description = "신청 마감 일시", example = "2025-05-30T10:00:00")
LocalDateTime deadlineTime,
@NotNull(message = "도시락 메뉴는 필수입니다.")
String lunch,
@Schema(description = "도시락 가격")
@NotNull(message = "도시락 가격은 필수입니다.")
@Positive(message = "도시락 가격은 양수여야 합니다.")
Integer lunchPrice,
@NotNull(message = "신청 마감 일시는 필수입니다.")
@Schema(description = "신청 마감 일시", example = "2025-05-30T10:00:00")
LocalDateTime deadlineTime,


@Schema(description = "수용 인원", example = "300")
@NotNull(message = "수용 인원은 필수입니다.")
@Positive(message = "수용 인원은 양수여야 합니다.")
Long capacity
) {

public SchoolJpaEntity toEntity() {
AddressJpaVO address = address().toValueObject();
return SchoolJpaEntity.builder()
.schoolName(schoolName)
.area(Area.valueOf(area))
.address(address)
.address(schoolAddress.toValueObject())
.area(Area.from(area))
.examDate(examDate)
.schoolName(schoolName)
.lunch(Lunch.from(lunch))
.lunchPrice(lunchPrice)
.deadlineTime(deadlineTime)
.capacity(capacity)
.build();
}
Expand Down