diff --git a/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmController.java b/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmController.java index e3ee0ca7..0da4884c 100644 --- a/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmController.java +++ b/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmController.java @@ -21,14 +21,19 @@ public class AlarmController implements AlarmSpecification { private final AlarmService alarmService; @GetMapping("/my") - public ApiResponse> getAllAlarm( - @AuthenticationPrincipal Principal userDetails) { + public ApiResponse> getAllAlarms(@AuthenticationPrincipal Principal userDetails) { return ApiResponse.success(alarmService.getAllAlarms(userDetails.getUserId())); } + @GetMapping("/unchecked/my") + public ApiResponse> getAllUncheckedAlarm( + @AuthenticationPrincipal Principal userDetails) { + return ApiResponse.success(alarmService.getAllUncheckedAlarms(userDetails.getUserId())); + } + @PostMapping("/my/check/all") public ApiResponse checkAlarm(@AuthenticationPrincipal Principal userDetails) { - alarmService.checkAllAlarm(userDetails.getUserId()); + alarmService.checkAllAlarmWithoutInvite(userDetails.getUserId()); return ApiResponse.noContent(); } diff --git a/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmSpecification.java b/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmSpecification.java index a857f960..5eb2290a 100644 --- a/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmSpecification.java +++ b/src/main/java/grep/neogulcoder/domain/alram/controller/AlarmSpecification.java @@ -11,8 +11,11 @@ @Tag(name = "Alarm", description = "알림 관련 API 명세") public interface AlarmSpecification { - @Operation(summary = "내 알림 목록 조회", description = "로그인한 사용자의 알림 목록을 조회합니다.") - ApiResponse> getAllAlarm(@AuthenticationPrincipal Principal userDetails); + @Operation(summary = "읽음 여부 관련 없이 내 전체 알림 목록 조회", description = "로그인한 사용자의 전체 알림 목록을 조회합니다.") + ApiResponse> getAllAlarms(@AuthenticationPrincipal Principal userDetails); + + @Operation(summary = "내 읽지 않은 알림 목록 조회", description = "로그인한 사용자의 읽지 않은 알림 목록을 조회합니다.") + ApiResponse> getAllUncheckedAlarm(@AuthenticationPrincipal Principal userDetails); @Operation(summary = "내 알림 전체 읽음 처리", description = "로그인한 사용자의 모든 알림을 읽음 처리합니다.") ApiResponse checkAlarm(@AuthenticationPrincipal Principal userDetails); diff --git a/src/main/java/grep/neogulcoder/domain/alram/controller/dto/response/AlarmResponse.java b/src/main/java/grep/neogulcoder/domain/alram/controller/dto/response/AlarmResponse.java index 98e96bf7..df200ed9 100644 --- a/src/main/java/grep/neogulcoder/domain/alram/controller/dto/response/AlarmResponse.java +++ b/src/main/java/grep/neogulcoder/domain/alram/controller/dto/response/AlarmResponse.java @@ -1,6 +1,5 @@ package grep.neogulcoder.domain.alram.controller.dto.response; -import grep.neogulcoder.domain.alram.entity.Alarm; import grep.neogulcoder.domain.alram.type.AlarmType; import grep.neogulcoder.domain.alram.type.DomainType; import lombok.Builder; @@ -21,26 +20,30 @@ public class AlarmResponse { private String message; + private boolean checked; + public static AlarmResponse toResponse(Long id, Long receiverUserId, AlarmType alarmType, DomainType domainType, - Long domainId, String message) { + Long domainId, String message, boolean checked) { return AlarmResponse.builder() - .id(id) - .receiverUserId(receiverUserId) - .alarmType(alarmType) - .domainType(domainType) - .domainId(domainId) - .message(message) - .build(); + .id(id) + .receiverUserId(receiverUserId) + .alarmType(alarmType) + .domainType(domainType) + .domainId(domainId) + .message(message) + .checked(checked) + .build(); } @Builder private AlarmResponse(Long id, Long receiverUserId, AlarmType alarmType, DomainType domainType, - Long domainId, String message) { + Long domainId, String message, boolean checked) { this.id = id; this.receiverUserId = receiverUserId; this.alarmType = alarmType; this.domainType = domainType; this.domainId = domainId; this.message = message; + this.checked = checked; } } diff --git a/src/main/java/grep/neogulcoder/domain/alram/repository/AlarmRepository.java b/src/main/java/grep/neogulcoder/domain/alram/repository/AlarmRepository.java index 7a03e15b..95e3196c 100644 --- a/src/main/java/grep/neogulcoder/domain/alram/repository/AlarmRepository.java +++ b/src/main/java/grep/neogulcoder/domain/alram/repository/AlarmRepository.java @@ -6,5 +6,6 @@ public interface AlarmRepository extends JpaRepository { List findAllByReceiverUserIdAndCheckedFalse(Long receiverUserId); + List findAllByReceiverUserId(Long receiverUserId); } diff --git a/src/main/java/grep/neogulcoder/domain/alram/service/AlarmService.java b/src/main/java/grep/neogulcoder/domain/alram/service/AlarmService.java index d62165d8..0d39dcd7 100644 --- a/src/main/java/grep/neogulcoder/domain/alram/service/AlarmService.java +++ b/src/main/java/grep/neogulcoder/domain/alram/service/AlarmService.java @@ -15,10 +15,13 @@ import grep.neogulcoder.domain.study.repository.StudyMemberQueryRepository; import grep.neogulcoder.domain.study.repository.StudyMemberRepository; import grep.neogulcoder.domain.study.repository.StudyRepository; +import grep.neogulcoder.domain.timevote.event.TimeVotePeriodCreatedEvent; import grep.neogulcoder.global.exception.business.BusinessException; import grep.neogulcoder.global.exception.business.NotFoundException; import grep.neogulcoder.global.provider.finder.MessageFinder; + import java.util.List; + import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service; @@ -44,33 +47,47 @@ public void saveAlarm(Long receiverId, AlarmType alarmType, DomainType domainTyp alarmRepository.save(Alarm.init(alarmType, receiverId, domainType, domainId, message)); } - public List getAllAlarms(Long receiverUserId) { + public List getAllUncheckedAlarms(Long receiverUserId) { return alarmRepository.findAllByReceiverUserIdAndCheckedFalse(receiverUserId).stream() - .map(alarm -> AlarmResponse.toResponse( - alarm.getId(), - alarm.getReceiverUserId(), - alarm.getAlarmType(), - alarm.getDomainType(), - alarm.getDomainId(), - alarm.getMessage())) - .toList(); + .map(alarm -> AlarmResponse.toResponse( + alarm.getId(), + alarm.getReceiverUserId(), + alarm.getAlarmType(), + alarm.getDomainType(), + alarm.getDomainId(), + alarm.getMessage(), + alarm.isChecked())) + .toList(); + } + + public List getAllAlarms(Long receiverUserId) { + return alarmRepository.findAllByReceiverUserId(receiverUserId).stream() + .map(alarm -> AlarmResponse.toResponse( + alarm.getId(), + alarm.getReceiverUserId(), + alarm.getAlarmType(), + alarm.getDomainType(), + alarm.getDomainId(), + alarm.getMessage(), + alarm.isChecked())) + .toList(); } @Transactional - public void checkAllAlarm(Long receiverUserId) { + public void checkAllAlarmWithoutInvite(Long receiverUserId) { List alarms = alarmRepository.findAllByReceiverUserIdAndCheckedFalse(receiverUserId); alarms.stream() - .filter(alarm -> alarm.getAlarmType() != AlarmType.INVITE) - .forEach(Alarm::checkAlarm); + .filter(alarm -> alarm.getAlarmType() != AlarmType.INVITE) + .forEach(Alarm::checkAlarm); } @EventListener public void handleStudyInviteEvent(StudyInviteEvent event) { saveAlarm( - event.targetUserId(), - AlarmType.INVITE, - DomainType.STUDY, - event.studyId() + event.targetUserId(), + AlarmType.INVITE, + DomainType.STUDY, + event.studyId() ); } @@ -82,7 +99,7 @@ public void acceptInvite(Long targetUserId, Long alarmId) { Alarm alarm = findValidAlarm(alarmId); Long studyId = alarm.getDomainId(); Study study = findValidStudy(studyId); - StudyMember.createMember(study,targetUserId); + StudyMember.createMember(study, targetUserId); alarm.checkAlarm(); } @@ -99,10 +116,10 @@ public void handleStudyExtendEvent(StudyExtendEvent event) { for (StudyMember member : members) { if (!member.isLeader()) { saveAlarm( - member.getUserId(), - AlarmType.STUDY_EXTEND, - DomainType.STUDY, - event.studyId() + member.getUserId(), + AlarmType.STUDY_EXTEND, + DomainType.STUDY, + event.studyId() ); } } @@ -111,23 +128,39 @@ public void handleStudyExtendEvent(StudyExtendEvent event) { @EventListener public void handleStudyExtensionReminderEvent(StudyExtensionReminderEvent event) { StudyMember leader = studyMemberRepository.findByStudyIdAndRoleAndActivatedTrue(event.studyId(), StudyMemberRole.LEADER) - .orElseThrow(() -> new BusinessException(STUDY_LEADER_NOT_FOUND)); + .orElseThrow(() -> new BusinessException(STUDY_LEADER_NOT_FOUND)); saveAlarm( - leader.getUserId(), - AlarmType.STUDY_EXTENSION_REMINDER, - DomainType.STUDY, - event.studyId() + leader.getUserId(), + AlarmType.STUDY_EXTENSION_REMINDER, + DomainType.STUDY, + event.studyId() ); } + @EventListener + public void handleTimeVotePeriodCreatedEvent(TimeVotePeriodCreatedEvent event) { + List members = studyMemberRepository.findAllByStudyIdAndActivatedTrue(event.studyId()); + + for (StudyMember member : members) { + if (!member.getUserId().equals(event.excludedUserId())) { + saveAlarm( + member.getUserId(), + AlarmType.TIME_VOTE_REQUEST, + DomainType.TIME_VOTE, + event.studyId() + ); + } + } + } + private Alarm findValidAlarm(Long alarmId) { return alarmRepository.findById(alarmId).orElseThrow(() -> new NotFoundException(AlarmErrorCode.ALARM_NOT_FOUND)); } private Study findValidStudy(Long studyId) { return studyRepository.findById(studyId) - .orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND)); + .orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND)); } private void validateParticipantStudyLimit(Long userId) { diff --git a/src/main/java/grep/neogulcoder/domain/alram/type/AlarmType.java b/src/main/java/grep/neogulcoder/domain/alram/type/AlarmType.java index 40abbcec..0133176b 100644 --- a/src/main/java/grep/neogulcoder/domain/alram/type/AlarmType.java +++ b/src/main/java/grep/neogulcoder/domain/alram/type/AlarmType.java @@ -1,5 +1,5 @@ package grep.neogulcoder.domain.alram.type; public enum AlarmType { - INVITE, STUDY_EXTEND, STUDY_EXTENSION_REMINDER + INVITE, STUDY_EXTEND, STUDY_EXTENSION_REMINDER, TIME_VOTE_REQUEST } diff --git a/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentController.java b/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentController.java index 3a5f332d..3d5c2ca0 100644 --- a/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentController.java +++ b/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentController.java @@ -10,21 +10,22 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; -@RequestMapping("/recruitment-posts/comments") +@RequestMapping("/recruitment-posts") @RequiredArgsConstructor @RestController public class RecruitmentPostCommentController implements RecruitmentPostCommentSpecification { private final RecruitmentPostCommentService commentService; - @PostMapping - public ApiResponse save(@RequestBody @Valid RecruitmentCommentSaveRequest request, + @PostMapping("/{post-id}/comments") + public ApiResponse save(@PathVariable("post-id") long postId, + @RequestBody @Valid RecruitmentCommentSaveRequest request, @AuthenticationPrincipal Principal userDetails) { - long commentId = commentService.save(request, userDetails.getUserId()); + long commentId = commentService.save(postId, request, userDetails.getUserId()); return ApiResponse.success(commentId); } - @PutMapping("/{comment-id}") + @PutMapping("/comments/{comment-id}") public ApiResponse update(@PathVariable("comment-id") long commentId, @RequestBody RecruitmentCommentUpdateRequest request, @AuthenticationPrincipal Principal userDetails) { @@ -32,7 +33,7 @@ public ApiResponse update(@PathVariable("comment-id") long commentId, return ApiResponse.noContent(); } - @DeleteMapping("/{comment-id}") + @DeleteMapping("/comments/{comment-id}") public ApiResponse delete(@PathVariable("comment-id") long commentId, @AuthenticationPrincipal Principal userDetails) { commentService.delete(commentId, userDetails.getUserId()); diff --git a/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentSpecification.java b/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentSpecification.java index 885b304d..e95ad90c 100644 --- a/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentSpecification.java +++ b/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/RecruitmentPostCommentSpecification.java @@ -11,7 +11,7 @@ public interface RecruitmentPostCommentSpecification { @Operation(summary = "모집글 댓글 작성", description = "모집글에 대한 댓글을 작성 합니다.") - ApiResponse save(RecruitmentCommentSaveRequest request, Principal userDetails); + ApiResponse save(long postId, RecruitmentCommentSaveRequest request, Principal userDetails); @Operation(summary = "모집글 댓글 수정", description = "모집글에 대한 댓글을 수정 합니다.") ApiResponse update(long commentId, RecruitmentCommentUpdateRequest request, Principal userDetails); diff --git a/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/dto/request/RecruitmentCommentSaveRequest.java b/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/dto/request/RecruitmentCommentSaveRequest.java index f7a61f66..8cea399d 100644 --- a/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/dto/request/RecruitmentCommentSaveRequest.java +++ b/src/main/java/grep/neogulcoder/domain/recruitment/comment/controller/dto/request/RecruitmentCommentSaveRequest.java @@ -8,16 +8,13 @@ @Getter public class RecruitmentCommentSaveRequest { - @Schema(example = "2", description = "모집글 ID") - private long postId; - @Schema(example = "저도 참여 할래요!", description = "모집글 내용") private String content; private RecruitmentCommentSaveRequest() { } - public RecruitmentPostComment toEntity(RecruitmentPost post, long userId){ + public RecruitmentPostComment toEntity(RecruitmentPost post, long userId) { return RecruitmentPostComment.builder() .recruitmentPost(post) .userId(userId) diff --git a/src/main/java/grep/neogulcoder/domain/recruitment/comment/service/RecruitmentPostCommentService.java b/src/main/java/grep/neogulcoder/domain/recruitment/comment/service/RecruitmentPostCommentService.java index 36ad9303..8a9b0c77 100644 --- a/src/main/java/grep/neogulcoder/domain/recruitment/comment/service/RecruitmentPostCommentService.java +++ b/src/main/java/grep/neogulcoder/domain/recruitment/comment/service/RecruitmentPostCommentService.java @@ -25,8 +25,8 @@ public class RecruitmentPostCommentService { private final RecruitmentPostCommentQueryRepository commentQueryRepository; @Transactional - public long save(RecruitmentCommentSaveRequest request, long userId) { - RecruitmentPost post = postRepository.findPostBy(request.getPostId()) + public long save(long postId, RecruitmentCommentSaveRequest request, long userId) { + RecruitmentPost post = postRepository.findPostBy(postId) .orElseThrow(() -> new NotFoundException(NOT_FOUND)); return commentRepository.save(request.toEntity(post, userId)).getId(); diff --git a/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementController.java b/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementController.java index 19f4cd6e..266b4173 100644 --- a/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementController.java +++ b/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementController.java @@ -49,11 +49,11 @@ public ApiResponse delegateLeader(@PathVariable("studyId") Long studyId, } @PostMapping("/extension") - public ApiResponse extendStudy(@PathVariable("studyId") Long studyId, + public ApiResponse extendStudy(@PathVariable("studyId") Long studyId, @RequestBody @Valid ExtendStudyRequest request, @AuthenticationPrincipal Principal userDetails) { - studyManagementService.extendStudy(studyId, request, userDetails.getUserId()); - return ApiResponse.noContent(); + Long extendStudyId = studyManagementService.extendStudy(studyId, request, userDetails.getUserId()); + return ApiResponse.success(extendStudyId); } @PostMapping("/extension/participations") diff --git a/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementSpecification.java b/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementSpecification.java index e15dc8ba..b808d6d1 100644 --- a/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementSpecification.java +++ b/src/main/java/grep/neogulcoder/domain/study/controller/StudyManagementSpecification.java @@ -27,7 +27,7 @@ public interface StudyManagementSpecification { ApiResponse delegateLeader(Long studyId, DelegateLeaderRequest request, Principal userDetails); @Operation(summary = "스터디 연장", description = "스터디장이 스터디를 연장합니다.") - ApiResponse extendStudy(Long studyId, ExtendStudyRequest request, Principal userDetails); + ApiResponse extendStudy(Long studyId, ExtendStudyRequest request, Principal userDetails); @Operation(summary = "연장 스터디 참여", description = "스터디원이 연장된 스터디에 참여합니다.") ApiResponse registerExtensionParticipation(Long studyId, Principal userDetails); diff --git a/src/main/java/grep/neogulcoder/domain/study/service/StudyManagementService.java b/src/main/java/grep/neogulcoder/domain/study/service/StudyManagementService.java index 92f6f968..b9c302d5 100644 --- a/src/main/java/grep/neogulcoder/domain/study/service/StudyManagementService.java +++ b/src/main/java/grep/neogulcoder/domain/study/service/StudyManagementService.java @@ -120,7 +120,7 @@ public void deleteUserFromStudies(Long userId) { } @Transactional - public void extendStudy(Long studyId, ExtendStudyRequest request, Long userId) { + public Long extendStudy(Long studyId, ExtendStudyRequest request, Long userId) { Study originStudy = findValidStudy(studyId); StudyMember leader = findValidStudyMember(studyId, userId); @@ -141,6 +141,8 @@ public void extendStudy(Long studyId, ExtendStudyRequest request, Long userId) { studyMemberRepository.save(extendedLeader); eventPublisher.publishEvent(new StudyExtendEvent(originStudy.getId())); + + return extendedStudy.getId(); } @Transactional diff --git a/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationPagingResponse.java b/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationPagingResponse.java index c31b5a4b..9f652cfc 100644 --- a/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationPagingResponse.java +++ b/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationPagingResponse.java @@ -13,7 +13,7 @@ public class MyApplicationPagingResponse { @Schema( description = "내가 신청한 스터디 목록", example = "[{" + - "\"applicationId\": 1," + + "\"recruitmentPostId\": 1," + "\"name\": \"자바 스터디\"," + "\"leaderNickname\": \"너굴\"," + "\"capacity\": 4," + diff --git a/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationResponse.java b/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationResponse.java index 6bc046dc..eb380f83 100644 --- a/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationResponse.java +++ b/src/main/java/grep/neogulcoder/domain/studyapplication/controller/dto/response/MyApplicationResponse.java @@ -12,8 +12,8 @@ @Getter public class MyApplicationResponse { - @Schema(description = "신청 번호", example = "1") - private Long applicationId; + @Schema(description = "모집글 번호", example = "1") + private Long recruitmentPostId; @Schema(description = "스터디 이름", example = "자바 스터디") private String name; @@ -49,9 +49,9 @@ public class MyApplicationResponse { private ApplicationStatus status; @QueryProjection - public MyApplicationResponse(Long applicationId, String name, String leaderNickname, int capacity, int currentCount, LocalDateTime startDate, + public MyApplicationResponse(Long recruitmentPostId, String name, String leaderNickname, int capacity, int currentCount, LocalDateTime startDate, String imageUrl,String introduction, Category category, StudyType studyType, boolean isRead, ApplicationStatus status) { - this.applicationId = applicationId; + this.recruitmentPostId = recruitmentPostId; this.name = name; this.leaderNickname = leaderNickname; this.capacity = capacity; diff --git a/src/main/java/grep/neogulcoder/domain/studyapplication/repository/ApplicationQueryRepository.java b/src/main/java/grep/neogulcoder/domain/studyapplication/repository/ApplicationQueryRepository.java index 6323b851..eccb16ad 100644 --- a/src/main/java/grep/neogulcoder/domain/studyapplication/repository/ApplicationQueryRepository.java +++ b/src/main/java/grep/neogulcoder/domain/studyapplication/repository/ApplicationQueryRepository.java @@ -72,7 +72,7 @@ public Page findReceivedApplicationsPaging(Long rec public Page findMyStudyApplicationsPaging(Pageable pageable, Long userId, ApplicationStatus status) { List applications = queryFactory .select(new QMyApplicationResponse( - studyApplication.id, + recruitmentPost.id, study.name, user.nickname, study.capacity, diff --git a/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/request/StudyPostUpdateRequest.java b/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/request/StudyPostUpdateRequest.java index 74a5d478..db91e6e6 100644 --- a/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/request/StudyPostUpdateRequest.java +++ b/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/request/StudyPostUpdateRequest.java @@ -3,6 +3,7 @@ import grep.neogulcoder.domain.studypost.Category; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Builder; import lombok.Getter; @@ -15,7 +16,7 @@ public class StudyPostUpdateRequest { private String title; @Schema(description = "카테고리: NOTICE(공지), FREE(자유)", example = "NOTICE") - @NotBlank + @NotNull private Category category; @Schema(description = "내용", example = "오늘은 각자 공부한 내용에 대해 발표가 있는 날 입니다!") diff --git a/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/response/CommentInfo.java b/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/response/CommentInfo.java index f2b0321c..ff5ae35f 100644 --- a/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/response/CommentInfo.java +++ b/src/main/java/grep/neogulcoder/domain/studypost/controller/dto/response/CommentInfo.java @@ -21,7 +21,7 @@ public class CommentInfo { private String profileImageUrl; @Schema(description = "댓글 ID", example = "100") - private long id; + private long commentId; @Schema(description = "댓글 내용", example = "정말 좋은 정보 감사합니다!") private String content; @@ -30,12 +30,12 @@ public class CommentInfo { private LocalDateTime createdAt; @QueryProjection - public CommentInfo(long userId, String nickname, String profileImageUrl, long id, + public CommentInfo(long userId, String nickname, String profileImageUrl, long commentId, String content, LocalDateTime createdAt) { this.userId = userId; this.nickname = nickname; this.profileImageUrl = profileImageUrl; - this.id = id; + this.commentId = commentId; this.content = content; this.createdAt = createdAt; } diff --git a/src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVote.java b/src/main/java/grep/neogulcoder/domain/timevote/TimeVote.java similarity index 95% rename from src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVote.java rename to src/main/java/grep/neogulcoder/domain/timevote/TimeVote.java index cdff9bb4..e5bd95e7 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVote.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/TimeVote.java @@ -1,4 +1,4 @@ -package grep.neogulcoder.domain.timevote.entity; +package grep.neogulcoder.domain.timevote; import grep.neogulcoder.global.entity.BaseEntity; import jakarta.persistence.Column; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVotePeriod.java b/src/main/java/grep/neogulcoder/domain/timevote/TimeVotePeriod.java similarity index 96% rename from src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVotePeriod.java rename to src/main/java/grep/neogulcoder/domain/timevote/TimeVotePeriod.java index c8a7e0bc..5e14800a 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVotePeriod.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/TimeVotePeriod.java @@ -1,4 +1,4 @@ -package grep.neogulcoder.domain.timevote.entity; +package grep.neogulcoder.domain.timevote; import grep.neogulcoder.global.entity.BaseEntity; import jakarta.persistence.Column; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVoteStat.java b/src/main/java/grep/neogulcoder/domain/timevote/TimeVoteStat.java similarity index 96% rename from src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVoteStat.java rename to src/main/java/grep/neogulcoder/domain/timevote/TimeVoteStat.java index fb146405..252eec02 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/entity/TimeVoteStat.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/TimeVoteStat.java @@ -1,4 +1,4 @@ -package grep.neogulcoder.domain.timevote.entity; +package grep.neogulcoder.domain.timevote; import grep.neogulcoder.global.entity.BaseEntity; import jakarta.persistence.Column; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/controller/TimeVoteController.java b/src/main/java/grep/neogulcoder/domain/timevote/controller/TimeVoteController.java index 5c7efe53..6d173ef2 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/controller/TimeVoteController.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/controller/TimeVoteController.java @@ -7,7 +7,6 @@ import grep.neogulcoder.domain.timevote.dto.response.TimeVoteResponse; import grep.neogulcoder.domain.timevote.dto.response.TimeVoteStatResponse; import grep.neogulcoder.domain.timevote.dto.response.TimeVoteSubmissionStatusResponse; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; import grep.neogulcoder.domain.timevote.service.TimeVotePeriodService; import grep.neogulcoder.domain.timevote.service.TimeVoteService; import grep.neogulcoder.domain.timevote.service.TimeVoteStatService; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteCreateRequest.java b/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteCreateRequest.java index 0bb2846c..e8324d86 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteCreateRequest.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteCreateRequest.java @@ -1,7 +1,7 @@ package grep.neogulcoder.domain.timevote.dto.request; -import grep.neogulcoder.domain.timevote.entity.TimeVote; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVote; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; import java.time.LocalDateTime; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVotePeriodCreateRequest.java b/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVotePeriodCreateRequest.java index 99986fd9..1e484906 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVotePeriodCreateRequest.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVotePeriodCreateRequest.java @@ -1,6 +1,6 @@ package grep.neogulcoder.domain.timevote.dto.request; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteUpdateRequest.java b/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteUpdateRequest.java index 1c459296..d58f85dc 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteUpdateRequest.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/dto/request/TimeVoteUpdateRequest.java @@ -1,7 +1,7 @@ package grep.neogulcoder.domain.timevote.dto.request; -import grep.neogulcoder.domain.timevote.entity.TimeVote; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVote; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; import java.time.LocalDateTime; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVotePeriodResponse.java b/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVotePeriodResponse.java index 1b024cc2..0616cea8 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVotePeriodResponse.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVotePeriodResponse.java @@ -1,9 +1,8 @@ package grep.neogulcoder.domain.timevote.dto.response; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; -import java.util.List; import lombok.Builder; import lombok.Getter; @@ -20,23 +19,18 @@ public class TimeVotePeriodResponse { @Schema(description = "종료일", example = "2025-07-30T23:59:59") private LocalDateTime endDate; - @Schema(description = "알림이 전송된 팀원 멤버 ID 목록", example = "[11, 12, 13]") - private List notifiedMemberIds; - @Builder - private TimeVotePeriodResponse(Long studyId, LocalDateTime startDate, LocalDateTime endDate, List notifiedMemberIds) { + private TimeVotePeriodResponse(Long studyId, LocalDateTime startDate, LocalDateTime endDate) { this.studyId = studyId; this.startDate = startDate; this.endDate = endDate; - this.notifiedMemberIds = notifiedMemberIds; } - public static TimeVotePeriodResponse from(TimeVotePeriod timeVotePeriod, List notifiedMemberIds) { + public static TimeVotePeriodResponse from(TimeVotePeriod timeVotePeriod) { return TimeVotePeriodResponse.builder() .studyId(timeVotePeriod.getStudyId()) .startDate(timeVotePeriod.getStartDate()) .endDate(timeVotePeriod.getEndDate()) - .notifiedMemberIds(notifiedMemberIds) .build(); } } diff --git a/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteResponse.java b/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteResponse.java index 028e3143..86142566 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteResponse.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteResponse.java @@ -1,6 +1,6 @@ package grep.neogulcoder.domain.timevote.dto.response; -import grep.neogulcoder.domain.timevote.entity.TimeVote; +import grep.neogulcoder.domain.timevote.TimeVote; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteStatResponse.java b/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteStatResponse.java index 4de22a69..feabf262 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteStatResponse.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/dto/response/TimeVoteStatResponse.java @@ -1,7 +1,7 @@ package grep.neogulcoder.domain.timevote.dto.response; -import grep.neogulcoder.domain.timevote.entity.TimeVoteStat; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVoteStat; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import io.swagger.v3.oas.annotations.media.Schema; import java.util.Comparator; import lombok.Builder; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/event/TimeVotePeriodCreatedEvent.java b/src/main/java/grep/neogulcoder/domain/timevote/event/TimeVotePeriodCreatedEvent.java new file mode 100644 index 00000000..ebe24113 --- /dev/null +++ b/src/main/java/grep/neogulcoder/domain/timevote/event/TimeVotePeriodCreatedEvent.java @@ -0,0 +1,6 @@ +package grep.neogulcoder.domain.timevote.event; + +public record TimeVotePeriodCreatedEvent( + Long studyId, + Long excludedUserId +) {} diff --git a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVotePeriodRepository.java b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVotePeriodRepository.java index 1bf549ca..44e6c1e5 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVotePeriodRepository.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVotePeriodRepository.java @@ -1,6 +1,6 @@ package grep.neogulcoder.domain.timevote.repository; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteQueryRepository.java b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteQueryRepository.java index a45234f7..8fe1e292 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteQueryRepository.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteQueryRepository.java @@ -7,7 +7,7 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import grep.neogulcoder.domain.study.QStudyMember; import grep.neogulcoder.domain.timevote.dto.response.TimeVoteSubmissionStatusResponse; -import grep.neogulcoder.domain.timevote.entity.QTimeVote; +import grep.neogulcoder.domain.timevote.QTimeVote; import grep.neogulcoder.domain.users.entity.QUser; import jakarta.persistence.EntityManager; import com.querydsl.core.Tuple; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteRepository.java b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteRepository.java index 02e02b16..16ce126a 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteRepository.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteRepository.java @@ -1,7 +1,7 @@ package grep.neogulcoder.domain.timevote.repository; -import grep.neogulcoder.domain.timevote.entity.TimeVote; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVote; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatQueryRepository.java b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatQueryRepository.java index 0b68ded5..770e3569 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatQueryRepository.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatQueryRepository.java @@ -2,10 +2,10 @@ import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQueryFactory; -import grep.neogulcoder.domain.timevote.entity.QTimeVote; -import grep.neogulcoder.domain.timevote.entity.QTimeVoteStat; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; -import grep.neogulcoder.domain.timevote.entity.TimeVoteStat; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVoteStat; +import grep.neogulcoder.domain.timevote.QTimeVote; +import grep.neogulcoder.domain.timevote.QTimeVoteStat; import jakarta.persistence.EntityManager; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatRepository.java b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatRepository.java index b0dcafc0..5e0a862d 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatRepository.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/repository/TimeVoteStatRepository.java @@ -1,7 +1,7 @@ package grep.neogulcoder.domain.timevote.repository; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; -import grep.neogulcoder.domain.timevote.entity.TimeVoteStat; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVoteStat; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVotePeriodService.java b/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVotePeriodService.java index a12f591d..ce1038e3 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVotePeriodService.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVotePeriodService.java @@ -1,15 +1,8 @@ package grep.neogulcoder.domain.timevote.service; -import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.FORBIDDEN_TIME_VOTE_CREATE; -import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.INVALID_TIME_VOTE_PERIOD; -import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.STUDY_MEMBER_NOT_FOUND; -import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.STUDY_NOT_FOUND; -import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.TIME_VOTE_INVALID_DATE_RANGE; -import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.TIME_VOTE_PERIOD_START_DATE_IN_PAST; +import static grep.neogulcoder.domain.timevote.exception.code.TimeVoteErrorCode.*; import grep.neogulcoder.domain.alram.service.AlarmService; -import grep.neogulcoder.domain.alram.type.AlarmType; -import grep.neogulcoder.domain.alram.type.DomainType; import grep.neogulcoder.domain.study.Study; import grep.neogulcoder.domain.study.StudyMember; import grep.neogulcoder.domain.study.enums.StudyMemberRole; @@ -17,7 +10,8 @@ import grep.neogulcoder.domain.study.repository.StudyRepository; import grep.neogulcoder.domain.timevote.dto.request.TimeVotePeriodCreateRequest; import grep.neogulcoder.domain.timevote.dto.response.TimeVotePeriodResponse; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.event.TimeVotePeriodCreatedEvent; import grep.neogulcoder.domain.timevote.repository.TimeVotePeriodRepository; import grep.neogulcoder.domain.timevote.repository.TimeVoteRepository; import grep.neogulcoder.domain.timevote.repository.TimeVoteStatRepository; @@ -26,9 +20,8 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -44,6 +37,7 @@ public class TimeVotePeriodService { private final StudyMemberRepository studyMemberRepository; private final AlarmService alarmService; private final MessageFinder messageFinder; + private final ApplicationEventPublisher eventPublisher; public TimeVotePeriodResponse createTimeVotePeriodAndReturn(TimeVotePeriodCreateRequest request, Long studyId, Long userId) { StudyMember studyMember = getValidStudyMember(studyId, userId); @@ -62,19 +56,8 @@ public TimeVotePeriodResponse createTimeVotePeriodAndReturn(TimeVotePeriodCreate TimeVotePeriod savedPeriod = timeVotePeriodRepository.save(request.toEntity(studyId, adjustedEndDate)); getValidStudy(studyId); - messageFinder.findMessage(AlarmType.TIME_VOTE_REQUEST, DomainType.TIME_VOTE, studyId); - - List members = studyMemberRepository.findAllByStudyIdAndActivatedTrue(studyId); - List notifiedUserIds = new ArrayList<>(); - for (StudyMember member : members) { - if (!member.getUserId().equals(userId)) { - alarmService.saveAlarm(member.getUserId(), AlarmType.TIME_VOTE_REQUEST, - DomainType.TIME_VOTE, studyId); - notifiedUserIds.add(member.getId()); - } - } - - return TimeVotePeriodResponse.from(savedPeriod, notifiedUserIds); + eventPublisher.publishEvent(new TimeVotePeriodCreatedEvent(studyId, userId)); + return TimeVotePeriodResponse.from(savedPeriod); } public void deleteAllTimeVoteDate(Long studyId) { diff --git a/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteService.java b/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteService.java index 2e9d8aba..9778158b 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteService.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteService.java @@ -8,8 +8,8 @@ import grep.neogulcoder.domain.timevote.dto.request.TimeVoteUpdateRequest; import grep.neogulcoder.domain.timevote.dto.response.TimeVoteResponse; import grep.neogulcoder.domain.timevote.dto.response.TimeVoteSubmissionStatusResponse; -import grep.neogulcoder.domain.timevote.entity.TimeVote; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVote; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; import grep.neogulcoder.domain.timevote.repository.TimeVotePeriodRepository; import grep.neogulcoder.domain.timevote.repository.TimeVoteRepository; import grep.neogulcoder.domain.timevote.repository.TimeVoteQueryRepository; diff --git a/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteStatService.java b/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteStatService.java index 7415c4c8..4165d563 100644 --- a/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteStatService.java +++ b/src/main/java/grep/neogulcoder/domain/timevote/service/TimeVoteStatService.java @@ -5,8 +5,8 @@ import grep.neogulcoder.domain.study.StudyMember; import grep.neogulcoder.domain.study.repository.StudyMemberRepository; import grep.neogulcoder.domain.timevote.dto.response.TimeVoteStatResponse; -import grep.neogulcoder.domain.timevote.entity.TimeVotePeriod; -import grep.neogulcoder.domain.timevote.entity.TimeVoteStat; +import grep.neogulcoder.domain.timevote.TimeVotePeriod; +import grep.neogulcoder.domain.timevote.TimeVoteStat; import grep.neogulcoder.domain.timevote.repository.TimeVotePeriodRepository; import grep.neogulcoder.domain.timevote.repository.TimeVoteStatQueryRepository; import grep.neogulcoder.domain.timevote.repository.TimeVoteStatRepository; diff --git a/src/main/java/grep/neogulcoder/global/config/security/SecurityConfig.java b/src/main/java/grep/neogulcoder/global/config/security/SecurityConfig.java index 5599a514..c08ed123 100644 --- a/src/main/java/grep/neogulcoder/global/config/security/SecurityConfig.java +++ b/src/main/java/grep/neogulcoder/global/config/security/SecurityConfig.java @@ -78,6 +78,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http, ClientRegistra (requests) -> requests .requestMatchers("/auth/**", "/", "/api/users/signup", + "/recruitment-posts", "/oauth2/**", "/login/**", "/signup", diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 1b395143..270c6707 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -41,11 +41,11 @@ INSERT INTO study_member (study_id, user_id, role, participated, activated) VALU INSERT INTO study_member (study_id, user_id, role, participated, activated) VALUES (6, 9, 'MEMBER', FALSE, TRUE); -- [ recruitment_post ] -INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated) VALUES (3, 1, '자바 스터디 모집', '이펙티브 자바 공부하실분 구해요!!', 3, '2025-04-19', 'COMPLETE', true); -INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated) VALUES (2, 4, '면접 스터디 모집', '삼성 면접 1차 합격자 분들 같이 준비하실분들 찾습니다', 1, '2025-07-08', 'COMPLETE', true); -INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated) VALUES (5, 2, '호밀밭의 파수꾼 책 같이 읽으실분', '책 같이 읽고 의견을 공유 하실분을 찾고 있습니다!! 많은 참여 부탁드려요', 5, '2025-06-10', 'IN_PROGRESS', true); -INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated) VALUES (3, 5, '클라이밍 같이 하실분 모집 합니다', '클라이밍 좋아하시는 분들의 많은 관심 바랍니다!', 5, '2025-06-08', 'IN_PROGRESS', true); -INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated) VALUES (2, 3, '토익 스터디', '토익 고수들의 많은 참여 부탁 드립니다', 2, '2025-03-31', 'IN_PROGRESS', true); +INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated, created_date) VALUES (3, 1, '자바 스터디 모집', '이펙티브 자바 공부하실분 구해요!!', 3, '2025-04-19', 'COMPLETE', true, '2025-08-02 12:00:00'); +INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated, created_date) VALUES (2, 4, '면접 스터디 모집', '삼성 면접 1차 합격자 분들 같이 준비하실분들 찾습니다', 1, '2025-07-08', 'COMPLETE', true, '2025-08-11 12:00:00'); +INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated, created_date) VALUES (5, 2, '호밀밭의 파수꾼 책 같이 읽으실분', '책 같이 읽고 의견을 공유 하실분을 찾고 있습니다!! 많은 참여 부탁드려요', 5, '2025-06-10', 'IN_PROGRESS', true, '2025-09-02 12:00:00'); +INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated, created_date) VALUES (3, 5, '클라이밍 같이 하실분 모집 합니다', '클라이밍 좋아하시는 분들의 많은 관심 바랍니다!', 5, '2025-06-08', 'IN_PROGRESS', true, '2025-09-06 12:00:00'); +INSERT INTO recruitment_post (user_id, study_id, subject, content, recruitment_count, expired_date, status, activated, created_date) VALUES (2, 3, '토익 스터디', '토익 고수들의 많은 참여 부탁 드립니다', 2, '2025-03-31', 'IN_PROGRESS', true, '2025-07-16 12:00:00'); -- [ study_application ] INSERT INTO study_application (user_id, recruitment_post_id, application_reason, is_read, status, activated) VALUES (1, 1, '자바 스터디에 참여하고 싶습니다.', FALSE, 'APPLYING', TRUE);