Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
13 commits
Select commit Hold shift + click to select a range
504ad4d
docs : λͺ©ν‘œ 및 μš”κ΅¬μ‚¬ν•­ md 파일 μž‘μ„±
chanani Dec 7, 2025
487809c
refactor : ν”Όλ“œλ°± 받은 λ‚΄μš© μˆ˜μ • μ§„ν–‰(Session, SessionRecordμ—μ„œ 직접 λ³€ν™˜ν•˜μ§€ μ•Šκ³  Mapper…
chanani Dec 8, 2025
4260bb7
refactor : Session ν΄λž˜μŠ€μ—μ„œ 상속 λ°›λ˜ SessionCore μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ‘œ 이동, BaseEntity 생성…
chanani Dec 8, 2025
48db9b3
refactor : SessionCoreFacade interface 생성, SessionCoreV2 생성
chanani Dec 8, 2025
cb43233
refactor : κ°•μ˜ μ§„ν–‰ μƒνƒœ enum 정보 λ³€κ²½, SessionCoreV2 ν΄λž˜μŠ€μ— λͺ¨μ§‘ μƒνƒœ κ°’ μΆ”κ°€ 및 ν…ŒμŠ€νŠΈ 코…
chanani Dec 8, 2025
b43e419
feat : 컀버 이미지 μΌκΈ‰μ»¬λž™μ…˜ 생성 및 ν…ŒμŠ€νŠΈ μ½”λ“œ 생성
chanani Dec 9, 2025
a080189
refactor : κ°•μ˜μ— μ—¬λŸ¬ 이미지 등둝할 수 μžˆλ„λ‘ μˆ˜μ •
chanani Dec 9, 2025
ec74984
feat : μ„ λ°œ μ—¬λΆ€, 승인 μ—¬λΆ€ μƒνƒœ Enum 생성
chanani Dec 10, 2025
adf6a1b
refactor : μŠ€ν‚€λ§ˆ, sql μˆ˜μ •, Jdbc μˆ˜κ°•μ‹ μ²­ 등둝, 쑰회 μˆ˜μ •
chanani Dec 10, 2025
1610636
refactor : enum에 λ©”μ‹œμ§€ 보낼 수 μžˆλ„λ‘ λ©”μ„œλ“œ μΆ”κ°€
chanani Dec 14, 2025
8fffc11
refactor : SessionCoreFacade λ©”μ„œλ“œ 제거, SessionCoreV2λ₯Ό SessionCore둜 λ¦¬νŒ©ν„°λ§
chanani Dec 14, 2025
dabddc0
refactor : μˆ˜κ°•μ‹ μ²­ κ²€μ¦λ‘œμ§ Sessionμ—μ„œ EnrollmentApply 클래슀둜 이동 및 ν…ŒμŠ€νŠΈ μ½”λ“œ 일괄 μˆ˜μ •β€¦
chanani Dec 14, 2025
dbc998d
docs : pr 링크 κΈ°μž… 및 README μˆ˜μ •
chanani Dec 14, 2025
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

## μ§„ν–‰ 방법
* ν•™μŠ΅ 관리 μ‹œμŠ€ν…œμ˜ μˆ˜κ°•μ‹ μ²­ μš”κ΅¬μ‚¬ν•­μ„ νŒŒμ•…ν•œλ‹€.
Expand Down
43 changes: 43 additions & 0 deletions docs/04-lms-refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# πŸš€ 4단계 - μˆ˜κ°•μ‹ μ²­(μš”κ΅¬μ‚¬ν•­ λ³€κ²½)

***

## μ½”λ“œ 리뷰

> PR 링크 : [#808](https://github.com/next-step/java-lms/pull/808)

## λ‚˜μ˜ ν•™μŠ΅ λͺ©ν‘œ

### 1. 컴파일 였λ₯˜κ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ λ¦¬νŒ©ν„°λ§ν•˜μž.

- ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬μ‚¬ν•­μ—μ„œμ™€ 같이 λ¦¬νŒ©ν„°λ§ν•  λ•Œ 컴파일 μ—λŸ¬κ°€ μ΅œλŒ€ν•œ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ κ΅¬ν˜„ν•œλ‹€.
- 이 λͺ©ν‘œλ₯Ό μ§€ν‚€λ €λ©΄ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ°”λ‘œ μˆ˜μ •ν•˜λŠ” 것이 μ•„λ‹Œ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³΅μ‚¬ν•œ λ’€ μ μ§„μ μœΌλ‘œ μ½”λ“œλ₯Ό μˆ˜μ •ν•΄ λ‚˜μ•„κ°„λ‹€.

## 핡심 ν•™μŠ΅ λͺ©ν‘œ

- DB ν…Œμ΄λΈ”μ΄ 변경될 λ•Œλ„ μŠ€νŠΈλž­κΈ€λŸ¬ νŒ¨ν„΄μ„ μ μš©ν•΄ 점진적인 λ¦¬νŒ©ν„°λ§μ„ μ—°μŠ΅ν•œλ‹€.
- [μŠ€νŠΈλž­κΈ€λŸ¬(κ΅μ‚΄μž) νŒ¨ν„΄ - λ§ˆν‹΄ 파울러](https://martinfowler.com/bliki/StranglerFigApplication.html)
- [μŠ€νŠΈλž­κΈ€λŸ¬ 무화과 νŒ¨ν„΄](https://learn.microsoft.com/ko-kr/azure/architecture/patterns/strangler-fig)

## λ³€κ²½λœ κΈ°λŠ₯ μš”κ΅¬μ‚¬ν•­

### κ°•μ˜ μˆ˜κ°•μ‹ μ²­μ€ κ°•μ˜ μƒνƒœκ°€ λͺ¨μ§‘쀑일 λ•Œλ§Œ κ°€λŠ₯ν•˜λ‹€.

- κ°•μ˜κ°€ μ§„ν–‰ 쀑인 μƒνƒœμ—μ„œλ„ μˆ˜κ°•μ‹ μ²­μ΄ κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€.
- κ°•μ˜ μ§„ν–‰ μƒνƒœ(쀀비쀑, 진행쀑, μ’…λ£Œ)와 λͺ¨μ§‘ μƒνƒœ(λΉ„λͺ¨μ§‘쀑, λͺ¨μ§‘쀑)둜 μƒνƒœ 값을 뢄리해야 ν•œλ‹€.

### κ°•μ˜λŠ” κ°•μ˜ 컀버 이미지 정보λ₯Ό κ°€μ§„λ‹€.

- κ°•μ˜λŠ” ν•˜λ‚˜ μ΄μƒμ˜ 컀버 이미지λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

### 강사가 μŠΉμΈν•˜μ§€ μ•Šμ•„λ„ μˆ˜κ°• μ‹ μ²­ν•˜λŠ” λͺ¨λ“  μ‚¬λžŒμ΄ μˆ˜κ°• κ°€λŠ₯ν•˜λ‹€.

- μš°μ•„ν•œν…Œν¬μ½”μŠ€(무료), μš°μ•„ν•œν…Œν¬μΊ ν”„ Pro(유료)와 같이 μ„ λ°œλœ μΈμ›λ§Œ μˆ˜κ°• κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€.
- κ°•μ‚¬λŠ” μˆ˜κ°•μ‹ μ²­ν•œ μ‚¬λžŒ 쀑 μ„ λ°œλœ 인원에 λŒ€ν•΄μ„œλ§Œ μˆ˜κ°• 승인이 κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€.
- κ°•μ‚¬λŠ” μˆ˜κ°•μ‹ μ²­ν•œ μ‚¬λžŒ 쀑 μ„ λ°œλ˜μ§€ μ•Šμ€ μ‚¬λžŒμ€ μˆ˜κ°•μ„ μ·¨μ†Œν•  수 μžˆμ–΄μ•Ό ν•œλ‹€.

## ν”„λ‘œκ·Έλž˜λ° μš”κ΅¬μ‚¬ν•­

- λ¦¬νŒ©ν„°λ§ν•  λ•Œ 컴파일 μ—λŸ¬μ™€ 기쑴의 λ‹¨μœ„ ν…ŒμŠ€νŠΈμ˜ μ‹€νŒ¨λ₯Ό μ΅œμ†Œν™”ν•˜λ©΄μ„œ 점진적인 λ¦¬νŒ©ν„°λ§μ΄ κ°€λŠ₯ν•˜λ„λ‘ ν•œλ‹€.
- DB ν…Œμ΄λΈ”μ— 데이터가 μ‘΄μž¬ν•œλ‹€λŠ” κ°€μ •ν•˜μ— λ¦¬νŒ©ν„°λ§ν•΄μ•Ό ν•œλ‹€.
- 즉, 기쑴에 μŒ“μΈ 데이터λ₯Ό μ œκ±°ν•˜μ§€ μ•Šμ€ μƒνƒœλ‘œ λ¦¬νŒ©ν„°λ§ ν•΄μ•Ό ν•œλ‹€.
26 changes: 4 additions & 22 deletions src/main/java/nextstep/courses/domain/Course.java
Original file line number Diff line number Diff line change
@@ -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<Session> 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;
}
Expand All @@ -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 +
'}';
}
}
16 changes: 9 additions & 7 deletions src/main/java/nextstep/courses/domain/image/CoverImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<CoverImage> findBySessionId(Long id);
}
34 changes: 34 additions & 0 deletions src/main/java/nextstep/courses/domain/image/CoverImages.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package nextstep.courses.domain.image;

import java.util.ArrayList;
import java.util.List;

public class CoverImages {
Copy link
Contributor

Choose a reason for hiding this comment

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

일급 μ½œλ ‰μ…˜ 적용 πŸ‘


private List<CoverImage> coverImages;

public CoverImages() {
this.coverImages = new ArrayList<>();
}

public CoverImages(CoverImage... coverImage) {
this.coverImages = List.of(coverImage);
}

public CoverImages(List<CoverImage> coverImages) {
this.coverImages = coverImages;
}

public void add(CoverImage coverImage) {
coverImages.add(coverImage);
}

public int size() {
return coverImages.size();
}

public List<CoverImage> getCoverImages() {
return coverImages;
}

}
27 changes: 16 additions & 11 deletions src/main/java/nextstep/courses/domain/service/SessionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
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.EnrollmentApply;
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;
Expand All @@ -22,7 +25,7 @@
import java.util.Optional;

@Service
public class SessionService {
public class SessionService {

private final SessionRepository sessionRepository;
private final CoverImageRepository coverImageRepository;
Expand All @@ -47,26 +50,29 @@ public SessionService(SessionRepository sessionRepository,

public Session findById(Long id) {
SessionRecord sessionRecord = sessionRepository.findById(id);
CoverImage saveCoverImage = coverImageRepository.findById(sessionRecord.getCoverImageId());
List<CoverImage> saveCoverImages = coverImageRepository.findBySessionId(id);
Course saveCourse = courseRepository.findById(sessionRecord.getCourseId());
List<EnrollmentRecord> enrollmentRecords = enrollmentRepository.findBySessionId(id);
Enrollments enrollments = toEnrollments(enrollmentRecords);

return sessionRecord.toSession(saveCourse, saveCoverImage, enrollments);
return SessionMapper.toDomain(sessionRecord, saveCourse, saveCoverImages, enrollments);
}

@Transactional
public int save(Session session) {
coverImageRepository.save(session.getCoverImage());
return sessionRepository.save(session.toSessionRecord());
for (CoverImage coverImage : session.getCoverImages()) {
coverImageRepository.save(coverImage);
}

return sessionRepository.save(SessionMapper.toEntity(session));
}

@Transactional
public int saveEnrollment(Enrollment enrollment, Payment payment) {
SessionRecord sessionRecord = sessionRepository.findById(enrollment.getSessionId());
List<EnrollmentRecord> enrollmentRecords = enrollmentRepository.findBySessionId(enrollment.getSessionId());
Session session = sessionRecord.toSession(null, null, toEnrollments(enrollmentRecords));
session.addEnrollment(enrollment, payment);
public int saveEnrollment(NsUser user, Long sessionId, Payment payment) {
SessionRecord sessionRecord = sessionRepository.findById(sessionId);
List<EnrollmentRecord> enrollmentRecords = enrollmentRepository.findBySessionId(sessionId);
EnrollmentApply enrollmentApply = new EnrollmentApply(toEnrollments(enrollmentRecords), payment, sessionRecord.createdSessionCore());
Enrollment enrollment = enrollmentApply.enroll(user, sessionId);

paymentRepository.save(payment);

Expand All @@ -84,5 +90,4 @@ private Enrollments toEnrollments(List<EnrollmentRecord> enrollmentRecords) {
return enrollments;
}


}
28 changes: 28 additions & 0 deletions src/main/java/nextstep/courses/domain/session/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Loading