Skip to content

Commit

Permalink
#274 Feat: 팀 프로젝트 생성 API
Browse files Browse the repository at this point in the history
  • Loading branch information
yumzen committed Nov 21, 2024
1 parent ef78270 commit 6057846
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static List<MemberResponseDTO.SimpleMemberDTO> toSimpleFollowResponseDto(
.collect(Collectors.toList());
}

public static MemberResponseDTO.SimpleMemberProfileDTO tosimpleMemberProfileResponseDto(Member member) {
public static MemberResponseDTO.SimpleMemberProfileDTO toSimpleMemberProfileResponseDto(Member member) {
return MemberResponseDTO.SimpleMemberProfileDTO.builder()
.userId(member.getMemberId())
.userName(member.getNickname())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.codiary.backend.domain.coauthor.entity.Authors;
import com.codiary.backend.domain.comment.entity.Comment;
import com.codiary.backend.domain.project.entity.Project;
import com.codiary.backend.domain.member.dto.request.MemberRequestDTO;
import com.codiary.backend.domain.member.enumerate.MemberState;
import com.codiary.backend.domain.post.entity.Bookmark;
Expand Down Expand Up @@ -78,7 +79,7 @@ public enum Gender {Male, Female}
private List<Authors> authorsList = new ArrayList<>();

@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<MemberProjectMap> memberProjectMapList = new ArrayList<>();
private List<Project> projectList = new ArrayList<>();

@OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Comment> commentList = new ArrayList<>();
Expand Down Expand Up @@ -127,15 +128,7 @@ public void setImage(MemberImage image) {
this.image = image;
}

public void setMemberProjectMapList(List<MemberProjectMap> projects) {
this.memberProjectMapList = projects;
}

public void setTeamMemberList(List<TeamMember> teamMembers) {
this.teamMemberList = teamMembers;
}

public void addProject(MemberProjectMap memberProjectMap) {
memberProjectMapList.add(memberProjectMap);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.codiary.backend.domain.member.repository;

import com.codiary.backend.domain.member.entity.Member;
import com.codiary.backend.domain.member.entity.MemberProjectMap;
import com.codiary.backend.domain.team.entity.TeamMember;
import com.codiary.backend.domain.project.entity.Project;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;

Expand All @@ -13,7 +13,6 @@
import static com.codiary.backend.domain.member.entity.QMember.member;
import static com.codiary.backend.domain.member.entity.QMemberCategory.memberCategory;
import static com.codiary.backend.domain.techstack.entity.QTechStacks.techStacks;
import static com.codiary.backend.domain.member.entity.QMemberProjectMap.memberProjectMap;
import static com.codiary.backend.domain.project.entity.QProject.project;
import static com.codiary.backend.domain.team.entity.QTeamMember.teamMember;
import static com.codiary.backend.domain.team.entity.QTeam.team;
Expand Down Expand Up @@ -88,13 +87,12 @@ public Optional<Member> findByIdWithFollowers(Long id) {
}

private void fetchMemberProjects(Long userId, Member fetchedMember) {
List<MemberProjectMap> projects = queryFactory
.selectFrom(memberProjectMap)
.leftJoin(memberProjectMap.project, project)
.where(memberProjectMap.member.memberId.eq(userId))
List<Project> projects = queryFactory
.selectFrom(project)
.leftJoin(member.projectList, project)
.where(member.memberId.eq(userId)
.and(project.deletedAt.isNull()))
.fetch();

fetchedMember.setMemberProjectMapList(projects);
}

private void fetchTeamMembers(Long userId, Member fetchedMember) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ public ApiResponse<List<ProjectResponseDTO.SimpleProjectResponseDTO>> getMyProje
return ApiResponse.onSuccess(SuccessStatus.PROJECT_OK, ProjectConverter.toSimpleProjectListResponseDTO(projects));
}

@Operation(summary = "팀 프로젝트 생성", description = "팀 프로젝트를 생성합니다.")
@PostMapping("/create/team/{team_id}/{project_name}")
public ApiResponse<ProjectResponseDTO.SimpleProjectResponseDTO> createTeamProject(@AuthenticationPrincipal CustomMemberDetails memberDetails,
@PathVariable("team_id") Long teamId,
@PathVariable("project_name") String projectName) {
Project project = projectService.createTeamProject(memberDetails.getId(), teamId, projectName);
return ApiResponse.onSuccess(SuccessStatus.PROJECT_OK, ProjectConverter.toSimpleProjectResponseDTO(project));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@

public class ProjectConverter {
public static ProjectResponseDTO.ProjectDetailResponseDTO toProjectDetailResponseDTO(Project project) {
Boolean isTeam = project.getTeam() != null;
return ProjectResponseDTO.ProjectDetailResponseDTO.builder()
.projectId(project.getProjectId())
.name(project.getProjectName())
.members(project.getMemberProjectMaps().stream()
.map(memberProjectMap -> MemberConverter.tosimpleMemberProfileResponseDto(memberProjectMap.getMember()))
.collect(Collectors.toList()))
.isTeam(isTeam)
.projectMembers(
isTeam
? project.getTeam().getTeamMemberList().stream()
.map(teamMember -> MemberConverter.toSimpleMemberProfileResponseDto(teamMember.getMember()))
.collect(Collectors.toList())
: List.of(MemberConverter.toSimpleMemberProfileResponseDto(project.getMember()))
)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public record SimpleProjectResponseDTO(
public record ProjectDetailResponseDTO(
Long projectId,
String name,
List<MemberResponseDTO.SimpleMemberProfileDTO> members
Boolean isTeam,
List<MemberResponseDTO.SimpleMemberProfileDTO> projectMembers
) {
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package com.codiary.backend.domain.project.entity;

import com.codiary.backend.domain.member.entity.MemberProjectMap;
import com.codiary.backend.domain.member.entity.Member;
import com.codiary.backend.domain.post.entity.Post;
import com.codiary.backend.domain.team.entity.Team;
import com.codiary.backend.global.common.BaseEntity;
import jakarta.persistence.*;
import lombok.*;
Expand All @@ -25,13 +26,20 @@ public class Project extends BaseEntity {
private String projectName;

@OneToMany(mappedBy = "project")
private List<MemberProjectMap> memberProjectMaps = new ArrayList<>();
private List<Post> posts = new ArrayList<>();

@OneToMany(mappedBy = "project")
private List<Post> posts = new ArrayList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;

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

@Builder
public Project(String projectName) {
public Project(Team team, Member member, String projectName) {
this.team = team;
this.member = member;
this.projectName = projectName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import static com.codiary.backend.domain.post.entity.QPost.post;
import static com.codiary.backend.domain.project.entity.QProject.project;
import static com.codiary.backend.domain.team.entity.QTeam.team;
import static com.codiary.backend.domain.team.entity.QTeamMember.teamMember;

@RequiredArgsConstructor
public class ProjectRepositoryImpl implements ProjectRepositoryCustom {
Expand All @@ -40,8 +42,17 @@ public Map<LocalDate, List<Project>> findProjectsForCalendar(Long memberId, Loca
public List<Project> findByMemberProjectMapsMember(Member member) {
return queryFactory
.selectFrom(project)
.leftJoin(project.memberProjectMaps).fetchJoin()
.where(project.memberProjectMaps.any().member.eq(member))
.leftJoin(project.member)
.leftJoin(project.team, team)
.leftJoin(team.teamMemberList, teamMember)
.where(
project.member.eq(member)
.and(project.deletedAt.isNull())
.or(
team.teamMemberList.any().member.eq(member)
.and(team.deletedAt.isNull())
)
)
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.codiary.backend.domain.project.service;

import com.codiary.backend.domain.member.entity.Member;
import com.codiary.backend.domain.member.entity.MemberProjectMap;
import com.codiary.backend.domain.project.entity.Project;
import com.codiary.backend.domain.member.repository.MemberRepository;
import com.codiary.backend.domain.project.repository.ProjectRepository;
import com.codiary.backend.domain.team.entity.Team;
import com.codiary.backend.domain.team.repository.TeamRepository;
import com.codiary.backend.global.apiPayload.code.status.ErrorStatus;
import com.codiary.backend.global.apiPayload.exception.GeneralException;
import lombok.RequiredArgsConstructor;
Expand All @@ -19,34 +20,28 @@
public class ProjectService {
private final ProjectRepository projectRepository;
private final MemberRepository memberRepository;
private final TeamRepository teamRepository;

@Transactional
public Project createPersonalProject(Long memberId, String projectName) {
//validation
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));
Project project = projectRepository.findByProjectNameAndDeletedAtIsNull(projectName)
Project existingProject = projectRepository.findByProjectNameAndDeletedAtIsNull(projectName)
.orElse(null);

//business
if (project != null) { // 프로젝트 이름 중복 확인
// business
if (existingProject != null) { // 프로젝트 이름 중복 확인
throw new GeneralException(ErrorStatus.PROJECT_ALREADY_EXISTS);
} else {
project = Project.builder()
Project project = Project.builder()
.projectName(projectName)
.build();
projectRepository.save(project);

MemberProjectMap memberProjectMap = MemberProjectMap.builder()
.team(null)
.member(member)
.project(project)
.build();

member.addProject(memberProjectMap);
projectRepository.save(project);
return project;
}

//return
return project;
}

public List<Project> getMyProject(Long id) {
Expand All @@ -57,4 +52,34 @@ public List<Project> getMyProject(Long id) {
//return
return projectRepository.findByMemberProjectMapsMember(member);
}

@Transactional
public Project createTeamProject(Long id, Long teamId, String projectName) {
// validation
Member member = memberRepository.findById(id)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));

Team team = teamRepository.findByTeamIdAndDeletedAtIsNull(teamId)
.orElseThrow(() -> new GeneralException(ErrorStatus.TEAM_NOT_FOUND));

if (teamRepository.isTeamMember(team, member)) {
throw new GeneralException(ErrorStatus.TEAM_MEMBER_ONLY_ACCESS);
}

Project existingProject = projectRepository.findByProjectNameAndDeletedAtIsNull(projectName)
.orElse(null);

// business
if (existingProject != null) { // 프로젝트 이름 중복 확인
throw new GeneralException(ErrorStatus.PROJECT_ALREADY_EXISTS);
} else {
Project project = Project.builder()
.projectName(projectName)
.team(team)
.member(member)
.build();
projectRepository.save(project);
return project;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public static TeamResponseDTO.TeamFollowersDTO toTeamFollowersResponseDTO(Long t
public static TeamResponseDTO.TeamMemberDTO toTeamMemberResponseDTO(TeamMember teamMember){
return TeamResponseDTO.TeamMemberDTO.builder()
.teamMemberId(teamMember.getTeamMemberId())
.member(MemberConverter.tosimpleMemberProfileResponseDto(teamMember.getMember()))
.member(MemberConverter.toSimpleMemberProfileResponseDto(teamMember.getMember()))
.teamMemberRole(teamMember.getTeamMemberRole().name())
.teamMemberPosition(teamMember.getMemberPosition())
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.codiary.backend.domain.team.entity;

import com.codiary.backend.domain.post.entity.Post;
import com.codiary.backend.domain.project.entity.Project;
import com.codiary.backend.domain.team.dto.request.TeamRequestDTO;
import com.codiary.backend.global.common.BaseEntity;
import jakarta.persistence.CascadeType;
Expand Down Expand Up @@ -51,7 +52,7 @@ public class Team extends BaseEntity {
private String instagram;

@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
private List<TeamProjectMap> teamProjectMapList = new ArrayList<>();
private List<Project> projectList = new ArrayList<>();

@OneToMany(mappedBy = "team", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> postList = new ArrayList<>();
Expand All @@ -69,7 +70,7 @@ public class Team extends BaseEntity {
private TeamProfileImage profileImage;

@Builder
public Team(Long teamId, String name, String intro, String github, String email, String linkedin, String discord, String instagram, List<TeamProjectMap> teamProjectMapList, List<Post> postList, List<TeamMember> teamMemberList, List<TeamFollow> followers, TeamBannerImage bannerImage, TeamProfileImage profileImage) {
public Team(Long teamId, String name, String intro, String github, String email, String linkedin, String discord, String instagram, List<Post> postList, List<TeamMember> teamMemberList, List<TeamFollow> followers, TeamBannerImage bannerImage, TeamProfileImage profileImage) {
this.teamId = teamId;
this.name = name;
this.intro = intro;
Expand All @@ -78,7 +79,6 @@ public Team(Long teamId, String name, String intro, String github, String email,
this.linkedin = linkedin;
this.discord = discord;
this.instagram = instagram;
this.teamProjectMapList = teamProjectMapList;
this.postList = postList;
this.teamMemberList = teamMemberList;
this.followers = followers;
Expand Down

This file was deleted.

0 comments on commit 6057846

Please sign in to comment.