diff --git a/src/main/java/com/threestar/trainus/domain/lesson/student/dto/LessonDetailResponseDto.java b/src/main/java/com/threestar/trainus/domain/lesson/student/dto/LessonDetailResponseDto.java index d4ee043..8746f0b 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/student/dto/LessonDetailResponseDto.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/student/dto/LessonDetailResponseDto.java @@ -37,4 +37,4 @@ public record LessonDetailResponseDto( LocalDateTime updatedAt, List lessonImages ) { -} \ No newline at end of file +} diff --git a/src/main/java/com/threestar/trainus/domain/lesson/student/mapper/LessonApplicationMapper.java b/src/main/java/com/threestar/trainus/domain/lesson/student/mapper/LessonApplicationMapper.java index 9b80f9e..b753687 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/student/mapper/LessonApplicationMapper.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/student/mapper/LessonApplicationMapper.java @@ -46,4 +46,4 @@ public static MyLessonApplicationListResponseDto toDtoListWithCount(List> getCreatedLess return PagedResponse.ok("개설한 레슨 목록 조회 완료.", wrapperDto, responseDto.count(), HttpStatus.OK); } + @PatchMapping("/lessons/{lessonId}") + @Operation(summary = "레슨 수정 api", description = "레슨 정보를 수정") + public ResponseEntity> updateLesson( + @PathVariable Long lessonId, + @Valid @RequestBody LessonUpdateRequestDto requestDto, + @LoginUser Long loginUserId) { + + LessonUpdateResponseDto responseDto = adminLessonService.updateLesson(lessonId, requestDto, loginUserId); + return BaseResponse.ok("레슨이 수정되었습니다.", responseDto, HttpStatus.OK); + } + } diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonCreateRequestDto.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonCreateRequestDto.java index f2aa805..ec398c6 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonCreateRequestDto.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonCreateRequestDto.java @@ -67,11 +67,4 @@ public record LessonCreateRequestDto( List lessonImages ) { - - public LessonCreateRequestDto { - // null 체크 등 추가 검증 로직 - if (lessonImages == null) { - lessonImages = List.of(); // 빈 리스트로 초기화 - } - } } diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonUpdateRequestDto.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonUpdateRequestDto.java new file mode 100644 index 0000000..cefc797 --- /dev/null +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonUpdateRequestDto.java @@ -0,0 +1,72 @@ +package com.threestar.trainus.domain.lesson.teacher.dto; + +import java.time.LocalDateTime; +import java.util.List; + +import com.threestar.trainus.domain.lesson.teacher.entity.Category; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.Size; + +/** + * 레슨 수정 요청 데이터 + */ +public record LessonUpdateRequestDto( + + @Size(max = 50, message = "레슨명은 50자 이내여야 합니다.") + String lessonName, + + @Size(max = 255, message = "레슨 설명은 255자 이내여야 합니다.") + String description, + + Category category, + + @Min(value = 0, message = "가격은 0원 이상이어야 합니다.") + Integer price, + + @Min(value = 1, message = "최대 참가 인원은 1명 이상이어야 합니다.") + @Max(value = 100, message = "최대 참가 인원은 100명 이하여야 합니다.") + Integer maxParticipants, + + LocalDateTime startAt, + + LocalDateTime endAt, + + LocalDateTime openTime, + + Boolean openRun, + + @Size(max = 10, message = "시/도는 10자 이하여야 합니다.") + String city, + + @Size(max = 10, message = "시/군/구는 10자 이하여야 합니다.") + String district, + + @Size(max = 10, message = "읍/면/동은 10자 이하여야 합니다.") + String dong, + + @Size(max = 25, message = "상세주소는 25자 이하여야 합니다.") + String addressDetail, + + @Size(max = 5, message = "이미지는 최대 5장까지 첨부 가능합니다.") + List lessonImages + +) { + + // 레슨이름, 설명, 이미지는 항상 수정가능 + public boolean hasBasicInfoChanges() { + return lessonName != null || description != null || (lessonImages != null && !lessonImages.isEmpty()); + } + + // 제한된 필드들은 수정(참가자 없을때만 가능) + public boolean hasRestrictedChanges() { + return category != null || price != null || startAt != null || endAt != null || openTime != null + || openRun != null || city != null || district != null || dong != null || addressDetail != null; + } + + //시간 관련 필드 수정 체크 + public boolean hasTimeChanges() { + return startAt != null || endAt != null; + } +} diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonUpdateResponseDto.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonUpdateResponseDto.java new file mode 100644 index 0000000..0b0ca16 --- /dev/null +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/dto/LessonUpdateResponseDto.java @@ -0,0 +1,36 @@ +package com.threestar.trainus.domain.lesson.teacher.dto; + +import java.time.LocalDateTime; +import java.util.List; + +import com.threestar.trainus.domain.lesson.teacher.entity.Category; +import com.threestar.trainus.domain.lesson.teacher.entity.LessonStatus; + +import lombok.Builder; + +/** + * 레슨 수정 응답 데이터 + */ +@Builder +public record LessonUpdateResponseDto( + Long id, + String lessonName, + String description, + Long lessonLeader, + Category category, + Integer price, + Integer maxParticipants, + LocalDateTime startAt, + LocalDateTime endAt, + LocalDateTime openTime, + Boolean openRun, + String city, + String district, + String dong, + String addressDetail, + LessonStatus status, + LocalDateTime createdAt, + LocalDateTime updatedAt, + List lessonImages +) { +} diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/entity/Lesson.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/entity/Lesson.java index a83e782..bb72304 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/teacher/entity/Lesson.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/entity/Lesson.java @@ -3,6 +3,8 @@ import java.time.LocalDateTime; import com.threestar.trainus.global.entity.BaseDateEntity; +import com.threestar.trainus.global.exception.domain.ErrorCode; +import com.threestar.trainus.global.exception.handler.BusinessException; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -130,4 +132,83 @@ public void incrementParticipantCount() { } } + //레슨 이름 수정 + public void updateLessonName(String lessonName) { + if (lessonName != null && !lessonName.trim().isEmpty()) { + this.lessonName = lessonName; + } + } + + //레슨 설명 수정 + public void updateDescription(String description) { + if (description != null && !description.trim().isEmpty()) { + this.description = description; + } + } + + //카테고리 수정 + public void updateCategory(Category category) { + if (category != null) { + this.category = category; + } + } + + //가격 수정 + public void updatePrice(Integer price) { + if (price != null) { + this.price = price; + } + } + + //최대 참가자수 수정(참가자가 이미 있는 경우는 참가자수 증가만 가능) + public void updateMaxParticipants(Integer newMaxParticipants, boolean hasParticipants) { + if (newMaxParticipants != null) { + if (hasParticipants && newMaxParticipants < this.maxParticipants) { + throw new BusinessException(ErrorCode.LESSON_MAX_PARTICIPANTS_CANNOT_DECREASE); + } + this.maxParticipants = newMaxParticipants; + } + } + + //레슨 시간 수정 + public void updateLessonTime(LocalDateTime startAt, LocalDateTime endAt) { + if (startAt != null) { + this.startAt = startAt; + } + if (endAt != null) { + this.endAt = endAt; + } + } + + //오픈시각 수정 + public void updateOpenTime(LocalDateTime openTime) { + this.openTime = openTime; + } + + //참여방식 수정 + public void updateOpenRun(Boolean openRun) { + if (openRun != null) { + this.openRun = openRun; + } + } + + //지역정보 수정 + public void updateLocation(String city, String district, String dong) { + if (city != null && !city.trim().isEmpty()) { + this.city = city; + } + if (district != null && !district.trim().isEmpty()) { + this.district = district; + } + if (dong != null && !dong.trim().isEmpty()) { + this.dong = dong; + } + } + + //상세주소 수정 + public void updateAddressDetail(String addressDetail) { + if (addressDetail != null && !addressDetail.trim().isEmpty()) { + this.addressDetail = addressDetail; + } + } } diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/mapper/LessonMapper.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/mapper/LessonMapper.java index abbe2c6..898767b 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/teacher/mapper/LessonMapper.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/mapper/LessonMapper.java @@ -5,6 +5,7 @@ import com.threestar.trainus.domain.lesson.student.dto.LessonDetailResponseDto; import com.threestar.trainus.domain.lesson.teacher.dto.LessonCreateRequestDto; import com.threestar.trainus.domain.lesson.teacher.dto.LessonResponseDto; +import com.threestar.trainus.domain.lesson.teacher.dto.LessonUpdateResponseDto; import com.threestar.trainus.domain.lesson.teacher.entity.Lesson; import com.threestar.trainus.domain.lesson.teacher.entity.LessonImage; import com.threestar.trainus.domain.profile.entity.Profile; @@ -98,4 +99,34 @@ public static LessonDetailResponseDto toLessonDetailDto( .lessonImages(lessonImages) .build(); } + + //레슨 수정 + public static LessonUpdateResponseDto toUpdateResponseDto(Lesson lesson, List lessonImages) { + // 이미지 엔티티 목록에서 URL만 추출 + List imageUrls = lessonImages.stream() + .map(LessonImage::getImageUrl) + .toList(); + + return LessonUpdateResponseDto.builder() + .id(lesson.getId()) + .lessonName(lesson.getLessonName()) + .description(lesson.getDescription()) + .lessonLeader(lesson.getLessonLeader()) + .category(lesson.getCategory()) + .price(lesson.getPrice()) + .maxParticipants(lesson.getMaxParticipants()) + .startAt(lesson.getStartAt()) + .endAt(lesson.getEndAt()) + .openTime(lesson.getOpenTime()) + .openRun(lesson.getOpenRun()) + .city(lesson.getCity()) + .district(lesson.getDistrict()) + .dong(lesson.getDong()) + .addressDetail(lesson.getAddressDetail()) + .status(lesson.getStatus()) + .createdAt(lesson.getCreatedAt()) + .updatedAt(lesson.getUpdatedAt()) + .lessonImages(imageUrls) + .build(); + } } diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/repository/LessonRepository.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/repository/LessonRepository.java index 340b943..7d2769b 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/teacher/repository/LessonRepository.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/repository/LessonRepository.java @@ -18,20 +18,43 @@ public interface LessonRepository extends JpaRepository { Optional findByIdAndDeletedAtIsNull(Long lessonId); // 중복 레슨 검증(같은 강사가 같은 이름과 시작시간으로 레슨 생성했는지 체크) - @Query("SELECT COUNT(l) > 0 FROM Lesson l WHERE " + "l.lessonLeader = :lessonLeader AND " - + "l.lessonName = :lessonName AND " + "l.startAt = :startAt AND " + "l.deletedAt IS NULL") + @Query(""" + SELECT COUNT(l) > 0 FROM Lesson l + WHERE l.lessonLeader = :lessonLeader + AND l.lessonName = :lessonName + AND l.startAt = :startAt + AND l.deletedAt IS NULL + """) boolean existsDuplicateLesson(@Param("lessonLeader") Long lessonLeader, @Param("lessonName") String lessonName, @Param("startAt") LocalDateTime startAt); - // 시간 겹침 검증(같은 강사가 동일 시간대에 다른 레슨이 있는지 체크) - @Query( - "SELECT COUNT(l) > 0 FROM Lesson l WHERE " + "l.lessonLeader = :lessonLeader AND " + "l.deletedAt IS NULL AND " - + "(l.startAt < :endAt AND l.endAt > :startAt)") + // 시간 겹침 검증(같은 강사가 동일 시간대에 다른 레슨이 있는지 체크) ->레슨생성시에 사용 + @Query(""" + SELECT COUNT(l) > 0 FROM Lesson l + WHERE l.lessonLeader = :lessonLeader + AND l.deletedAt IS NULL + AND (l.startAt < :endAt AND l.endAt > :startAt) + """) boolean hasTimeConflictLesson(@Param("lessonLeader") Long lessonLeader, @Param("startAt") LocalDateTime startAt, @Param("endAt") LocalDateTime endAt); + //시간 겹침 검증 ->레슨 수정시 사용 (현재 수정중인 레슨 제외) + @Query(""" + SELECT COUNT(l) > 0 FROM Lesson l + WHERE l.lessonLeader = :lessonLeader + AND l.deletedAt IS NULL + AND l.id != :excludeLessonId + AND (l.startAt < :endAt AND l.endAt > :startAt) + """) + boolean hasTimeConflictForUpdate( + @Param("lessonLeader") Long lessonLeader, + @Param("startAt") LocalDateTime startAt, + @Param("endAt") LocalDateTime endAt, + @Param("excludeLessonId") Long excludeLessonId + ); + // 강사가 개설한 레슨 목록 조회 (페이징) Page findByLessonLeaderAndDeletedAtIsNull(Long lessonLeader, Pageable pageable); @@ -51,8 +74,7 @@ Page findByLessonLeaderAndStatusAndDeletedAtIsNull(Long lessonLeader, Le :search IS NULL OR LOWER(l.lessonName) LIKE LOWER(CONCAT('%', :search, '%')) ) - """ - ) + """) Page findBySearchConditions( @Param("category") Category category, @Param("city") String city, diff --git a/src/main/java/com/threestar/trainus/domain/lesson/teacher/service/AdminLessonService.java b/src/main/java/com/threestar/trainus/domain/lesson/teacher/service/AdminLessonService.java index 609e703..f2dc1de 100644 --- a/src/main/java/com/threestar/trainus/domain/lesson/teacher/service/AdminLessonService.java +++ b/src/main/java/com/threestar/trainus/domain/lesson/teacher/service/AdminLessonService.java @@ -15,6 +15,8 @@ import com.threestar.trainus.domain.lesson.teacher.dto.LessonApplicationListResponseDto; import com.threestar.trainus.domain.lesson.teacher.dto.LessonCreateRequestDto; import com.threestar.trainus.domain.lesson.teacher.dto.LessonResponseDto; +import com.threestar.trainus.domain.lesson.teacher.dto.LessonUpdateRequestDto; +import com.threestar.trainus.domain.lesson.teacher.dto.LessonUpdateResponseDto; import com.threestar.trainus.domain.lesson.teacher.dto.ParticipantListResponseDto; import com.threestar.trainus.domain.lesson.teacher.entity.ApplicationAction; import com.threestar.trainus.domain.lesson.teacher.entity.ApplicationStatus; @@ -200,6 +202,50 @@ public ApplicationProcessResponseDto processLessonApplication( .build(); } + //레슨 수정 + @Transactional + public LessonUpdateResponseDto updateLesson(Long lessonId, LessonUpdateRequestDto requestDto, Long userId) { + // 레슨 존재 및 권한 확인 + Lesson lesson = validateLessonAccess(lessonId, userId); + + // 레슨이 모집중 상태인지 확인 + if (lesson.getStatus() != LessonStatus.RECRUITING) { + throw new BusinessException(ErrorCode.LESSON_NOT_EDITABLE); + } + + // 현재 참가자 수 확인 + int currentParticipants = lesson.getParticipantCount(); + boolean hasParticipants = currentParticipants > 0; + + // 수정할 필드가 있는지 확인 + if (!requestDto.hasBasicInfoChanges() && !requestDto.hasRestrictedChanges() + && requestDto.maxParticipants() == null) { + throw new BusinessException(ErrorCode.INVALID_REQUEST_DATA); + } + + // 기본 정보 수정 + updateBasicInfo(lesson, requestDto); + + // 최대 참가 인원 수정 -> 참가자 있을 때는 증가만 가능 + if (requestDto.maxParticipants() != null) { + lesson.updateMaxParticipants(requestDto.maxParticipants(), hasParticipants); + } + + // 제한된 필드 수정 -> 참가자 없을 때만 가능 + if (requestDto.hasRestrictedChanges()) { + if (hasParticipants) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + updateRestrictedFields(lesson, requestDto, userId, lessonId); + } + + Lesson savedLesson = lessonRepository.save(lesson); + + List updatedImages = updateLessonImagesIfNeeded(savedLesson, requestDto.lessonImages()); + + return LessonMapper.toUpdateResponseDto(savedLesson, updatedImages); + } + //레슨 참가자 목록 조회(승인된 사람들만 있음) public ParticipantListResponseDto getLessonParticipants( Long lessonId, int page, int limit, Long userId) { @@ -226,9 +272,7 @@ public CreatedLessonListResponseDto getCreatedLessons( Long userId, int page, int limit, String status) { // User 존재 확인 - //TODO: 공통메소드 - User user = userRepository.findById(userId) - .orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); + User user = userService.getUserById(userId); // 페이징 설정 Pageable pageable = PageRequest.of(page - 1, limit, Sort.by("createdAt").descending()); @@ -315,9 +359,7 @@ public void validateLessonNotDeleted(Lesson lesson) { //레슨 접근 권한 검증 -> 올린사람(강사)가 맞는지 체크 private Lesson validateLessonAccess(Long lessonId, Long userId) { // User 존재 확인 - //TODO : 공통메서드 - User user = userRepository.findById(userId) - .orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); + User user = userService.getUserById(userId); // 레슨 존재하는지 확인 Lesson lesson = findLessonById(lessonId); @@ -353,4 +395,116 @@ private LessonStatus validateLessonStatus(String status) { } } + //참가자가 있을때 수정 검증 + private void validatePeopleInLessonUpdate(Lesson lesson, LessonUpdateRequestDto requestDto) { + // 카테고리 변경 불가 + if (!lesson.getCategory().equals(requestDto.category())) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + + // 가격 변경 불가 + if (!lesson.getPrice().equals(requestDto.price())) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + + // 참여방식 변경 불가 + if (!lesson.getOpenRun().equals(requestDto.openRun())) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + + // 레슨 시간 변경 불가 + if (!lesson.getStartAt().equals(requestDto.startAt()) || !lesson.getEndAt().equals(requestDto.endAt())) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + + // 지역 정보 변경 불가 + if (!lesson.getCity().equals(requestDto.city()) || !lesson.getDistrict().equals(requestDto.district()) + || !lesson.getDong().equals(requestDto.dong())) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + + // 상세주소 변경 불가 + if (!lesson.getAddressDetail().equals(requestDto.addressDetail())) { + throw new BusinessException(ErrorCode.LESSON_PARTICIPANTS_EXIST_RESTRICTION); + } + } + + //레슨 이미지 업데이트 + private List updateLessonImages(Lesson lesson, List imageUrls) { + // 기존 이미지 삭제 + List existingImages = lessonImageRepository.findByLesson(lesson); + lessonImageRepository.deleteAll(existingImages); + + // 새 이미지 저장 + if (imageUrls == null || imageUrls.isEmpty()) { + return List.of(); + } + + List newImages = imageUrls.stream() + .map(url -> LessonImage.builder() + .lesson(lesson) + .imageUrl(url) + .build()) + .toList(); + + return lessonImageRepository.saveAll(newImages); + } + + //기본 정보 수정 + private void updateBasicInfo(Lesson lesson, LessonUpdateRequestDto requestDto) { + lesson.updateLessonName(requestDto.lessonName()); + lesson.updateDescription(requestDto.description()); + } + + //제한되어 있는 필드 수정 + private void updateRestrictedFields(Lesson lesson, LessonUpdateRequestDto requestDto, Long userId, Long lessonId) { + // 시간 관련 검증 + if (requestDto.hasTimeChanges()) { + LocalDateTime newStartAt = requestDto.startAt() != null ? requestDto.startAt() : lesson.getStartAt(); + LocalDateTime newEndAt = requestDto.endAt() != null ? requestDto.endAt() : lesson.getEndAt(); + + // 시간 검증 + validateLessonTimes(newStartAt, newEndAt); + + // 시간 겹침 검증 + boolean hasConflict = lessonRepository.hasTimeConflictForUpdate( + userId, newStartAt, newEndAt, lessonId + ); + if (hasConflict) { + throw new BusinessException(ErrorCode.LESSON_TIME_OVERLAP); + } + } + + lesson.updateCategory(requestDto.category()); + lesson.updatePrice(requestDto.price()); + lesson.updateLessonTime(requestDto.startAt(), requestDto.endAt()); + lesson.updateOpenTime(requestDto.openTime()); + lesson.updateOpenRun(requestDto.openRun()); + lesson.updateLocation(requestDto.city(), requestDto.district(), requestDto.dong()); + lesson.updateAddressDetail(requestDto.addressDetail()); + } + + //레슨 이미지 수정 + private List updateLessonImagesIfNeeded(Lesson lesson, List newImageUrls) { + if (newImageUrls != null) { + // 기존 이미지 삭제 + List existingImages = lessonImageRepository.findByLesson(lesson); + lessonImageRepository.deleteAll(existingImages); + + // 새 이미지 저장 + if (!newImageUrls.isEmpty()) { + List newImages = newImageUrls.stream() + .map(url -> LessonImage.builder() + .lesson(lesson) + .imageUrl(url) + .build()) + .toList(); + return lessonImageRepository.saveAll(newImages); + } + return List.of(); + } else { + // 이미지 수정 요청 없으면 -> 기존 이미지 유지 + return lessonImageRepository.findByLesson(lesson); + } + } } diff --git a/src/main/java/com/threestar/trainus/domain/profile/mapper/ProfileLessonMapper.java b/src/main/java/com/threestar/trainus/domain/profile/mapper/ProfileLessonMapper.java index b36fb1f..1159596 100644 --- a/src/main/java/com/threestar/trainus/domain/profile/mapper/ProfileLessonMapper.java +++ b/src/main/java/com/threestar/trainus/domain/profile/mapper/ProfileLessonMapper.java @@ -37,7 +37,6 @@ public static ProfileCreatedLessonListResponseDto toProfileCreatedLessonListResp List lessonDtos = lessons.stream() .map(ProfileLessonMapper::toProfileCreatedLessonDto) .toList(); - return ProfileCreatedLessonListResponseDto.builder() .lessons(lessonDtos) .count(totalCount.intValue()) diff --git a/src/main/java/com/threestar/trainus/domain/profile/service/ProfileLessonService.java b/src/main/java/com/threestar/trainus/domain/profile/service/ProfileLessonService.java index 9c36f77..319e1b6 100644 --- a/src/main/java/com/threestar/trainus/domain/profile/service/ProfileLessonService.java +++ b/src/main/java/com/threestar/trainus/domain/profile/service/ProfileLessonService.java @@ -53,4 +53,4 @@ public ProfileCreatedLessonListResponseDto getUserCreatedLessons( lessonPage.getTotalElements() ); } -} \ No newline at end of file +} diff --git a/src/main/java/com/threestar/trainus/global/config/MockDataInitializer.java b/src/main/java/com/threestar/trainus/global/config/MockDataInitializer.java index fe73b50..b0c9996 100644 --- a/src/main/java/com/threestar/trainus/global/config/MockDataInitializer.java +++ b/src/main/java/com/threestar/trainus/global/config/MockDataInitializer.java @@ -211,7 +211,6 @@ private List createLessons(List instructors) { private void createReviews(List instructors, List students, List lessons) { for (User instructor : instructors) { - ProfileMetadata metadata = profileMetadataRepository.findByUserId(instructor.getId()) .orElseThrow(); diff --git a/src/main/java/com/threestar/trainus/global/exception/domain/ErrorCode.java b/src/main/java/com/threestar/trainus/global/exception/domain/ErrorCode.java index a7ca0ed..e79e7bc 100644 --- a/src/main/java/com/threestar/trainus/global/exception/domain/ErrorCode.java +++ b/src/main/java/com/threestar/trainus/global/exception/domain/ErrorCode.java @@ -67,6 +67,9 @@ public enum ErrorCode { LESSON_CREATOR_CANNOT_APPLY(HttpStatus.BAD_REQUEST, "레슨 개설자는 자신이 개설한 레슨에 참여 신청할 수 없습니다."), CANNOT_CANCEL_APPROVED_APPLICATION(HttpStatus.BAD_REQUEST, "승인된 신청은 취소할 수 없습니다."), INVALID_CATEGORY(HttpStatus.BAD_REQUEST, "잘못된 카테고리입니다."), + LESSON_NOT_EDITABLE(HttpStatus.BAD_REQUEST, "수정할 수 없는 상태의 레슨입니다. 모집중 상태의 레슨만 수정 가능합니다."), + LESSON_MAX_PARTICIPANTS_CANNOT_DECREASE(HttpStatus.BAD_REQUEST, "참가자가 있는 레슨은 최대 참가 인원을 줄일 수 없습니다."), + LESSON_PARTICIPANTS_EXIST_RESTRICTION(HttpStatus.BAD_REQUEST, "참가자가 있어 해당 필드는 수정할 수 없습니다."), // 403 Forbidden LESSON_DELETE_FORBIDDEN(HttpStatus.FORBIDDEN, "레슨 삭제 권한이 없습니다. 강사만 삭제할 수 있습니다."),