Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 이번주 과제 조회 API 구현 #647

Merged
merged 19 commits into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
21dcdd7
feat: 이번주 과제 조회 API 구현
AlmondBreez3 Aug 18, 2024
dc17536
feat: 불필요한 코드 제거 및 엔드포인트 수정
AlmondBreez3 Aug 20, 2024
f1d9c91
feat: 코드 오타 수정
AlmondBreez3 Aug 20, 2024
0fe4c06
fix: 레포지토리 메소드 위치 수정
AlmondBreez3 Aug 20, 2024
ed8f8d1
feat: 이번주까지 마감인 과제들 반환 로직 추가
AlmondBreez3 Aug 21, 2024
6513447
Merge branch 'develop' of https://github.com/GDSC-Hongik/gdsc-server …
AlmondBreez3 Aug 21, 2024
15c5bb7
feat: 도메인 메소드에 추가
AlmondBreez3 Aug 21, 2024
1b29a9a
feat: 도메인 메소드 주석 가독성 향상
AlmondBreez3 Aug 21, 2024
1c614a8
fix: 머지 컨플릭트 수정
AlmondBreez3 Aug 21, 2024
c71c2ff
fix: 머지 컨플릭트 해결
AlmondBreez3 Aug 22, 2024
7197c4a
feat: 과제 제출 내역이 null일때 고려해서 response반환
AlmondBreez3 Aug 22, 2024
36692d4
feat: 과제 제출 이력이 없을 때 StudyDetail에서 가져와서 반환
AlmondBreez3 Aug 23, 2024
f86e788
feat: 과제 응답 클래스명 변경
AlmondBreez3 Aug 23, 2024
d9fccc6
feat: 과제 응답 로직 개선
AlmondBreez3 Aug 23, 2024
497038a
feat: 과제 응답 Response 개선
AlmondBreez3 Aug 23, 2024
8b09f4f
feat: npe 예방 코드
AlmondBreez3 Aug 23, 2024
0ca5d97
fix: 머지 컨플릭트 해결
AlmondBreez3 Aug 24, 2024
1a50295
Merge branch 'develop' of https://github.com/GDSC-Hongik/gdsc-server …
AlmondBreez3 Aug 24, 2024
dc9d745
feat: merge develop
AlmondBreez3 Aug 24, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.gdschongik.gdsc.domain.study.application.StudentStudyDetailService;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentDashboardResponse;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentHistoryStatusResponse;
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentSessionResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -29,6 +30,14 @@ public ResponseEntity<AssignmentDashboardResponse> getSubmittableAssignments(
return ResponseEntity.ok(response);
}

@Operation(summary = "이번주 제출해야 할 과제 조회", description = "마감 기한이 이번주까지인 과제를 조회합니다.")
@GetMapping("/assignments/upcoming")
public ResponseEntity<List<AssignmentHistoryStatusResponse>> getUpcomingAssignments(
@RequestParam(name = "studyId") Long studyId) {
List<AssignmentHistoryStatusResponse> response = studentStudyDetailService.getUpcomingAssignments(studyId);
return ResponseEntity.ok(response);
}

// TODO 스터디 세션 워딩을 커리큘럼으로 변경해야함
@Operation(summary = "스터디 커리큘럼 조회", description = "해당 스터디의 커리큘럼들을 조회합니다.")
@GetMapping("/sessions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.gdschongik.gdsc.domain.study.domain.StudyDetail;
import com.gdschongik.gdsc.domain.study.domain.StudyHistory;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentDashboardResponse;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentHistoryStatusResponse;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentSubmittableDto;
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentSessionResponse;
import com.gdschongik.gdsc.global.exception.CustomException;
Expand Down Expand Up @@ -38,7 +39,7 @@ public AssignmentDashboardResponse getSubmittableAssignments(Long studyId) {
.findByStudentAndStudyId(currentMember, studyId)
.orElseThrow(() -> new CustomException(ErrorCode.STUDY_HISTORY_NOT_FOUND));
List<AssignmentHistory> assignmentHistories =
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudy(currentMember, studyId);
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudyId(currentMember, studyId);
List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId).stream()
.filter(studyDetail ->
studyDetail.getAssignment().isOpen() && studyDetail.isAssignmentDeadlineRemaining())
Expand All @@ -53,12 +54,30 @@ studyDetail, getSubmittedAssignment(assignmentHistories, studyDetail)))
return AssignmentDashboardResponse.of(studyHistory.getRepositoryLink(), isAnySubmitted, submittableAssignments);
}

@Transactional(readOnly = true)
public List<AssignmentHistoryStatusResponse> getUpcomingAssignments(Long studyId) {
Member currentMember = memberUtil.getCurrentMember();
List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyId(studyId).stream()
.filter(studyDetail -> studyDetail.isAssignmentDeadlineThisWeek())
Copy link
Member

Choose a reason for hiding this comment

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

이거 아마 한번 돌려보시면 assignment.deadline이 null인 경우에 익셉션 던져질거에요!

Copy link
Member Author

Choose a reason for hiding this comment

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

위에 구현하신 isOpen가져와서 비교하는 대로 수정했습니다

.toList();
List<AssignmentHistory> assignmentHistories =
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudyId(currentMember, studyId).stream()
.filter(assignmentHistory ->
assignmentHistory.getStudyDetail().isAssignmentDeadlineThisWeek())
.toList();
Copy link
Member

Choose a reason for hiding this comment

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

제출한 이력이 없는 과제에 대해서는 AssignmentHistory가 존재하지 않습니다.
따라서, 이 방법으로는 제출한 적 있는 과제에 대해서만 조회가 가능합니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

Response한번 보시겠어요??

Copy link
Member Author

Choose a reason for hiding this comment

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

아 이해했습니다~

Copy link
Member Author

Choose a reason for hiding this comment

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

아 이해했어용

Copy link
Member Author

Choose a reason for hiding this comment

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

근데 질문이 있는데 수강신청하면 자동으로 저 assignmentHistory가 생기는게 아닌가요?

Copy link
Member

Choose a reason for hiding this comment

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

StudentStudyHistoryService의 findOrCreate 메서드 확인해주세요

Copy link
Member Author

Choose a reason for hiding this comment

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

그런데 상욱님 제가 만든 Response를 보시면 null이면 Assignment를 반환하게 만들었는데 이걸로 충분한거 같은데 왜 다른 로직이 필요하다고 생각하신지 여쭈어봐도 될까용

Copy link
Member Author

Choose a reason for hiding this comment

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

어 아니에요!! 무시하셔두 됩니다 제가 오늘 밤에 퇴근하고 고칠게요


return studyDetails.stream()
.map(studyDetail -> AssignmentHistoryStatusResponse.of(
studyDetail, getSubmittedAssignment(assignmentHistories, studyDetail)))
.toList();
}

@Transactional(readOnly = true)
public List<StudyStudentSessionResponse> getStudySessions(Long studyId) {
Member member = memberUtil.getCurrentMember();
final List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId);
final List<AssignmentHistory> assignmentHistories =
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudy(member, studyId);
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudyId(member, studyId);
final List<Attendance> attendances = attendanceRepository.findByMemberAndStudyId(member, studyId);

return studyDetails.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private String getOwnerRepo(String repositoryLink) {
public List<AssignmentHistoryResponse> getAllAssignmentHistories(Long studyId) {
Member currentMember = memberUtil.getCurrentMember();

return assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudy(currentMember, studyId).stream()
return assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudyId(currentMember, studyId).stream()
.map(AssignmentHistoryResponse::from)
.toList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ public interface AssignmentHistoryCustomRepository {

boolean existsSubmittedAssignmentByMemberAndStudy(Member member, Study study);

List<AssignmentHistory> findAssignmentHistoriesByStudentAndStudy(Member member, Long studyId);
List<AssignmentHistory> findAssignmentHistoriesByStudentAndStudyId(Member member, Long studyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private BooleanExpression isSubmitted() {
}

@Override
public List<AssignmentHistory> findAssignmentHistoriesByStudentAndStudy(Member currentMember, Long studyId) {
public List<AssignmentHistory> findAssignmentHistoriesByStudentAndStudyId(Member currentMember, Long studyId) {
return queryFactory
.selectFrom(assignmentHistory)
.join(assignmentHistory.studyDetail, studyDetail)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@
public interface StudyDetailRepository extends JpaRepository<StudyDetail, Long> {

List<StudyDetail> findAllByStudyIdOrderByWeekAsc(Long studyId);

List<StudyDetail> findAllByStudyId(Long studyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public boolean isAssignmentDeadlineRemaining() {
return assignment.isDeadlineRemaining();
}

public boolean isAssignmentDeadlineThisWeek() {
return assignment.isDeadLineThisWeek();
}

// 스터디 시작일자 + 현재 주차 * 7 + (스터디 요일 - 스터디 기간 시작 요일)
public LocalDate getAttendanceDay() {
return study.getStartDate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.Builder;
Expand Down Expand Up @@ -93,4 +95,17 @@ public boolean isDeadlineRemaining() {
LocalDateTime now = LocalDateTime.now();
return now.isBefore(deadline);
}

public boolean isDeadLineThisWeek() {
// 현재 날짜와 마감일의 날짜 부분을 비교할 것이므로 LocalDate로 변환
LocalDate now = LocalDate.now();
LocalDate startOfWeek = now.with(DayOfWeek.MONDAY); // 이번 주 월요일
LocalDate endOfWeek = now.with(DayOfWeek.SUNDAY); // 이번 주 일요일

// 마감일의 날짜 부분을 가져옴
LocalDate deadlineDate = deadline.toLocalDate();

// 마감일이 이번 주 내에 있는지 확인
return !deadlineDate.isBefore(startOfWeek) && !deadlineDate.isAfter(endOfWeek);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.gdschongik.gdsc.domain.study.dto.response;

import static com.gdschongik.gdsc.domain.study.domain.SubmissionFailureType.NOT_SUBMITTED;

import com.gdschongik.gdsc.domain.study.domain.*;
import com.gdschongik.gdsc.domain.study.domain.vo.Assignment;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Nullable;
import java.time.LocalDateTime;

public record AssignmentHistoryStatusResponse(
Long studyDetailId,
@Schema(description = "과제 상태") StudyStatus assignmentStatus,
@Schema(description = "주차") Long week,
@Nullable @Schema(description = "과제 제목") String title,
// TODO 추후 처리 예정
@Nullable @Schema(description = "과제 제출 상태") AssignmentSubmissionStatus assignmentSubmissionStatus,
@Nullable @Schema(description = "과제 명세 링크") String descriptionLink,
@Nullable @Schema(description = "마감 기한") LocalDateTime deadline,
@Nullable @Schema(description = "과제 제출 링크") String submissionLink,
@Nullable @Schema(description = "과제 제출 실패 사유. 제출 여부도 포함되어 있습니다. 미제출 상태라면 기본 과제 정보만 반환합니다.")
SubmissionFailureType submissionFailureType,
@Nullable @Schema(description = "최종 수정 일시") LocalDateTime committedAt) {
Comment on lines +11 to +23
Copy link

Choose a reason for hiding this comment

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

필드 정의가 잘 되어 있습니다.

필드에 대한 API 문서화가 적절하게 이루어졌습니다. TODO 주석은 추후 작업을 나타냅니다.

추후 작업에 대한 도움이 필요하시면 말씀해 주세요. 관련 GitHub 이슈를 생성할 수 있습니다.


// 과제 제출이 없는 경우, 과제 정보만 사용하여 AssignmentHistoryStatusResponse 생성
public static AssignmentHistoryStatusResponse of(StudyDetail studyDetail, AssignmentHistory assignmentHistory) {
if (assignmentHistory == null) {
return new AssignmentHistoryStatusResponse(
studyDetail.getId(),
studyDetail.getAssignment().getStatus(),
studyDetail.getWeek(),
studyDetail.getAssignment().getTitle(),
null,
studyDetail.getAssignment().getDescriptionLink(),
studyDetail.getAssignment().getDeadline(),
null,
NOT_SUBMITTED,
null);
}

Assignment assignment = studyDetail.getAssignment();
return new AssignmentHistoryStatusResponse(
studyDetail.getId(),
assignment.getStatus(),
studyDetail.getWeek(),
assignment.getTitle(),
assignmentHistory.getSubmissionStatus(),
assignment.getDescriptionLink(),
assignment.getDeadline(),
assignmentHistory.getSubmissionLink(),
assignmentHistory.getSubmissionFailureType(),
assignmentHistory.getCommittedAt());
}
}