Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
Q&A 서비스에서 세션 존재 여부 확인 시 사용
JpaRepository<엔티티 타입, PK 타입> 을 상속하면 findById, save, delete 등 기본 메서드가 자동으로 제공
*/
public interface CurriculumRepository extends JpaRepository<StudySession, Integer> {
public interface CurriculumRepository extends JpaRepository<StudySession, Long> {
List<StudySession> findByStatusOrderBySessionDateAscDayPartAsc(SessionStatus status);

List<StudySession> findByStatusOrderBySessionDateDescDayPartDesc(SessionStatus status);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public CurriculumResDTO.CreateSessionRes createSession(CurriculumReqDTO.CreateSe

@Transactional
public CurriculumResDTO.UpdateSessionRes updateSession(Long sessionId, CurriculumReqDTO.UpdateSessionReq req) {
StudySession session = curriculumRepository.findById(Math.toIntExact(sessionId))
StudySession session = curriculumRepository.findById(sessionId)
.orElseThrow(() -> new CurriculumException(HttpStatus.NOT_FOUND, "세션을 찾을 수 없습니다."));

session.update(req.getGeneration(), req.getWeek(), req.getSessionDate(), req.getDayPart(),
Expand All @@ -63,7 +63,7 @@ public CurriculumResDTO.UpdateSessionRes updateSession(Long sessionId, Curriculu

@Transactional
public void deleteSession(Long sessionId) {
StudySession session = curriculumRepository.findById(Math.toIntExact(sessionId))
StudySession session = curriculumRepository.findById(sessionId)
.orElseThrow(() -> new CurriculumException(HttpStatus.NOT_FOUND, "세션을 찾을 수 없습니다."));

curriculumRepository.delete(session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@ public ResponseEntity<ApiResponse<QuestionResDTO.LikeRes>> toggleLike(
questionService.toggleLike(questionId, userId));
}

// 이해도 체크 생성
// POST /api/sessions/{sessionId}/understanding-checks
@PostMapping("/api/sessions/{sessionId}/understanding-checks")
public ResponseEntity<ApiResponse<QuestionResDTO.UnderstandingCheckCreateResponse>> createUnderstandingCheck(
@PathVariable Long sessionId,
@RequestBody QuestionReqDTO.UnderstandingCheckCreateReq request,
@AuthenticationPrincipal Long userId
) {
return ResponseUtil.success(QuestionSuccessCode.UNDERSTANDING_CHECK_CREATED,
questionService.createUnderstandingCheck(sessionId, request, userId));
}

// 이해도 체크 응답
// POST /api/sessions/{sessionId}/understanding-checks/{checkId}/responses
@PostMapping("/api/sessions/{sessionId}/understanding-checks/{checkId}/responses")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,11 @@ public static class CommentReq {
public static class UnderstandingResponseReq {
private UnderstandResChoice choice;
}

// 이해도 체크 생성 요청
@Getter
@NoArgsConstructor
public static class UnderstandingCheckCreateReq {
private String content;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ public record UnderstandingSliceResponse(

public record UnderstandingCheckResponse(
Long checkId,
String title,
String description,
String content,
Integer understoodCount,
Integer notUnderstoodCount,
LocalDateTime createdAt
Expand Down Expand Up @@ -139,4 +138,13 @@ public record UnderstandingResponseResult(
Integer notUnderstoodCount
) {
}

public record UnderstandingCheckCreateResponse(
Long checkId,
String content,
Integer understoodCount,
Integer notUnderstoodCount,
LocalDateTime createdAt
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public enum QuestionSuccessCode implements BaseCode {
LIKE_TOGGLED(HttpStatus.OK, "QUESTION200_3", "좋아요가 처리되었습니다."), // ← 추가
UNDERSTANDING_RESPONSE_OK(HttpStatus.OK, "QUESTION200_4", "이해도 응답이 반영되었습니다."),
QUESTION_CREATED(HttpStatus.CREATED, "QUESTION201_1", "질문이 등록되었습니다."),
COMMENT_CREATED(HttpStatus.CREATED, "QUESTION201_2", "댓글이 등록되었습니다.");
COMMENT_CREATED(HttpStatus.CREATED, "QUESTION201_2", "댓글이 등록되었습니다."),
UNDERSTANDING_CHECK_CREATED(HttpStatus.CREATED, "QUESTION201_3", "이해도 체크가 생성되었습니다.");

private final HttpStatus status;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,30 @@ public QuestionResDTO.LikeRes toggleLike(Long questionId, Long userId) {
});
}

// 이해도 체크 생성
@Transactional
public QuestionResDTO.UnderstandingCheckCreateResponse createUnderstandingCheck(
Long sessionId, QuestionReqDTO.UnderstandingCheckCreateReq request, Long userId
) {
validateUnderstandingCheckCreateRequest(request);
User loginUser = findLoginUser(userId);
validateAdmin(loginUser);
StudySession session = findSession(sessionId);

Comment on lines +245 to +249
LocalDateTime now = LocalDateTime.now();
UnderstandingCheck check = understandingCheckRepository.save(UnderstandingCheck.builder()
.session(session)
.createdBy(loginUser)
.title(request.getContent().trim())
.createdAt(now)
.updatedAt(now)
.build());

return new QuestionResDTO.UnderstandingCheckCreateResponse(
check.getId(), check.getTitle(), 0, 0, check.getCreatedAt()
);
}

// 이해도 체크 응답
@Transactional
public QuestionResDTO.UnderstandingResponseResult respondUnderstandingCheck(
Expand All @@ -263,13 +287,25 @@ private User findLoginUser(Long userId) {
.orElseThrow(() -> new QuestionException(HttpStatus.UNAUTHORIZED, "로그인 사용자를 찾을 수 없습니다."));
}

private void validateAdmin(User loginUser) {
if (loginUser.getRole() != Role.ADMIN) {
throw new QuestionException(HttpStatus.FORBIDDEN, "관리자만 이해도 체크를 생성할 수 있습니다.");
}
}

private void validateUnderstandingCheckCreateRequest(QuestionReqDTO.UnderstandingCheckCreateReq request) {
if (request == null || request.getContent() == null || request.getContent().isBlank()) {
throw new IllegalArgumentException("이해도 체크 내용은 필수입니다.");
}
}

private Question findQuestion(Long questionId) {
return questionRepository.findByIdAndDeletedAtIsNull(questionId)
.orElseThrow(() -> new QuestionException(HttpStatus.NOT_FOUND, "질문을 찾을 수 없습니다."));
}

private StudySession findSession(Long sessionId) {
return curriculumRepository.findById(Math.toIntExact(sessionId))
return curriculumRepository.findById(sessionId)
.orElseThrow(() -> new QuestionException(HttpStatus.NOT_FOUND, "세션을 찾을 수 없습니다."));
}

Expand Down Expand Up @@ -346,7 +382,7 @@ private QuestionResDTO.UnderstandingSliceResponse getUnderstandingSlice(StudySes

private QuestionResDTO.UnderstandingCheckResponse toUnderstandingCheckResponse(UnderstandingCheck check) {
return new QuestionResDTO.UnderstandingCheckResponse(
check.getId(), check.getTitle(), check.getDescription(),
check.getId(), check.getTitle(),
understandingResponseRepository.countByCheckAndChoice(check, UnderstandResChoice.UNDERSTOOD),
understandingResponseRepository.countByCheckAndChoice(check, UnderstandResChoice.NOT_UNDERSTOOD),
check.getCreatedAt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers(HttpMethod.PATCH, "/api/curriculums/{id}").hasRole("ADMIN")
.requestMatchers(HttpMethod.DELETE, "/api/curriculums/{id}").hasRole("ADMIN")

// understanding check: 생성은 ADMIN만 가능
.requestMatchers(HttpMethod.POST, "/api/sessions/{sessionId}/understanding-checks").hasRole("ADMIN")

// Swagger
.requestMatchers(
"/swagger-ui/**",
Expand Down
Loading