Skip to content

Commit

Permalink
Feat : Career Detail 활동 기록 생성 API 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
hyeonda02 committed Jul 30, 2024
1 parent c2b1b8e commit 4d54cc6
Show file tree
Hide file tree
Showing 13 changed files with 314 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/main/java/umc/kkijuk/server/career/domain/Career.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
import jakarta.persistence.*;
import lombok.*;
import umc.kkijuk.server.career.domain.base.BaseEntity;
import umc.kkijuk.server.careerdetail.domain.CareerDetail;

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

@Entity
@Getter
Expand Down Expand Up @@ -41,6 +44,12 @@ public class Career extends BaseEntity {
@JoinColumn(name = "category_id")
private Category category;


@OneToMany(mappedBy = "career", cascade = CascadeType.ALL)
private List<CareerDetail> careerDetailList = new ArrayList<>();



public void setName(String name) {
this.name = name;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package umc.kkijuk.server.careerdetail.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.careerdetail.controller.response.CareerDetailResponse;
import umc.kkijuk.server.careerdetail.domain.CareerDetail;
import umc.kkijuk.server.careerdetail.dto.CareerDetailRequestDto;
import umc.kkijuk.server.careerdetail.dto.CareerDetailResponseDto;
import umc.kkijuk.server.careerdetail.dto.converter.CareerDetailConverter;
import umc.kkijuk.server.careerdetail.service.CareerDetailService;

@Tag(name="careerdetail",description = "내커리어 활동 기록 관련 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/career")
public class CareerDetailController {
private final CareerDetailService careerDetailService;
@PostMapping("/{careerId}")
@Operation(summary = "활동 기록 추가 API", description = "내 커리어 - 활동 기록을 생성하는 API")
@Parameter(name = "careerId", description = "활동 Id, path Variable 입니다.")
public CareerDetailResponse<CareerDetailResponseDto.CareerDetailResult> create(@RequestBody @Valid CareerDetailRequestDto.CareerDetailCreate request ,
@PathVariable Long careerId) {
CareerDetail newCareerDetail = careerDetailService.create(request, careerId);
return CareerDetailResponse.success(HttpStatus.CREATED, "활동 기록을 성공적으로 생성했습니다.", CareerDetailConverter.toCareerDetailResult(newCareerDetail));
}

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

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.springframework.http.HttpStatus;


@Getter
@Builder
@AllArgsConstructor
public class CareerDetailResponse<T> {
private int staus;
private String message;

@JsonInclude(JsonInclude.Include.NON_NULL)
private T data;
public static <T> CareerDetailResponse<T> success(HttpStatus status, String message, T data){
return new CareerDetailResponse<>(status.value(),message,data);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import jakarta.persistence.*;
import lombok.*;
import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.domain.base.BaseEntity;
import umc.kkijuk.server.careerdetail.domain.mapping.CareerTag;

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

@Entity
@Getter
Expand All @@ -16,10 +20,25 @@ public class CareerDetail extends BaseEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="career_detail_id")
private Long id;
@Column(name="career_detail_name", length = 30)
private String name;
@Column(name="career_detail_titlw", length = 30)
private String title;
@Column(name="career_detail_content", length = 800)
private String content;
@Column(name="career_detail_date")
private LocalDate date;
@Column(name="career_detail_startdate")
private LocalDate startDate;
@Column(name="career_detail_enddate")
private LocalDate endDate;


@OneToMany(mappedBy = "careerDetail", cascade = CascadeType.ALL)
private List<CareerTag> careerTagList = new ArrayList<>();

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="career_id")
private Career career;

public void setCareer(Career career) {
this.career = career;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package umc.kkijuk.server.careerdetail.domain.mapping;


import jakarta.persistence.*;
import lombok.*;
import umc.kkijuk.server.careerdetail.domain.CareerDetail;
import umc.kkijuk.server.tag.domain.Tag;

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

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="career_detail_id")
private CareerDetail careerDetail;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="tag_id")
private Tag tag;

public void setCareerDetail(CareerDetail careerDetail) {
if (this.careerDetail != null) {
careerDetail.getCareerTagList().remove(this);
}
this.careerDetail = careerDetail;
careerDetail.getCareerTagList().add(this);
}




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

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

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


public class CareerDetailRequestDto {
@Getter
@Builder
public static class CareerDetailCreate{

@Size(max = 30)
@NotNull
@Schema(description = "활동 기록 제목", example = "역량 키워드", type="string")
String title;

@Size(max = 800) @NotNull
@Schema(description = "활동 기록 내용", example = "역량 키워드", type="string")
String content;

@NotNull
@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-04-14", type="string")
LocalDate endDate;

@Schema(description = "태그 리스트")
List<Long> tagList;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package umc.kkijuk.server.careerdetail.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

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

public class CareerDetailResponseDto {
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class CareerDetailResult{
Long id;
Long careerId;
String title;
String content;
LocalDate startDate;
LocalDate endDate;
List<CareerTag> careerTagList;
}
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class CareerTag{
Long id;
String tagName;
}

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

import umc.kkijuk.server.careerdetail.domain.CareerDetail;
import umc.kkijuk.server.careerdetail.dto.CareerDetailRequestDto;
import umc.kkijuk.server.careerdetail.dto.CareerDetailResponseDto;

import java.util.ArrayList;
import java.util.stream.Collectors;

public class CareerDetailConverter {
public static CareerDetail toCareerDetail(CareerDetailRequestDto.CareerDetailCreate request) {
return CareerDetail.builder()
.title(request.getTitle())
.content(request.getContent())
.startDate(request.getStartDate())
.endDate(request.getEndDate())
.careerTagList(new ArrayList<>())
.build();
}

public static CareerDetailResponseDto.CareerDetailResult toCareerDetailResult(CareerDetail careerDetail) {
return CareerDetailResponseDto.CareerDetailResult.builder()
.id(careerDetail.getId())
.careerId(careerDetail.getCareer().getId())
.title(careerDetail.getTitle())
.content(careerDetail.getContent())
.startDate(careerDetail.getStartDate())
.endDate(careerDetail.getEndDate())
.careerTagList(careerDetail.getCareerTagList().stream()
.map(careerTag -> CareerDetailResponseDto.CareerTag.builder()
.id(careerTag.getTag().getId())
.tagName(careerTag.getTag().getName())
.build())
.collect(Collectors.toList()))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package umc.kkijuk.server.careerdetail.dto.converter;

import umc.kkijuk.server.careerdetail.domain.mapping.CareerTag;
import umc.kkijuk.server.tag.domain.Tag;

import java.util.List;
import java.util.stream.Collectors;

public class CareerTagConverter {
public static List<CareerTag> toCareerTagList(List<Tag> tagList) {
return tagList.stream()
.map(tag -> CareerTag.builder().tag(tag).build()).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package umc.kkijuk.server.careerdetail.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import umc.kkijuk.server.careerdetail.domain.CareerDetail;

public interface CareerDetailRepository extends JpaRepository<CareerDetail,Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package umc.kkijuk.server.careerdetail.service;

import umc.kkijuk.server.careerdetail.domain.CareerDetail;
import umc.kkijuk.server.careerdetail.dto.CareerDetailRequestDto;

public interface CareerDetailService {
CareerDetail create(CareerDetailRequestDto.CareerDetailCreate request, Long careerId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package umc.kkijuk.server.careerdetail.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import umc.kkijuk.server.career.domain.Career;
import umc.kkijuk.server.career.repository.CareerRepository;
import umc.kkijuk.server.careerdetail.domain.CareerDetail;
import umc.kkijuk.server.careerdetail.domain.mapping.CareerTag;
import umc.kkijuk.server.careerdetail.dto.CareerDetailRequestDto;
import umc.kkijuk.server.careerdetail.dto.converter.CareerDetailConverter;
import umc.kkijuk.server.careerdetail.dto.converter.CareerTagConverter;
import umc.kkijuk.server.careerdetail.repository.CareerDetailRepository;
import umc.kkijuk.server.common.domian.exception.ResourceNotFoundException;
import umc.kkijuk.server.tag.domain.Tag;
import umc.kkijuk.server.tag.repository.TagRepository;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CareerDetailServiceImpl implements CareerDetailService{
private final CareerRepository careerRepository;
private final TagRepository tagRepository;
private final CareerDetailRepository careerDetailRepository;

@Override
@Transactional
public CareerDetail create(CareerDetailRequestDto.CareerDetailCreate request, Long careerId) {
Career career = careerRepository.findById(careerId).orElseThrow(() -> new ResourceNotFoundException("Career", careerId));
CareerDetail newCareerDetail = CareerDetailConverter.toCareerDetail(request);
newCareerDetail.setCareer(career);

List<Tag> tagList = request.getTagList().stream().map(tagId -> {
return tagRepository.findById(tagId).orElseThrow(() -> new ResourceNotFoundException("Tag", tagId));
}).collect(Collectors.toList());
List<CareerTag> careerTagList = CareerTagConverter.toCareerTagList(tagList);
careerTagList.forEach(careerTag -> careerTag.setCareerDetail(newCareerDetail));

return careerDetailRepository.save(newCareerDetail);


}


}
2 changes: 1 addition & 1 deletion src/test/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ spring.datasource.password=testPW
# spring jpa
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.format_sql=true


Expand Down

0 comments on commit 4d54cc6

Please sign in to comment.