Skip to content

Commit

Permalink
Merge pull request #12 from kduoh99/Feat/#11
Browse files Browse the repository at this point in the history
Feat: 팀 빌딩 정보 저장 구현
  • Loading branch information
kduoh99 authored Oct 31, 2024
2 parents 3c6a2fb + 11125b6 commit af91258
Show file tree
Hide file tree
Showing 19 changed files with 247 additions and 121 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.hackathon.momento.auth.api;

import com.hackathon.momento.auth.api.dto.AuthResDto;
import com.hackathon.momento.auth.api.dto.response.AuthResDto;
import com.hackathon.momento.global.oauth.KakaoOauthService;
import com.hackathon.momento.global.template.RspTemplate;
import io.swagger.v3.oas.annotations.Operation;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.hackathon.momento.auth.api.dto;
package com.hackathon.momento.auth.api.dto.response;

import lombok.Builder;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.hackathon.momento.global.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OpenAIConfig {

@Value("${openai.api.key}")
private String openAIKey;

@Bean
public RestTemplate template() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add((request, body, execution) -> {
request.getHeaders().add("Authorization", "Bearer " + openAIKey);
return execution.execute(request, body);
});
return restTemplate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public class SecurityConfig {
private final String[] PERMIT_ALL_URLS = {
"swagger-ui/**",
"v3/api-docs/**",
"profile",
"api/v1/auth/**",
"api/v1/member/**"
"/",
"/profile",
"/api/v1/**"
};

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hackathon.momento.auth.api.dto.AuthResDto;
import com.hackathon.momento.auth.api.dto.response.AuthResDto;
import com.hackathon.momento.auth.application.TokenRenewService;
import com.hackathon.momento.global.jwt.TokenProvider;
import com.hackathon.momento.global.oauth.exception.OauthException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.security.Principal;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -25,6 +24,8 @@
@Tag(name = "사용자 정보", description = "사용자 정보를 담당하는 API 그룹")
public class MemberController {

private static final Long TEMP_MEMBER_ID = 1L; // 테스트용 임시 사용자 ID

private final MemberService memberService;

@PutMapping("/complete-profile")
Expand All @@ -37,12 +38,11 @@ public class MemberController {
@ApiResponse(responseCode = "500", description = "서버 오류")
}
)
public RspTemplate<String> completeProfile(
Principal principal,
public RspTemplate<Void> completeProfile(
@Valid @RequestBody ProfileReqDto reqDto) {

memberService.completeProfile(principal, reqDto);
return new RspTemplate<>(HttpStatus.OK, "프로필 완성!");
memberService.completeProfile(TEMP_MEMBER_ID, reqDto);
return new RspTemplate<>(HttpStatus.OK, "프로필 완성 성공");
}

@GetMapping("/profile")
Expand All @@ -55,8 +55,8 @@ public RspTemplate<String> completeProfile(
@ApiResponse(responseCode = "500", description = "서버 오류")
}
)
public RspTemplate<ProfileResDto> getProfile(Principal principal) {
ProfileResDto profile = memberService.getProfile(principal);
public RspTemplate<ProfileResDto> getProfile() {
ProfileResDto profile = memberService.getProfile(TEMP_MEMBER_ID);
return new RspTemplate<>(HttpStatus.OK, "프로필 조회 성공", profile);
}

Expand All @@ -72,10 +72,9 @@ public RspTemplate<ProfileResDto> getProfile(Principal principal) {
}
)
public RspTemplate<ProfileResDto> updateProfile(
Principal principal,
@Valid @RequestBody UpdateProfileReqDto reqDto) {

ProfileResDto updatedProfile = memberService.updateProfile(principal, reqDto);
ProfileResDto updatedProfile = memberService.updateProfile(TEMP_MEMBER_ID, reqDto);
return new RspTemplate<>(HttpStatus.OK, "프로필 수정 성공", updatedProfile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.hackathon.momento.member.domain.repository.MemberRepository;
import com.hackathon.momento.member.exception.FirstLoginOnlyException;
import com.hackathon.momento.member.exception.MemberNotFoundException;
import java.security.Principal;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -20,8 +19,10 @@ public class MemberService {
private final MemberRepository memberRepository;

@Transactional
public void completeProfile(Principal principal, ProfileReqDto reqDto) {
Member member = getMemberByPrincipal(principal);
public void completeProfile(Long memberId, ProfileReqDto reqDto) {
// Member member = getMemberByPrincipal(principal);
Member member = memberRepository.findById(memberId)
.orElseThrow(MemberNotFoundException::new);

if (!member.isFirstLogin()) {
throw new FirstLoginOnlyException();
Expand All @@ -31,23 +32,27 @@ public void completeProfile(Principal principal, ProfileReqDto reqDto) {
memberRepository.save(member);
}

public ProfileResDto getProfile(Principal principal) {
Member member = getMemberByPrincipal(principal);
public ProfileResDto getProfile(Long memberId) {
// Member member = getMemberByPrincipal(principal);
Member member = memberRepository.findById(memberId)
.orElseThrow(MemberNotFoundException::new);

return ProfileResDto.from(member);
}

@Transactional
public ProfileResDto updateProfile(Principal principal, UpdateProfileReqDto reqDto) {
Member member = getMemberByPrincipal(principal);
member.updateProfile(reqDto.name(), reqDto.stack(), reqDto.persona(), reqDto.ability());
public ProfileResDto updateProfile(Long memberId, UpdateProfileReqDto reqDto) {
// Member member = getMemberByPrincipal(principal);
Member member = memberRepository.findById(memberId)
.orElseThrow(MemberNotFoundException::new);

member.updateProfile(reqDto.name(), reqDto.stack(), reqDto.persona(), reqDto.ability());
return ProfileResDto.from(member);
}

private Member getMemberByPrincipal(Principal principal) {
Long memberId = Long.parseLong(principal.getName());
return memberRepository.findById(memberId)
.orElseThrow(MemberNotFoundException::new);
}
// private Member getMemberByPrincipal(Principal principal) {
// Long memberId = Long.parseLong(principal.getName());
// return memberRepository.findById(memberId)
// .orElseThrow(MemberNotFoundException::new);
// }
}
44 changes: 44 additions & 0 deletions src/main/java/com/hackathon/momento/team/api/TeamController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.hackathon.momento.team.api;

import com.hackathon.momento.global.template.RspTemplate;
import com.hackathon.momento.team.api.dto.request.TeamBuildingReqDto;
import com.hackathon.momento.team.application.TeamService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/team")
@Tag(name = "팀", description = "팀을 담당하는 API 그룹")
public class TeamController {

private static final Long TEMP_MEMBER_ID = 1L; // 테스트용 임시 사용자 ID

private final TeamService teamService;

@PostMapping("/building")
@Operation(
summary = "팀 빌딩 정보 저장",
description = "사용자가 팀 빌딩을 위해 필요한 정보들을 입력합니다.",
responses = {
@ApiResponse(responseCode = "200", description = "팀 빌딩 정보 저장 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 요청"),
@ApiResponse(responseCode = "500", description = "서버 오류")
}
)
public RspTemplate<Void> saveTeamBuilding(
// Principal principal,
@Valid @RequestBody TeamBuildingReqDto reqDto) {

teamService.saveTeamBuilding(TEMP_MEMBER_ID, reqDto);
return new RspTemplate<>(HttpStatus.OK, "팀 빌딩 정보 저장 성공");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.hackathon.momento.team.api.dto.request;

import com.hackathon.momento.member.domain.Member;
import com.hackathon.momento.team.domain.Status;
import com.hackathon.momento.team.domain.TeamBuilding;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;

public record TeamBuildingReqDto(
@NotNull(message = "프로젝트 시작 날짜는 필수 입력 항목입니다")
@DateTimeFormat(pattern = "yyyy-MM-dd")
LocalDate startDate,

@NotNull(message = "프로젝트 종료 날짜는 필수 입력 항목입니다")
@DateTimeFormat(pattern = "yyyy-MM-dd")
LocalDate endDate,

@Min(value = 2, message = "팀 인원 수는 최소 2명이어야 합니다")
@Max(value = 6, message = "팀 인원 수는 최대 6명이어야 합니다")
int teamSize,

@NotBlank(message = "본인 포지션은 필수 입력 항목입니다")
String myPosition,

@NotBlank(message = "요구 포지션 조합은 필수 입력 항목입니다")
String positionCombination
) {
public TeamBuilding toEntity(Member member) {
return TeamBuilding.builder()
.startDate(this.startDate)
.endDate(this.endDate)
.teamSize(this.teamSize)
.myPosition(this.myPosition)
.positionCombination(this.positionCombination)
.status(Status.PENDING)
.member(member)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.hackathon.momento.team.application;

import com.hackathon.momento.member.domain.Member;
import com.hackathon.momento.member.domain.repository.MemberRepository;
import com.hackathon.momento.member.exception.MemberNotFoundException;
import com.hackathon.momento.team.api.dto.request.TeamBuildingReqDto;
import com.hackathon.momento.team.domain.Status;
import com.hackathon.momento.team.domain.repository.TeamBuildingRepository;
import com.hackathon.momento.team.exception.TeamBuildingConflictException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class TeamService {

private final TeamBuildingRepository teamBuildingRepository;
private final MemberRepository memberRepository;

@Transactional
public void saveTeamBuilding(Long memberId, TeamBuildingReqDto reqDto) {
// Long memberId = Long.parseLong(principal.getName());
Member member = memberRepository.findById(memberId)
.orElseThrow(MemberNotFoundException::new);

if (teamBuildingRepository.existsByMemberAndStatus(member, Status.PENDING)) {
throw new TeamBuildingConflictException();
}

teamBuildingRepository.save(reqDto.toEntity(member));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.hackathon.momento.team.domain;

public enum Status {
PENDING, COMPLETED
PENDING, RETRY, COMPLETED
}
24 changes: 21 additions & 3 deletions src/main/java/com/hackathon/momento/team/domain/TeamBuilding.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.hackathon.momento.team.domain;

import com.hackathon.momento.global.entity.BaseEntity;
import com.hackathon.momento.member.domain.Member;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import java.time.LocalDate;
import lombok.AccessLevel;
import lombok.Builder;
Expand All @@ -34,18 +38,32 @@ public class TeamBuilding extends BaseEntity {
private int teamSize;

@Column(nullable = false)
private String position;
private String myPosition;

@Column(nullable = false, length = 1024)
private String positionCombination;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Status status;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
private Member member;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_info_id")
private TeamInfo teamInfo;

@Builder
private TeamBuilding(LocalDate startDate, LocalDate endDate, int teamSize, String position, Status status) {
private TeamBuilding(LocalDate startDate, LocalDate endDate, int teamSize, String myPosition,
String positionCombination, Status status, Member member) {
this.startDate = startDate;
this.endDate = endDate;
this.teamSize = teamSize;
this.position = position;
this.myPosition = myPosition;
this.positionCombination = positionCombination;
this.status = status;
this.member = member;
}
}
Loading

0 comments on commit af91258

Please sign in to comment.