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
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.5.3'
id 'io.spring.dependency-management' version '1.1.7'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}

group = 'grep'
Expand Down Expand Up @@ -69,8 +70,8 @@ dependencies {

//JWT 의존성
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'

// OAuth2 의존성
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
Expand All @@ -82,9 +83,8 @@ dependencies {
implementation 'dev.langchain4j:langchain4j-spring-boot-starter:1.0.0-beta3'
implementation 'dev.langchain4j:langchain4j-google-ai-gemini-spring-boot-starter:1.0.0-beta3'


// 배포 관련 의존성
// runtimeOnly 'org.postgresql:postgresql'
// runtimeOnly 'org.postgresql:postgresql'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'com.google.cloud:spring-cloud-gcp-starter-secretmanager:4.9.1'
implementation 'com.google.cloud:google-cloud-storage:2.38.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public enum RecruitmentErrorCode implements ErrorCode {
NOT_FOUND(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.name(), "모집글을 찾지 못했습니다."),
NOT_FOUND_STUDY_MEMBER(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.name(), "스터디에 참여하고 있지 않은 회원 입니다."),
NOT_FOUND_COMMENT(HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND.name(), "댓글을 찾지 못했습니다"),
NOT_OWNER(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.name(), "모집글을 등록한 당사자가 아닙니다.");
NOT_OWNER(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.name(), "모집글을 등록한 당사자가 아닙니다."),
END_DATE_ERROR(HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST.name(), "모집글은 스터디가 시작되고 종료될 때까지 작성 가능 합니다.");

private static final String BASIC_MESSAGE = "RECRUITMENT";
private final HttpStatus status;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package grep.neogulcoder.domain.recruitment.post.controller;

import grep.neogulcoder.domain.recruitment.post.controller.dto.request.save.RecruitmentPostCreateRequest;
import grep.neogulcoder.domain.recruitment.post.controller.dto.response.save.JoinedStudyLoadInfo;
import grep.neogulcoder.domain.recruitment.post.controller.dto.response.save.JoinedStudiesInfo;
import grep.neogulcoder.domain.recruitment.post.controller.dto.response.save.JoinedStudyLoadInfo;
import grep.neogulcoder.domain.recruitment.post.service.RecruitmentPostSaveService;
import grep.neogulcoder.global.auth.Principal;
import grep.neogulcoder.global.response.ApiResponse;
Expand All @@ -21,7 +21,7 @@ public class RecruitmentPostSaveController implements RecruitmentPostSaveSpecifi

@PostMapping
public ResponseEntity<ApiResponse<Long>> save(@Valid @RequestBody RecruitmentPostCreateRequest request,
@AuthenticationPrincipal Principal userDetails) {
@AuthenticationPrincipal Principal userDetails) {
long postId = recruitmentPostService.create(request.toServiceRequest(), userDetails.getUserId());
return ResponseEntity.ok(ApiResponse.success(postId));
}
Expand All @@ -34,7 +34,7 @@ public ResponseEntity<ApiResponse<JoinedStudiesInfo>> getJoinedStudyInfo(@Authen

@GetMapping("/studies/{study-id}")
public ResponseEntity<ApiResponse<JoinedStudyLoadInfo>> getJoinedStudyLoadInfo(@PathVariable("study-id") long studyId,
@AuthenticationPrincipal Principal userDetails) {
@AuthenticationPrincipal Principal userDetails) {
JoinedStudyLoadInfo response = recruitmentPostService.getJoinedStudyLoadInfo(studyId, userDetails.getUserId());
return ResponseEntity.ok(ApiResponse.success(response));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import grep.neogulcoder.domain.recruitment.post.service.request.RecruitmentPostCreateServiceRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.FutureOrPresent;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
Expand Down Expand Up @@ -31,7 +30,7 @@ public class RecruitmentPostCreateRequest {
private int recruitmentCount;

@Schema(example = "2025-07-10", description = "모집 마감일")
@FutureOrPresent(message = "모집 마감일은 현재 날짜 이전으로 설정이 불가능 합니다.")
@NotNull
private LocalDateTime expiredDate;

private RecruitmentPostCreateRequest() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

import static grep.neogulcoder.domain.recruitment.RecruitmentErrorCode.*;
import static grep.neogulcoder.domain.recruitment.RecruitmentErrorCode.NOT_FOUND_STUDY_MEMBER;
import static grep.neogulcoder.domain.recruitment.RecruitmentErrorCode.NOT_STUDY_LEADER;

Expand All @@ -28,12 +30,16 @@ public class RecruitmentPostSaveService {

@Transactional
public long create(RecruitmentPostCreateServiceRequest request, long userId) {
StudyMember studyMember = studyMemberRepository.findByStudyIdAndUserId(request.getStudyId(), userId);
StudyMember studyMember = studyMemberRepository.findMemberWithStudyBy(request.getStudyId(), userId);

if (studyMember.hasNotRoleLeader()) {
throw new BusinessException(NOT_STUDY_LEADER);
}

if(studyMember.getStudy().hasEndDateBefore(request.getExpiredDate())){
throw new BusinessException(END_DATE_ERROR);
}

return recruitmentPostRepository.save(request.toEntity(userId)).getId();
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/grep/neogulcoder/domain/study/Study.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ public boolean isReviewableAt(LocalDateTime currentDateTime) {
(currentDateTime.isEqual(reviewableDateTime) || currentDateTime.isBefore(reviewableDateTime));
}

public boolean hasEndDateBefore(LocalDateTime dateTime) {
return this.endDate.isBefore(dateTime);
}

public static boolean isOverJoinLimit(int joinedStudyCount) {
return joinedStudyCount >= MAX_JOINED_STUDY_COUNT;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public ResponseEntity<ApiResponse<Void>> registerExtensionParticipation(@PathVar
}

@PostMapping("/invite/user")
public ResponseEntity<ApiResponse<Void>> inviteUser(@PathVariable("studyId") Long studyId, @AuthenticationPrincipal Principal userDetails, String targetUserNickname) {
public ResponseEntity<ApiResponse<Void>> inviteUser(@PathVariable("studyId") Long studyId, @AuthenticationPrincipal Principal userDetails, @RequestParam String targetUserNickname) {
studyManagementService.inviteTargetUser(studyId, userDetails.getUserId(), targetUserNickname);
return ResponseEntity.ok(ApiResponse.noContent());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ public StudyMember findByStudyIdAndUserId(long studyId, long userId) {
.fetchOne();
}

public StudyMember findMemberWithStudyBy(long studyId, long userId) {
return queryFactory.select(studyMember)
.from(studyMember)
.join(studyMember.study, study).fetchJoin()
.where(
studyMember.study.id.eq(studyId),
studyMember.userId.eq(userId),
studyMember.activated.isTrue()
)
.fetchOne();
}

public List<ExtendParticipationResponse> findExtendParticipation(Long studyId) {
return queryFactory
.select(Projections.constructor(
Expand Down