Skip to content

Commit a40d6cd

Browse files
authored
v2.3.0 (#716)
2 parents 9c87b8a + 0eb992e commit a40d6cd

33 files changed

+340
-100
lines changed

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ plugins {
44
id 'io.spring.dependency-management' version '1.1.4'
55
id 'org.asciidoctor.jvm.convert' version '3.3.2'
66
id 'com.diffplug.spotless' version '6.23.3'
7+
id "io.sentry.jvm.gradle" version "4.11.0"
78
}
89

910
group = 'com.gdschongik'
@@ -95,6 +96,9 @@ dependencies {
9596

9697
// Github
9798
implementation 'org.kohsuke:github-api:1.323'
99+
100+
// Sentry
101+
implementation 'io.sentry:sentry-logback:7.14.0'
98102
}
99103

100104
tasks.named('test') {

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ services:
1010
- .env
1111
environment:
1212
- TZ=Asia/Seoul
13+
- DOCKER_IMAGE_TAG=${IMAGE_FULL_URL}
1314
redis:
1415
image: "redis:alpine"
1516
container_name: redis

src/main/java/com/gdschongik/gdsc/domain/order/application/OrderService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ public void createFreeOrder(OrderCreateRequest request) {
164164
orderValidator.validateFreeOrderCreate(membership, issuedCoupon, currentMember);
165165

166166
Order order = Order.createFree(request.orderNanoId(), membership, issuedCoupon.orElse(null), moneyInfo);
167+
issuedCoupon.ifPresent(IssuedCoupon::use);
167168

168169
orderRepository.save(order);
169170

src/main/java/com/gdschongik/gdsc/domain/study/api/MentorStudyDetailController.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import com.gdschongik.gdsc.domain.study.application.MentorStudyDetailService;
44
import com.gdschongik.gdsc.domain.study.dto.request.AssignmentCreateUpdateRequest;
55
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentResponse;
6-
import com.gdschongik.gdsc.domain.study.dto.response.StudySessionResponse;
6+
import com.gdschongik.gdsc.domain.study.dto.response.StudyCurriculumResponse;
7+
import com.gdschongik.gdsc.domain.study.dto.response.StudyMentorAttendanceResponse;
78
import io.swagger.v3.oas.annotations.Operation;
89
import io.swagger.v3.oas.annotations.tags.Tag;
910
import jakarta.validation.Valid;
@@ -64,11 +65,19 @@ public ResponseEntity<Void> cancelStudyAssignment(@PathVariable Long studyDetail
6465
return ResponseEntity.noContent().build();
6566
}
6667

67-
// TODO 스터디 세션 워딩을 커리큘럼으로 변경해야함
6868
@Operation(summary = "스터디 주차별 커리큘럼 목록 조회", description = "멘토가 자신의 스터디 커리큘럼 목록을 조회합니다")
69-
@GetMapping("/sessions")
70-
public ResponseEntity<List<StudySessionResponse>> getStudySessions(@RequestParam(name = "study") Long studyId) {
71-
List<StudySessionResponse> response = mentorStudyDetailService.getSessions(studyId);
69+
@GetMapping("/curriculums")
70+
public ResponseEntity<List<StudyCurriculumResponse>> getStudyCurriculums(
71+
@RequestParam(name = "studyId") Long studyId) {
72+
List<StudyCurriculumResponse> response = mentorStudyDetailService.getCurriculums(studyId);
73+
return ResponseEntity.ok(response);
74+
}
75+
76+
@Operation(summary = "스터디 주차별 출결번호 조회", description = "멘토가 자신의 스터디 출결번호 목록을 조회합니다. 지난 출석은 목록에서 제외합니다.")
77+
@GetMapping("/attendances")
78+
public ResponseEntity<List<StudyMentorAttendanceResponse>> getAttendanceNumbers(
79+
@RequestParam(name = "studyId") Long studyId) {
80+
List<StudyMentorAttendanceResponse> response = mentorStudyDetailService.getAttendanceNumbers(studyId);
7281
return ResponseEntity.ok(response);
7382
}
7483
}

src/main/java/com/gdschongik/gdsc/domain/study/api/StudentStudyDetailController.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.gdschongik.gdsc.domain.study.application.StudentStudyDetailService;
44
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentDashboardResponse;
55
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentHistoryStatusResponse;
6-
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentSessionResponse;
6+
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentCurriculumResponse;
77
import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse;
88
import io.swagger.v3.oas.annotations.Operation;
99
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -38,12 +38,11 @@ public ResponseEntity<List<StudyTodoResponse>> getStudyTodoList(@RequestParam(na
3838
return ResponseEntity.ok(response);
3939
}
4040

41-
// TODO 스터디 세션 워딩을 커리큘럼으로 변경해야함
4241
@Operation(summary = "스터디 커리큘럼 조회", description = "해당 스터디의 커리큘럼들을 조회합니다.")
43-
@GetMapping("/sessions")
44-
public ResponseEntity<List<StudyStudentSessionResponse>> getStudySessions(
42+
@GetMapping("/curriculums")
43+
public ResponseEntity<List<StudyStudentCurriculumResponse>> getStudyCurriculums(
4544
@RequestParam(name = "studyId") Long studyId) {
46-
List<StudyStudentSessionResponse> response = studentStudyDetailService.getStudySessions(studyId);
45+
List<StudyStudentCurriculumResponse> response = studentStudyDetailService.getStudyCurriculums(studyId);
4746
return ResponseEntity.ok(response);
4847
}
4948

src/main/java/com/gdschongik/gdsc/domain/study/application/AdminStudyService.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ public class AdminStudyService {
3030

3131
@Transactional
3232
public void createStudyAndStudyDetail(StudyCreateRequest request) {
33-
// TODO: 멘토 권한 부여
34-
final Member mentor = getMemberById(request.mentorId());
33+
Member mentor = getMemberById(request.mentorId());
34+
mentor.assignToMentor();
35+
memberRepository.save(mentor);
3536

3637
Study study = studyDomainFactory.createNewStudy(request, mentor);
3738
final Study savedStudy = studyRepository.save(study);

src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyDetailService.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import com.gdschongik.gdsc.domain.study.domain.StudyDetailValidator;
99
import com.gdschongik.gdsc.domain.study.dto.request.AssignmentCreateUpdateRequest;
1010
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentResponse;
11-
import com.gdschongik.gdsc.domain.study.dto.response.StudySessionResponse;
11+
import com.gdschongik.gdsc.domain.study.dto.response.StudyCurriculumResponse;
12+
import com.gdschongik.gdsc.domain.study.dto.response.StudyMentorAttendanceResponse;
1213
import com.gdschongik.gdsc.global.exception.CustomException;
1314
import com.gdschongik.gdsc.global.util.MemberUtil;
15+
import java.time.LocalDate;
1416
import java.util.List;
1517
import lombok.RequiredArgsConstructor;
1618
import lombok.extern.slf4j.Slf4j;
@@ -86,8 +88,19 @@ public void updateStudyAssignment(Long studyDetailId, AssignmentCreateUpdateRequ
8688
}
8789

8890
@Transactional(readOnly = true)
89-
public List<StudySessionResponse> getSessions(Long studyId) {
91+
public List<StudyCurriculumResponse> getCurriculums(Long studyId) {
9092
List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId);
91-
return studyDetails.stream().map(StudySessionResponse::from).toList();
93+
return studyDetails.stream().map(StudyCurriculumResponse::from).toList();
94+
}
95+
96+
@Transactional(readOnly = true)
97+
public List<StudyMentorAttendanceResponse> getAttendanceNumbers(Long studyId) {
98+
List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId);
99+
100+
// 출석일이 오늘 or 오늘이후인 StudyDetail
101+
return studyDetails.stream()
102+
.filter(studyDetail -> studyDetail.isAttendanceDayNotPassed(LocalDate.now()))
103+
.map(StudyMentorAttendanceResponse::from)
104+
.toList();
92105
}
93106
}

src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import com.gdschongik.gdsc.domain.study.domain.StudyHistory;
1414
import com.gdschongik.gdsc.domain.study.domain.StudyValidator;
1515
import com.gdschongik.gdsc.domain.study.dto.request.StudyAnnouncementCreateUpdateRequest;
16-
import com.gdschongik.gdsc.domain.study.dto.request.StudySessionCreateRequest;
16+
import com.gdschongik.gdsc.domain.study.dto.request.StudyCurriculumCreateRequest;
1717
import com.gdschongik.gdsc.domain.study.dto.request.StudyUpdateRequest;
1818
import com.gdschongik.gdsc.domain.study.dto.response.MentorStudyResponse;
1919
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentResponse;
@@ -101,7 +101,6 @@ public void deleteStudyAnnouncement(Long studyAnnouncementId) {
101101
log.info("[MentorStudyService] 스터디 공지 삭제 완료: studyAnnouncementId={}", studyAnnouncement.getId());
102102
}
103103

104-
// TODO session -> curriculum 변경
105104
@Transactional
106105
public void updateStudy(Long studyId, StudyUpdateRequest request) {
107106
Member currentMember = memberUtil.getCurrentMember();
@@ -112,9 +111,9 @@ public void updateStudy(Long studyId, StudyUpdateRequest request) {
112111
// StudyDetail ID를 추출하여 Set으로 저장
113112
Set<Long> studyDetailIds = studyDetails.stream().map(StudyDetail::getId).collect(Collectors.toSet());
114113

115-
// 요청된 StudySessionCreateRequest의 StudyDetail ID를 추출하여 Set으로 저장
116-
Set<Long> requestIds = request.studySessions().stream()
117-
.map(StudySessionCreateRequest::studyDetailId)
114+
// 요청된 StudyCurriculumCreateRequest의 StudyDetail ID를 추출하여 Set으로 저장
115+
Set<Long> requestIds = request.studyCurriculums().stream()
116+
.map(StudyCurriculumCreateRequest::studyDetailId)
118117
.collect(Collectors.toSet());
119118

120119
studyDetailValidator.validateUpdateStudyDetail(studyDetailIds, requestIds);
@@ -123,24 +122,24 @@ public void updateStudy(Long studyId, StudyUpdateRequest request) {
123122
studyRepository.save(study);
124123
log.info("[MentorStudyService] 스터디 기본 정보 수정 완료: studyId={}", studyId);
125124

126-
updateAllStudyDetailSession(studyDetails, request.studySessions());
125+
updateAllStudyDetailCurriculum(studyDetails, request.studyCurriculums());
127126
}
128127

129-
private void updateAllStudyDetailSession(
130-
List<StudyDetail> studyDetails, List<StudySessionCreateRequest> studySessions) {
128+
private void updateAllStudyDetailCurriculum(
129+
List<StudyDetail> studyDetails, List<StudyCurriculumCreateRequest> studyCurriculums) {
131130
for (StudyDetail studyDetail : studyDetails) {
132131
Long id = studyDetail.getId();
133-
StudySessionCreateRequest matchingSession = studySessions.stream()
134-
.filter(session -> session.studyDetailId().equals(id))
132+
StudyCurriculumCreateRequest matchingCurriculum = studyCurriculums.stream()
133+
.filter(curriculum -> curriculum.studyDetailId().equals(id))
135134
.findFirst()
136135
.get();
137136

138-
studyDetail.updateSession(
137+
studyDetail.updateCurriculum(
139138
studyDetail.getStudy().getStartTime(),
140-
matchingSession.title(),
141-
matchingSession.description(),
142-
matchingSession.difficulty(),
143-
matchingSession.status());
139+
matchingCurriculum.title(),
140+
matchingCurriculum.description(),
141+
matchingCurriculum.difficulty(),
142+
matchingCurriculum.status());
144143
}
145144
studyDetailRepository.saveAll(studyDetails);
146145
log.info("[MentorStudyService] 스터디 상세정보 커리큘럼 작성 완료: studyDetailId={}", studyDetails);

src/main/java/com/gdschongik/gdsc/domain/study/application/StudentStudyDetailService.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@
99
import com.gdschongik.gdsc.domain.study.domain.Attendance;
1010
import com.gdschongik.gdsc.domain.study.domain.StudyDetail;
1111
import com.gdschongik.gdsc.domain.study.domain.StudyHistory;
12-
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentDashboardResponse;
13-
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentHistoryStatusResponse;
14-
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentSubmittableDto;
15-
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentSessionResponse;
16-
import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse;
12+
import com.gdschongik.gdsc.domain.study.dto.response.*;
1713
import com.gdschongik.gdsc.global.exception.CustomException;
1814
import com.gdschongik.gdsc.global.exception.ErrorCode;
1915
import com.gdschongik.gdsc.global.util.MemberUtil;
@@ -69,7 +65,7 @@ public List<StudyTodoResponse> getStudyTodoList(Long studyId) {
6965
List<StudyTodoResponse> response = new ArrayList<>();
7066
// 출석체크 정보 (개설 상태이고, 오늘이 출석체크날짜인 것)
7167
studyDetails.stream()
72-
.filter(studyDetail -> studyDetail.getSession().isOpen()
68+
.filter(studyDetail -> studyDetail.getCurriculum().isOpen()
7369
&& studyDetail.getAttendanceDay().equals(now))
7470
.forEach(studyDetail -> response.add(StudyTodoResponse.createAttendanceType(
7571
studyDetail, now, isAttended(attendances, studyDetail))));
@@ -83,15 +79,15 @@ public List<StudyTodoResponse> getStudyTodoList(Long studyId) {
8379
return response;
8480
}
8581

86-
public List<StudyStudentSessionResponse> getStudySessions(Long studyId) {
82+
public List<StudyStudentCurriculumResponse> getStudyCurriculums(Long studyId) {
8783
Member member = memberUtil.getCurrentMember();
8884
final List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId);
8985
final List<AssignmentHistory> assignmentHistories =
9086
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudyId(member, studyId);
9187
final List<Attendance> attendances = attendanceRepository.findByMemberAndStudyId(member, studyId);
9288

9389
return studyDetails.stream()
94-
.map(studyDetail -> StudyStudentSessionResponse.of(
90+
.map(studyDetail -> StudyStudentCurriculumResponse.of(
9591
studyDetail,
9692
getSubmittedAssignment(assignmentHistories, studyDetail),
9793
isAttended(attendances, studyDetail),

src/main/java/com/gdschongik/gdsc/domain/study/application/StudentStudyService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.gdschongik.gdsc.global.exception.CustomException;
1818
import com.gdschongik.gdsc.global.util.MemberUtil;
1919
import java.time.LocalDate;
20+
import java.time.LocalDateTime;
2021
import java.util.List;
2122
import java.util.Optional;
2223
import lombok.RequiredArgsConstructor;
@@ -106,7 +107,8 @@ public void attend(Long studyDetailId, StudyAttendCreateRequest request) {
106107
public StudentMyCurrentStudyResponse getMyCurrentStudy() {
107108
Member currentMember = memberUtil.getCurrentMember();
108109
StudyHistory studyHistory = studyHistoryRepository.findAllByStudent(currentMember).stream()
109-
.filter(s -> s.getStudy().isStudyOngoing())
110+
.filter(s -> s.getStudy().getApplicationPeriod().getStartDate().isBefore(LocalDateTime.now())
111+
&& s.getStudy().getPeriod().getEndDate().isAfter(LocalDateTime.now()))
110112
.findFirst()
111113
.orElse(null);
112114
return StudentMyCurrentStudyResponse.from(studyHistory);

src/main/java/com/gdschongik/gdsc/domain/study/domain/Study.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public static Study createStudy(
114114
DayOfWeek dayOfWeek,
115115
LocalTime startTime,
116116
LocalTime endTime) {
117-
validateApplicationStartDateBeforeSessionStartDate(applicationPeriod.getStartDate(), period.getStartDate());
117+
validateApplicationStartDateBeforeCurriculumStartDate(applicationPeriod.getStartDate(), period.getStartDate());
118118
validateMentorRole(mentor);
119119
validateStudyTime(studyType, startTime, endTime);
120120
return Study.builder()
@@ -134,7 +134,7 @@ public static Study createStudy(
134134

135135
// 검증 로직
136136

137-
private static void validateApplicationStartDateBeforeSessionStartDate(
137+
private static void validateApplicationStartDateBeforeCurriculumStartDate(
138138
LocalDateTime applicationStartDate, LocalDateTime startDate) {
139139
if (!applicationStartDate.isBefore(startDate)) {
140140
throw new CustomException(STUDY_APPLICATION_START_DATE_INVALID);

src/main/java/com/gdschongik/gdsc/domain/study/domain/StudyDetail.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import com.gdschongik.gdsc.domain.common.model.BaseEntity;
66
import com.gdschongik.gdsc.domain.recruitment.domain.vo.Period;
77
import com.gdschongik.gdsc.domain.study.domain.vo.Assignment;
8-
import com.gdschongik.gdsc.domain.study.domain.vo.Session;
8+
import com.gdschongik.gdsc.domain.study.domain.vo.Curriculum;
99
import com.gdschongik.gdsc.global.exception.CustomException;
1010
import jakarta.persistence.*;
1111
import java.time.DayOfWeek;
@@ -41,12 +41,12 @@ public class StudyDetail extends BaseEntity {
4141
private Period period;
4242

4343
@Embedded
44-
@AttributeOverride(name = "title", column = @Column(name = "session_title"))
45-
@AttributeOverride(name = "difficulty", column = @Column(name = "session_difficulty"))
46-
@AttributeOverride(name = "startAt", column = @Column(name = "session_start_at"))
47-
@AttributeOverride(name = "description", column = @Column(name = "session_description"))
48-
@AttributeOverride(name = "status", column = @Column(name = "session_status"))
49-
private Session session;
44+
@AttributeOverride(name = "title", column = @Column(name = "curriculum_title"))
45+
@AttributeOverride(name = "difficulty", column = @Column(name = "curriculum_difficulty"))
46+
@AttributeOverride(name = "startAt", column = @Column(name = "curriculum_start_at"))
47+
@AttributeOverride(name = "description", column = @Column(name = "curriculum_description"))
48+
@AttributeOverride(name = "status", column = @Column(name = "curriculum_status"))
49+
private Curriculum curriculum;
5050

5151
@Embedded
5252
@AttributeOverride(name = "title", column = @Column(name = "assignment_title"))
@@ -57,12 +57,17 @@ public class StudyDetail extends BaseEntity {
5757

5858
@Builder(access = AccessLevel.PRIVATE)
5959
private StudyDetail(
60-
Study study, Long week, String attendanceNumber, Period period, Session session, Assignment assignment) {
60+
Study study,
61+
Long week,
62+
String attendanceNumber,
63+
Period period,
64+
Curriculum curriculum,
65+
Assignment assignment) {
6166
this.study = study;
6267
this.week = week;
6368
this.attendanceNumber = attendanceNumber;
6469
this.period = period;
65-
this.session = session;
70+
this.curriculum = curriculum;
6671
this.assignment = assignment;
6772
}
6873

@@ -73,7 +78,7 @@ public static StudyDetail createStudyDetail(Study study, Long week, String atten
7378
.period(period)
7479
.attendanceNumber(attendanceNumber)
7580
.period(period)
76-
.session(Session.createEmptySession())
81+
.curriculum(Curriculum.createEmptyCurriculum())
7782
.assignment(Assignment.createEmptyAssignment())
7883
.build();
7984
}
@@ -123,9 +128,14 @@ public LocalDate getAttendanceDay() {
123128
return startDate.plusDays(daysToAdd);
124129
}
125130

126-
public void updateSession(
131+
// 출석일이 오늘 or 오늘이후인지 확인
132+
public boolean isAttendanceDayNotPassed(LocalDate now) {
133+
return !getAttendanceDay().isBefore(now);
134+
}
135+
136+
public void updateCurriculum(
127137
LocalTime startAt, String title, String description, Difficulty difficulty, StudyStatus status) {
128-
session = Session.generateSession(startAt, title, description, difficulty, status);
138+
curriculum = Curriculum.generateCurriculum(startAt, title, description, difficulty, status);
129139
}
130140

131141
public void validateAssignmentSubmittable(LocalDateTime now) {

src/main/java/com/gdschongik/gdsc/domain/study/domain/StudyDetailValidator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ private void validateUpdateDeadline(
5757
}
5858

5959
public void validateUpdateStudyDetail(Set<Long> studyDetails, Set<Long> requests) {
60-
// StudyDetail 목록과 요청된 StudySessionCreateRequest 목록의 크기를 먼저 비교
60+
// StudyDetail 목록과 요청된 StudyCurriculumCreateRequest 목록의 크기를 먼저 비교
6161
if (studyDetails.size() != requests.size()) {
62-
throw new CustomException(STUDY_DETAIL_SESSION_SIZE_MISMATCH);
62+
throw new CustomException(STUDY_DETAIL_CURRICULUM_SIZE_MISMATCH);
6363
}
6464

6565
// 두 ID 집합이 동일한지 비교하여 ID 불일치 시 예외를 던짐

src/main/java/com/gdschongik/gdsc/domain/study/domain/StudyType.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
@AllArgsConstructor
88
public enum StudyType {
99
ASSIGNMENT("과제 스터디"),
10-
ONLINE("온라인 세션"),
11-
OFFLINE("오프라인 세션");
10+
ONLINE("온라인 커리큘럼"),
11+
OFFLINE("오프라인 커리큘럼");
1212

1313
private final String value;
1414
}

0 commit comments

Comments
 (0)