Skip to content

Commit

Permalink
Feat : Career 활동 저장 API 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonda02 committed Jul 20, 2024
1 parent 628c169 commit fa89bfe
Show file tree
Hide file tree
Showing 30 changed files with 830 additions and 4 deletions.
Binary file added .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ out/

### VS Code ###
.vscode/


application.properties
2 changes: 2 additions & 0 deletions src/main/java/umc/kkijuk/server/ServerApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@SpringBootApplication
@EnableJpaAuditing
public class ServerApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package umc.kkijuk.server.career.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import umc.kkijuk.server.career.controller.response.CareerResponse;
import umc.kkijuk.server.career.controller.response.CareerResponseMessage;
import umc.kkijuk.server.career.controller.response.CareerStatusCode;
import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.dto.CareerRequestDto;
import umc.kkijuk.server.career.dto.CareerResponseDto;
import umc.kkijuk.server.career.dto.converter.CareerConverter;
import umc.kkijuk.server.career.service.CareerService;
import umc.kkijuk.server.common.LoginUser;

@Tag(name="career",description = "내커리어 관련 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/career")
public class CareerController {
private final CareerService careerService;
@PostMapping("")
@Operation(summary = "활동 추가 API", description = "내 커리어 - 활동을 추가하는 API")
public CareerResponse<CareerResponseDto.CareerResultDto> create(@RequestBody @Valid CareerRequestDto.CareerDto request){
LoginUser loginUser = LoginUser.get();
Career career = careerService.createCareer(request);
return CareerResponse.success(CareerStatusCode.CREATED,
CareerResponseMessage.CAREER_CREATE_SUCCESS,
CareerConverter.tocareerResultDto(career));
}

@DeleteMapping("/{careerId}")
@Operation(summary = "활동 삭제 API", description = "내 커리어 - 활동을 삭제하는 API")
@Parameters({
@Parameter(name="careerId",description = "활동 아이디, path variable 입니다.")
})
// * CareerID 있는지 검증 해야함
public CareerResponse<Object> delete(@PathVariable Long careerId){
LoginUser loginUser = LoginUser.get();
careerService.deleteCareer(careerId);
return CareerResponse.success(CareerStatusCode.OK,
CareerResponseMessage.CAREER_DELETE_SUCCESS,null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package umc.kkijuk.server.career.controller.exception;


import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import umc.kkijuk.server.career.controller.response.CareerResponse;
import umc.kkijuk.server.career.controller.response.CareerResponseMessage;


@RestControllerAdvice(assignableTypes = {umc.kkijuk.server.career.controller.CareerController.class})
public class CareerExceptionControllerAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<CareerResponse<?>> handleValidationExceptions(BindingResult bindingResult) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CareerResponse.createFail(bindingResult));
}
@ExceptionHandler(InvalidFormatException.class)
public ResponseEntity<CareerResponse<?>> handleInvalidFormatExceptions(InvalidFormatException e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CareerResponse.createError(CareerResponseMessage.CAREER_FOTMAT_INVALID));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package umc.kkijuk.server.career.controller.response;


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import org.hibernate.annotations.AnyKeyJavaClass;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Builder
@Getter
public class CareerResponse<T> {
private int status;
private String message;
@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;

public CareerResponse(final int status,final String message,T data){
this.status = status;
this.message = message;
this.data = data;
}
public static <T> CareerResponse<T> success(int status, String message, T data){
return new CareerResponse<>(status,message,data);
}
public static <T> CareerResponse<T> Success(int status, String message){
return new CareerResponse<>(status, message, null);
}
public static <T> CareerResponse<T> success(HttpStatus status, String message, T data){
return new CareerResponse<>(status.value(),message,data);
}
public static CareerResponse<?> createFail (BindingResult bindingResult){
Map<String, String> errors = new HashMap<>();
List<ObjectError> allErrors = bindingResult.getAllErrors();
for ( ObjectError error: allErrors ) {
if( error instanceof FieldError) {
errors.put(((FieldError)error).getField(),error.getDefaultMessage());
}else{
errors.put(error.getObjectName(),error.getDefaultMessage());
}
}
return new CareerResponse<>(CareerStatusCode.FAIL,CareerResponseMessage.CAREER_CREATE_FAIL,errors);
}
public static CareerResponse<?> createError(String message){
return new CareerResponse<>(CareerStatusCode.FAIL, message, null);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package umc.kkijuk.server.career.controller.response;

public class CareerResponseMessage {
public static final String CAREER_CREATE_SUCCESS = "활동 추가가 정상적으로 이루어졌습니다.";
public static final String CAREER_CREATE_FAIL = "활동 추가를 실패했습니다.";
public static final String CAREER_FOTMAT_INVALID = "올바른 날짜 형식이 아닙니다. YYYY-MM-DD 형식으로 입력해야 합니다.";
public static final String CAREER_ENDDATE = "현재 진행중이 아니라면, 활동 종료 날짜를 입력해야 합니다.";
public static final String CAREER_PERIOD_FAIL = "시작 날짜는 종료 날짜보다 앞에 있어야 합니다.";
public static final String CATEGORY_NOT_FOUND = "존재하는 카테고리 Id가 아닙니다.";
public static final String CAREER_DELETE_SUCCESS = "활동 삭제가 정상적으로 이루어졌습니다.";
public static final String CAREER_DELETE_FAIL = "활동 삭제를 실패했습니다.";


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package umc.kkijuk.server.career.controller.response;

public class CareerStatusCode {
public static final int OK = 200;
public static final int CREATED = 201;
public static final int FAIL = 400;
}
47 changes: 47 additions & 0 deletions src/main/java/umc/kkijuk/server/career/domain/Career.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package umc.kkijuk.server.career.domain;

import jakarta.persistence.*;
import lombok.*;
import umc.kkijuk.server.career.domain.base.BaseEntity;

import java.time.LocalDate;

@Entity
@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Career extends BaseEntity {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="career_id")
private Long id;

@Column(name="career_name", length = 20)
private String name;

@Column(name="career_alias", length = 20)
private String alias;

@Column(name="career_current")
private Boolean current;

@Column(name="career_year")
private int year;

@Column(name="career_startdate")
private LocalDate startdate;

@Column(name="career_enddate")
private LocalDate enddate;

@ManyToOne
@JoinColumn(name = "category_id")
private Category category;

public void setCategory(Category category) {
this.category = category;
}
public void setYear(int dayOfYear) {
this.year = dayOfYear;
}
}
25 changes: 25 additions & 0 deletions src/main/java/umc/kkijuk/server/career/domain/Category.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package umc.kkijuk.server.career.domain;


import jakarta.persistence.*;
import lombok.*;

import java.util.List;

@Entity
@Getter
@Builder
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class Category {

@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="category_id")
private Long id;

@Column(name="category_name", nullable = false, length = 20)
private String name;

@OneToMany(mappedBy = "category")
private List<Career> careers;
}
24 changes: 24 additions & 0 deletions src/main/java/umc/kkijuk/server/career/domain/base/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package umc.kkijuk.server.career.domain.base;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import lombok.Getter;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
@CreatedDate
@Column(length = 6)
private LocalDateTime createdAt;

@LastModifiedDate
@Column(length = 6)
private LocalDateTime updatedAt;
}
51 changes: 51 additions & 0 deletions src/main/java/umc/kkijuk/server/career/dto/CareerRequestDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package umc.kkijuk.server.career.dto;

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 jakarta.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;
import umc.kkijuk.server.career.validation.ValidCategory;
import umc.kkijuk.server.career.validation.ValidPeriod;

import java.time.LocalDate;

public class CareerRequestDto {
@Getter
@Builder
@ValidPeriod
public static class CareerDto{

@NotBlank(message = "활동명은 필수 입력 항목입니다. 최대 20자 까지 입력 가능")
@Size(max = 20)
@Schema(description = "활동명", example = "IT 서비스 개발 동아리", type="string")
String careerName;

@NotBlank(message = "활동 별칭은 필수 입력 항목입니다. 최대 20자 까지 입력 가능")
@Size(max = 20)
@Schema(description = "활동 별칭", example = "동아리", type="string")
String alias;

@NotNull(message = "활동 여부는 필수 선택 항목입니다.")
@Schema(description = "활동 여부", example = "false", type = "boolean")
Boolean isCurrent;

@NotNull(message = "활동 시작 날짜는 필수 입력 항목입니다.")
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
@Schema(description = "활동 시작 날짜", example = "2024-04-14", type="string")
LocalDate startDate;


@JsonFormat(shape=JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
@Schema(description = "활동 종료 날짜", example = "2024-07-20", type = "string")
LocalDate endDate;

@ValidCategory
@NotNull(message = "활동 카테고리는 필수 선택 항목입니다.")
@Schema(description = "활동 카테고리", example = "1", type = "int")
int category;
}

}
21 changes: 21 additions & 0 deletions src/main/java/umc/kkijuk/server/career/dto/CareerResponseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package umc.kkijuk.server.career.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class CareerResponseDto {

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CareerResultDto{
@Schema(description = "생성된 활동 Id", example = "1", type = "Long")
private Long careerId;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package umc.kkijuk.server.career.dto.converter;

import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.dto.CareerRequestDto;
import umc.kkijuk.server.career.dto.CareerResponseDto;

public class CareerConverter {

public static Career toCareer(CareerRequestDto.CareerDto request){
return Career.builder()
.name(request.getCareerName())
.alias(request.getAlias())
.startdate(request.getStartDate())
.current(request.getIsCurrent())
.enddate(request.getEndDate())
.build();
}
public static CareerResponseDto.CareerResultDto tocareerResultDto(Career career){
return CareerResponseDto.CareerResultDto.builder()
.careerId(career.getId())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package umc.kkijuk.server.career.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import umc.kkijuk.server.career.domain.Career;

public interface CareerRepository extends JpaRepository<Career, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package umc.kkijuk.server.career.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import umc.kkijuk.server.career.domain.Category;

public interface CategoryRepository extends JpaRepository<Category,Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package umc.kkijuk.server.career.service;

import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.dto.CareerRequestDto;

public interface CareerService {
Career createCareer(CareerRequestDto.CareerDto request);
void deleteCareer(Long careerId);
}
Loading

0 comments on commit fa89bfe

Please sign in to comment.