Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import com.brainpix.api.ApiResponse;
import com.brainpix.api.CommonPageResponse;
import com.brainpix.api.swagger.SwaggerPageable;
import com.brainpix.profile.dto.CreatePortfolioDto;
import com.brainpix.profile.dto.request.PortfolioRequest;
import com.brainpix.profile.dto.response.PortfolioDetailResponse;
Expand All @@ -26,6 +27,7 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
Expand All @@ -41,7 +43,7 @@ public class PortfolioController {
@PostMapping
public ResponseEntity<ApiResponse<CreatePortfolioDto.Response>> createPortfolio(
@UserId Long userId,
@RequestBody PortfolioRequest request
@Valid @RequestBody PortfolioRequest request
) {
Long portfolioId = portfolioService.createPortfolio(userId, request);

Expand All @@ -55,7 +57,7 @@ public ResponseEntity<ApiResponse<CreatePortfolioDto.Response>> createPortfolio(
public ResponseEntity<ApiResponse<Void>> updatePortfolio(
@UserId Long userId,
@PathVariable long portfolioId,
@RequestBody PortfolioRequest request
@Valid @RequestBody PortfolioRequest request
) {
try {
portfolioService.updatePortfolio(userId, portfolioId, request);
Expand All @@ -79,6 +81,7 @@ public ResponseEntity<ApiResponse<Void>> deletePortfolio(
@AllUser
@Operation(summary = "내 포트폴리오 목록 조회", description = "사용자 ID를 기준으로 포트폴리오 목록을 페이징 처리하여 조회합니다.")
@GetMapping
@SwaggerPageable
public ResponseEntity<CommonPageResponse<PortfolioResponse>> findMyPortfolios(
@UserId Long userId,
@PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,33 @@

import java.time.YearMonth;
import java.util.List;
import java.util.Optional;

import org.springframework.format.annotation.DateTimeFormat;

import com.brainpix.profile.entity.Portfolio;
import com.brainpix.profile.entity.Profile;
import com.brainpix.profile.entity.Specialization;
import com.fasterxml.jackson.annotation.JsonFormat;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

public record PortfolioRequest(
@NotBlank(message = "포트폴리오 제목을 입력해주세요.")
String title,
List<SpecializationRequest> specializations,
List<Specialization> specializations,
@NotBlank(message = "시작 날짜를 입력해주세요.")
@Schema(type = "string", example = "yyyy-MM")
@DateTimeFormat(pattern = "yyyy-MM")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM")
YearMonth startDate,
@NotBlank(message = "종료 날짜를 입력해주세요.")
@Schema(type = "string", example = "yyyy-MM")
@DateTimeFormat(pattern = "yyyy-MM")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM")
YearMonth endDate,
@NotBlank(message = "포트폴리오 내용을 입력해주세요.")
String content,
String profileImage
) {
Expand All @@ -23,14 +37,11 @@ public record PortfolioRequest(
* DTO -> Entity 변환 (생성 시 사용)
*/
public Portfolio toEntity(Profile profile) {
List<Specialization> specs = specializations.stream()
.map(SpecializationRequest::toDomain)
.toList();

return Portfolio.create(
profile,
title,
specs,
specializations,
startDate,
endDate,
content,
Expand All @@ -42,17 +53,14 @@ public Portfolio toEntity(Profile profile) {
* 엔티티 수정에 반영할 메서드 (update)
*/
public void applyTo(Portfolio portfolio) {
List<Specialization> specs = specializations.stream()
.map(SpecializationRequest::toDomain)
.toList();

portfolio.update(
title,
specs,
startDate,
endDate,
content,
profileImage
Optional.ofNullable(title).orElse(portfolio.getTitle()), // null이면 기존 값 유지
Optional.ofNullable(specializations).orElse(portfolio.getSpecializationList()), // null이면 기존 값 유지
Optional.ofNullable(startDate).orElse(portfolio.getStartDate()),
Optional.ofNullable(endDate).orElse(portfolio.getEndDate()),
Optional.ofNullable(content).orElse(portfolio.getContent()),
Optional.ofNullable(profileImage).orElse(portfolio.getProfileImage())
);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package com.brainpix.profile.dto.request;

import com.brainpix.api.code.error.CommonErrorCode;
import com.brainpix.api.exception.BrainPixException;
import com.brainpix.profile.entity.Specialization;

public record SpecializationRequest(String specialization) {
import jakarta.validation.constraints.NotNull;

public Specialization toDomain() {
if (specialization == null || specialization.trim().isEmpty()) {
throw new BrainPixException(CommonErrorCode.RESOURCE_NOT_FOUND);
}
public record SpecializationRequest(@NotNull(message = "전문 분야는 필수 입력값입니다.") Specialization specialization) {

try {
return Specialization.of(specialization);
} catch (BrainPixException e) {
throw new BrainPixException(CommonErrorCode.RESOURCE_NOT_FOUND);
}
public Specialization toDomain() {
return specialization;
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
package com.brainpix.profile.dto.response;

import java.time.YearMonth;
import java.util.List;

import org.springframework.format.annotation.DateTimeFormat;

import com.brainpix.profile.entity.Portfolio;
import com.brainpix.profile.entity.Specialization;
import com.fasterxml.jackson.annotation.JsonFormat;

import io.swagger.v3.oas.annotations.media.Schema;

public record PortfolioDetailResponse(
long id,
String title,
List<String> specializations,
String startDate,
String endDate,
List<Specialization> specializations,
@Schema(type = "string", example = "yyyy-MM")
@DateTimeFormat(pattern = "yyyy-MM")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM")
YearMonth startDate,

@Schema(type = "string", example = "yyyy-MM")
@DateTimeFormat(pattern = "yyyy-MM")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM")
YearMonth endDate,
String content,
String profileImage
) {
public static PortfolioDetailResponse of(Portfolio portfolio) {
List<String> specs = portfolio.getSpecializationList().stream()
.map(Enum::name)
.toList();
List<Specialization> specs = portfolio.getSpecializationList();

return new PortfolioDetailResponse(
portfolio.getId(),
portfolio.getTitle(),
specs,
portfolio.getStartDate().toString(),
portfolio.getEndDate().toString(),
portfolio.getStartDate(),
portfolio.getEndDate(),
portfolio.getContent(),
portfolio.getProfileImage()
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package com.brainpix.profile.dto.response;

import java.time.LocalDateTime;
import java.time.LocalDate;

import com.brainpix.profile.entity.Portfolio;

public record PortfolioResponse(long id,
String title,
LocalDateTime createdDate,
LocalDate createdDate,
String profileImage
) {

public static PortfolioResponse from(Portfolio portfolio) {
return new PortfolioResponse(
portfolio.getId(),
portfolio.getTitle(),
portfolio.getCreatedAt(),
portfolio.getCreatedAt().toLocalDate(),
portfolio.getProfileImage()
);
}
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/com/brainpix/profile/entity/Portfolio.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.List;

import com.brainpix.api.code.error.PortfolioErrorCode;
import com.brainpix.api.exception.BrainPixException;
import com.brainpix.jpa.BaseTimeEntity;
import com.brainpix.user.entity.User;

Expand Down Expand Up @@ -83,9 +84,7 @@ public void update(String title, List<Specialization> specializationList, YearMo

public void validateOwnership(User user) {
if (!this.profile.getUser().equals(user)) {
throw new IllegalArgumentException(
PortfolioErrorCode.NOT_OWNED_PORTFOLIO.getMessage()
);
throw new BrainPixException(PortfolioErrorCode.NOT_OWNED_PORTFOLIO);
}
}
}
12 changes: 0 additions & 12 deletions src/main/java/com/brainpix/profile/entity/Specialization.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,4 @@ public enum Specialization {
IT_TECH, // IT · 테크
OTHERS; //기타

public static Specialization of(String name) {
if (name == null) {
throw new IllegalArgumentException("Specialization cannot be null.");
}
try {
// valueOf로 매칭된 enum 반환
return Specialization.valueOf(name.toUpperCase());
} catch (IllegalArgumentException e) {
// 그 외 값은 예외 발생
throw new IllegalArgumentException("Invalid Specialization: " + name);
}
}
}