[π μ¬μ΄ν΄2 - λ―Έμ (μμ½ λ³κ²½/μ·¨μμ μλ¬ μ²λ¦¬)] λ¬΄λΉ λ―Έμ μ μΆν©λλ€.#432
[π μ¬μ΄ν΄2 - λ―Έμ
(μμ½ λ³κ²½/μ·¨μμ μλ¬ μ²λ¦¬)] λ¬΄λΉ λ―Έμ
μ μΆν©λλ€.#432mvg01 wants to merge 112 commits into
Conversation
- μμ μμ μλ ID μ λ ₯ μ μμΈμ²λ¦¬ μ κ±°
- reservaiton ν μ΄λΈ μ½μ ν λλ©μΈμ λ°ννκΈ° μν΄ joinνλ κ³Όμ μ μ κ±°ν¨. - ReservationServiceμμ λ€λ₯Έ Serviceλ₯Ό μμ‘΄νλλ‘ λ³κ²½ν¨. - ReservationRepositoryμ λ€λ₯Έ serviceμ response κ°μ μ λ¬ν¨.
- μμ½ ν λ§ μμ μ CASCADE - μμ½ μκ° μμ μ RESTRICT
- μ΄λ―Έ μ‘΄μ¬νλ μκ°μ λν΄μλ 컀μ€ν μλ¬ μλ΅ λ°ν
- themes/ranks limit λ²μ κ²μ¦
- κΈ°μ‘΄ ResponseEntityExceptionHandler μμ μ κ±°
- GET /themes/ranks μ limit λλ½ ν μ€νΈ μΆκ°
- μ΄λ―Έ μ§λ μκ°μ μμ½ μμ λ°©μ§ - μ΄λ―Έ μ§λ μκ°μΌλ‘μ μμ½ μμ λ°©μ§
Gyuchool
left a comment
There was a problem hiding this comment.
μλ
νμΈμ 무λΉ!
λΉ λ₯΄κ² ꡬνν΄μ£Όμ
¨λ€μπ λ€λ§, λ΄ μμ½μ μμ νλλ° μμ½κ΄λ¦¬μλ κ·Έλλ‘ μλλ° μ΄λΆλΆ νμΈλΆνλ릴κ»μ!
λ§μ§λ§ μ¬μ΄ν΄2λ νμ΄ν μ λλ€πͺ
λͺ κ°μ§ μ½λ©νΈλ₯Ό λ¨κ²¨λμμΌλ λ°μ λ° μ견 μ£Όμλ©΄ μ’μ κ² κ°μ΅λλ€.π
κΆκΈν μ μ DMμ΄λ PR 컀λ©νΈλ‘ μΈμ λ μ§ μ¬μ€λ΄μ£ΌμΈμ!
mockData.sqlμ λν ν μ€νΈ μμ‘΄μ±
μ§ννλ€ λ³΄λ 컨νΈλ‘€λ¬ ν μ€νΈλ€μ΄ mockData.sqlμ κ°νκ² μμ‘΄νκ² λλ€λ κ±Έ λκΌμ΅λλ€.
μμ‘΄μ±μ΄ κ°ν΄μ§λ©΄ μ΄λ»κ² ν΄κ²°ν μ μμκΉμ?π μμ‘΄μ±μ λμ΄λ΄λ³ΌκΉμ?
ErrorCode Enum νμ©
μ΄λ° λ°©μμΌλ‘ μλ¬ μλ΅μ ν΅μΌνλ κ² μ μ νμ§ κΆκΈν©λλ€. μ΄λ€ λΆλΆμ΄ λΆμ‘±νκ±°λ κ³Όνμ§ νΌλλ°± λΆνλ립λλ€.
ErrorCodeλ₯Ό EnumμΌλ‘ κ΄λ¦¬νλ κ²λ³΄λ€ λ λμ κ΅¬μ‘°κ° μλ€λ©΄ μκ³ μΆμ΅λλ€.
μμΈν μλ¬ μ€λͺ μ ν¨κ» μ 곡ν΄μ£Όμ μ μ΄ μ’λ€μ π
λ€λ§ ν κ°μ§ λ κ³ λ―Όν΄λ³Ό λΆλΆμ, μ¬μ©μμκ² κ΅¬μ²΄μ μΈ μμΈ λ΄μ©μ μ΄λκΉμ§ λ ΈμΆν κ²μΈκ°λΌκ³ μκ°ν΄μ. μλ₯Ό λ€μ΄ λ‘κ·ΈμΈ κΈ°λ₯μμ "λΉλ°λ²νΈκ° νλ Έμ΅λλ€" λλ "λΉλ°λ²νΈλ 8μ μ΄μμ΄μ΄μΌ ν©λλ€"μ κ°μ΄ μμΈν μ 보λ₯Ό μ 곡νλ©΄, μ¬μ©μμκ²λ μΉμ ν μ μμ§λ§ 곡격μμκ²λ μ μ©ν ννΈλ₯Ό μ€ μ μλ€κ³ μκ°ν΄μμ.
λ°λΌμ μλ¬ λ©μμ§λ₯Ό λꡬμκ² μ 곡νλμ§, κ·Έλ¦¬κ³ λλ²κΉ μ μν κ²μΈμ§ UX κ°μ μ μν κ²μΈμ§ λ¨Όμ λͺ νν νλ κ²μ΄ μ€μνλ€κ³ μκ°ν΄μ. μ΄λ₯Ό λ°νμΌλ‘ μ¬μ©μ νΈμμ±κ³Ό 보μ μ¬μ΄μμ μ μ ν μμ€μ μ 보λ₯Ό μ 곡νλ λ°©ν₯μΌλ‘ κ³ λ―Όν΄λ³΄λ©΄ μ’μκ² κ°λ€μπ
λν ErrorCode enumμ λͺ¨λ μ’ λ₯μ μμΈλ₯Ό νκ³³μ λͺ¨μΌκΈ° μμνλ©΄ λΉ λ₯΄κ² 무거μμ§ μ μμ΅λλ€. λ§μ½ ErrorCodeλ₯Ό λͺ¨μλκΈ°λ‘ νλ€λ©΄ κ°μΈμ μΌλ‘λ λΉμ¦λμ€ λ‘μ§κ³Ό κ΄λ ¨λ ν΅μ¬ μμΈλΆν° enumμΌλ‘ κ΄λ¦¬ν κ² κ°λ€μ.
| this.date = date; | ||
| this.time = time; | ||
| this.theme = theme; | ||
| validateName(name); |
There was a problem hiding this comment.
validateλ₯Ό 맨μλλ‘ λ΄λ¦° μ΄μ κ° μμκΉμ?
There was a problem hiding this comment.
μ΄μ μ¬μ΄ν΄μμ νλ μ€μμ μμ¬κ° λ¨μμμλ€μ!! λ°μνκ² μ΅λλ€.
| private final LocalDate date; | ||
| private final ReservationTime time; | ||
| private final Theme theme; | ||
| public record Reservation(Long id, String name, LocalDate date, ReservationTime time, Theme theme) { |
There was a problem hiding this comment.
recordλ‘ λ°κΎΌ μ΄μ κ° μμκΉμ?
There was a problem hiding this comment.
κ°μ²΄ μμ²΄κ° λ³κ²½λ μ¬μ§κ° μλ€κ³ νλ¨ν΄μ μ λλ€. λ§μ°¬κ°μ§λ‘ ReservationTimeλ recordμΈλ° μλΉμ€ λ‘μ§μ΄λ μλͺ μ£ΌκΈ°μμ λ³κ²½λ μ¬μ§κ° μμμ΅λλ€.
νμ§λ§ java recordμ μλ―Έλ₯Ό λ€μ μ΄ν΄λ³΄λ μμνκ² λ°μ΄ν°λ₯Ό λ΄λ λͺ©μ μλ§ μ΅μ νλ ν΄λμ€λΌκ³ ν©λλ€. μ λ λ±ν μ΄λ° μλ―Έλ₯Ό λͺ°λμ΄μ, λ¨μν 보μΌλ¬νλ μ΄νΈ μ½λλ₯Ό μ€μ΄κΈ° μν΄μ μ¬μ©νλ κ² κ°μ΅λλ€.
λν λλ©μΈμ λΉμ¦λμ€ λ‘μ§λ λ΄κ²¨μμΌλ, recordλ³΄λ¨ classκ° μ ν©νλ€κ³ νλ¨λ©λλ€. μμ ν΄μ λ°μνκ² μ΅λλ€.
| private static void validateName(String name) { | ||
| if (name.isBlank() || name.length() > MAX_THEME_LENGTH) { |
There was a problem hiding this comment.
requestμμ validλ₯Ό μ κ±°ν μ΄μ κ° μμκΉμ?
There was a problem hiding this comment.
requestμμ validateλ₯Ό μ κ±°ν μ΄μ λ, DTOλ λ°μ΄ν°μ μ΄λ/λ³ν μ± μλ§ λ΄λΉν΄μΌ νλ€κ³ νλ¨νκΈ° λλ¬Έμ λλ€.
κ²μ¦ μμΉλ λ κ³³μ λλ€.
- Service: νλ μμ²΄κ° nullμΈμ§(μ λ ₯κ°μ΄ μμ μ λ€μ΄μ¨ μνμΈμ§)
- Model: κ°μ΄ μλλΌλ λλ©μΈ κ·μΉμ μ ν¨νμ§ μμ κ²½μ°(blank, κΈΈμ΄ μ΄κ³Ό, μ λ ₯κ° κ·Έ μμ²΄κ° μ ν¨νμ§)
μΆκ°λ‘ λλ©μΈμμμ κ²μ¦μ κΈ°μ€μ, Repositoryμμ λλ©μΈ κ°μ²΄λ₯Ό λ§λλ κ³Όμ μ΄ μκΈ° λλ¬Έμ λλ©μΈ μ€μ€λ‘ μμ μ κ° κ²½κ³λ₯Ό 보μ₯ν΄μΌ νλ€κ³ νλ¨νμ΅λλ€.
|
|
||
| public boolean existsByDateAndTimeIdAndThemeId(LocalDate date, Long timeId, Long themeId) { | ||
| String sql = "SELECT COUNT(*) FROM reservation WHERE date = ? AND time_id = ? AND theme_id = ?"; | ||
| String sql = "SELECT COUNT(id) FROM reservation WHERE date = ? AND time_id = ? AND theme_id = ?"; |
There was a problem hiding this comment.
idκ° λ€μ΄κ°κ²κ³Ό *κ° λ€μ΄κ°κ²μ μ°¨μ΄κ° μμκΉμ? idλ₯Ό μΉ΄μ΄νΈνλλ‘ λ°κΎΌ μ΄μ κ° μμκΉμ?
There was a problem hiding this comment.
μ΄μ μ SELECT * μ¬μ©μ λν 리뷰μ μν₯μΌλ‘ λ³κ²½νμ κ²μ΄λΌλ©΄, COUNT(*)μμ μ¬μ©λ *κ° μ΄λ€ μλ―Έλ₯Ό κ°μ§λμ§λ ν λ² μκ°ν΄λ³΄μλ©΄ μ’κ² μ΅λλ€.
μ κ° λλ¦° 리뷰μ μλλ λͺ¨λ SQLμμ *λ₯Ό μ¬μ©νλ©΄ μ λλ€λ λ»μ μλμμ΄μ! SELECT μ COUNT()μ *λ μν κ³Ό μλ―Έκ° μλ‘ λ€λ₯΄κΈ° λλ¬Έμ λ€μ μκ°ν΄λ³΄μμ£ !
There was a problem hiding this comment.
COUNT(*)μ ν κ°μλ₯Ό 체ν¬νλ μλ―ΈλΌ μ§κΈ μ½λμμ μ¬μ€ λ¬Έμ μμ΄ μ¬μ©ν μ μμ΅λλ€. νμ§λ§ COUNT(id)λ idκ° nullμ΄ μλ νμ μΈμ£Όλ κ²μ΄κΈ° λλ¬Έμ μλ―Έκ° μ½κ° λ¬λμ΅λλ€. μ€νλ € COUNT(*) μ΄ μ μ§κ° λ λμ κ² κ°μμ κ·Έλ κ² μμ νκ² μ΅λλ€!
| private void reservationRequestDayCheck(LocalDate date, ReservationTime time) { | ||
| if (date.isBefore(LocalDate.now())) { | ||
| throw new RoomescapeException(ErrorCode.RESERVATION_WRONG_DATE); | ||
| } | ||
| if (date.isEqual(LocalDate.now())) { | ||
| if (time.startAt().getHour() <= LocalTime.now().getHour()) { | ||
| throw new RoomescapeException(ErrorCode.RESERVATION_WRONG_TIME); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
νμ κ°μ κΈ°μ€ μμ μΌλ‘ λΉκ΅λλ€κ³ λ³Ό μ μμκΉμ?
μλ₯Ό λ€μ΄ λ μ§λ₯Ό λΉκ΅νλ μκ°κ³Ό μκ°μ λΉκ΅νλ μκ° μ¬μ΄μ μκ°μ΄ μμ£Ό μ‘°κΈμ΄λΌλ νλ₯Έλ€λ©΄, μ΄ λ‘μ§μ νλμ λμΌν βνμ¬ μκ°βμ κΈ°μ€μΌλ‘ νλ¨νλ€κ³ λ§ν μ μμμ§ κ³ λ―Όν΄λ³΄λ©΄ μ’κ² μ΅λλ€.
| private void reservationRequestValidate(ReservationRequest reservationRequest) { | ||
| if (reservationRequest.name() == null) { |
There was a problem hiding this comment.
requestμ λν validationμΈλ° nullλ§ κ²μ¬νλ μ΄μ κ° μμκΉμ?
| PRIMARY KEY (id), | ||
| FOREIGN KEY (time_id) REFERENCES reservation_time (id), | ||
| FOREIGN KEY (theme_id) REFERENCES theme (id) | ||
| FOREIGN KEY (theme_id) REFERENCES theme (id) ON DELETE CASCADE |
There was a problem hiding this comment.
CASCADEλ₯Ό κ±°μ μ΄μ κ° μμκΉμ? μ΄λ€ μ₯λ¨μ μ΄ μλμ?
| reservation.time(), reservation.theme()); | ||
| } | ||
|
|
||
| public boolean existsByDateAndTimeIdAndThemeId(LocalDate date, Long timeId, Long themeId) { |
There was a problem hiding this comment.
κ°μ date, timeId, themeIdλ₯Ό κ°μ§λ©΄ μμ½μ λͺ»νλ λ‘μ§μΈκ±°κ°μλ°, μ§κΈμ λμμ μμ²μ΄ λ€μ΄μ€λ©΄ μμ±μ΄ κ°λ₯νκ² λ€μ? μ΄λ»κ² ν΄κ²°ν μ μμκΉμ?
ννΈ: λ°μ΄ν°λ² μ΄μ€
|
|
||
| Assertions.assertThatThrownBy(() -> reservationService.register(reservationRequest)) | ||
| .isInstanceOf(RoomescapeException.class); | ||
| } |
There was a problem hiding this comment.
μ¬κΈ°μ timeId=1Lμ μ€μ 10μμ λλ€. μ€μ 10μ μ΄μ μ μ΄ ν μ€νΈλ₯Ό λ리면 μ μ μμ½ μμ²μΌλ‘ κ°μ£Όλμ΄ ν μ€νΈκ° μ€ν¨νκ³ , μ΄νλΌλ©΄ μ±κ³΅ν©λλ€. μλ²½μ μμ ν΄λ μ€ν¨ν κ²μ λλ€..
"μ€λ λ μ§μ΄λ©΄μ μ΄λ―Έ μ§λ μκ°μλ μμ½/μμ μ΄ λΆκ°λ₯νλ€"λ μΌμ΄μ€λ₯Ό μμ μ μΌλ‘ ν μ€νΈνλ €λ©΄ μ΄λ»κ² ν΄μΌ ν μ§ λͺ¨λ₯΄κ² μ΅λλ€. μ§κΈμ²λΌ mockData.sqlμ λ°μ΄ν°λ₯Ό νμ©νλ μμΌλ‘λ λΆκ°λ₯ν κ²μΌκΉμ?
- μ κ° μκ° μ μ± μ λλ©μΈ κ²μ¦λ³΄λ¨ μλΉμ€ κ²μ¦μ΄ μ¬λ°λ₯΄λ€κ³ νλ¨ - μλͺ»λ κ° μ½μ μ μμΈ, μ‘°ν μ κ²½κ³ λ‘κ·Έλ‘ λΆλ¦¬(μμΈλ μν°μ§)
κ°μ
μλ νμΈμ κΈ°λ‘ , λ¦¬λ·°μ΄ λ¬΄λΉμ λλ€.
μ΄λ²μλ 리뷰 νν κΈ°κ°μ μΆ©λΆν ν보νλ €κ³ "μΌλ¨ λμνλ ꡬν"μ μ°μ ν΄μ λΉ λ₯΄κ² PRμ μ¬λ Έμ΅λλ€. κ·Έλ¬λ€ 보λ μ΄μ λ―Έμ λ³΄λ€ μ½λ μΌκ΄μ±μ΄ λ¨μ΄μ§λ λΆλΆμ΄ μμ κ² κ°μ΅λλ€.
μ΄λ² 리뷰μ λͺ©νλ, λ€μ λ―Έμ μμ νμ΄κ° μ μ½λλ₯Ό μ½κ³ μλλ₯Ό λΉ λ₯΄κ² νμ ν μ μλ μμ€κΉμ§ λμ΄μ¬λ¦¬λ κ²μ λλ€. κ°λ μ μΌλ‘ κΆκΈν λΆλΆμ μλμ, μ½λ λ¨μμμ κΆκΈν λΆλΆμ μΈλΌμΈ μ½λ©νΈλ‘ λ¨κ²¨λμμ΅λλ€.
μ΄λ² 리뷰λ μ λΆνλ립λλ€. κ°μ¬ν©λλ€!
μ²΄ν¬ λ¦¬μ€νΈ
testλ₯Ό μ€ννμ λ, λͺ¨λ ν μ€νΈκ° μ μμ μΌλ‘ ν΅κ³Όνλμ?λ² μ΄μ€ μ½λ μ ν 체ν¬
μ΄λ€ λΆλΆμ μ§μ€νμ¬ λ¦¬λ·°ν΄μΌ ν κΉμ?
1. mockData.sqlμ λν ν μ€νΈ μμ‘΄μ±
μ§ννλ€ λ³΄λ 컨νΈλ‘€λ¬ ν μ€νΈλ€μ΄
mockData.sqlμ κ°νκ² μμ‘΄νκ² λλ€λ κ±Έ λκΌμ΅λλ€. λ€μν μΌμ΄μ€λ₯Ό ν μ€νΈνκΈ° μν΄mockData.sqlμ λ°μ΄ν°λ₯Ό μΆκ°νλ©΄, κ·Έλλ§λ€ κΈ°μ‘΄ ν μ€νΈλ€μ΄ κΉ¨μ§κ³€ νμ΅λλ€.mockData.sqlμ μμ νλ κ² λλ €μμ§ μ λμμ΅λλ€. μ΄ λ°μ΄ν°κ° λ°λμ΄λ ν μ€νΈκ° μμ°μ€λ½κ² λ°λΌκ° μ μλ λ°©λ²μ΄ μμκΉμ? μ΄ λΆνΈν¨μ ν΄κ²°νλ λ°©λ²λ‘ μ΄λ λκ΅¬κ° μμ κ² κ°μλ°, μ§κΈ μμ μμ μ λͺ¨λ₯΄κ² μ΅λλ€.2. ErrorCode Enum νμ©
ν λ‘ μ‘°μλ€κ³Ό ν¨κ» μμΈ μλ΅μ λ΄κΈΈ λ΄μ©μ μ μνκ³ , μλ νμμ λ°λμ΅λλ€.
μλ¬ μλ΅ νμ (ν λ‘ κ·Έλ£Ήμμ μ ν νμ)
μ΄ νλ¨μ΄ μ λ΅μΈμ§ μλμ§λ κ³ λ €νμ§ μμκ³ , κ°μμ κ°μ΄ νμνλ€κ³ μκ°ν μ΄μ λ λ€μκ³Ό κ°μ΅λλ€.
κ·Έλ¦¬κ³ μ½λλ₯Ό μμ±νκΈ° μ μ μ§μ μ΄λ°μμΌλ‘ μμ²μ λνμ¬ λ°μν μ μλ μμΈ μν©μ 미리 μ 리ν΄λ΄€μ΅λλ€.

μ½λ μμ± μ μ λ°μ κ°λ₯ν μμΈ μν©μ 미리 μ 리ν΄λμκ³ , ν΄λΉ λ΄μ©μ study-log/error-design.mdμ κΈ°λ‘ν΄λμμ΅λλ€.
ꡬννλ©΄μ λλ λΆνΈν μ λ μμμ΅λλ€. ErrorCode Enumμ 미리 μ μΈν΄μΌ νλ νλͺ©μ΄ λ§μμ§μλ‘ ν΄λμ€ μ체μ κ°λ μ±μ΄ λ¨μ΄μ§λ€κ³ λκΌμ΅λλ€. 컀μ€ν μμΈ κ΅¬μ‘°λ μ νλ¨λλ‘ μμ λ‘κ² μ€κ³ν κ²μ΄λΌ μ μ νμ§ νμ μ΄ μμ΅λλ€.