Skip to content

Commit

Permalink
Merge pull request #3 from 지원 공고 CRUD 기초
Browse files Browse the repository at this point in the history
지원 공고 CRUD 기초
  • Loading branch information
tape4 authored Jul 19, 2024
2 parents c1bb59e + 72487b5 commit 5f76228
Show file tree
Hide file tree
Showing 20 changed files with 634 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package umc.kkijuk.server.common.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import umc.kkijuk.server.common.domian.exception.ResourceNotFoundException;
import umc.kkijuk.server.common.domian.response.ErrorResponse;

@RestControllerAdvice
@RequiredArgsConstructor
public class ExceptionControllerAdvice {

@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(ResourceNotFoundException.class)
public ErrorResponse resourceNotFoundException(ResourceNotFoundException exception) {
return new ErrorResponse(exception.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package umc.kkijuk.server.common.domian.exception;

public class ResourceNotFoundException extends RuntimeException{
public ResourceNotFoundException(String dataSource, long id) {
super(dataSource + "에서 ID " + id + "를 찾을 수 없습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package umc.kkijuk.server.common.domian.response;

import lombok.Getter;

@Getter
public class ErrorResponse {
private final String message;

public ErrorResponse(String message) {
this.message = message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
import org.springframework.web.bind.annotation.*;
import umc.kkijuk.server.common.LoginUser;
import umc.kkijuk.server.recruit.controller.port.RecruitService;
import umc.kkijuk.server.recruit.controller.response.RecruitResponse;
import umc.kkijuk.server.recruit.domain.Recruit;
import umc.kkijuk.server.recruit.domain.RecruitCreateDto;
import umc.kkijuk.server.recruit.controller.response.RecruitInfoResponse;
import umc.kkijuk.server.recruit.domain.*;
import umc.kkijuk.server.recruit.controller.response.RecruitIdResponse;

import java.util.ArrayList;

@Tag(name = "recruit", description = "모집 공고 API")
@RestController
Expand All @@ -20,11 +22,49 @@ public class RecruitController {
private final RecruitService recruitService;

@PostMapping
public ResponseEntity<RecruitResponse> create(@RequestBody @Valid RecruitCreateDto recruitCreateDto) {
public ResponseEntity<RecruitIdResponse> create(@RequestBody @Valid RecruitCreateDto recruitCreateDto) {
LoginUser loginUser = LoginUser.get();
Recruit recruit = recruitService.create(recruitCreateDto);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(RecruitResponse.from(recruit));
.body(RecruitIdResponse.from(recruit));
}

@PutMapping("/{recruitId}")
public ResponseEntity<Long> update(@RequestBody @Valid RecruitUpdate recruitUpdate,
@PathVariable long recruitId) {
LoginUser loginUser = LoginUser.get();
return ResponseEntity
.status(HttpStatus.OK)
.body(recruitService.update(recruitId, recruitUpdate).getId());
}

@PatchMapping("/{recruitId}")
public ResponseEntity<Long> updateState(@RequestBody @Valid RecruitStatusUpdate recruitStatusUpdate,
@PathVariable long recruitId) {
LoginUser loginUser = LoginUser.get();
return ResponseEntity
.ok()
.body(recruitService.updateStatus(recruitId, recruitStatusUpdate).getId());
}

@DeleteMapping("/{recruitId}")
public ResponseEntity<Long> delete(@PathVariable long recruitId) {
LoginUser loginUser = LoginUser.get();
return ResponseEntity
.ok()
.body(recruitService.disable(recruitId).getId());
}

// review 만든 후 테스트 코드 작성
@GetMapping("/{recruitId}")
public ResponseEntity<RecruitInfoResponse> getRecruitInfo(@PathVariable long recruitId) {
LoginUser loginUser = LoginUser.get();
Recruit recruit = recruitService.getById(recruitId);
// List<Review> reviews = reviewService.getByRecruitId(recruitId);

return ResponseEntity
.ok()
.body(RecruitInfoResponse.from(recruit, new ArrayList<>()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@

import umc.kkijuk.server.recruit.domain.Recruit;
import umc.kkijuk.server.recruit.domain.RecruitCreateDto;
import umc.kkijuk.server.recruit.domain.RecruitStatusUpdate;
import umc.kkijuk.server.recruit.domain.RecruitUpdate;

import javax.net.ssl.SSLSession;

public interface RecruitService {
Recruit create(RecruitCreateDto recruitCreateDto);

Recruit update(Long recruitId, RecruitUpdate recruitUpdate);

Recruit getById(long id);

Recruit updateStatus(long recruitId, RecruitStatusUpdate recruitStatusUpdate);

Recruit disable(long recruitId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

@Getter
@Builder
public class RecruitResponse {
public class RecruitIdResponse {
private final Long id;
public static RecruitResponse from(Recruit recruit) {
return RecruitResponse.builder()
public static RecruitIdResponse from(Recruit recruit) {
return RecruitIdResponse.builder()
.id(recruit.getId())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package umc.kkijuk.server.recruit.controller.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import umc.kkijuk.server.recruit.domain.Recruit;
import umc.kkijuk.server.recruit.domain.Review;

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

@Getter
@Builder
public class RecruitInfoResponse {
private final String title;

@Schema(description = "공고 모집 시작 날짜", example = "2022-09-18 10:11", pattern = "yyyy-MM-dd HH:mm", type = "string")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
private final LocalDateTime startTime;

@Schema(description = "공고 모집 마감 날짜", example = "2022-09-25 10:11", pattern = "yyyy-MM-dd HH:mm", type = "string" )
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
private final LocalDateTime endTime;

@Schema(description = "공고 지원 날짜", example = "2024-07-19")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private final LocalDate applyDate;
private final List<String> tags;
private final int reviewCount;
private final String link;
private final List<ReviewResponse> reviews;

public static RecruitInfoResponse from(Recruit recruit, List<Review> reviews) {
return RecruitInfoResponse.builder()
.title(recruit.getTitle())
.startTime(recruit.getStartTime())
.endTime(recruit.getEndTime())
.applyDate(recruit.getApplyDate())
.tags(recruit.getTags())
.link(recruit.getLink())
.reviewCount(reviews.size())
.reviews(reviews.stream().map(ReviewResponse::from).toList())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package umc.kkijuk.server.recruit.controller.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import umc.kkijuk.server.recruit.domain.Review;

import java.time.LocalDate;

@Getter
@Builder
public class ReviewResponse {
private final Long reviewId;
private final String title;
private final String content;

@Schema(description = "날짜", example = "2024-07-19")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private final LocalDate date;

public static ReviewResponse from(Review review) {
return ReviewResponse.builder()
.reviewId(review.getId())
.title(review.getTitle())
.content(review.getContent())
.date(review.getDate())
.build();
}
}
49 changes: 48 additions & 1 deletion src/main/java/umc/kkijuk/server/recruit/domain/Recruit.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

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

@Builder
Expand All @@ -18,6 +19,8 @@ public class Recruit {
private final LocalDate applyDate;
private final List<String> tags;
private final String link;
private final Boolean isActive;
private final LocalDateTime disabledTime;

public static Recruit from(RecruitCreateDto recruitCreateDto) {
return Recruit.builder()
Expand All @@ -26,8 +29,52 @@ public static Recruit from(RecruitCreateDto recruitCreateDto) {
.startTime(recruitCreateDto.getStartTime())
.endTime(recruitCreateDto.getEndTime())
.applyDate(recruitCreateDto.getApplyDate())
.tags(recruitCreateDto.getTags())
.tags(recruitCreateDto.getTags() != null ? recruitCreateDto.getTags() : new ArrayList<>())
.link(recruitCreateDto.getLink())
.isActive(true)
.build();
}

public Recruit update(RecruitUpdate recruitUpdate) {
return Recruit.builder()
.id(this.id)
.title(recruitUpdate.getTitle())
.status(recruitUpdate.getStatus())
.startTime(recruitUpdate.getStartTime())
.endTime(recruitUpdate.getEndTime())
.applyDate(recruitUpdate.getApplyDate())
.tags(recruitUpdate.getTags() != null ? recruitUpdate.getTags() : new ArrayList<>())
.link(recruitUpdate.getLink())
.isActive(this.isActive)
.build();
}

public Recruit updateStatus(RecruitStatusUpdate recruitStatusUpdate) {
return Recruit.builder()
.id(this.id)
.title(this.getTitle())
.status(recruitStatusUpdate.getStatus())
.startTime(this.getStartTime())
.endTime(this.getEndTime())
.applyDate(this.getApplyDate())
.tags(this.getTags())
.link(this.getLink())
.isActive(this.isActive)
.build();
}

public Recruit disable() {
return Recruit.builder()
.id(this.id)
.title(this.getTitle())
.status(this.getStatus())
.startTime(this.getStartTime())
.endTime(this.getEndTime())
.applyDate(this.getApplyDate())
.tags(this.getTags())
.link(this.getLink())
.isActive(false)
.disabledTime(LocalDateTime.now())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.stream.Stream;

public enum RecruitStatus {
INVALID, UNAPPLIED, PLANNED, APPLYING, EJECTED, ACCEPTED;
INVALID, UNAPPLIED, PLANNED, APPLYING, REJECTED, ACCEPTED;

@JsonCreator
public static RecruitStatus parsing(String value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package umc.kkijuk.server.recruit.domain;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.*;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class RecruitStatusUpdate {
@NotNull
@Schema(description = "변경될 공고 상태", example = "REJECTED", type = "string")
private RecruitStatus status;
}
45 changes: 45 additions & 0 deletions src/main/java/umc/kkijuk/server/recruit/domain/RecruitUpdate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package umc.kkijuk.server.recruit.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.*;

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

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class RecruitUpdate {
@NotBlank(message = "공고 제목은 필수 입력 항목입니다.")
@Schema(description = "수정될 공고 제목", example = "[00] 공고제목", type = "string")
private String title;

@NotNull(message = "공고 모집 시작 날짜는 필수 입력 항목입니다.")
@Schema(description = "수정될 공고 모집 시작 날짜", example = "2022-09-18 10:11", pattern = "yyyy-MM-dd HH:mm", type = "string")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
private LocalDateTime startTime;

@NotNull(message = "공고 모집 마감 날짜는 필수 입력 항목입니다.")
@Schema(description = "수정될 공고 모집 마감 날짜", example = "2022-09-18 10:11", pattern = "yyyy-MM-dd HH:mm", type = "string")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm", timezone = "Asia/Seoul")
private LocalDateTime endTime;

@NotNull(message = "유효하지 않은 지원 상태가 입력 되었습니다.")
@Schema(description = "수정될 공고 지원 상태", example = "PLANNED", type = "string")
private RecruitStatus status;

@Schema(description = "수정될 공고 지원 날짜", pattern = "yyyy-MM-dd")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
private LocalDate applyDate;

// @Schema(description = "태그", example = "[\"코딩 테스트\", \"인턴\", \"대외 활동\"]", type = "string")
private List<String> tags;

@Schema(description = "수정될 공고 링크", example = "https://www.naver.com", type = "string")
private String link;
}
15 changes: 15 additions & 0 deletions src/main/java/umc/kkijuk/server/recruit/domain/Review.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package umc.kkijuk.server.recruit.domain;

import lombok.Builder;
import lombok.Getter;

import java.time.LocalDate;

@Getter
@Builder
public class Review {
private final Long id;
private final String title;
private final String content;
private final LocalDate date;
}
Loading

0 comments on commit 5f76228

Please sign in to comment.