Skip to content

Commit

Permalink
Merge branch 'develop' into mvp/member
Browse files Browse the repository at this point in the history
  • Loading branch information
tape4 authored Jul 26, 2024
2 parents 3232ec5 + 9ae99b8 commit 81ba544
Show file tree
Hide file tree
Showing 31 changed files with 1,472 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ out/
/.nb-gradle/

### VS Code ###
.vscode/
.vscode/
.DS_Store
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'mysql:mysql-connector-java:8.0.32'
implementation 'org.springframework.boot:spring-boot-starter-validation'

implementation 'org.openapitools:jackson-databind-nullable:0.2.1'
}

tasks.named('test') {
Expand Down
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,84 @@
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.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import umc.kkijuk.server.career.controller.response.CareerGroupedByResponse;
import umc.kkijuk.server.career.controller.response.CareerResponse;
import umc.kkijuk.server.career.controller.response.CareerResponseMessage;
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;

import java.util.List;

@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.CreateCareerDto request){
LoginUser loginUser = LoginUser.get();
Career career = careerService.createCareer(request);
return CareerResponse.success(HttpStatus.CREATED,
CareerResponseMessage.CAREER_CREATE_SUCCESS,
CareerConverter.toCareerResultDto(career));
}

@DeleteMapping("/{careerId}")
@Operation(summary = "활동 삭제 API", description = "내 커리어 - 활동을 삭제하는 API")
@Parameter(name="careerId", description = "활동 Id, path variable 입니다.",example = "1")
public CareerResponse<Object> delete(@PathVariable Long careerId){
LoginUser loginUser = LoginUser.get();
careerService.deleteCareer(careerId);
return CareerResponse.success(HttpStatus.OK,
CareerResponseMessage.CAREER_DELETE_SUCCESS,null);
}

@PatchMapping("/{careerId}")
@Operation(summary = "활동 수정 API", description = "내 커리어 - 활동을 수정하는 API")
@Parameter(name="careerId", description = "활동 Id, path variable 입니다.",example = "1")
public CareerResponse<Object> update(@RequestBody @Valid CareerRequestDto.UpdateCareerDto request,
@PathVariable Long careerId) {
LoginUser loginUser = LoginUser.get();
Career updateCareer = careerService.updateCareer(careerId, request);
return CareerResponse.success(HttpStatus.OK,
CareerResponseMessage.CAREER_UPDATE_SUCCESS,
CareerConverter.toCareerDto(updateCareer));
}

@GetMapping("")
@Operation(
summary = "활동 조회 API - category(카테고리 기준) , year(연도 기준) ",
description = "내 커리어 - 활동을 카테고리 별로 조회하는 API입니다. query 값으로 category 나 year 값을 주세요. " )
public CareerResponse<List<? extends CareerGroupedByResponse>> read(@RequestParam(name="status") String value){
return CareerResponse.success(HttpStatus.OK,
CareerResponseMessage.CAREER_FINDALL_SUCCESS,
careerService.getCareerGroupedBy(value));
}



}










Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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));
}

@ExceptionHandler(CareerValidationException.class)
public ResponseEntity<CareerResponse<?>> handleCareerValidationException(CareerValidationException e){
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(CareerResponse.createError(e.getMessage()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package umc.kkijuk.server.career.controller.exception;

public class CareerValidationException extends RuntimeException{

public CareerValidationException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package umc.kkijuk.server.career.controller.response;

public abstract class CareerGroupedByResponse {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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(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<>(HttpStatus.BAD_REQUEST.value(), CareerResponseMessage.CAREER_CREATE_FAIL,errors);
}
public static CareerResponse<?> createError(String message){
return new CareerResponse<>(HttpStatus.BAD_REQUEST.value(), message, null);
}


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

public class CareerResponseMessage {
public static final String CAREER_CREATE_SUCCESS = "활동 추가가 정상적으로 이루어졌습니다.";
public static final String CAREER_UPDATE_SUCCESS = "활동 수정이 정상적으로 이루어졌습니다.";
public static final String CAREER_DELETE_SUCCESS = "활동 삭제가 정상적으로 이루어졌습니다.";
public static final String CAREER_FINDALL_SUCCESS = "활동 조회가 정상적으로 이루어졌습니다.";


public static final String CAREER_NOT_FOUND ="존재하는 활동 Id가 아닙니다.";
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_FINDALL_FAIL = "올바른 요청이 아닙니다. category, year 요청을 주세요";









}
74 changes: 74 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,74 @@
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_summary",length = 50)
private String summary;

@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 setName(String name) {
this.name = name;
}

public void setAlias(String alias) {
this.alias = alias;
}

public void setCurrent(Boolean current) {
this.current = current;
}

public void setSummary(String summary) {
this.summary = summary;
}

public void setStartdate(LocalDate startdate) {
this.startdate = startdate;
}

public void setEnddate(LocalDate enddate) {
this.enddate = enddate;
}

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;
}
Loading

0 comments on commit 81ba544

Please sign in to comment.