From 504ad4da29c05737f6f329258f9762256297c2ab Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Sun, 7 Dec 2025 20:12:22 +0900 Subject: [PATCH 01/13] =?UTF-8?q?docs=20:=20=EB=AA=A9=ED=91=9C=20=EB=B0=8F?= =?UTF-8?q?=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20md=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/04-lms-refactor.md | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/04-lms-refactor.md diff --git a/docs/04-lms-refactor.md b/docs/04-lms-refactor.md new file mode 100644 index 000000000..1a6481bd1 --- /dev/null +++ b/docs/04-lms-refactor.md @@ -0,0 +1,43 @@ +# πŸš€ 4단계 - μˆ˜κ°•μ‹ μ²­(μš”κ΅¬μ‚¬ν•­ λ³€κ²½) + +*** + +## μ½”λ“œ 리뷰 + +> PR 링크 : + +## λ‚˜μ˜ ν•™μŠ΅ λͺ©ν‘œ + +### 1. 컴파일 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ λ¦¬νŒ©ν„°λ§ν•˜μž. + +- ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬μ‚¬ν•­μ—μ„œμ™€ 같이 λ¦¬νŒ©ν„°λ§ν•  λ•Œ 컴파일 μ—λŸ¬κ°€ μ΅œλŒ€ν•œ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ κ΅¬ν˜„ν•œλ‹€. +- 이 λͺ©ν‘œλ₯Ό μ§€ν‚€λ €λ©΄ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ°”λ‘œ μˆ˜μ •ν•˜λŠ” 것이 μ•„λ‹Œ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³΅μ‚¬ν•œ λ’€ μ μ§„μ μœΌλ‘œ μ½”λ“œλ₯Ό μˆ˜μ •ν•΄ λ‚˜μ•„κ°„λ‹€. + +## 핡심 ν•™μŠ΅ λͺ©ν‘œ + +- DB ν…Œμ΄λΈ”μ΄ 변경될 λ•Œλ„ μŠ€νŠΈλž­κΈ€λŸ¬ νŒ¨ν„΄μ„ μ μš©ν•΄ 점진적인 λ¦¬νŒ©ν„°λ§μ„ μ—°μŠ΅ν•œλ‹€. + - [μŠ€νŠΈλž­κΈ€λŸ¬(κ΅μ‚΄μž) νŒ¨ν„΄ - λ§ˆν‹΄ 파울러](https://martinfowler.com/bliki/StranglerFigApplication.html) + - [μŠ€νŠΈλž­κΈ€λŸ¬ 무화과 νŒ¨ν„΄](https://learn.microsoft.com/ko-kr/azure/architecture/patterns/strangler-fig) + +## λ³€κ²½λœ κΈ°λŠ₯ μš”κ΅¬μ‚¬ν•­ + +### κ°•μ˜ μˆ˜κ°•μ‹ μ²­μ€ κ°•μ˜ μƒνƒœκ°€ λͺ¨μ§‘쀑일 λ•Œλ§Œ κ°€λŠ₯ν•˜λ‹€. + +- κ°•μ˜κ°€ μ§„ν–‰ 쀑인 μƒνƒœμ—μ„œλ„ μˆ˜κ°•μ‹ μ²­μ΄ κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€. + - κ°•μ˜ μ§„ν–‰ μƒνƒœ(쀀비쀑, 진행쀑, μ’…λ£Œ)와 λͺ¨μ§‘ μƒνƒœ(λΉ„λͺ¨μ§‘쀑, λͺ¨μ§‘쀑)둜 μƒνƒœ 값을 뢄리해야 ν•œλ‹€. + +### κ°•μ˜λŠ” κ°•μ˜ 컀버 이미지 정보λ₯Ό κ°€μ§„λ‹€. + +- κ°•μ˜λŠ” ν•˜λ‚˜ μ΄μƒμ˜ 컀버 이미지λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€. + +### 강사가 μŠΉμΈν•˜μ§€ μ•Šμ•„λ„ μˆ˜κ°• μ‹ μ²­ν•˜λŠ” λͺ¨λ“  μ‚¬λžŒμ΄ μˆ˜κ°• κ°€λŠ₯ν•˜λ‹€. + +- μš°μ•„ν•œν…Œν¬μ½”μŠ€(무료), μš°μ•„ν•œν…Œν¬μΊ ν”„ Pro(유료)와 같이 μ„ λ°œλœ μΈμ›λ§Œ μˆ˜κ°• κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€. + - κ°•μ‚¬λŠ” μˆ˜κ°•μ‹ μ²­ν•œ μ‚¬λžŒ 쀑 μ„ λ°œλœ 인원에 λŒ€ν•΄μ„œλ§Œ μˆ˜κ°• 승인이 κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€. + - κ°•μ‚¬λŠ” μˆ˜κ°•μ‹ μ²­ν•œ μ‚¬λžŒ 쀑 μ„ λ°œλ˜μ§€ μ•Šμ€ μ‚¬λžŒμ€ μˆ˜κ°•μ„ μ·¨μ†Œν•  수 μžˆμ–΄μ•Ό ν•œλ‹€. + +## ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬μ‚¬ν•­ + +- λ¦¬νŒ©ν„°λ§ν•  λ•Œ 컴파일 μ—λŸ¬μ™€ 기쑴의 λ‹¨μœ„ ν…ŒμŠ€νŠΈμ˜ μ‹€νŒ¨λ₯Ό μ΅œμ†Œν™”ν•˜λ©΄μ„œ 점진적인 λ¦¬νŒ©ν„°λ§μ΄ κ°€λŠ₯ν•˜λ„λ‘ ν•œλ‹€. +- DB ν…Œμ΄λΈ”μ— 데이터가 μ‘΄μž¬ν•œλ‹€λŠ” κ°€μ •ν•˜μ— λ¦¬νŒ©ν„°λ§ν•΄μ•Ό ν•œλ‹€. + - 즉, 기쑴에 μŒ“μΈ 데이터λ₯Ό μ œκ±°ν•˜μ§€ μ•Šμ€ μƒνƒœλ‘œ λ¦¬νŒ©ν„°λ§ ν•΄μ•Ό ν•œλ‹€. \ No newline at end of file From 487809cdcaffeebc62bf97bfa581f7a98d3d994d Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Mon, 8 Dec 2025 10:30:15 +0900 Subject: [PATCH 02/13] =?UTF-8?q?refactor=20:=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=9B=EC=9D=80=20=EB=82=B4=EC=9A=A9=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=A7=84=ED=96=89(Session,=20SessionRecord?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=A7=81=EC=A0=91=20=EB=B3=80=ED=99=98?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EA=B3=A0=20Mapper=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20Entity,=20Domain=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EB=B0=98=ED=99=98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/SessionService.java | 7 ++-- .../courses/domain/session/Session.java | 16 -------- .../domain/session/mapper/SessionMapper.java | 39 +++++++++++++++++++ .../courses/record/SessionRecord.java | 13 +++---- .../infrastructure/SessionRepositoryTest.java | 3 +- 5 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java diff --git a/src/main/java/nextstep/courses/domain/service/SessionService.java b/src/main/java/nextstep/courses/domain/service/SessionService.java index 34190bed5..d3c344c37 100644 --- a/src/main/java/nextstep/courses/domain/service/SessionService.java +++ b/src/main/java/nextstep/courses/domain/service/SessionService.java @@ -7,6 +7,7 @@ import nextstep.courses.domain.session.Enrollment; import nextstep.courses.domain.session.Enrollments; import nextstep.courses.domain.session.Session; +import nextstep.courses.domain.session.mapper.SessionMapper; import nextstep.courses.domain.session.repository.EnrollmentRepository; import nextstep.courses.domain.session.repository.SessionRepository; import nextstep.courses.record.EnrollmentRecord; @@ -52,20 +53,20 @@ public Session findById(Long id) { List enrollmentRecords = enrollmentRepository.findBySessionId(id); Enrollments enrollments = toEnrollments(enrollmentRecords); - return sessionRecord.toSession(saveCourse, saveCoverImage, enrollments); + return SessionMapper.toDomain(sessionRecord, saveCourse, saveCoverImage, enrollments); } @Transactional public int save(Session session) { coverImageRepository.save(session.getCoverImage()); - return sessionRepository.save(session.toSessionRecord()); + return sessionRepository.save(SessionMapper.toEntity(session)); } @Transactional public int saveEnrollment(Enrollment enrollment, Payment payment) { SessionRecord sessionRecord = sessionRepository.findById(enrollment.getSessionId()); List enrollmentRecords = enrollmentRepository.findBySessionId(enrollment.getSessionId()); - Session session = sessionRecord.toSession(null, null, toEnrollments(enrollmentRecords)); + Session session = SessionMapper.toDomain(sessionRecord, null, null, toEnrollments(enrollmentRecords)); session.addEnrollment(enrollment, payment); paymentRepository.save(payment); diff --git a/src/main/java/nextstep/courses/domain/session/Session.java b/src/main/java/nextstep/courses/domain/session/Session.java index 37c53f627..5b11c24e3 100644 --- a/src/main/java/nextstep/courses/domain/session/Session.java +++ b/src/main/java/nextstep/courses/domain/session/Session.java @@ -85,22 +85,6 @@ public List getEnrollments() { return enrollments.getEnrollments(); } - public SessionRecord toSessionRecord() { - return new SessionRecord( - this.id, - this.course.getId(), - this.coverImage.getId(), - this.getSessionRange().getStartDate(), - this.getSessionRange().getEndDate(), - this.getMaxCapacity(), - this.getTuition(), - this.getSessionType(), - this.getSessionStatus().toString(), - this.createdAt, - this.updatedAt - ); - } - @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; diff --git a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java new file mode 100644 index 000000000..3a65df0d6 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java @@ -0,0 +1,39 @@ +package nextstep.courses.domain.session.mapper; + +import nextstep.courses.domain.Course; +import nextstep.courses.domain.image.CoverImage; +import nextstep.courses.domain.session.Enrollments; +import nextstep.courses.domain.session.Session; +import nextstep.courses.domain.session.constant.SessionStatus; +import nextstep.courses.record.SessionRecord; + +public class SessionMapper { + + public static SessionRecord toEntity(Session session) { + return new SessionRecord( + session.getId(), + session.getCourse().getId(), + session.getCoverImage().getId(), + session.getStartDate(), + session.getEndDate(), + session.getMaxCapacity(), + session.getTuition(), + session.getSessionType(), + session.getSessionStatus().name(), + session.getCreatedAt(), + session.getUpdatedAt() + ); + } + + public static Session toDomain(SessionRecord record, Course course, CoverImage coverImage, Enrollments enrollments) { + return new Session( + record.getId(), + course, + record.createdSessionRange(), + record.createdSessionPolicy(), + SessionStatus.from(record.getSessionStatus()), + coverImage, + enrollments + ); + } +} diff --git a/src/main/java/nextstep/courses/record/SessionRecord.java b/src/main/java/nextstep/courses/record/SessionRecord.java index 51d1e893e..9c411a31f 100644 --- a/src/main/java/nextstep/courses/record/SessionRecord.java +++ b/src/main/java/nextstep/courses/record/SessionRecord.java @@ -39,19 +39,18 @@ public SessionRecord(Long id, Long courseId, Long coverImageId, this.updatedAt = updatedAt; } - public Session toSession(Course course, CoverImage coverImage, Enrollments enrollments) { - return new Session(this.id, course, createdSessionRange(), createdSessionPolicy(), - SessionStatus.from(this.sessionStatus), coverImage, enrollments); - } - - private SessionRange createdSessionRange() { + public SessionRange createdSessionRange() { return new SessionRange(this.startDate, this.endDate); } - private SessionPolicy createdSessionPolicy() { + public SessionPolicy createdSessionPolicy() { return new SessionPolicy(this.maxCapacity, this.tuition, this.sessionType); } + public Long getId() { + return id; + } + public Long getCourseId() { return courseId; } diff --git a/src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java index f3cd618fb..892789d03 100644 --- a/src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java +++ b/src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java @@ -1,6 +1,7 @@ package nextstep.courses.infrastructure; import nextstep.courses.domain.session.Session; +import nextstep.courses.domain.session.mapper.SessionMapper; import nextstep.courses.domain.session.repository.SessionRepository; import nextstep.courses.domain.session.builder.SessionBuilder; import nextstep.courses.record.SessionRecord; @@ -31,7 +32,7 @@ void setUp() { @Test void crud(){ Session session = new SessionBuilder().withId(2L).build(); - int count = sessionRepository.save(session.toSessionRecord()); + int count = sessionRepository.save(SessionMapper.toEntity(session)); assertThat(count).isEqualTo(1); SessionRecord sessionRecord = sessionRepository.findById(1000L); From 4260bb787685414be86f18d8cbdd3e7de7b2f72f Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:34:33 +0900 Subject: [PATCH 03/13] =?UTF-8?q?refactor=20:=20Session=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=EC=84=9C=20=EC=83=81=EC=86=8D=20?= =?UTF-8?q?=EB=B0=9B=EB=8D=98=20SessionCore=20=EC=9D=B8=EC=8A=A4=ED=84=B4?= =?UTF-8?q?=EC=8A=A4=20=EB=B3=80=EC=88=98=EB=A1=9C=20=EC=9D=B4=EB=8F=99,?= =?UTF-8?q?=20BaseEntity=20=EC=83=9D=EC=84=B1=20=ED=9B=84=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=ED=81=B4=EB=9E=98=EC=8A=A4=EC=97=90=20?= =?UTF-8?q?=EC=83=81=EC=86=8D(SessionCore=20=EC=9A=94=EA=B5=AC=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20?= =?UTF-8?q?=EC=83=81=EC=86=8D=EC=9D=B4=20=EC=95=84=EB=8B=8C=20=EC=9D=B8?= =?UTF-8?q?=EC=8A=A4=ED=84=B4=EC=8A=A4=20=EB=B3=80=EC=88=98=EB=A1=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20=EA=B2=83=EC=9D=B4=20?= =?UTF-8?q?=EC=A2=8B=EA=B2=A0=EB=8B=A4=EA=B3=A0=20=ED=8C=90=EB=8B=A8.)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/courses/domain/Course.java | 26 ++--------- .../courses/domain/session/BaseEntity.java | 28 ++++++++++++ .../courses/domain/session/Enrollment.java | 19 +++----- .../courses/domain/session/Session.java | 45 +++++++------------ .../courses/domain/session/SessionCore.java | 2 +- .../domain/session/SessionOperations.java | 12 +++++ .../domain/session/mapper/SessionMapper.java | 12 ++--- .../JdbcEnrollmentRespository.java | 4 +- .../courses/record/EnrollmentRecord.java | 2 +- .../courses/record/SessionRecord.java | 3 -- src/main/resources/data.sql | 4 +- .../domain/session/EnrollmentTest.java | 4 +- .../courses/domain/session/SessionTest.java | 16 +++---- .../session/builder/EnrollmentBuilder.java | 4 +- .../session/builder/SessionBuilder.java | 2 +- .../EnrollmentRepositoryTest.java | 3 +- 16 files changed, 96 insertions(+), 90 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/session/BaseEntity.java create mode 100644 src/main/java/nextstep/courses/domain/session/SessionOperations.java diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index 966093b63..65516c654 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -1,47 +1,35 @@ package nextstep.courses.domain; +import nextstep.courses.domain.session.BaseEntity; import nextstep.courses.domain.session.Session; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -public class Course { - private Long id; +public class Course extends BaseEntity { private String title; private Long creatorId; - private LocalDateTime createdAt; - - private LocalDateTime updatedAt; - private List sessions = new ArrayList<>(); - public Course() { - } public Course(String title, Long creatorId) { this(0L, title, creatorId, LocalDateTime.now(), null); } public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt) { - this.id = id; + super(id, createdAt, updatedAt); this.title = title; this.creatorId = creatorId; - this.createdAt = createdAt; - this.updatedAt = updatedAt; } public void addSession(Session session) { this.sessions.add(session); } - public Long getId() { - return id; - } - public String getTitle() { return title; } @@ -50,18 +38,12 @@ public Long getCreatorId() { return creatorId; } - public LocalDateTime getCreatedAt() { - return createdAt; - } @Override public String toString() { return "Course{" + - "id=" + id + - ", title='" + title + '\'' + + " title='" + title + '\'' + ", creatorId=" + creatorId + - ", createdAt=" + createdAt + - ", updatedAt=" + updatedAt + '}'; } } diff --git a/src/main/java/nextstep/courses/domain/session/BaseEntity.java b/src/main/java/nextstep/courses/domain/session/BaseEntity.java new file mode 100644 index 000000000..c0ccec250 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/BaseEntity.java @@ -0,0 +1,28 @@ +package nextstep.courses.domain.session; + +import java.time.LocalDateTime; + +public abstract class BaseEntity { + + private final Long id; + private final LocalDateTime createdAt; + private final LocalDateTime updatedAt; + + public BaseEntity(Long id, LocalDateTime createdAt, LocalDateTime updatedAt) { + this.id = id; + this.createdAt = createdAt; + this.updatedAt = updatedAt; + } + + public Long getId() { + return id; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } +} diff --git a/src/main/java/nextstep/courses/domain/session/Enrollment.java b/src/main/java/nextstep/courses/domain/session/Enrollment.java index 04f9263d2..8c3e88e44 100644 --- a/src/main/java/nextstep/courses/domain/session/Enrollment.java +++ b/src/main/java/nextstep/courses/domain/session/Enrollment.java @@ -2,28 +2,24 @@ import nextstep.users.domain.NsUser; +import java.time.LocalDateTime; import java.util.Objects; -public class Enrollment { +public class Enrollment extends BaseEntity { - private final Long id; private final NsUser user; private final Long sessionId; - public Enrollment(NsUser user, Long sessionId) { - this(0L, user, sessionId); + public Enrollment(NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt) { + this(0L, user, sessionId, createdAt, updatedAt); } - public Enrollment(Long id, NsUser user, Long sessionId) { - this.id = id; + public Enrollment(Long id, NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt) { + super(id, createdAt, updatedAt); this.user = user; this.sessionId = sessionId; } - public Long getId() { - return id; - } - public NsUser getUser() { return user; } @@ -47,8 +43,7 @@ public int hashCode() { @Override public String toString() { return "Enrollment{" + - "id=" + id + - ", user=" + user + + " user=" + user + ", sessionId=" + sessionId + '}'; } diff --git a/src/main/java/nextstep/courses/domain/session/Session.java b/src/main/java/nextstep/courses/domain/session/Session.java index 5b11c24e3..0433b8221 100644 --- a/src/main/java/nextstep/courses/domain/session/Session.java +++ b/src/main/java/nextstep/courses/domain/session/Session.java @@ -4,21 +4,18 @@ import nextstep.courses.domain.image.CoverImage; import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.courses.domain.session.constant.SessionType; -import nextstep.courses.record.SessionRecord; import nextstep.payments.domain.Payment; import java.time.LocalDateTime; import java.util.List; import java.util.Objects; -public class Session extends SessionCore { +public class Session extends BaseEntity { - private final Long id; private Course course; private final CoverImage coverImage; private final Enrollments enrollments; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; + private SessionCore sessionCore; public Session(Long id, LocalDateTime startDate, LocalDateTime endDate, String sessionType, String sessionStatus, CoverImage coverImage) { this(id, startDate, endDate, sessionType, Integer.MAX_VALUE, 0L, sessionStatus, coverImage); @@ -37,33 +34,28 @@ public Session(Long id, SessionRange sessionRange, SessionType sessionType, Capa } public Session(Long id, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage) { - this(id, null, sessionRange, sessionPolicy, sessionStatus, coverImage, new Enrollments(), LocalDateTime.now(), null); + this(id, null, coverImage, new Enrollments(), LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); } public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage, Enrollments enrollments) { - this(id, course, sessionRange, sessionPolicy, sessionStatus, coverImage, enrollments, LocalDateTime.now(), null); + this(id, course, coverImage, enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); } - public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt) { - super(sessionRange, sessionPolicy, sessionStatus); - this.id = id; + public Session(Long id, Course course, CoverImage coverImage, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCore sessionCore) { + super(id, createdAt, updatedAt); this.course = course; this.coverImage = coverImage; this.enrollments = enrollments; - this.createdAt = createdAt; - this.updatedAt = updatedAt; + this.sessionCore = sessionCore; } public void addEnrollment(Enrollment enrollment, Payment payment) { - validatePaymentAmount(payment); - validateNotFull(this.enrollments); - validateSessionStatus(); + sessionCore.validatePaymentAmount(payment); + sessionCore.validateNotFull(this.enrollments); + sessionCore.validateSessionStatus(); this.enrollments.add(enrollment); } - public Long getId() { - return id; - } public Course getCourse() { return course; @@ -73,12 +65,8 @@ public CoverImage getCoverImage() { return coverImage; } - public LocalDateTime getCreatedAt() { - return createdAt; - } - - public LocalDateTime getUpdatedAt() { - return updatedAt; + public SessionCore getSessionCore() { + return sessionCore; } public List getEnrollments() { @@ -89,22 +77,21 @@ public List getEnrollments() { public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; Session session = (Session) o; - return Objects.equals(id, session.id) && Objects.equals(coverImage, session.coverImage) && Objects.equals(enrollments, session.enrollments); + return Objects.equals(getCourse(), session.getCourse()) && Objects.equals(getCoverImage(), session.getCoverImage()) && Objects.equals(getEnrollments(), session.getEnrollments()) && Objects.equals(getSessionCore(), session.getSessionCore()); } @Override public int hashCode() { - return Objects.hash(id, coverImage, enrollments); + return Objects.hash(getCourse(), getCoverImage(), getEnrollments(), getSessionCore()); } @Override public String toString() { return "Session{" + - "id=" + id + + "course=" + course + ", coverImage=" + coverImage + ", enrollments=" + enrollments + + ", sessionCore=" + sessionCore + '}'; } - - } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCore.java b/src/main/java/nextstep/courses/domain/session/SessionCore.java index ab5040a75..f43c02d01 100644 --- a/src/main/java/nextstep/courses/domain/session/SessionCore.java +++ b/src/main/java/nextstep/courses/domain/session/SessionCore.java @@ -6,7 +6,7 @@ import java.time.LocalDateTime; -public abstract class SessionCore { +public class SessionCore { private final SessionRange sessionRange; private final SessionPolicy sessionPolicy; diff --git a/src/main/java/nextstep/courses/domain/session/SessionOperations.java b/src/main/java/nextstep/courses/domain/session/SessionOperations.java new file mode 100644 index 000000000..2ac528f1e --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/SessionOperations.java @@ -0,0 +1,12 @@ +package nextstep.courses.domain.session; + +import nextstep.payments.domain.Payment; + +public interface SessionOperations { + + void validateNotFull(Enrollments enrollments); + void validatePaymentAmount(Payment payment); + void validateSessionStatus(); + + +} diff --git a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java index 3a65df0d6..33589ef93 100644 --- a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java +++ b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java @@ -14,12 +14,12 @@ public static SessionRecord toEntity(Session session) { session.getId(), session.getCourse().getId(), session.getCoverImage().getId(), - session.getStartDate(), - session.getEndDate(), - session.getMaxCapacity(), - session.getTuition(), - session.getSessionType(), - session.getSessionStatus().name(), + session.getSessionCore().getStartDate(), + session.getSessionCore().getEndDate(), + session.getSessionCore().getMaxCapacity(), + session.getSessionCore().getTuition(), + session.getSessionCore().getSessionType(), + session.getSessionCore().getSessionStatus().name(), session.getCreatedAt(), session.getUpdatedAt() ); diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java b/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java index 2cc762205..edc9b0544 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java @@ -19,8 +19,8 @@ public JdbcEnrollmentRespository(JdbcOperations jdbcTemplate) { @Override public int save(Enrollment enrollment) { - String sql = "insert into enrollment (session_id, user_id) values (?, ?)"; - return jdbcTemplate.update(sql, enrollment.getSessionId(), enrollment.getUser().getId()); + String sql = "insert into enrollment (session_id, user_id, created_at) values (?, ?, ?)"; + return jdbcTemplate.update(sql, enrollment.getSessionId(), enrollment.getUser().getId(), enrollment.getCreatedAt()); } @Override diff --git a/src/main/java/nextstep/courses/record/EnrollmentRecord.java b/src/main/java/nextstep/courses/record/EnrollmentRecord.java index bfac04bf9..0fbcf27b8 100644 --- a/src/main/java/nextstep/courses/record/EnrollmentRecord.java +++ b/src/main/java/nextstep/courses/record/EnrollmentRecord.java @@ -16,7 +16,7 @@ public EnrollmentRecord(Long id, Long userId, Long sessionId) { } public Enrollment toEnrollment(NsUser user) { - return new Enrollment(this.id, user, this.sessionId); + return new Enrollment(this.id, user, this.sessionId, null, null); } public Long getId() { diff --git a/src/main/java/nextstep/courses/record/SessionRecord.java b/src/main/java/nextstep/courses/record/SessionRecord.java index 9c411a31f..417d53c7f 100644 --- a/src/main/java/nextstep/courses/record/SessionRecord.java +++ b/src/main/java/nextstep/courses/record/SessionRecord.java @@ -1,9 +1,6 @@ package nextstep.courses.record; -import nextstep.courses.domain.Course; -import nextstep.courses.domain.image.CoverImage; import nextstep.courses.domain.session.*; -import nextstep.courses.domain.session.constant.SessionStatus; import java.time.LocalDateTime; diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 26559d7a5..33b8cdab4 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -19,5 +19,5 @@ VALUES (2, 1, 1,CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 100, 300000, 'PAID', ' INSERT INTO cover_image (id, size, type, width, height) VALUES (1, 1, 'png', 300, 200); -INSERT INTO enrollment (id, user_id, session_id) VALUES (1, 1, 1); -INSERT INTO enrollment (id, user_id, session_id) VALUES (2, 2, 1); \ No newline at end of file +INSERT INTO enrollment (id, user_id, session_id, created_at) VALUES (1, 1, 1, CURRENT_TIMESTAMP()); +INSERT INTO enrollment (id, user_id, session_id, created_at) VALUES (2, 2, 1, CURRENT_TIMESTAMP()); \ No newline at end of file diff --git a/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java b/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java index 977f22349..8c3020b4e 100644 --- a/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java +++ b/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java @@ -3,13 +3,15 @@ import nextstep.users.domain.NsUserTest; import org.junit.jupiter.api.Test; +import java.time.LocalDateTime; + import static org.assertj.core.api.Assertions.*; class EnrollmentTest { @Test void μˆ˜κ°•μ‹ μ²­_정상_생성() { - Enrollment enrollment = new Enrollment(NsUserTest.JAVAJIGI, 1L); + Enrollment enrollment = new Enrollment(NsUserTest.JAVAJIGI, 1L, LocalDateTime.now(), null); assertThat(enrollment).isNotNull(); } diff --git a/src/test/java/nextstep/courses/domain/session/SessionTest.java b/src/test/java/nextstep/courses/domain/session/SessionTest.java index 08b6c5959..ff49805b5 100644 --- a/src/test/java/nextstep/courses/domain/session/SessionTest.java +++ b/src/test/java/nextstep/courses/domain/session/SessionTest.java @@ -24,19 +24,19 @@ public class SessionTest { void 유료_κ°•μ˜_정상_생성() { Session sessionBuilder = new SessionBuilder().build(); - assertThat(sessionBuilder.getSessionPolicy().getSessionType()).isEqualTo(SessionType.PAID); - assertThat(sessionBuilder.getSessionPolicy().getTuition()).isEqualTo(new Tuition(300_000L)); - assertThat(sessionBuilder.getSessionStatus()).isEqualTo(SessionStatus.PENDING); - assertThat(sessionBuilder.getSessionPolicy().getMaxCapacity()).isEqualTo(new Capacity(100)); + assertThat(sessionBuilder.getSessionCore().getSessionPolicy().getSessionType()).isEqualTo(SessionType.PAID); + assertThat(sessionBuilder.getSessionCore().getSessionPolicy().getTuition()).isEqualTo(new Tuition(300_000L)); + assertThat(sessionBuilder.getSessionCore().getSessionStatus()).isEqualTo(SessionStatus.PENDING); + assertThat(sessionBuilder.getSessionCore().getSessionPolicy().getMaxCapacity()).isEqualTo(new Capacity(100)); } @Test void 무료_κ°•μ˜_정상_생성() { Session session = new Session(1L, START_DATE, END_DATE, "free", "pending", COVER_IMAGE); - assertThat(session.getSessionPolicy().getSessionType()).isEqualTo(SessionType.FREE); - assertThat(session.getSessionPolicy().getMaxCapacity()).isEqualTo(new Capacity(Integer.MAX_VALUE)); - assertThat(session.getSessionPolicy().getTuition()).isEqualTo(new Tuition(0L)); + assertThat(session.getSessionCore().getSessionPolicy().getSessionType()).isEqualTo(SessionType.FREE); + assertThat(session.getSessionCore().getSessionPolicy().getMaxCapacity()).isEqualTo(new Capacity(Integer.MAX_VALUE)); + assertThat(session.getSessionCore().getSessionPolicy().getTuition()).isEqualTo(new Tuition(0L)); } @Test @@ -58,7 +58,7 @@ public class SessionTest { .withEnrollment(new EnrollmentBuilder().build()) .build(); - Enrollment newEnrollment = new Enrollment(NsUserTest.SANJIGI, 1L); + Enrollment newEnrollment = new Enrollment(NsUserTest.SANJIGI, 1L, LocalDateTime.now(), null); Payment payment = new Payment(1L, 1L, 300_000L); assertThatThrownBy(() -> session.addEnrollment(newEnrollment, payment)) diff --git a/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java index e1805c560..5f5be6298 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java @@ -4,6 +4,8 @@ import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; +import java.time.LocalDateTime; + public class EnrollmentBuilder { private NsUser user = new NsUser(1L, "javajigi", "password", "name", "javajigi@slipp.net"); @@ -21,7 +23,7 @@ public EnrollmentBuilder withSessionId(Long sessionId) { public Enrollment build() { - return new Enrollment(user, sessionId); + return new Enrollment(user, sessionId, LocalDateTime.now(), null); } } diff --git a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java index 5c1c54df9..cad12d8b2 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java @@ -66,7 +66,7 @@ public SessionBuilder withUpdatedAt(LocalDateTime updatedAt) { } public Session build() { - return new Session(id, course, sessionRange, sessionPolicy, sessionStatus, coverImage, enrollments, createdAt, updatedAt); + return new Session(id, course, coverImage, enrollments, createdAt, updatedAt, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); } } diff --git a/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java index acc8b125d..97dcf7136 100644 --- a/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java +++ b/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java @@ -13,6 +13,7 @@ import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; import org.springframework.jdbc.core.JdbcTemplate; +import java.time.LocalDateTime; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -33,7 +34,7 @@ void setUp() { @Test void crud() { - int count = enrollmentRepository.save(new Enrollment(NsUserTest.JAVAJIGI, 1L)); + int count = enrollmentRepository.save(new Enrollment(NsUserTest.JAVAJIGI, 1L, LocalDateTime.now(), null)); assertThat(count).isEqualTo(1); List enrollments = enrollmentRepository.findBySessionId(1L); From 48db9b388507e6ad0acc4782380913a5bd5a704b Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Mon, 8 Dec 2025 17:31:20 +0900 Subject: [PATCH 04/13] =?UTF-8?q?refactor=20:=20SessionCoreFacade=20interf?= =?UTF-8?q?ace=20=EC=83=9D=EC=84=B1,=20SessionCoreV2=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20SessionCoreV2=EC=97=90=EC=84=9C=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=EB=90=9C=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20=EC=98=88=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/domain/session/Session.java | 6 +- .../courses/domain/session/SessionCore.java | 11 ++- .../domain/session/SessionCoreFacade.java | 22 ++++++ .../courses/domain/session/SessionCoreV2.java | 73 +++++++++++++++++++ .../domain/session/SessionOperations.java | 12 --- 5 files changed, 105 insertions(+), 19 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java create mode 100644 src/main/java/nextstep/courses/domain/session/SessionCoreV2.java delete mode 100644 src/main/java/nextstep/courses/domain/session/SessionOperations.java diff --git a/src/main/java/nextstep/courses/domain/session/Session.java b/src/main/java/nextstep/courses/domain/session/Session.java index 0433b8221..dedb50aa5 100644 --- a/src/main/java/nextstep/courses/domain/session/Session.java +++ b/src/main/java/nextstep/courses/domain/session/Session.java @@ -15,7 +15,7 @@ public class Session extends BaseEntity { private Course course; private final CoverImage coverImage; private final Enrollments enrollments; - private SessionCore sessionCore; + private final SessionCoreFacade sessionCore; public Session(Long id, LocalDateTime startDate, LocalDateTime endDate, String sessionType, String sessionStatus, CoverImage coverImage) { this(id, startDate, endDate, sessionType, Integer.MAX_VALUE, 0L, sessionStatus, coverImage); @@ -41,7 +41,7 @@ public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy this(id, course, coverImage, enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); } - public Session(Long id, Course course, CoverImage coverImage, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCore sessionCore) { + public Session(Long id, Course course, CoverImage coverImage, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCoreFacade sessionCore) { super(id, createdAt, updatedAt); this.course = course; this.coverImage = coverImage; @@ -65,7 +65,7 @@ public CoverImage getCoverImage() { return coverImage; } - public SessionCore getSessionCore() { + public SessionCoreFacade getSessionCore() { return sessionCore; } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCore.java b/src/main/java/nextstep/courses/domain/session/SessionCore.java index f43c02d01..8a8dca190 100644 --- a/src/main/java/nextstep/courses/domain/session/SessionCore.java +++ b/src/main/java/nextstep/courses/domain/session/SessionCore.java @@ -6,7 +6,7 @@ import java.time.LocalDateTime; -public class SessionCore { +public class SessionCore implements SessionCoreFacade { private final SessionRange sessionRange; private final SessionPolicy sessionPolicy; @@ -18,19 +18,22 @@ public SessionCore(SessionRange sessionRange, SessionPolicy sessionPolicy, Sessi this.sessionStatus = sessionStatus; } - protected void validatePaymentAmount(Payment payment) { + @Override + public void validatePaymentAmount(Payment payment) { if (this.sessionPolicy.isSessionType()) { sessionPolicy.matchAmount(payment); } } - protected void validateNotFull(Enrollments enrollments) { + @Override + public void validateNotFull(Enrollments enrollments) { if (this.sessionPolicy.matchSize(enrollments.size())) { throw new IllegalArgumentException("μˆ˜κ°•μΈμ›μ΄ μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."); } } - protected void validateSessionStatus() { + @Override + public void validateSessionStatus() { if (!this.sessionStatus.equals(SessionStatus.ACTIVE)) { throw new IllegalArgumentException("ν˜„μž¬λŠ” κ°•μ˜ λͺ¨μ§‘쀑이 μ•„λ‹™λ‹ˆλ‹€."); } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java b/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java new file mode 100644 index 000000000..4efefaf2f --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java @@ -0,0 +1,22 @@ +package nextstep.courses.domain.session; + +import nextstep.courses.domain.session.constant.SessionStatus; +import nextstep.payments.domain.Payment; + +import java.time.LocalDateTime; + +public interface SessionCoreFacade { + + LocalDateTime getStartDate(); + LocalDateTime getEndDate(); + int getMaxCapacity(); + Long getTuition(); + String getSessionType(); + SessionPolicy getSessionPolicy(); + SessionRange getSessionRange(); + SessionStatus getSessionStatus(); + + void validatePaymentAmount(Payment payment); + void validateNotFull(Enrollments enrollments); + void validateSessionStatus(); +} diff --git a/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java b/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java new file mode 100644 index 000000000..9b665aa23 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java @@ -0,0 +1,73 @@ +package nextstep.courses.domain.session; + +import nextstep.courses.domain.session.constant.SessionStatus; +import nextstep.payments.domain.Payment; + +import java.time.LocalDateTime; + +public class SessionCoreV2 implements SessionCoreFacade{ + + private final SessionRange sessionRange; + private final SessionPolicy sessionPolicy; + private final SessionStatus sessionStatus; + + public SessionCoreV2(SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus) { + this.sessionRange = sessionRange; + this.sessionPolicy = sessionPolicy; + this.sessionStatus = sessionStatus; + } + + @Override + public void validatePaymentAmount(Payment payment) { + if (this.sessionPolicy.isSessionType()) { + sessionPolicy.matchAmount(payment); + } + } + + @Override + public void validateNotFull(Enrollments enrollments) { + if (this.sessionPolicy.matchSize(enrollments.size())) { + throw new IllegalArgumentException("μˆ˜κ°•μΈμ›μ΄ μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."); + } + } + + @Override + public void validateSessionStatus() { + if (!this.sessionStatus.equals(SessionStatus.ACTIVE)) { + throw new IllegalArgumentException("ν˜„μž¬λŠ” κ°•μ˜ λͺ¨μ§‘쀑이 μ•„λ‹™λ‹ˆλ‹€."); + } + } + + public LocalDateTime getStartDate() { + return sessionRange.getStartDate(); + } + + public LocalDateTime getEndDate() { + return sessionRange.getEndDate(); + } + + public int getMaxCapacity() { + return sessionPolicy.getMaxCapacity().getValue(); + } + + public Long getTuition() { + return sessionPolicy.getTuition().getValue(); + } + + public String getSessionType() { + return sessionPolicy.getSessionType().toString(); + } + + public SessionPolicy getSessionPolicy() { + return sessionPolicy; + } + + public SessionRange getSessionRange() { + return sessionRange; + } + + public SessionStatus getSessionStatus() { + return sessionStatus; + } + +} diff --git a/src/main/java/nextstep/courses/domain/session/SessionOperations.java b/src/main/java/nextstep/courses/domain/session/SessionOperations.java deleted file mode 100644 index 2ac528f1e..000000000 --- a/src/main/java/nextstep/courses/domain/session/SessionOperations.java +++ /dev/null @@ -1,12 +0,0 @@ -package nextstep.courses.domain.session; - -import nextstep.payments.domain.Payment; - -public interface SessionOperations { - - void validateNotFull(Enrollments enrollments); - void validatePaymentAmount(Payment payment); - void validateSessionStatus(); - - -} From cb4323308cdd0605301d77f541f08b59b9750f0f Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:45:12 +0900 Subject: [PATCH 05/13] =?UTF-8?q?refactor=20:=20=EA=B0=95=EC=9D=98=20?= =?UTF-8?q?=EC=A7=84=ED=96=89=20=EC=83=81=ED=83=9C=20enum=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=B3=80=EA=B2=BD,=20SessionCoreV2=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EC=97=90=20=EB=AA=A8=EC=A7=91=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EA=B0=92=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/domain/session/Session.java | 1 + .../courses/domain/session/SessionCore.java | 5 ++++ .../domain/session/SessionCoreFacade.java | 1 + .../courses/domain/session/SessionCoreV2.java | 16 +++++++++--- .../constant/SessionRecruitmentStatus.java | 15 +++++++++++ .../session/constant/SessionStatus.java | 2 +- src/main/resources/schema.sql | 3 +++ .../domain/session/SessionCoreV2Test.java | 26 +++++++++++++++++++ .../courses/domain/session/SessionTest.java | 10 +++++++ .../session/builder/SessionBuilder.java | 17 +++++++++++- 10 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java create mode 100644 src/test/java/nextstep/courses/domain/session/SessionCoreV2Test.java diff --git a/src/main/java/nextstep/courses/domain/session/Session.java b/src/main/java/nextstep/courses/domain/session/Session.java index dedb50aa5..c08d198a1 100644 --- a/src/main/java/nextstep/courses/domain/session/Session.java +++ b/src/main/java/nextstep/courses/domain/session/Session.java @@ -53,6 +53,7 @@ public void addEnrollment(Enrollment enrollment, Payment payment) { sessionCore.validatePaymentAmount(payment); sessionCore.validateNotFull(this.enrollments); sessionCore.validateSessionStatus(); + sessionCore.validateRecruitmentStatus(); this.enrollments.add(enrollment); } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCore.java b/src/main/java/nextstep/courses/domain/session/SessionCore.java index 8a8dca190..ca8a001ec 100644 --- a/src/main/java/nextstep/courses/domain/session/SessionCore.java +++ b/src/main/java/nextstep/courses/domain/session/SessionCore.java @@ -39,6 +39,11 @@ public void validateSessionStatus() { } } + @Override + public void validateRecruitmentStatus() { + + } + public LocalDateTime getStartDate() { return sessionRange.getStartDate(); } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java b/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java index 4efefaf2f..381501bbd 100644 --- a/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java +++ b/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java @@ -19,4 +19,5 @@ public interface SessionCoreFacade { void validatePaymentAmount(Payment payment); void validateNotFull(Enrollments enrollments); void validateSessionStatus(); + void validateRecruitmentStatus(); } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java b/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java index 9b665aa23..300e5fa69 100644 --- a/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java +++ b/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java @@ -1,5 +1,6 @@ package nextstep.courses.domain.session; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.payments.domain.Payment; @@ -10,11 +11,13 @@ public class SessionCoreV2 implements SessionCoreFacade{ private final SessionRange sessionRange; private final SessionPolicy sessionPolicy; private final SessionStatus sessionStatus; + private final SessionRecruitmentStatus sessionRecruitmentStatus; - public SessionCoreV2(SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus) { + public SessionCoreV2(SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, SessionRecruitmentStatus sessionRecruitmentStatus) { this.sessionRange = sessionRange; this.sessionPolicy = sessionPolicy; this.sessionStatus = sessionStatus; + this.sessionRecruitmentStatus = sessionRecruitmentStatus; } @Override @@ -33,8 +36,15 @@ public void validateNotFull(Enrollments enrollments) { @Override public void validateSessionStatus() { - if (!this.sessionStatus.equals(SessionStatus.ACTIVE)) { - throw new IllegalArgumentException("ν˜„μž¬λŠ” κ°•μ˜ λͺ¨μ§‘쀑이 μ•„λ‹™λ‹ˆλ‹€."); + if (this.sessionStatus.equals(SessionStatus.FINISHED)) { + throw new IllegalArgumentException("μ’…λ£Œλœ κ°•μ˜μž…λ‹ˆλ‹€."); + } + } + + @Override + public void validateRecruitmentStatus() { + if(this.sessionRecruitmentStatus.equals(SessionRecruitmentStatus.NOT_RECRUITING)) { + throw new IllegalArgumentException("ν˜„μž¬λŠ” λͺ¨μ§‘기간이 μ•„λ‹™λ‹ˆλ‹€."); } } diff --git a/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java b/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java new file mode 100644 index 000000000..dcaf33205 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java @@ -0,0 +1,15 @@ +package nextstep.courses.domain.session.constant; + +public enum SessionRecruitmentStatus { + + NOT_RECRUITING("λΉ„λͺ¨μ§‘쀑"), + RECRUITING("λͺ¨μ§‘쀑"); + + private String status; + + SessionRecruitmentStatus(String status) { + this.status = status; + } + + +} diff --git a/src/main/java/nextstep/courses/domain/session/constant/SessionStatus.java b/src/main/java/nextstep/courses/domain/session/constant/SessionStatus.java index d35253271..db813a472 100644 --- a/src/main/java/nextstep/courses/domain/session/constant/SessionStatus.java +++ b/src/main/java/nextstep/courses/domain/session/constant/SessionStatus.java @@ -11,7 +11,7 @@ public static SessionStatus from(String value) { return Arrays.stream(SessionStatus.values()) .filter(status -> status.matchStatus(value)) .findFirst() - .orElseThrow(() -> new IllegalArgumentException("쀀비쀑, λͺ¨μ§‘쀑, μ’…λ£Œ 3κ°€μ§€ μƒνƒœλ‘œλ§Œ 생성 κ°€λŠ₯ν•©λ‹ˆλ‹€.")); + .orElseThrow(() -> new IllegalArgumentException("쀀비쀑, 진행쀑, μ’…λ£Œ 3κ°€μ§€ μƒνƒœλ‘œλ§Œ 생성 κ°€λŠ₯ν•©λ‹ˆλ‹€.")); } private boolean matchStatus(String value) { diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 842cfb707..a4e0ec80d 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -57,6 +57,7 @@ create table session ( end_date timestamp not null, max_capacity int not null, tuition bigint not null, + recruit varchar(30), session_type varchar(30), session_status varchar(30), created_at timestamp not null, @@ -77,6 +78,8 @@ create table enrollment ( id bigint not null generated by default as identity(start with 1000), session_id bigint not null, user_id bigint not null, + created_at timestamp not null, + updated_at timestamp, primary key (id) ); diff --git a/src/test/java/nextstep/courses/domain/session/SessionCoreV2Test.java b/src/test/java/nextstep/courses/domain/session/SessionCoreV2Test.java new file mode 100644 index 000000000..5decba22f --- /dev/null +++ b/src/test/java/nextstep/courses/domain/session/SessionCoreV2Test.java @@ -0,0 +1,26 @@ +package nextstep.courses.domain.session; + +import nextstep.courses.domain.session.builder.EnrollmentBuilder; +import nextstep.courses.domain.session.builder.SessionBuilder; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; +import nextstep.payments.domain.Payment; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; + +class SessionCoreV2Test { + + @Test + void κ°•μ˜μ‹ μ²­μ‹œ_λΉ„λͺ¨μ§‘μƒνƒœ_μ—λŸ¬λ°œμƒ(){ + Session session = new SessionBuilder().withRecruit(SessionRecruitmentStatus.NOT_RECRUITING).build(); + assertThatThrownBy(() -> session.addEnrollment(new EnrollmentBuilder().build(), new Payment(1L, 1L, 300_000L))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void κ°•μ˜μ‹ μ²­μ‹œ_λͺ¨μ§‘μƒνƒœ_정상_μ‹ μ²­(){ + Session session = new SessionBuilder().withRecruit(SessionRecruitmentStatus.RECRUITING).build(); + session.addEnrollment(new EnrollmentBuilder().build(), new Payment(1L, 1L, 300_000L)); + assertThat(session.getEnrollments()).hasSize(1); + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/courses/domain/session/SessionTest.java b/src/test/java/nextstep/courses/domain/session/SessionTest.java index ff49805b5..efd201254 100644 --- a/src/test/java/nextstep/courses/domain/session/SessionTest.java +++ b/src/test/java/nextstep/courses/domain/session/SessionTest.java @@ -66,4 +66,14 @@ public class SessionTest { .hasMessageContaining("μˆ˜κ°•μΈμ›μ΄ μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."); } + @Test + void λͺ¨μ§‘정보_μΆ”κ°€ν•˜μ—¬_κ°•μ˜_생성() { + Session sessionBuilder = new SessionBuilder().build(); + + assertThat(sessionBuilder.getSessionCore().getSessionPolicy().getSessionType()).isEqualTo(SessionType.PAID); + assertThat(sessionBuilder.getSessionCore().getSessionPolicy().getTuition()).isEqualTo(new Tuition(300_000L)); + assertThat(sessionBuilder.getSessionCore().getSessionStatus()).isEqualTo(SessionStatus.PENDING); + assertThat(sessionBuilder.getSessionCore().getSessionPolicy().getMaxCapacity()).isEqualTo(new Capacity(100)); + } + } diff --git a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java index cad12d8b2..4a8bb2c0c 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java @@ -3,6 +3,7 @@ import nextstep.courses.domain.Course; import nextstep.courses.domain.image.CoverImage; import nextstep.courses.domain.session.*; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; import nextstep.courses.domain.session.constant.SessionStatus; import java.time.LocalDateTime; @@ -19,6 +20,7 @@ public class SessionBuilder { private Enrollments enrollments = new Enrollments(); private LocalDateTime createdAt = LocalDateTime.now(); private LocalDateTime updatedAt; + private SessionRecruitmentStatus recruit; public SessionBuilder withId(Long id) { this.id = id; @@ -65,8 +67,21 @@ public SessionBuilder withUpdatedAt(LocalDateTime updatedAt) { return this; } + public SessionBuilder withRecruit(SessionRecruitmentStatus recruit) { + this.recruit = recruit; + return this; + } + + private SessionCoreFacade createdSessionCore(){ + if(this.recruit != null) { + return new SessionCoreV2(this.sessionRange, this.sessionPolicy, this.sessionStatus, recruit); + } + + return new SessionCore(this.sessionRange, this.sessionPolicy, this.sessionStatus); + } + public Session build() { - return new Session(id, course, coverImage, enrollments, createdAt, updatedAt, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); + return new Session(id, course, coverImage, enrollments, createdAt, updatedAt, createdSessionCore()); } } From b43e4195885ddcd39b3a54129e4062b14786e200 Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Tue, 9 Dec 2025 09:20:45 +0900 Subject: [PATCH 06/13] =?UTF-8?q?feat=20:=20=EC=BB=A4=EB=B2=84=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=9D=BC=EA=B8=89=EC=BB=AC=EB=9E=99?= =?UTF-8?q?=EC=85=98=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/domain/image/CoverImages.java | 26 +++++++++++++++++++ .../courses/domain/image/CoverImagesTest.java | 17 ++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/main/java/nextstep/courses/domain/image/CoverImages.java create mode 100644 src/test/java/nextstep/courses/domain/image/CoverImagesTest.java diff --git a/src/main/java/nextstep/courses/domain/image/CoverImages.java b/src/main/java/nextstep/courses/domain/image/CoverImages.java new file mode 100644 index 000000000..53232f106 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/image/CoverImages.java @@ -0,0 +1,26 @@ +package nextstep.courses.domain.image; + +import java.util.ArrayList; +import java.util.List; + +public class CoverImages { + + private List coverImages; + + public CoverImages() { + this.coverImages = new ArrayList<>(); + } + + public void add(CoverImage coverImage) { + coverImages.add(coverImage); + } + + public int size() { + return coverImages.size(); + } + + public List getCoverImages() { + return coverImages; + } + +} diff --git a/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java b/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java new file mode 100644 index 000000000..8a3d36c00 --- /dev/null +++ b/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java @@ -0,0 +1,17 @@ +package nextstep.courses.domain.image; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + + +class CoverImagesTest { + + @Test + void 이미지_등둝(){ + CoverImages coverImages = new CoverImages(); + CoverImage coverImage = new CoverImage(1L, "png", 300, 200); + coverImages.add(coverImage); + Assertions.assertThat(coverImages.size()).isEqualTo(1); + } + +} \ No newline at end of file From a080189679b83a2b4fd90b5257a4b4a40dbb6544 Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Tue, 9 Dec 2025 10:28:02 +0900 Subject: [PATCH 07/13] =?UTF-8?q?refactor=20:=20=EA=B0=95=EC=9D=98?= =?UTF-8?q?=EC=97=90=20=EC=97=AC=EB=9F=AC=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95=20-=20session=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EC=97=90=EC=84=9C=20cover=5Fimage=5Fid?= =?UTF-8?q?=EB=A5=BC=20=EA=B4=80=EB=A6=AC=ED=96=88=EB=8A=94=EB=8D=B0=20cov?= =?UTF-8?q?er=5Fimage=20=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=EC=84=9C=20se?= =?UTF-8?q?ssion=5Fid=20=EA=B4=80=EB=A6=AC=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20-=20DB=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EA=B0=80=20=EC=A1=B4=EC=9E=AC=ED=95=9C=EB=8B=A4?= =?UTF-8?q?=EB=8A=94=20=EA=B0=80=EC=A0=95=ED=95=98=EC=97=90=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=84=B0=EB=A7=81=20=EC=A7=84=ED=96=89=ED=95=98?= =?UTF-8?q?=EB=9D=BC=EB=8A=94=20=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD?= =?UTF-8?q?=EC=9D=B4=20=EC=9E=88=EC=97=88=EB=8A=94=EB=8D=B0,=20=EC=B5=9C?= =?UTF-8?q?=EC=B4=88=20DB=20=EC=84=A4=EA=B3=84=20=EC=8B=9C=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EB=A1=9C=20=EC=9D=B4=EB=A5=BC=20=EC=A7=80=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=AA=BB=ED=96=88=EC=8A=B5=EB=8B=88=EB=8B=A4.=20?= =?UTF-8?q?=ED=95=98=EC=A7=80=EB=A7=8C=20=EC=8B=A4=EB=AC=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EB=9F=B0=20=EC=83=81=ED=99=A9=EC=9D=B4=20?= =?UTF-8?q?=EC=98=A8=EB=8B=A4=EB=A9=B4,=20=EA=B8=B0=EC=A1=B4=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=EC=97=90=20=EB=AC=B8=EC=A0=9C=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=EB=A5=BC=20=EC=9E=91=EC=84=B1=ED=95=A0=20?= =?UTF-8?q?=EA=B2=83=EA=B0=99=EC=8A=B5=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/domain/image/CoverImage.java | 16 ++++++----- .../domain/image/CoverImageRepository.java | 4 ++- .../courses/domain/image/CoverImages.java | 8 ++++++ .../domain/service/SessionService.java | 10 ++++--- .../courses/domain/session/Session.java | 27 ++++++++++++------- .../domain/session/mapper/SessionMapper.java | 7 ++--- .../JdbcCoverImageRespository.java | 12 ++++++--- .../JdbcSessionRespository.java | 6 ++--- .../courses/record/SessionRecord.java | 9 ++----- src/main/resources/data.sql | 10 +++---- src/main/resources/schema.sql | 2 +- .../courses/domain/image/CoverImagesTest.java | 6 +++-- .../session/builder/SessionBuilder.java | 9 ++++--- 13 files changed, 75 insertions(+), 51 deletions(-) diff --git a/src/main/java/nextstep/courses/domain/image/CoverImage.java b/src/main/java/nextstep/courses/domain/image/CoverImage.java index 2f16273e0..e0979eaaa 100644 --- a/src/main/java/nextstep/courses/domain/image/CoverImage.java +++ b/src/main/java/nextstep/courses/domain/image/CoverImage.java @@ -7,6 +7,7 @@ public class CoverImage { public static final double MAX_FILE_SIZE = 1024 * 1024; // 1MB private Long id; + private final long sessionId; private final long size; private final ImageType type; private final ImageDimentsion dimentsion; @@ -15,21 +16,22 @@ public CoverImage(long size, String type, int width, int height) { this(size, ImageType.fromName(type.toUpperCase()), width, height); } - public CoverImage(Long id, long size, String type, int width, int height) { - this(id, size, ImageType.fromName(type.toUpperCase()), width, height); + public CoverImage(Long id, Long sessionId, long size, String type, int width, int height) { + this(id, sessionId, size, ImageType.fromName(type.toUpperCase()), width, height); } - public CoverImage(long size, ImageType type, int width, int height) { - this(0L, size, type, new ImageDimentsion(width, height)); + public CoverImage(long size, ImageType type, int width, int height) { + this(0L, 0L, size, type, new ImageDimentsion(width, height)); } - public CoverImage(Long id, long size, ImageType type, int width, int height) { - this(id, size, type, new ImageDimentsion(width, height)); + public CoverImage(Long id, Long sessionId,long size, ImageType type, int width, int height) { + this(id, sessionId, size, type, new ImageDimentsion(width, height)); } - public CoverImage(Long id, long size, ImageType type, ImageDimentsion dimentsion) { + public CoverImage(Long id, Long sessionId, long size, ImageType type, ImageDimentsion dimentsion) { validateFileSize(size); this.id = id; + this.sessionId = sessionId; this.size = size; this.type = type; this.dimentsion = dimentsion; diff --git a/src/main/java/nextstep/courses/domain/image/CoverImageRepository.java b/src/main/java/nextstep/courses/domain/image/CoverImageRepository.java index cbe21b3a7..2c75886e3 100644 --- a/src/main/java/nextstep/courses/domain/image/CoverImageRepository.java +++ b/src/main/java/nextstep/courses/domain/image/CoverImageRepository.java @@ -1,8 +1,10 @@ package nextstep.courses.domain.image; +import java.util.List; + public interface CoverImageRepository { int save(CoverImage coverImage); - CoverImage findById(Long id); + List findBySessionId(Long id); } diff --git a/src/main/java/nextstep/courses/domain/image/CoverImages.java b/src/main/java/nextstep/courses/domain/image/CoverImages.java index 53232f106..393c203a4 100644 --- a/src/main/java/nextstep/courses/domain/image/CoverImages.java +++ b/src/main/java/nextstep/courses/domain/image/CoverImages.java @@ -11,6 +11,14 @@ public CoverImages() { this.coverImages = new ArrayList<>(); } + public CoverImages(CoverImage... coverImage) { + this.coverImages = List.of(coverImage); + } + + public CoverImages(List coverImages) { + this.coverImages = coverImages; + } + public void add(CoverImage coverImage) { coverImages.add(coverImage); } diff --git a/src/main/java/nextstep/courses/domain/service/SessionService.java b/src/main/java/nextstep/courses/domain/service/SessionService.java index d3c344c37..4eb933996 100644 --- a/src/main/java/nextstep/courses/domain/service/SessionService.java +++ b/src/main/java/nextstep/courses/domain/service/SessionService.java @@ -4,6 +4,7 @@ import nextstep.courses.domain.CourseRepository; import nextstep.courses.domain.image.CoverImage; import nextstep.courses.domain.image.CoverImageRepository; +import nextstep.courses.domain.image.CoverImages; import nextstep.courses.domain.session.Enrollment; import nextstep.courses.domain.session.Enrollments; import nextstep.courses.domain.session.Session; @@ -48,17 +49,20 @@ public SessionService(SessionRepository sessionRepository, public Session findById(Long id) { SessionRecord sessionRecord = sessionRepository.findById(id); - CoverImage saveCoverImage = coverImageRepository.findById(sessionRecord.getCoverImageId()); + List saveCoverImages = coverImageRepository.findBySessionId(id); Course saveCourse = courseRepository.findById(sessionRecord.getCourseId()); List enrollmentRecords = enrollmentRepository.findBySessionId(id); Enrollments enrollments = toEnrollments(enrollmentRecords); - return SessionMapper.toDomain(sessionRecord, saveCourse, saveCoverImage, enrollments); + return SessionMapper.toDomain(sessionRecord, saveCourse, saveCoverImages, enrollments); } @Transactional public int save(Session session) { - coverImageRepository.save(session.getCoverImage()); + for (CoverImage coverImage : session.getCoverImages()) { + coverImageRepository.save(coverImage); + } + return sessionRepository.save(SessionMapper.toEntity(session)); } diff --git a/src/main/java/nextstep/courses/domain/session/Session.java b/src/main/java/nextstep/courses/domain/session/Session.java index c08d198a1..9e91961e5 100644 --- a/src/main/java/nextstep/courses/domain/session/Session.java +++ b/src/main/java/nextstep/courses/domain/session/Session.java @@ -2,6 +2,7 @@ import nextstep.courses.domain.Course; import nextstep.courses.domain.image.CoverImage; +import nextstep.courses.domain.image.CoverImages; import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.courses.domain.session.constant.SessionType; import nextstep.payments.domain.Payment; @@ -13,7 +14,7 @@ public class Session extends BaseEntity { private Course course; - private final CoverImage coverImage; + private CoverImages coverImages; private final Enrollments enrollments; private final SessionCoreFacade sessionCore; @@ -34,21 +35,26 @@ public Session(Long id, SessionRange sessionRange, SessionType sessionType, Capa } public Session(Long id, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage) { - this(id, null, coverImage, new Enrollments(), LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); + this(id, null, new CoverImages(coverImage), new Enrollments(), LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); } public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage, Enrollments enrollments) { - this(id, course, coverImage, enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); + this(id, course, new CoverImages(coverImage), enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); } - public Session(Long id, Course course, CoverImage coverImage, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCoreFacade sessionCore) { + public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, List coverImages, Enrollments enrollments) { + this(id, course, new CoverImages(coverImages), enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); + } + + public Session(Long id, Course course, CoverImages coverImages, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCoreFacade sessionCore) { super(id, createdAt, updatedAt); this.course = course; - this.coverImage = coverImage; + this.coverImages = coverImages; this.enrollments = enrollments; this.sessionCore = sessionCore; } + public void addEnrollment(Enrollment enrollment, Payment payment) { sessionCore.validatePaymentAmount(payment); sessionCore.validateNotFull(this.enrollments); @@ -62,8 +68,8 @@ public Course getCourse() { return course; } - public CoverImage getCoverImage() { - return coverImage; + public List getCoverImages() { + return coverImages.getCoverImages(); } public SessionCoreFacade getSessionCore() { @@ -74,23 +80,24 @@ public List getEnrollments() { return enrollments.getEnrollments(); } + @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; Session session = (Session) o; - return Objects.equals(getCourse(), session.getCourse()) && Objects.equals(getCoverImage(), session.getCoverImage()) && Objects.equals(getEnrollments(), session.getEnrollments()) && Objects.equals(getSessionCore(), session.getSessionCore()); + return Objects.equals(getCourse(), session.getCourse()) && Objects.equals(getCoverImages(), session.getCoverImages()) && Objects.equals(getEnrollments(), session.getEnrollments()) && Objects.equals(getSessionCore(), session.getSessionCore()); } @Override public int hashCode() { - return Objects.hash(getCourse(), getCoverImage(), getEnrollments(), getSessionCore()); + return Objects.hash(getCourse(), getCoverImages(), getEnrollments(), getSessionCore()); } @Override public String toString() { return "Session{" + "course=" + course + - ", coverImage=" + coverImage + + ", coverImages=" + coverImages + ", enrollments=" + enrollments + ", sessionCore=" + sessionCore + '}'; diff --git a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java index 33589ef93..e150ef438 100644 --- a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java +++ b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java @@ -7,13 +7,14 @@ import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.courses.record.SessionRecord; +import java.util.List; + public class SessionMapper { public static SessionRecord toEntity(Session session) { return new SessionRecord( session.getId(), session.getCourse().getId(), - session.getCoverImage().getId(), session.getSessionCore().getStartDate(), session.getSessionCore().getEndDate(), session.getSessionCore().getMaxCapacity(), @@ -25,14 +26,14 @@ public static SessionRecord toEntity(Session session) { ); } - public static Session toDomain(SessionRecord record, Course course, CoverImage coverImage, Enrollments enrollments) { + public static Session toDomain(SessionRecord record, Course course, List coverImages, Enrollments enrollments) { return new Session( record.getId(), course, record.createdSessionRange(), record.createdSessionPolicy(), SessionStatus.from(record.getSessionStatus()), - coverImage, + coverImages, enrollments ); } diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcCoverImageRespository.java b/src/main/java/nextstep/courses/infrastructure/JdbcCoverImageRespository.java index 898069a63..3308d0b18 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcCoverImageRespository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcCoverImageRespository.java @@ -5,6 +5,9 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.stereotype.Repository; +import java.util.Collections; +import java.util.List; + @Repository("coverImageRepository") public class JdbcCoverImageRespository implements CoverImageRepository { private JdbcOperations jdbcTemplate; @@ -24,16 +27,17 @@ public int save(CoverImage coverImage) { } @Override - public CoverImage findById(Long id) { - String sql = "select * from cover_image where id = ?"; - return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> { + public List findBySessionId(Long sessionId) { + String sql = "select * from cover_image where session_id = ?"; + return jdbcTemplate.query(sql, (rs, rowNum) -> { return new CoverImage( rs.getLong("id"), + rs.getLong("session_id"), rs.getLong("size"), rs.getString("type"), rs.getInt("width"), rs.getInt("height") ); - }, id); + }, sessionId); } } diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcSessionRespository.java b/src/main/java/nextstep/courses/infrastructure/JdbcSessionRespository.java index 444d4348a..67429db5d 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcSessionRespository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcSessionRespository.java @@ -19,11 +19,10 @@ public JdbcSessionRespository(JdbcOperations jdbcTemplate) { @Override public int save(SessionRecord sessionRecord) { String sql = "insert into session" + - " (course_id, cover_image_id, start_date, end_date, max_capacity, tuition, session_type, session_status, created_at)" + - " values (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + " (course_id, start_date, end_date, max_capacity, tuition, session_type, session_status, created_at)" + + " values (?, ?, ?, ?, ?, ?, ?, ?)"; return jdbcTemplate.update(sql, sessionRecord.getCourseId(), - sessionRecord.getCoverImageId(), sessionRecord.getStartDate(), sessionRecord.getEndDate(), sessionRecord.getMaxCapacity(), @@ -40,7 +39,6 @@ public SessionRecord findById(Long id) { return new SessionRecord( rs.getLong("id"), rs.getLong("course_id"), - rs.getLong("cover_image_id"), toLocalDateTime(rs.getTimestamp("start_date")), toLocalDateTime(rs.getTimestamp("end_date")), rs.getInt("max_capacity"), diff --git a/src/main/java/nextstep/courses/record/SessionRecord.java b/src/main/java/nextstep/courses/record/SessionRecord.java index 417d53c7f..e783a53e0 100644 --- a/src/main/java/nextstep/courses/record/SessionRecord.java +++ b/src/main/java/nextstep/courses/record/SessionRecord.java @@ -3,12 +3,12 @@ import nextstep.courses.domain.session.*; import java.time.LocalDateTime; +import java.util.List; public class SessionRecord { private Long id; private Long courseId; - private Long coverImageId; private LocalDateTime startDate; private LocalDateTime endDate; private int maxCapacity; @@ -18,14 +18,13 @@ public class SessionRecord { private LocalDateTime createdAt; private LocalDateTime updatedAt; - public SessionRecord(Long id, Long courseId, Long coverImageId, + public SessionRecord(Long id, Long courseId, LocalDateTime startDate, LocalDateTime endDate, int maxCapacity, Long tuition, String sessionType, String sessionStatus, LocalDateTime createdAt, LocalDateTime updatedAt) { this.id = id; this.courseId = courseId; - this.coverImageId = coverImageId; this.startDate = startDate; this.endDate = endDate; this.maxCapacity = maxCapacity; @@ -52,10 +51,6 @@ public Long getCourseId() { return courseId; } - public Long getCoverImageId() { - return coverImageId; - } - public int getMaxCapacity() { return maxCapacity; } diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 33b8cdab4..699a130e3 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -11,13 +11,13 @@ INSERT INTO question (id, writer_id, title, contents, created_at, deleted) VALUE INSERT INTO course (id, title, creator_id, created_at) VALUES (1, 'TDD, 클린 μ½”λ“œ with Java', 1, CURRENT_TIMESTAMP()); -INSERT INTO session(id, course_id, cover_image_id, start_date, end_date, max_capacity, tuition, session_type, session_status, created_at) -VALUES (1, 1, 1,CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 100, 300000, 'PAID', 'ACTIVE', CURRENT_TIMESTAMP() ); +INSERT INTO session(id, course_id, start_date, end_date, max_capacity, tuition, session_type, session_status, created_at) +VALUES (1, 1, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 100, 300000, 'PAID', 'ACTIVE', CURRENT_TIMESTAMP() ); -INSERT INTO session(id, course_id, cover_image_id, start_date, end_date, max_capacity, tuition, session_type, session_status, created_at) -VALUES (2, 1, 1,CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 100, 300000, 'PAID', 'ACTIVE', CURRENT_TIMESTAMP() ); +INSERT INTO session(id, course_id, start_date, end_date, max_capacity, tuition, session_type, session_status, created_at) +VALUES (2, 1,CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 100, 300000, 'PAID', 'ACTIVE', CURRENT_TIMESTAMP() ); -INSERT INTO cover_image (id, size, type, width, height) VALUES (1, 1, 'png', 300, 200); +INSERT INTO cover_image (id, session_id, size, type, width, height) VALUES (1, 1, 1, 'png', 300, 200); INSERT INTO enrollment (id, user_id, session_id, created_at) VALUES (1, 1, 1, CURRENT_TIMESTAMP()); INSERT INTO enrollment (id, user_id, session_id, created_at) VALUES (2, 2, 1, CURRENT_TIMESTAMP()); \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index a4e0ec80d..b9b96c35c 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -52,7 +52,6 @@ create table delete_history ( create table session ( id bigint not null generated by default as identity(start with 1000), course_id bigint not null, - cover_image_id bigint, start_date timestamp not null, end_date timestamp not null, max_capacity int not null, @@ -67,6 +66,7 @@ create table session ( create table cover_image ( id bigint not null generated by default as identity(start with 1000), + session_id bigint not null, size bigint, type varchar(30), width int, diff --git a/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java b/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java index 8a3d36c00..a1f82f62b 100644 --- a/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java +++ b/src/test/java/nextstep/courses/domain/image/CoverImagesTest.java @@ -7,11 +7,13 @@ class CoverImagesTest { @Test - void 이미지_등둝(){ + void μ—¬λŸ¬_이미지_등둝(){ CoverImages coverImages = new CoverImages(); CoverImage coverImage = new CoverImage(1L, "png", 300, 200); + CoverImage coverImage2 = new CoverImage(1L, "png", 300, 200); coverImages.add(coverImage); - Assertions.assertThat(coverImages.size()).isEqualTo(1); + coverImages.add(coverImage2); + Assertions.assertThat(coverImages.size()).isEqualTo(2); } } \ No newline at end of file diff --git a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java index 4a8bb2c0c..3a612444e 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java @@ -2,6 +2,7 @@ import nextstep.courses.domain.Course; import nextstep.courses.domain.image.CoverImage; +import nextstep.courses.domain.image.CoverImages; import nextstep.courses.domain.session.*; import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; import nextstep.courses.domain.session.constant.SessionStatus; @@ -13,7 +14,7 @@ public class SessionBuilder { private Long id = 23334L; private Course course = new Course("TDD, 클린 μ½”λ“œ with Java", 1L); - private CoverImage coverImage = new CoverImage(2L, "png", 300, 200); + private CoverImages coverImages = new CoverImages(new CoverImage(2L, "png", 300, 200)); private SessionRange sessionRange = new SessionRangeBuilder().build(); private SessionPolicy sessionPolicy = new SessionPolicyBuilder().build(); private SessionStatus sessionStatus = SessionStatus.PENDING; @@ -32,8 +33,8 @@ public SessionBuilder withCourse(Course course) { return this; } - public SessionBuilder withCoverImage(CoverImage coverImage) { - this.coverImage = coverImage; + public SessionBuilder withCoverImages(CoverImages coverImages) { + this.coverImages = coverImages; return this; } @@ -81,7 +82,7 @@ private SessionCoreFacade createdSessionCore(){ } public Session build() { - return new Session(id, course, coverImage, enrollments, createdAt, updatedAt, createdSessionCore()); + return new Session(id, course, coverImages, enrollments, createdAt, updatedAt, createdSessionCore()); } } From ec7498495a2b6c62f7bbec53813304cf68b23379 Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:13:56 +0900 Subject: [PATCH 08/13] =?UTF-8?q?feat=20:=20=EC=84=A0=EB=B0=9C=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80,=20=EC=8A=B9=EC=9D=B8=20=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=20Enum=20=EC=83=9D=EC=84=B1=20refactor=20:?= =?UTF-8?q?=20=EC=88=98=EA=B0=95=EC=8B=A0=EC=B2=AD=20=EA=B0=9D=EC=B2=B4?= =?UTF-8?q?=EC=97=90=20=EC=83=81=ED=83=9C=EA=B0=92=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/domain/session/Enrollment.java | 59 ++++++++++++++++++- .../session/constant/EnrollmentStatus.java | 26 ++++++++ .../session/constant/SelectionStatus.java | 30 ++++++++++ .../courses/record/EnrollmentRecord.java | 20 ++++++- .../domain/session/EnrollmentTest.java | 31 ++++++++++ .../session/builder/EnrollmentBuilder.java | 17 +++++- 6 files changed, 177 insertions(+), 6 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java create mode 100644 src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java diff --git a/src/main/java/nextstep/courses/domain/session/Enrollment.java b/src/main/java/nextstep/courses/domain/session/Enrollment.java index 8c3e88e44..add475917 100644 --- a/src/main/java/nextstep/courses/domain/session/Enrollment.java +++ b/src/main/java/nextstep/courses/domain/session/Enrollment.java @@ -1,23 +1,38 @@ package nextstep.courses.domain.session; +import nextstep.courses.domain.session.constant.EnrollmentStatus; +import nextstep.courses.domain.session.constant.SelectionStatus; import nextstep.users.domain.NsUser; import java.time.LocalDateTime; import java.util.Objects; public class Enrollment extends BaseEntity { - private final NsUser user; + private final Long sessionId; + private SelectionStatus selectionStatus; + private EnrollmentStatus enrollmentStatus; public Enrollment(NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt) { - this(0L, user, sessionId, createdAt, updatedAt); + this(0L, user, sessionId, createdAt, updatedAt, SelectionStatus.PENDING, EnrollmentStatus.WAITING); + } + + public Enrollment(Long id, NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt, String selectionStatus, String enrollmentStatus) { + this(id, user, sessionId, createdAt, updatedAt, SelectionStatus.valueOf(selectionStatus.toUpperCase()), EnrollmentStatus.valueOf(enrollmentStatus.toUpperCase())); + } + + + public Enrollment(NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt, SelectionStatus selectionStatus, EnrollmentStatus enrollmentStatus) { + this(0L, user, sessionId, createdAt, updatedAt, selectionStatus, enrollmentStatus); } - public Enrollment(Long id, NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt) { + public Enrollment(Long id, NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt, SelectionStatus selectionStatus, EnrollmentStatus enrollmentStatus) { super(id, createdAt, updatedAt); this.user = user; this.sessionId = sessionId; + this.selectionStatus = selectionStatus; + this.enrollmentStatus = enrollmentStatus; } public NsUser getUser() { @@ -28,6 +43,44 @@ public Long getSessionId() { return sessionId; } + public void updateEnrollmentStatus(EnrollmentStatus enrollmentStatus) { + validateEnrollmentStatus(enrollmentStatus); + this.enrollmentStatus = enrollmentStatus; + } + + private void validateEnrollmentStatus(EnrollmentStatus enrollmentStatus) { + validateNotSeletedAndApproved(enrollmentStatus); + validateSelectedAndCancelled(enrollmentStatus); + } + + private void validateSelectedAndCancelled(EnrollmentStatus enrollmentStatus) { + if (isSelectedAndCancelled(enrollmentStatus)) { + throw new IllegalArgumentException("μ„ λ°œλœ 인원은 κ°•μ˜ μ·¨μ†Œκ°€ λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€."); + } + } + + private void validateNotSeletedAndApproved(EnrollmentStatus enrollmentStatus) { + if (isNotSelectedAndApproved(enrollmentStatus)) { + throw new IllegalArgumentException("λ―Έμ„ λ°œλœ 인원은 κ°•μ˜ 승인이 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€."); + } + } + + private boolean isSelectedAndCancelled(EnrollmentStatus enrollmentStatus) { + return this.selectionStatus.equals(SelectionStatus.SELECTED) && enrollmentStatus.equals(EnrollmentStatus.CANCELLED); + } + + private boolean isNotSelectedAndApproved(EnrollmentStatus enrollmentStatus) { + return this.selectionStatus.equals(SelectionStatus.NOT_SELECTED) && enrollmentStatus.equals(EnrollmentStatus.APPROVED); + } + + public SelectionStatus getSelectionStatus() { + return selectionStatus; + } + + public EnrollmentStatus getEnrollmentStatus() { + return enrollmentStatus; + } + @Override public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; diff --git a/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java b/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java new file mode 100644 index 000000000..3f4a93cc6 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java @@ -0,0 +1,26 @@ +package nextstep.courses.domain.session.constant; + +import java.util.Arrays; + +public enum EnrollmentStatus { + WAITING("λŒ€κΈ°"), + APPROVED("승인"), + CANCELLED("μ·¨μ†Œ"); + + private final String value; + + EnrollmentStatus(String value) { + this.value = value; + } + + public static EnrollmentStatus from(String name){ + return Arrays.stream(EnrollmentStatus.values()) + .filter(status -> status.matchStatus(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("μƒνƒœλͺ…을 잘λͺ» μž…λ ₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€.")); + } + + private boolean matchStatus(String value) { + return this.value.equals(value); + } +} diff --git a/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java b/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java new file mode 100644 index 000000000..1d80e014d --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java @@ -0,0 +1,30 @@ +package nextstep.courses.domain.session.constant; + +import java.util.Arrays; + +public enum SelectionStatus { + PENDING("μ„ λ°œ λŒ€κΈ°"), + SELECTED("μ„ λ°œ"), + NOT_SELECTED("λ―Έμ„ λ°œ"); + + private final String value; + + SelectionStatus(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static SelectionStatus from(String name) { + return Arrays.stream(SelectionStatus.values()) + .filter(status -> status.matchStatus(name)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("μƒνƒœλͺ…을 잘λͺ» μž…λ ₯ν•˜μ˜€μŠ΅λ‹ˆλ‹€.")); + } + + private boolean matchStatus(String value) { + return this.value.equals(value); + } +} diff --git a/src/main/java/nextstep/courses/record/EnrollmentRecord.java b/src/main/java/nextstep/courses/record/EnrollmentRecord.java index 0fbcf27b8..58a7512ad 100644 --- a/src/main/java/nextstep/courses/record/EnrollmentRecord.java +++ b/src/main/java/nextstep/courses/record/EnrollmentRecord.java @@ -1,13 +1,21 @@ package nextstep.courses.record; import nextstep.courses.domain.session.Enrollment; +import nextstep.courses.domain.session.constant.EnrollmentStatus; +import nextstep.courses.domain.session.constant.SelectionStatus; import nextstep.users.domain.NsUser; +import java.time.LocalDateTime; + public class EnrollmentRecord { private Long id; private Long userId; private Long sessionId; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + private String selectionStatus; + private String enrollmentStatus; public EnrollmentRecord(Long id, Long userId, Long sessionId) { this.id = id; @@ -16,7 +24,9 @@ public EnrollmentRecord(Long id, Long userId, Long sessionId) { } public Enrollment toEnrollment(NsUser user) { - return new Enrollment(this.id, user, this.sessionId, null, null); + return new Enrollment(this.id, user, this.sessionId, + this.createdAt, this.updatedAt, + this.selectionStatus, this.enrollmentStatus); } public Long getId() { @@ -30,4 +40,12 @@ public Long getUserId() { public Long getSessionId() { return sessionId; } + + public String getSelectionStatus() { + return selectionStatus; + } + + public String getEnrollmentStatus() { + return enrollmentStatus; + } } diff --git a/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java b/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java index 8c3020b4e..ad886690f 100644 --- a/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java +++ b/src/test/java/nextstep/courses/domain/session/EnrollmentTest.java @@ -1,5 +1,8 @@ package nextstep.courses.domain.session; +import nextstep.courses.domain.session.builder.EnrollmentBuilder; +import nextstep.courses.domain.session.constant.EnrollmentStatus; +import nextstep.courses.domain.session.constant.SelectionStatus; import nextstep.users.domain.NsUserTest; import org.junit.jupiter.api.Test; @@ -15,4 +18,32 @@ class EnrollmentTest { assertThat(enrollment).isNotNull(); } + @Test + void μ„ λ°œλœμΈμ›_μˆ˜κ°•μ‹ μ²­_승인(){ + Enrollment enrollment = new EnrollmentBuilder().withSelectionStatus(SelectionStatus.from("μ„ λ°œ")).build(); + enrollment.updateEnrollmentStatus(EnrollmentStatus.from("승인")); + assertThat(enrollment.getEnrollmentStatus()).isEqualTo(EnrollmentStatus.from("승인")); + } + + @Test + void λ―Έμ„ λ°œμΈμ›_μŠΉμΈμ‹œ_μ—λŸ¬λ°œμƒ(){ + Enrollment enrollment = new EnrollmentBuilder().withSelectionStatus(SelectionStatus.from("λ―Έμ„ λ°œ")).build(); + assertThatThrownBy(() -> enrollment.updateEnrollmentStatus(EnrollmentStatus.from("승인"))) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void λ―Έμ„ λ°œμΈμ›_μˆ˜κ°•μ·¨μ†Œ(){ + Enrollment enrollment = new EnrollmentBuilder().withSelectionStatus(SelectionStatus.from("λ―Έμ„ λ°œ")).build(); + enrollment.updateEnrollmentStatus(EnrollmentStatus.from("μ·¨μ†Œ")); + assertThat(enrollment.getEnrollmentStatus()).isEqualTo(EnrollmentStatus.from("μ·¨μ†Œ")); + } + + @Test + void μ„ λ°œμΈμ›_μˆ˜κ°•μ·¨μ†Œ_μ—λŸ¬λ°œμƒ(){ + Enrollment enrollment = new EnrollmentBuilder().withSelectionStatus(SelectionStatus.from("μ„ λ°œ")).build(); + assertThatThrownBy(() -> enrollment.updateEnrollmentStatus(EnrollmentStatus.from("μ·¨μ†Œ"))) + .isInstanceOf(IllegalArgumentException.class); + } + } \ No newline at end of file diff --git a/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java index 5f5be6298..c6bbdb60c 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java @@ -1,7 +1,8 @@ package nextstep.courses.domain.session.builder; import nextstep.courses.domain.session.Enrollment; -import nextstep.payments.domain.Payment; +import nextstep.courses.domain.session.constant.EnrollmentStatus; +import nextstep.courses.domain.session.constant.SelectionStatus; import nextstep.users.domain.NsUser; import java.time.LocalDateTime; @@ -10,6 +11,8 @@ public class EnrollmentBuilder { private NsUser user = new NsUser(1L, "javajigi", "password", "name", "javajigi@slipp.net"); private Long sessionId = 1L; + private SelectionStatus selectionStatus = SelectionStatus.PENDING; + private EnrollmentStatus enrollmentStatus = EnrollmentStatus.WAITING; public EnrollmentBuilder withUser(NsUser user) { this.user = user; @@ -21,9 +24,19 @@ public EnrollmentBuilder withSessionId(Long sessionId) { return this; } + public EnrollmentBuilder withSelectionStatus(SelectionStatus selectionStatus) { + this.selectionStatus = selectionStatus; + return this; + } + + public EnrollmentBuilder withEnrollmentStatus(EnrollmentStatus enrollmentStatus) { + this.enrollmentStatus = enrollmentStatus; + return this; + } + public Enrollment build() { - return new Enrollment(user, sessionId, LocalDateTime.now(), null); + return new Enrollment(user, sessionId, LocalDateTime.now(), null, selectionStatus, enrollmentStatus); } } From adf6a1bdfeb49ddad41a2ec2db8adf0b594cef0e Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Wed, 10 Dec 2025 13:55:35 +0900 Subject: [PATCH 09/13] =?UTF-8?q?refactor=20:=20=EC=8A=A4=ED=82=A4?= =?UTF-8?q?=EB=A7=88,=20sql=20=EC=88=98=EC=A0=95,=20Jdbc=20=EC=88=98?= =?UTF-8?q?=EA=B0=95=EC=8B=A0=EC=B2=AD=20=EB=93=B1=EB=A1=9D,=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JdbcEnrollmentRespository.java | 26 ++++++++++++++++--- .../courses/record/EnrollmentRecord.java | 10 ++++--- src/main/resources/data.sql | 4 +-- src/main/resources/schema.sql | 2 ++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java b/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java index edc9b0544..ccd5cc43c 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcEnrollmentRespository.java @@ -6,6 +6,8 @@ import org.springframework.jdbc.core.JdbcOperations; import org.springframework.stereotype.Repository; +import java.sql.Timestamp; +import java.time.LocalDateTime; import java.util.List; @Repository("enrollmentRepository") @@ -19,8 +21,15 @@ public JdbcEnrollmentRespository(JdbcOperations jdbcTemplate) { @Override public int save(Enrollment enrollment) { - String sql = "insert into enrollment (session_id, user_id, created_at) values (?, ?, ?)"; - return jdbcTemplate.update(sql, enrollment.getSessionId(), enrollment.getUser().getId(), enrollment.getCreatedAt()); + String sql = "insert into enrollment (session_id, user_id, selection_status, enrollment_status, created_at)" + + " values (?, ?, ?, ?, ?)"; + return jdbcTemplate.update(sql, + enrollment.getSessionId(), + enrollment.getUser().getId(), + enrollment.getSelectionStatus().name(), + enrollment.getEnrollmentStatus().name(), + enrollment.getCreatedAt() + ); } @Override @@ -30,8 +39,19 @@ public List findBySessionId(Long sessionId) { return new EnrollmentRecord( rs.getLong("id"), rs.getLong("user_id"), - rs.getLong("session_id") + rs.getLong("session_id"), + rs.getString("selection_status"), + rs.getString("enrollment_status"), + toLocalDateTime(rs.getTimestamp("created_at")), + toLocalDateTime(rs.getTimestamp("updated_at")) ); }, sessionId); } + + private LocalDateTime toLocalDateTime(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + return timestamp.toLocalDateTime(); + } } diff --git a/src/main/java/nextstep/courses/record/EnrollmentRecord.java b/src/main/java/nextstep/courses/record/EnrollmentRecord.java index 58a7512ad..cf24f5246 100644 --- a/src/main/java/nextstep/courses/record/EnrollmentRecord.java +++ b/src/main/java/nextstep/courses/record/EnrollmentRecord.java @@ -12,15 +12,19 @@ public class EnrollmentRecord { private Long id; private Long userId; private Long sessionId; - private LocalDateTime createdAt; - private LocalDateTime updatedAt; private String selectionStatus; private String enrollmentStatus; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; - public EnrollmentRecord(Long id, Long userId, Long sessionId) { + public EnrollmentRecord(Long id, Long userId, Long sessionId, String selectionStatus, String enrollmentStatus, LocalDateTime createdAt, LocalDateTime updatedAt) { this.id = id; this.userId = userId; this.sessionId = sessionId; + this.selectionStatus = selectionStatus; + this.enrollmentStatus = enrollmentStatus; + this.createdAt = createdAt; + this.updatedAt = updatedAt; } public Enrollment toEnrollment(NsUser user) { diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 699a130e3..a777f6c5d 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -19,5 +19,5 @@ VALUES (2, 1,CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 100, 300000, 'PAID', 'ACT INSERT INTO cover_image (id, session_id, size, type, width, height) VALUES (1, 1, 1, 'png', 300, 200); -INSERT INTO enrollment (id, user_id, session_id, created_at) VALUES (1, 1, 1, CURRENT_TIMESTAMP()); -INSERT INTO enrollment (id, user_id, session_id, created_at) VALUES (2, 2, 1, CURRENT_TIMESTAMP()); \ No newline at end of file +INSERT INTO enrollment (id, user_id, session_id, selection_status, enrollment_status, created_at) VALUES (1, 1, 1, 'PENDING','WAITING',CURRENT_TIMESTAMP()); +INSERT INTO enrollment (id, user_id, session_id, selection_status, enrollment_status, created_at) VALUES (2, 2, 1, 'SELECTED','WAITING',CURRENT_TIMESTAMP()); \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index b9b96c35c..87ff4e665 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -78,6 +78,8 @@ create table enrollment ( id bigint not null generated by default as identity(start with 1000), session_id bigint not null, user_id bigint not null, + selection_status varchar(30), + enrollment_status varchar(30), created_at timestamp not null, updated_at timestamp, primary key (id) From 16106368f3b79b483d7cc621d69b39b90d9d887f Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Sun, 14 Dec 2025 16:45:15 +0900 Subject: [PATCH 10/13] =?UTF-8?q?refactor=20:=20enum=EC=97=90=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EB=B3=B4=EB=82=BC=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/nextstep/courses/domain/session/Enrollment.java | 2 +- .../courses/domain/session/constant/EnrollmentStatus.java | 4 ++++ .../courses/domain/session/constant/SelectionStatus.java | 4 ++++ .../courses/infrastructure/EnrollmentRepositoryTest.java | 1 - 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/nextstep/courses/domain/session/Enrollment.java b/src/main/java/nextstep/courses/domain/session/Enrollment.java index add475917..045bf4125 100644 --- a/src/main/java/nextstep/courses/domain/session/Enrollment.java +++ b/src/main/java/nextstep/courses/domain/session/Enrollment.java @@ -66,7 +66,7 @@ private void validateNotSeletedAndApproved(EnrollmentStatus enrollmentStatus) { } private boolean isSelectedAndCancelled(EnrollmentStatus enrollmentStatus) { - return this.selectionStatus.equals(SelectionStatus.SELECTED) && enrollmentStatus.equals(EnrollmentStatus.CANCELLED); + return this.selectionStatus.isSelected() && enrollmentStatus.isCancled(); } private boolean isNotSelectedAndApproved(EnrollmentStatus enrollmentStatus) { diff --git a/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java b/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java index 3f4a93cc6..adc05cd6c 100644 --- a/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java +++ b/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java @@ -23,4 +23,8 @@ public static EnrollmentStatus from(String name){ private boolean matchStatus(String value) { return this.value.equals(value); } + + public boolean isCancled() { + return this.equals(CANCELLED); + } } diff --git a/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java b/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java index 1d80e014d..0750af7e4 100644 --- a/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java +++ b/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java @@ -27,4 +27,8 @@ public static SelectionStatus from(String name) { private boolean matchStatus(String value) { return this.value.equals(value); } + + public boolean isSelected() { + return this.equals(SELECTED); + } } diff --git a/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java index 97dcf7136..6889e8b54 100644 --- a/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java +++ b/src/test/java/nextstep/courses/infrastructure/EnrollmentRepositoryTest.java @@ -3,7 +3,6 @@ import nextstep.courses.domain.session.Enrollment; import nextstep.courses.domain.session.repository.EnrollmentRepository; import nextstep.courses.record.EnrollmentRecord; -import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUserTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; From 8fffc110049cc02e793574c5d9259ec37842eaaf Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Sun, 14 Dec 2025 17:17:30 +0900 Subject: [PATCH 11/13] =?UTF-8?q?refactor=20:=20SessionCoreFacade=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A0=9C=EA=B1=B0,=20SessionCore?= =?UTF-8?q?V2=EB=A5=BC=20SessionCore=EB=A1=9C=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/domain/session/Enrollment.java | 2 +- .../courses/domain/session/Session.java | 17 ++-- .../courses/domain/session/SessionCore.java | 24 +++--- .../domain/session/SessionCoreFacade.java | 23 ----- .../courses/domain/session/SessionCoreV2.java | 83 ------------------- .../session/constant/EnrollmentStatus.java | 4 + .../session/constant/SelectionStatus.java | 4 + .../constant/SessionRecruitmentStatus.java | 13 +++ .../domain/session/mapper/SessionMapper.java | 5 +- .../JdbcSessionRespository.java | 6 +- .../courses/record/SessionRecord.java | 9 +- src/main/resources/schema.sql | 1 + ...onCoreV2Test.java => SessionCoreTest.java} | 2 +- .../courses/domain/session/SessionTest.java | 6 +- .../session/builder/SessionBuilder.java | 10 +-- 15 files changed, 66 insertions(+), 143 deletions(-) delete mode 100644 src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java delete mode 100644 src/main/java/nextstep/courses/domain/session/SessionCoreV2.java rename src/test/java/nextstep/courses/domain/session/{SessionCoreV2Test.java => SessionCoreTest.java} (97%) diff --git a/src/main/java/nextstep/courses/domain/session/Enrollment.java b/src/main/java/nextstep/courses/domain/session/Enrollment.java index 045bf4125..aa102724b 100644 --- a/src/main/java/nextstep/courses/domain/session/Enrollment.java +++ b/src/main/java/nextstep/courses/domain/session/Enrollment.java @@ -70,7 +70,7 @@ private boolean isSelectedAndCancelled(EnrollmentStatus enrollmentStatus) { } private boolean isNotSelectedAndApproved(EnrollmentStatus enrollmentStatus) { - return this.selectionStatus.equals(SelectionStatus.NOT_SELECTED) && enrollmentStatus.equals(EnrollmentStatus.APPROVED); + return this.selectionStatus.isNotSelected() && enrollmentStatus.isApproved(); } public SelectionStatus getSelectionStatus() { diff --git a/src/main/java/nextstep/courses/domain/session/Session.java b/src/main/java/nextstep/courses/domain/session/Session.java index 9e91961e5..d5b3f8957 100644 --- a/src/main/java/nextstep/courses/domain/session/Session.java +++ b/src/main/java/nextstep/courses/domain/session/Session.java @@ -3,6 +3,7 @@ import nextstep.courses.domain.Course; import nextstep.courses.domain.image.CoverImage; import nextstep.courses.domain.image.CoverImages; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.courses.domain.session.constant.SessionType; import nextstep.payments.domain.Payment; @@ -16,7 +17,7 @@ public class Session extends BaseEntity { private Course course; private CoverImages coverImages; private final Enrollments enrollments; - private final SessionCoreFacade sessionCore; + private final SessionCore sessionCore; public Session(Long id, LocalDateTime startDate, LocalDateTime endDate, String sessionType, String sessionStatus, CoverImage coverImage) { this(id, startDate, endDate, sessionType, Integer.MAX_VALUE, 0L, sessionStatus, coverImage); @@ -35,18 +36,14 @@ public Session(Long id, SessionRange sessionRange, SessionType sessionType, Capa } public Session(Long id, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage) { - this(id, null, new CoverImages(coverImage), new Enrollments(), LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); + this(id, null, new CoverImages(coverImage), new Enrollments(), LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus, SessionRecruitmentStatus.RECRUITING)); } - public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, CoverImage coverImage, Enrollments enrollments) { - this(id, course, new CoverImages(coverImage), enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); + public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, List coverImages, Enrollments enrollments, SessionRecruitmentStatus sessionRecruitmentStatus) { + this(id, course, new CoverImages(coverImages), enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus, sessionRecruitmentStatus)); } - public Session(Long id, Course course, SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, List coverImages, Enrollments enrollments) { - this(id, course, new CoverImages(coverImages), enrollments, LocalDateTime.now(), null, new SessionCore(sessionRange, sessionPolicy, sessionStatus)); - } - - public Session(Long id, Course course, CoverImages coverImages, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCoreFacade sessionCore) { + public Session(Long id, Course course, CoverImages coverImages, Enrollments enrollments, LocalDateTime createdAt, LocalDateTime updatedAt, SessionCore sessionCore) { super(id, createdAt, updatedAt); this.course = course; this.coverImages = coverImages; @@ -72,7 +69,7 @@ public List getCoverImages() { return coverImages.getCoverImages(); } - public SessionCoreFacade getSessionCore() { + public SessionCore getSessionCore() { return sessionCore; } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCore.java b/src/main/java/nextstep/courses/domain/session/SessionCore.java index ca8a001ec..2aeb15fe0 100644 --- a/src/main/java/nextstep/courses/domain/session/SessionCore.java +++ b/src/main/java/nextstep/courses/domain/session/SessionCore.java @@ -1,47 +1,47 @@ package nextstep.courses.domain.session; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.payments.domain.Payment; import java.time.LocalDateTime; - -public class SessionCore implements SessionCoreFacade { +public class SessionCore { private final SessionRange sessionRange; private final SessionPolicy sessionPolicy; private final SessionStatus sessionStatus; + private final SessionRecruitmentStatus sessionRecruitmentStatus; - public SessionCore(SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus) { + public SessionCore(SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, SessionRecruitmentStatus sessionRecruitmentStatus) { this.sessionRange = sessionRange; this.sessionPolicy = sessionPolicy; this.sessionStatus = sessionStatus; + this.sessionRecruitmentStatus = sessionRecruitmentStatus; } - @Override public void validatePaymentAmount(Payment payment) { if (this.sessionPolicy.isSessionType()) { sessionPolicy.matchAmount(payment); } } - @Override public void validateNotFull(Enrollments enrollments) { if (this.sessionPolicy.matchSize(enrollments.size())) { throw new IllegalArgumentException("μˆ˜κ°•μΈμ›μ΄ μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."); } } - @Override public void validateSessionStatus() { - if (!this.sessionStatus.equals(SessionStatus.ACTIVE)) { - throw new IllegalArgumentException("ν˜„μž¬λŠ” κ°•μ˜ λͺ¨μ§‘쀑이 μ•„λ‹™λ‹ˆλ‹€."); + if (this.sessionStatus.equals(SessionStatus.FINISHED)) { + throw new IllegalArgumentException("μ’…λ£Œλœ κ°•μ˜μž…λ‹ˆλ‹€."); } } - @Override public void validateRecruitmentStatus() { - + if(this.sessionRecruitmentStatus.equals(SessionRecruitmentStatus.NOT_RECRUITING)) { + throw new IllegalArgumentException("ν˜„μž¬λŠ” λͺ¨μ§‘기간이 μ•„λ‹™λ‹ˆλ‹€."); + } } public LocalDateTime getStartDate() { @@ -75,4 +75,8 @@ public SessionRange getSessionRange() { public SessionStatus getSessionStatus() { return sessionStatus; } + + public SessionRecruitmentStatus getSessionRecruitmentStatus() { + return sessionRecruitmentStatus; + } } diff --git a/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java b/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java deleted file mode 100644 index 381501bbd..000000000 --- a/src/main/java/nextstep/courses/domain/session/SessionCoreFacade.java +++ /dev/null @@ -1,23 +0,0 @@ -package nextstep.courses.domain.session; - -import nextstep.courses.domain.session.constant.SessionStatus; -import nextstep.payments.domain.Payment; - -import java.time.LocalDateTime; - -public interface SessionCoreFacade { - - LocalDateTime getStartDate(); - LocalDateTime getEndDate(); - int getMaxCapacity(); - Long getTuition(); - String getSessionType(); - SessionPolicy getSessionPolicy(); - SessionRange getSessionRange(); - SessionStatus getSessionStatus(); - - void validatePaymentAmount(Payment payment); - void validateNotFull(Enrollments enrollments); - void validateSessionStatus(); - void validateRecruitmentStatus(); -} diff --git a/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java b/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java deleted file mode 100644 index 300e5fa69..000000000 --- a/src/main/java/nextstep/courses/domain/session/SessionCoreV2.java +++ /dev/null @@ -1,83 +0,0 @@ -package nextstep.courses.domain.session; - -import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; -import nextstep.courses.domain.session.constant.SessionStatus; -import nextstep.payments.domain.Payment; - -import java.time.LocalDateTime; - -public class SessionCoreV2 implements SessionCoreFacade{ - - private final SessionRange sessionRange; - private final SessionPolicy sessionPolicy; - private final SessionStatus sessionStatus; - private final SessionRecruitmentStatus sessionRecruitmentStatus; - - public SessionCoreV2(SessionRange sessionRange, SessionPolicy sessionPolicy, SessionStatus sessionStatus, SessionRecruitmentStatus sessionRecruitmentStatus) { - this.sessionRange = sessionRange; - this.sessionPolicy = sessionPolicy; - this.sessionStatus = sessionStatus; - this.sessionRecruitmentStatus = sessionRecruitmentStatus; - } - - @Override - public void validatePaymentAmount(Payment payment) { - if (this.sessionPolicy.isSessionType()) { - sessionPolicy.matchAmount(payment); - } - } - - @Override - public void validateNotFull(Enrollments enrollments) { - if (this.sessionPolicy.matchSize(enrollments.size())) { - throw new IllegalArgumentException("μˆ˜κ°•μΈμ›μ΄ μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."); - } - } - - @Override - public void validateSessionStatus() { - if (this.sessionStatus.equals(SessionStatus.FINISHED)) { - throw new IllegalArgumentException("μ’…λ£Œλœ κ°•μ˜μž…λ‹ˆλ‹€."); - } - } - - @Override - public void validateRecruitmentStatus() { - if(this.sessionRecruitmentStatus.equals(SessionRecruitmentStatus.NOT_RECRUITING)) { - throw new IllegalArgumentException("ν˜„μž¬λŠ” λͺ¨μ§‘기간이 μ•„λ‹™λ‹ˆλ‹€."); - } - } - - public LocalDateTime getStartDate() { - return sessionRange.getStartDate(); - } - - public LocalDateTime getEndDate() { - return sessionRange.getEndDate(); - } - - public int getMaxCapacity() { - return sessionPolicy.getMaxCapacity().getValue(); - } - - public Long getTuition() { - return sessionPolicy.getTuition().getValue(); - } - - public String getSessionType() { - return sessionPolicy.getSessionType().toString(); - } - - public SessionPolicy getSessionPolicy() { - return sessionPolicy; - } - - public SessionRange getSessionRange() { - return sessionRange; - } - - public SessionStatus getSessionStatus() { - return sessionStatus; - } - -} diff --git a/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java b/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java index adc05cd6c..8364fc25d 100644 --- a/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java +++ b/src/main/java/nextstep/courses/domain/session/constant/EnrollmentStatus.java @@ -27,4 +27,8 @@ private boolean matchStatus(String value) { public boolean isCancled() { return this.equals(CANCELLED); } + + public boolean isApproved() { + return this.equals(APPROVED); + } } diff --git a/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java b/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java index 0750af7e4..6ff9c292d 100644 --- a/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java +++ b/src/main/java/nextstep/courses/domain/session/constant/SelectionStatus.java @@ -31,4 +31,8 @@ private boolean matchStatus(String value) { public boolean isSelected() { return this.equals(SELECTED); } + + public boolean isNotSelected() { + return this.equals(NOT_SELECTED); + } } diff --git a/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java b/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java index dcaf33205..3e93293ac 100644 --- a/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java +++ b/src/main/java/nextstep/courses/domain/session/constant/SessionRecruitmentStatus.java @@ -1,5 +1,7 @@ package nextstep.courses.domain.session.constant; +import java.util.Arrays; + public enum SessionRecruitmentStatus { NOT_RECRUITING("λΉ„λͺ¨μ§‘쀑"), @@ -12,4 +14,15 @@ public enum SessionRecruitmentStatus { } + public static SessionRecruitmentStatus from(String value) { + return Arrays.stream(SessionRecruitmentStatus.values()) + .filter(status -> status.matchStatus(value)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("λͺ¨μ§‘쀑, λΉ„λͺ¨μ§‘쀑 2κ°€μ§€ μƒνƒœλ‘œλ§Œ 생성 κ°€λŠ₯ν•©λ‹ˆλ‹€.")); + } + + private boolean matchStatus(String value) { + return this.name().equals(value); + } + } diff --git a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java index e150ef438..7cce76b27 100644 --- a/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java +++ b/src/main/java/nextstep/courses/domain/session/mapper/SessionMapper.java @@ -4,6 +4,7 @@ import nextstep.courses.domain.image.CoverImage; import nextstep.courses.domain.session.Enrollments; import nextstep.courses.domain.session.Session; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; import nextstep.courses.domain.session.constant.SessionStatus; import nextstep.courses.record.SessionRecord; @@ -21,6 +22,7 @@ public static SessionRecord toEntity(Session session) { session.getSessionCore().getTuition(), session.getSessionCore().getSessionType(), session.getSessionCore().getSessionStatus().name(), + session.getSessionCore().getSessionRecruitmentStatus().name(), session.getCreatedAt(), session.getUpdatedAt() ); @@ -34,7 +36,8 @@ public static Session toDomain(SessionRecord record, Course course, List session.addEnrollment(enrollment, payment)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("ν˜„μž¬λŠ” κ°•μ˜ λͺ¨μ§‘쀑이 μ•„λ‹™λ‹ˆλ‹€."); + .isInstanceOf(IllegalArgumentException.class); } @Test diff --git a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java index 3a612444e..64e30e3ce 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/SessionBuilder.java @@ -21,7 +21,7 @@ public class SessionBuilder { private Enrollments enrollments = new Enrollments(); private LocalDateTime createdAt = LocalDateTime.now(); private LocalDateTime updatedAt; - private SessionRecruitmentStatus recruit; + private SessionRecruitmentStatus recruit = SessionRecruitmentStatus.RECRUITING; public SessionBuilder withId(Long id) { this.id = id; @@ -73,12 +73,8 @@ public SessionBuilder withRecruit(SessionRecruitmentStatus recruit) { return this; } - private SessionCoreFacade createdSessionCore(){ - if(this.recruit != null) { - return new SessionCoreV2(this.sessionRange, this.sessionPolicy, this.sessionStatus, recruit); - } - - return new SessionCore(this.sessionRange, this.sessionPolicy, this.sessionStatus); + private SessionCore createdSessionCore() { + return new SessionCore(this.sessionRange, this.sessionPolicy, this.sessionStatus, recruit); } public Session build() { From dabddc005155c672d9958dcd6bf8bc8aa791b8ba Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:02:39 +0900 Subject: [PATCH 12/13] =?UTF-8?q?refactor=20:=20=EC=88=98=EA=B0=95?= =?UTF-8?q?=EC=8B=A0=EC=B2=AD=20=EA=B2=80=EC=A6=9D=EB=A1=9C=EC=A7=81=20Ses?= =?UTF-8?q?sion=EC=97=90=EC=84=9C=20EnrollmentApply=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9D=BC=EA=B4=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95(=EC=BB=B4=ED=8C=8C=EC=9D=BC=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EB=B0=9C=EC=83=9D=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=9E=91=EC=97=85=20=EC=A7=84=ED=96=89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/SessionService.java | 14 ++++---- .../courses/domain/session/Enrollment.java | 6 ++-- .../domain/session/EnrollmentApply.java | 36 +++++++++++++++++++ .../courses/domain/session/Enrollments.java | 13 ++++++- .../session/mapper/EnrollmentMapper.java | 34 ++++++++++++++++++ .../courses/record/EnrollmentRecord.java | 8 +++++ .../courses/record/SessionRecord.java | 13 +++++++ .../domain/session/EnrollmentApplyTest.java | 28 +++++++++++++++ .../domain/session/EnrollmentsTest.java | 8 ++--- .../domain/session/SessionCoreTest.java | 13 +++++-- .../courses/domain/session/SessionTest.java | 10 +++--- .../session/builder/EnrollmentBuilder.java | 2 +- 12 files changed, 162 insertions(+), 23 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/session/EnrollmentApply.java create mode 100644 src/main/java/nextstep/courses/domain/session/mapper/EnrollmentMapper.java create mode 100644 src/test/java/nextstep/courses/domain/session/EnrollmentApplyTest.java diff --git a/src/main/java/nextstep/courses/domain/service/SessionService.java b/src/main/java/nextstep/courses/domain/service/SessionService.java index 4eb933996..83e86bc50 100644 --- a/src/main/java/nextstep/courses/domain/service/SessionService.java +++ b/src/main/java/nextstep/courses/domain/service/SessionService.java @@ -6,6 +6,7 @@ import nextstep.courses.domain.image.CoverImageRepository; import nextstep.courses.domain.image.CoverImages; import nextstep.courses.domain.session.Enrollment; +import nextstep.courses.domain.session.EnrollmentApply; import nextstep.courses.domain.session.Enrollments; import nextstep.courses.domain.session.Session; import nextstep.courses.domain.session.mapper.SessionMapper; @@ -24,7 +25,7 @@ import java.util.Optional; @Service -public class SessionService { +public class SessionService { private final SessionRepository sessionRepository; private final CoverImageRepository coverImageRepository; @@ -67,11 +68,11 @@ public int save(Session session) { } @Transactional - public int saveEnrollment(Enrollment enrollment, Payment payment) { - SessionRecord sessionRecord = sessionRepository.findById(enrollment.getSessionId()); - List enrollmentRecords = enrollmentRepository.findBySessionId(enrollment.getSessionId()); - Session session = SessionMapper.toDomain(sessionRecord, null, null, toEnrollments(enrollmentRecords)); - session.addEnrollment(enrollment, payment); + public int saveEnrollment(NsUser user, Long sessionId, Payment payment) { + SessionRecord sessionRecord = sessionRepository.findById(sessionId); + List enrollmentRecords = enrollmentRepository.findBySessionId(sessionId); + EnrollmentApply enrollmentApply = new EnrollmentApply(toEnrollments(enrollmentRecords), payment, sessionRecord.createdSessionCore()); + Enrollment enrollment = enrollmentApply.enroll(user, sessionId); paymentRepository.save(payment); @@ -89,5 +90,4 @@ private Enrollments toEnrollments(List enrollmentRecords) { return enrollments; } - } diff --git a/src/main/java/nextstep/courses/domain/session/Enrollment.java b/src/main/java/nextstep/courses/domain/session/Enrollment.java index aa102724b..1aa2de5b5 100644 --- a/src/main/java/nextstep/courses/domain/session/Enrollment.java +++ b/src/main/java/nextstep/courses/domain/session/Enrollment.java @@ -9,11 +9,14 @@ public class Enrollment extends BaseEntity { private final NsUser user; - private final Long sessionId; private SelectionStatus selectionStatus; private EnrollmentStatus enrollmentStatus; + public Enrollment(NsUser user, Long sessionId) { + this(user, sessionId, LocalDateTime.now(), null); + } + public Enrollment(NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt) { this(0L, user, sessionId, createdAt, updatedAt, SelectionStatus.PENDING, EnrollmentStatus.WAITING); } @@ -22,7 +25,6 @@ public Enrollment(Long id, NsUser user, Long sessionId, LocalDateTime createdAt, this(id, user, sessionId, createdAt, updatedAt, SelectionStatus.valueOf(selectionStatus.toUpperCase()), EnrollmentStatus.valueOf(enrollmentStatus.toUpperCase())); } - public Enrollment(NsUser user, Long sessionId, LocalDateTime createdAt, LocalDateTime updatedAt, SelectionStatus selectionStatus, EnrollmentStatus enrollmentStatus) { this(0L, user, sessionId, createdAt, updatedAt, selectionStatus, enrollmentStatus); } diff --git a/src/main/java/nextstep/courses/domain/session/EnrollmentApply.java b/src/main/java/nextstep/courses/domain/session/EnrollmentApply.java new file mode 100644 index 000000000..9dc555707 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/EnrollmentApply.java @@ -0,0 +1,36 @@ +package nextstep.courses.domain.session; + +import nextstep.payments.domain.Payment; +import nextstep.users.domain.NsUser; + +import java.time.LocalDateTime; +import java.util.List; + +public class EnrollmentApply { + private SessionCore sessionCore; + private Payment payment; + private Enrollments enrollments; + + public EnrollmentApply(Enrollments enrollments, Payment payment, SessionCore sessionCore) { + this.enrollments = enrollments; + this.payment = payment; + this.sessionCore = sessionCore; + } + + public Enrollment enroll(NsUser user, Long sessionId) { + sessionCore.validatePaymentAmount(payment); + sessionCore.validateNotFull(this.enrollments); + sessionCore.validateSessionStatus(); + sessionCore.validateRecruitmentStatus(); + enrollments.validateNotDuplicate(new Enrollment(user, sessionId)); + + Enrollment enrollment = new Enrollment(user, sessionId, LocalDateTime.now(), null); + enrollments.add(enrollment); + + return enrollment; + } + + public List getEnrollments() { + return enrollments.getEnrollments(); + } +} diff --git a/src/main/java/nextstep/courses/domain/session/Enrollments.java b/src/main/java/nextstep/courses/domain/session/Enrollments.java index 9d39202ea..df51d596e 100644 --- a/src/main/java/nextstep/courses/domain/session/Enrollments.java +++ b/src/main/java/nextstep/courses/domain/session/Enrollments.java @@ -2,11 +2,22 @@ import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class Enrollments { private final List enrollments = new ArrayList<>(); + public Enrollments() {} + + public Enrollments(Enrollment... enrollment) { + this.enrollments.addAll(List.of(enrollment)); + } + + public Enrollments(List enrollments) { + this.enrollments.addAll(enrollments); + } + public void add(Enrollment enrollment) { validateNotDuplicate(enrollment); this.enrollments.add(enrollment); @@ -16,7 +27,7 @@ public int size() { return this.enrollments.size(); } - private void validateNotDuplicate(Enrollment enrollment) { + public void validateNotDuplicate(Enrollment enrollment) { if (this.enrollments.contains(enrollment)) { throw new IllegalArgumentException("이미 μ‹ μ²­ν•œ κ°•μ˜μž…λ‹ˆλ‹€."); } diff --git a/src/main/java/nextstep/courses/domain/session/mapper/EnrollmentMapper.java b/src/main/java/nextstep/courses/domain/session/mapper/EnrollmentMapper.java new file mode 100644 index 000000000..aca34b4aa --- /dev/null +++ b/src/main/java/nextstep/courses/domain/session/mapper/EnrollmentMapper.java @@ -0,0 +1,34 @@ +package nextstep.courses.domain.session.mapper; + +import nextstep.courses.domain.session.Enrollment; +import nextstep.courses.domain.session.constant.EnrollmentStatus; +import nextstep.courses.domain.session.constant.SelectionStatus; +import nextstep.courses.record.EnrollmentRecord; +import nextstep.users.domain.NsUser; + +public class EnrollmentMapper { + + public static EnrollmentRecord toEntity(Enrollment enrollment) { + return new EnrollmentRecord( + enrollment.getId(), + enrollment.getUser().getId(), + enrollment.getSessionId(), + enrollment.getSelectionStatus().name(), + enrollment.getEnrollmentStatus().name(), + enrollment.getCreatedAt(), + enrollment.getUpdatedAt() + ); + } + + public static Enrollment toDomain(EnrollmentRecord record, NsUser user) { + return new Enrollment( + record.getId(), + user, + record.getSessionId(), + record.getCreatedAt(), + record.getUpdatedAt(), + SelectionStatus.from(record.getEnrollmentStatus()), + EnrollmentStatus.from(record.getEnrollmentStatus()) + ); + } +} diff --git a/src/main/java/nextstep/courses/record/EnrollmentRecord.java b/src/main/java/nextstep/courses/record/EnrollmentRecord.java index cf24f5246..7eae8cd0b 100644 --- a/src/main/java/nextstep/courses/record/EnrollmentRecord.java +++ b/src/main/java/nextstep/courses/record/EnrollmentRecord.java @@ -52,4 +52,12 @@ public String getSelectionStatus() { public String getEnrollmentStatus() { return enrollmentStatus; } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } } diff --git a/src/main/java/nextstep/courses/record/SessionRecord.java b/src/main/java/nextstep/courses/record/SessionRecord.java index 6df56afdb..300413e5a 100644 --- a/src/main/java/nextstep/courses/record/SessionRecord.java +++ b/src/main/java/nextstep/courses/record/SessionRecord.java @@ -1,8 +1,11 @@ package nextstep.courses.record; import nextstep.courses.domain.session.*; +import nextstep.courses.domain.session.constant.SessionRecruitmentStatus; +import nextstep.courses.domain.session.constant.SessionStatus; import java.time.LocalDateTime; +import java.util.List; public class SessionRecord { @@ -44,6 +47,15 @@ public SessionPolicy createdSessionPolicy() { return new SessionPolicy(this.maxCapacity, this.tuition, this.sessionType); } + public SessionCore createdSessionCore() { + return new SessionCore( + createdSessionRange(), + createdSessionPolicy(), + SessionStatus.from(this.sessionStatus), + SessionRecruitmentStatus.from(this.recruitmentStatus) + ); + } + public Long getId() { return id; } @@ -87,4 +99,5 @@ public LocalDateTime getUpdatedAt() { public String getRecruitmentStatus() { return recruitmentStatus; } + } diff --git a/src/test/java/nextstep/courses/domain/session/EnrollmentApplyTest.java b/src/test/java/nextstep/courses/domain/session/EnrollmentApplyTest.java new file mode 100644 index 000000000..fffe674ac --- /dev/null +++ b/src/test/java/nextstep/courses/domain/session/EnrollmentApplyTest.java @@ -0,0 +1,28 @@ +package nextstep.courses.domain.session; + +import nextstep.courses.domain.session.builder.SessionBuilder; +import nextstep.payments.domain.Payment; +import nextstep.users.domain.NsUser; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; + + +public class EnrollmentApplyTest { + + private NsUser U1 = new NsUser(1L, "chanani", "password", "μ΄μ°¬ν•œ", "aa@aa.aa"); + private Session S1 = new SessionBuilder().build(); + + @Test + void μˆ˜κ°•μ‹ μ²­_κ°€λŠ₯(){ + EnrollmentApply enrollmentApply = new EnrollmentApply( + new Enrollments(), + new Payment(1L, 1L, 300_000L), + S1.getSessionCore() + ); + + Enrollment enrollment = enrollmentApply.enroll(U1, 1L); + + assertThat(enrollment.getSessionId()).isEqualTo(1L); + } +} diff --git a/src/test/java/nextstep/courses/domain/session/EnrollmentsTest.java b/src/test/java/nextstep/courses/domain/session/EnrollmentsTest.java index d7cc00e32..d9d651fcb 100644 --- a/src/test/java/nextstep/courses/domain/session/EnrollmentsTest.java +++ b/src/test/java/nextstep/courses/domain/session/EnrollmentsTest.java @@ -6,11 +6,12 @@ import nextstep.payments.domain.Payment; import org.junit.jupiter.api.Test; - import static org.assertj.core.api.Assertions.assertThatThrownBy; class EnrollmentsTest { + private static final Enrollment E1 = new EnrollmentBuilder().build(); + @Test void 쀑볡_μˆ˜κ°•μ‹ μ²­μ‹œ_μ˜ˆμ™Έλ°œμƒ() { Session session = new SessionBuilder() @@ -18,10 +19,9 @@ class EnrollmentsTest { .withSessionStatus(SessionStatus.ACTIVE) .build(); - Enrollment newEnrollment = new EnrollmentBuilder().build(); - + EnrollmentApply enrollmentApply = new EnrollmentApply(new Enrollments(E1), new Payment(1L, 1L, 300_000L), session.getSessionCore()); - assertThatThrownBy(() -> session.addEnrollment(newEnrollment, new Payment(1L, 1L, 300_000L))) + assertThatThrownBy(() -> enrollmentApply.enroll(E1.getUser(), session.getId())) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("이미 μ‹ μ²­ν•œ κ°•μ˜μž…λ‹ˆλ‹€."); } diff --git a/src/test/java/nextstep/courses/domain/session/SessionCoreTest.java b/src/test/java/nextstep/courses/domain/session/SessionCoreTest.java index af1b9d4f5..841adb252 100644 --- a/src/test/java/nextstep/courses/domain/session/SessionCoreTest.java +++ b/src/test/java/nextstep/courses/domain/session/SessionCoreTest.java @@ -10,17 +10,24 @@ class SessionCoreTest { + @Test void κ°•μ˜μ‹ μ²­μ‹œ_λΉ„λͺ¨μ§‘μƒνƒœ_μ—λŸ¬λ°œμƒ(){ Session session = new SessionBuilder().withRecruit(SessionRecruitmentStatus.NOT_RECRUITING).build(); - assertThatThrownBy(() -> session.addEnrollment(new EnrollmentBuilder().build(), new Payment(1L, 1L, 300_000L))) + Enrollment enrollment = new EnrollmentBuilder().build(); + EnrollmentApply enrollmentApply = new EnrollmentApply(new Enrollments(enrollment), new Payment(1L, 1L, 300_000L), session.getSessionCore()); + + assertThatThrownBy(() -> enrollmentApply.enroll(enrollment.getUser(), session.getId())) .isInstanceOf(IllegalArgumentException.class); } @Test void κ°•μ˜μ‹ μ²­μ‹œ_λͺ¨μ§‘μƒνƒœ_정상_μ‹ μ²­(){ Session session = new SessionBuilder().withRecruit(SessionRecruitmentStatus.RECRUITING).build(); - session.addEnrollment(new EnrollmentBuilder().build(), new Payment(1L, 1L, 300_000L)); - assertThat(session.getEnrollments()).hasSize(1); + Enrollment enrollment = new EnrollmentBuilder().build(); + EnrollmentApply enrollmentApply = new EnrollmentApply(new Enrollments(), new Payment(1L, 1L, 300_000L), session.getSessionCore()); + enrollmentApply.enroll(enrollment.getUser(), session.getId()); + + assertThat(enrollmentApply.getEnrollments()).hasSize(1); } } \ No newline at end of file diff --git a/src/test/java/nextstep/courses/domain/session/SessionTest.java b/src/test/java/nextstep/courses/domain/session/SessionTest.java index 09174a0be..91a598d0c 100644 --- a/src/test/java/nextstep/courses/domain/session/SessionTest.java +++ b/src/test/java/nextstep/courses/domain/session/SessionTest.java @@ -44,9 +44,9 @@ public class SessionTest { void μˆ˜κ°•μ‹ μ²­μ‹œ_λͺ¨μ§‘쀑이_μ•„λ‹κ²½μš°_μ˜ˆμ™Έλ°œμƒ() { Session session = new SessionBuilder().withSessionStatus(SessionStatus.PENDING).withRecruit(SessionRecruitmentStatus.NOT_RECRUITING).build(); Enrollment enrollment = new EnrollmentBuilder().build(); - Payment payment = new Payment(1L, 1L, 300_000L); + EnrollmentApply enrollmentApply = new EnrollmentApply(new Enrollments(enrollment), new Payment(1L, 1L, 300_000L), session.getSessionCore()); - assertThatThrownBy(() -> session.addEnrollment(enrollment, payment)) + assertThatThrownBy(() -> enrollmentApply.enroll(enrollment.getUser(), session.getId())) .isInstanceOf(IllegalArgumentException.class); } @@ -58,10 +58,10 @@ public class SessionTest { .withEnrollment(new EnrollmentBuilder().build()) .build(); - Enrollment newEnrollment = new Enrollment(NsUserTest.SANJIGI, 1L, LocalDateTime.now(), null); - Payment payment = new Payment(1L, 1L, 300_000L); + Enrollment enrollment = new Enrollment(NsUserTest.SANJIGI, 1L, LocalDateTime.now(), null); + EnrollmentApply enrollmentApply = new EnrollmentApply(new Enrollments(enrollment), new Payment(1L, 1L, 300_000L), session.getSessionCore()); - assertThatThrownBy(() -> session.addEnrollment(newEnrollment, payment)) + assertThatThrownBy(() -> enrollmentApply.enroll(NsUserTest.SANJIGI, session.getId())) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("μˆ˜κ°•μΈμ›μ΄ μ΄ˆκ³Όν–ˆμŠ΅λ‹ˆλ‹€."); } diff --git a/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java b/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java index c6bbdb60c..ec7c9c8c3 100644 --- a/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java +++ b/src/test/java/nextstep/courses/domain/session/builder/EnrollmentBuilder.java @@ -10,7 +10,7 @@ public class EnrollmentBuilder { private NsUser user = new NsUser(1L, "javajigi", "password", "name", "javajigi@slipp.net"); - private Long sessionId = 1L; + private Long sessionId = 23334L; private SelectionStatus selectionStatus = SelectionStatus.PENDING; private EnrollmentStatus enrollmentStatus = EnrollmentStatus.WAITING; From dbc998da7ea861c86e586fc122c073095e73a0e7 Mon Sep 17 00:00:00 2001 From: CHANHAN <130114269+chanani@users.noreply.github.com> Date: Sun, 14 Dec 2025 22:06:57 +0900 Subject: [PATCH 13/13] =?UTF-8?q?docs=20:=20pr=20=EB=A7=81=ED=81=AC=20?= =?UTF-8?q?=EA=B8=B0=EC=9E=85=20=EB=B0=8F=20README=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + docs/04-lms-refactor.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5743fc362..41bb0a75e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ - [πŸš€ 1단계 - λ ˆκ±°μ‹œ μ½”λ“œ λ¦¬νŒ©ν„°λ§](./docs/01-refactoring.md) - [πŸš€ 2단계 - μˆ˜κ°•μ‹ μ²­(도메인 λͺ¨λΈ)](./docs/02-lms-domain-model.md) - [πŸš€ 3단계 - μˆ˜κ°•μ‹ μ²­(DB 적용)](./docs/03-lms-db.md) +- [πŸš€ 4단계 - μˆ˜κ°•μ‹ μ²­(μš”κ΅¬μ‚¬ν•­ λ³€κ²½)](./docs/04-lms-refactor.md) ## μ§„ν–‰ 방법 * ν•™μŠ΅ 관리 μ‹œμŠ€ν…œμ˜ μˆ˜κ°•μ‹ μ²­ μš”κ΅¬μ‚¬ν•­μ„ νŒŒμ•…ν•œλ‹€. diff --git a/docs/04-lms-refactor.md b/docs/04-lms-refactor.md index 1a6481bd1..605a7b121 100644 --- a/docs/04-lms-refactor.md +++ b/docs/04-lms-refactor.md @@ -4,7 +4,7 @@ ## μ½”λ“œ 리뷰 -> PR 링크 : +> PR 링크 : [#808](https://github.com/next-step/java-lms/pull/808) ## λ‚˜μ˜ ν•™μŠ΅ λͺ©ν‘œ