Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/step3요구사항.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 수강 신청 기능

## 2. 테이블 설계
- [ ] 객체 구조(도메인 구조)를 가능한 유지하면서 DB 테이블과 매핑한다.
- [ ] 성능보다 도메인 로직 구현에 집중한다.

### 2.1 session_image 테이블
- 컬럼: id, file_size, image_type, width, height

### 2.2 session 테이블
- 컬럼: id, course_id, cohort, start_date, end_date, image_id, status, session_type, max_capacity, fee, created_at, updated_at
- Course와 1:N
- SessionImage와 N:1

### 2.3 session_enrollment 테이블
- 컬럼: id, session_id, ns_user_id, enrolled_at
- Session과 1:N
- NsUser와 N:1
10 changes: 10 additions & 0 deletions src/main/java/nextstep/courses/domain/Course.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,23 @@ public Course(String title, Long creatorId, Sessions sessions) {
}

public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt) {
this(id, title, creatorId, createdAt, updatedAt, null);
}

public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, Sessions sessions) {
this.id = id;
this.title = title;
this.creatorId = creatorId;
this.createdAt = createdAt;
this.updatedAt = updatedAt;
this.sessions = sessions;
}

public Long getId() {
return id;
}


public String getTitle() {
return title;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package nextstep.courses.domain;

public interface CourseRepository {
int save(Course course);
Long save(Course course);

Course findById(Long id);
}
28 changes: 18 additions & 10 deletions src/main/java/nextstep/courses/domain/session/Enrollment.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,45 @@
public class Enrollment {
private final SessionStatus status;
private final SessionType sessionType;
private final Set<Long> enrolledStudentIds;
private final Set<Long> enrolledNsUserIds;

public Enrollment(SessionStatus status, SessionType sessionType) {
this(status, sessionType, new HashSet<>());
}

public Enrollment(SessionStatus status, SessionType sessionType, Set<Long> enrolledStudentIds) {
public Enrollment(SessionStatus status, SessionType sessionType, Set<Long> enrolledNsUserIds) {
this.status = status;
this.sessionType = sessionType;
this.enrolledStudentIds = enrolledStudentIds;
this.enrolledNsUserIds = enrolledNsUserIds;
}

public void enroll(Long studentId) {
enroll(studentId, null);
public void enroll(Long nsUserId) {
enroll(nsUserId, null);
}

public void enroll(Long studentId, Payment payment) {
public void enroll(Long nsUserId, Payment payment) {
if (!status.canEnroll()) {
throw new IllegalStateException("모집중인 강의만 수강 신청할 수 있다");
}
if (!sessionType.isValidPayment(payment)) {
throw new IllegalArgumentException("결제 금액이 수강료와 일치하지 않습니다.");
}

if (sessionType.isOverCapacity(enrolledStudentIds.size())) {
if (sessionType.isOverCapacity(enrolledNsUserIds.size())) {
throw new IllegalStateException("최대 수강 인원을 초과했습니다.");
}
enrolledStudentIds.add(studentId);
enrolledNsUserIds.add(nsUserId);
}

public boolean isEnrolled(Long studentId) {
return enrolledStudentIds.contains(studentId);
public boolean isEnrolled(Long nsUserId) {
return enrolledNsUserIds.contains(nsUserId);
}

public SessionStatus getStatus() {
return status;
}

public SessionType getSessionType() {
return sessionType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nextstep.courses.domain.session;

public interface EnrollmentRepository {
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

void save (Long sessionId, Long nsUserId);
}
37 changes: 29 additions & 8 deletions src/main/java/nextstep/courses/domain/session/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,55 @@ public Session(LocalDate startDate, LocalDate endDate, SessionImage image, Strin
this(new SessionPeriod(startDate, endDate), image, SessionStatus.from(status), new HashSet<>(), new PaidSessionType(maximumCapacity, fee));
}

public Session(SessionPeriod period, SessionImage coverImage, SessionStatus status, Set<Long> enrolledStudentIds, SessionType sessionType) {
this(1, period, coverImage, new Enrollment(status, sessionType, enrolledStudentIds));
public Session(SessionPeriod period, SessionImage coverImage, SessionStatus status, Set<Long> enrolledNsUserIds, SessionType sessionType) {
this(1, period, coverImage, new Enrollment(status, sessionType, enrolledNsUserIds));
}

public Session(int cohort, LocalDate startDate, LocalDate endDate, SessionImage image) {
this(cohort, new SessionPeriod(startDate, endDate), image, new Enrollment(SessionStatus.PREPARING, new FreeSessionType()));
}

public Session(int cohort, LocalDate startDate, LocalDate endDate, SessionImage image, Enrollment enrollment) {
this(cohort, new SessionPeriod(startDate, endDate), image, enrollment);
}

public Session(int cohort, SessionPeriod period, SessionImage coverImage, Enrollment enrollment) {
this.cohort = cohort;
this.period = period;
this.coverImage = coverImage;
this.enrollment = enrollment;
}

public void enroll(Long studentId) {
enrollment.enroll(studentId);
public void enroll(Long nsUserId) {
enrollment.enroll(nsUserId);
}

public void enroll(Long studentId, Payment pay) {
enrollment.enroll(studentId, pay);
public void enroll(Long nsUserId, Payment pay) {
enrollment.enroll(nsUserId, pay);
}

public boolean isEnrolled(Long studentId) {
return enrollment.isEnrolled(studentId);
public boolean isEnrolled(Long nsUserId) {
return enrollment.isEnrolled(nsUserId);
}

public int getCohort() {
return cohort;
}

public SessionImage getImage() {
return coverImage;
}

public Enrollment getEnrollment() {
return enrollment;
}

public LocalDate getStartDate() {
return period.getStartDate();
}

public LocalDate getEndDate() {
return period.getEndDate();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,11 @@ private void validateDate(LocalDate startDate, LocalDate endDate) {
}
}

public LocalDate getStartDate() {
return startDate;
}

public LocalDate getEndDate() {
return endDate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nextstep.courses.domain.session;

public interface SessionRepository {
void save(Long courseId, Session session);

Sessions findByCourseId(Long courseId);

Long findSessionIdByCourseIdAndCohort(Long courseId, int cohort);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ public static SessionStatus from(String value) {
public boolean canEnroll() {
return this == RECRUITING;
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ public static ImageType from(String extension) {
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("지원하지 않는 이미지 타입: " + extension));
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,20 @@ private void validateFileSize(long fileSize) {
}
}


public int getWidth() {
return imageDimension.getWidth();
}

public int getHeight() {
return imageDimension.getHeight();
}

public long getFileSize() {
return fileSize;
}

public String getImageTypeValue() {
return imageType.getValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import nextstep.courses.domain.CourseRepository;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.Timestamp;
import java.time.LocalDateTime;

Expand All @@ -18,23 +21,57 @@ public JdbcCourseRepository(JdbcOperations jdbcTemplate) {
}

@Override
public int save(Course course) {
public Long save(Course course) {
String sql = "insert into course (title, creator_id, created_at) values(?, ?, ?)";
return jdbcTemplate.update(sql, course.getTitle(), course.getCreatorId(), course.getCreatedAt());
KeyHolder keyHolder = new GeneratedKeyHolder();

jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, new String[]{"id"});
ps.setString(1, course.getTitle());
ps.setLong(2, course.getCreatorId());
ps.setTimestamp(3, Timestamp.valueOf(course.getCreatedAt()));
return ps;
}, keyHolder);

// Long courseId = Objects.requireNonNull(keyHolder.getKey()).longValue();
//
// if (course.getSessions() != null) {
// saveSessions(courseId, course.getSessions());
// }
//
// return courseId;
return keyHolder.getKey().longValue();
}

// private void saveSessions(Long courseId, Sessions sessions) {
// for (int i = 1; i <= sessions.size(); i++) {
// Session session = sessions.findByCohort(i);
// if (session != null) {
// sessionRepository.save(courseId, session);
// }
// }
// }


@Override
public Course findById(Long id) {
String sql = "select id, title, creator_id, created_at, updated_at from course where id = ?";
RowMapper<Course> rowMapper = (rs, rowNum) -> new Course(
rs.getLong(1),
rs.getString(2),
rs.getLong(3),
toLocalDateTime(rs.getTimestamp(4)),
toLocalDateTime(rs.getTimestamp(5)));
RowMapper<Course> rowMapper = (rs, rowNum) -> {
Course course = new Course(
rs.getLong(1),
rs.getString(2),
rs.getLong(3),
toLocalDateTime(rs.getTimestamp(4)),
toLocalDateTime(rs.getTimestamp(5)));
return course;
};
// Course course = jdbcTemplate.queryForObject(sql, rowMapper, id);
//
// return new Course(course.getId(), course.getTitle(), course.getCreatorId(), course.getCreatedAt(), null, sessionRepository.findByCourseId(id));
return jdbcTemplate.queryForObject(sql, rowMapper, id);
}


private LocalDateTime toLocalDateTime(Timestamp timestamp) {
if (timestamp == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package nextstep.courses.infrastructure;

import nextstep.courses.domain.session.EnrollmentRepository;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.stereotype.Repository;

import java.sql.Timestamp;
import java.time.LocalDateTime;

@Repository("enrollmentRepository")
public class JdbcEnrollmentRepository implements EnrollmentRepository {
private JdbcOperations jdbcTemplate;

public JdbcEnrollmentRepository(JdbcOperations jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public void save(Long sessionId, Long nsUserId) {
String sql = "insert into session_enrollment (session_id, ns_user_id, enrolled_at) values(?, ?, ?)";
jdbcTemplate.update(sql, sessionId, nsUserId, Timestamp.valueOf(LocalDateTime.now()));

}
}
Loading