Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 팀 탈퇴 기능 구현 #181

Merged
merged 19 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/java/com/tiki/server/note/adapter/NoteFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public List<Note> findByCreatedAtAfterOrderByModifiedAtAsc(final LocalDateTime c
return noteRepository.findByCreatedAtAfterOrderByModifiedAtAsc(createdAt, pageRequest);
}

public List<Note> findAllByMemberIdAndTeamId(final long memberId, final long teamId) {
return noteRepository.findAllByMemberIdAndTeamId(memberId, teamId);
}

public Note findById(final long noteId) {
return noteRepository.findById(noteId)
.orElseThrow(() -> new NoteException(INVALID_NOTE));
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/tiki/server/note/entity/Note.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public void updateValue(
this.noteType = noteType;
}

public void deleteMemberDependency(){
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
this.memberId = null;
}

private void checkAuthor(final long clientId) {
if (this.memberId != clientId) {
throw new NoteException(UPDATE_ONLY_AUTHOR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ public interface NoteRepository extends JpaRepository<Note, Long> {

@Query("SELECT n FROM Note n WHERE n.createdAt > :createdAt ORDER BY n.createdAt ASC")
List<Note> findByCreatedAtAfterOrderByModifiedAtAsc(@Param("createdAt") LocalDateTime createdAt, Pageable pageable);

List<Note> findAllByMemberIdAndTeamId(long memberId, long TeamId);
}
21 changes: 21 additions & 0 deletions src/main/java/com/tiki/server/team/controller/TeamController.java
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,27 @@ public ResponseEntity<SuccessResponse<CategoriesGetResponse>> getCategories() {
return ResponseEntity.ok().body(success(SUCCESS_GET_CATEGORIES.getMessage(), response));
}

@DeleteMapping("/{teamId}/members/{kickOutMemberId}")
public ResponseEntity<BaseResponse> kickOutMemberFromTeam(
Principal principal,
@PathVariable long teamId,
@PathVariable long kickOutMemberId
){
long memberId = Long.parseLong(principal.getName());
teamService.kickOutMemberFromTeam(memberId, teamId, kickOutMemberId);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{teamId}/leave")
public ResponseEntity<BaseResponse> leaveTeam(
Principal principal,
@PathVariable long teamId
){
long memberId = Long.parseLong(principal.getName());
teamService.leaveTeam(memberId, teamId);
return ResponseEntity.noContent().build();
}

@DeleteMapping("/{teamId}")
public ResponseEntity<BaseResponse> deleteTeam(
Principal principal,
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/com/tiki/server/team/message/ErrorCode.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package com.tiki.server.team.message;

import static org.springframework.http.HttpStatus.FORBIDDEN;
import static org.springframework.http.HttpStatus.NOT_FOUND;

import org.springframework.http.HttpStatus;

import lombok.AllArgsConstructor;
import lombok.Getter;

import static org.springframework.http.HttpStatus.*;

@Getter
@AllArgsConstructor
public enum ErrorCode {

/* 400 BAD_REQUEST : 잘못된 요청 */
TOO_HIGH_AUTHORIZATION(BAD_REQUEST, "어드민은 진행할 수 없습니다."),

/* 403 FORBIDDEN : 권한 없음 */
INVALID_AUTHORIZATION_DELETE(FORBIDDEN, "팀 삭제에 대한 권한이 없습니다."),
INVALID_AUTHORIZATION_DELETE(FORBIDDEN, "권한이 없습니다."),

/* 404 NOT_FOUND : 자원을 찾을 수 없음 */
INVALID_TEAM(NOT_FOUND, "유효하지 않은 단체입니다.");
Expand Down
146 changes: 89 additions & 57 deletions src/main/java/com/tiki/server/team/service/TeamService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@

import static com.tiki.server.common.entity.Position.ADMIN;
import static com.tiki.server.team.message.ErrorCode.INVALID_AUTHORIZATION_DELETE;
import static com.tiki.server.team.message.ErrorCode.TOO_HIGH_AUTHORIZATION;

import java.util.List;
import java.util.Optional;

import com.tiki.server.document.adapter.DocumentDeleter;
import com.tiki.server.document.adapter.DocumentFinder;
import com.tiki.server.document.entity.Document;
import com.tiki.server.memberteammanager.adapter.MemberTeamManagerDeleter;
import com.tiki.server.memberteammanager.adapter.MemberTeamManagerFinder;
import com.tiki.server.note.adapter.NoteFinder;
import com.tiki.server.note.entity.Note;
import com.tiki.server.team.adapter.TeamDeleter;
import com.tiki.server.team.adapter.TeamFinder;
import com.tiki.server.team.dto.response.CategoriesGetResponse;
Expand Down Expand Up @@ -40,61 +44,89 @@
@Transactional(readOnly = true)
public class TeamService {

private final TeamSaver teamSaver;
private final TeamFinder teamFinder;
private final TeamDeleter teamDeleter;
private final MemberFinder memberFinder;
private final DocumentFinder documentFinder;
private final DocumentDeleter documentDeleter;
private final TimeBlockDeleter timeBlockDeleter;
private final MemberTeamManagerFinder memberTeamManagerFinder;
private final MemberTeamManagerDeleter memberTeamManagerDeleter;
private final MemberTeamManagerSaver memberTeamManagerSaver;

@Transactional
public TeamCreateResponse createTeam(long memberId, TeamCreateRequest request) {
Member member = memberFinder.findById(memberId);
Team team = teamSaver.save(createTeam(request, member.getUniv()));
memberTeamManagerSaver.save(createMemberTeamManager(member, team, ADMIN));
return TeamCreateResponse.from(team);
}

public TeamsGetResponse getAllTeams(long memberId) {
Member member = memberFinder.findById(memberId);
University univ = member.getUniv();
List<TeamVO> team = teamFinder.findAllByUniv(univ);
return TeamsGetResponse.from(team);
}

public CategoriesGetResponse getCategories() {
Category[] categories = Category.values();
return CategoriesGetResponse.from(categories);
}

@Transactional
public void deleteTeam(long memberId, long teamId) {
checkIsAdmin(memberId, teamId);
List<MemberTeamManager> memberTeamManagers = memberTeamManagerFinder.findAllByTeamId(teamId);
memberTeamManagerDeleter.deleteAll(memberTeamManagers);
List<Document> documents = documentFinder.findAllByTeamId(teamId);
documentDeleter.deleteAll(documents);
timeBlockDeleter.deleteAllByTeamId(teamId);
teamDeleter.deleteById(teamId);
}

private Team createTeam(TeamCreateRequest request, University univ) {
return Team.of(request, univ);
}

private MemberTeamManager createMemberTeamManager(Member member, Team team, Position position) {
return MemberTeamManager.of(member, team, position);
}

private void checkIsAdmin(long memberId, long teamId) {
MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamIdOrElseThrow(memberId, teamId);
if (!memberTeamManager.getPosition().equals(ADMIN)) {
throw new TeamException(INVALID_AUTHORIZATION_DELETE);
}
memberTeamManagerDeleter.delete(memberTeamManager);
}
private final TeamSaver teamSaver;
private final TeamFinder teamFinder;
private final TeamDeleter teamDeleter;
private final MemberFinder memberFinder;
private final NoteFinder noteFinder;
private final DocumentFinder documentFinder;
private final DocumentDeleter documentDeleter;
private final TimeBlockDeleter timeBlockDeleter;
private final MemberTeamManagerFinder memberTeamManagerFinder;
private final MemberTeamManagerDeleter memberTeamManagerDeleter;
private final MemberTeamManagerSaver memberTeamManagerSaver;

@Transactional
public TeamCreateResponse createTeam(final long memberId, final TeamCreateRequest request) {
Member member = memberFinder.findById(memberId);
Team team = teamSaver.save(createTeam(request, member.getUniv()));
memberTeamManagerSaver.save(createMemberTeamManager(member, team, ADMIN));
return TeamCreateResponse.from(team);
}

public TeamsGetResponse getAllTeams(final long memberId) {
Member member = memberFinder.findById(memberId);
University univ = member.getUniv();
List<TeamVO> team = teamFinder.findAllByUniv(univ);
return TeamsGetResponse.from(team);
}

public CategoriesGetResponse getCategories() {
Category[] categories = Category.values();
return CategoriesGetResponse.from(categories);
}

@Transactional
public void deleteTeam(final long memberId, final long teamId) {
checkIsAdmin(memberId, teamId);
List<MemberTeamManager> memberTeamManagers = memberTeamManagerFinder.findAllByTeamId(teamId);
memberTeamManagerDeleter.deleteAll(memberTeamManagers);
List<Document> documents = documentFinder.findAllByTeamId(teamId);
documentDeleter.deleteAll(documents);
timeBlockDeleter.deleteAllByTeamId(teamId);
teamDeleter.deleteById(teamId);
}

@Transactional
public void kickOutMemberFromTeam(final long memberId, final long teamId, final long kickOutMemberId) {
checkIsAdmin(memberId, teamId);
Optional<MemberTeamManager> memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(kickOutMemberId, teamId);
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
deleteNoteDependency(memberId, teamId);
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
memberTeamManager.ifPresent(memberTeamManagerDeleter::delete);
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
}

@Transactional
public void leaveTeam(final long memberId, final long teamId) {
MemberTeamManager memberTeamManager = checkIsNotAdmin(memberId, teamId);
deleteNoteDependency(memberId, teamId);
memberTeamManagerDeleter.delete(memberTeamManager);
}

private void deleteNoteDependency(final long memberId, final long teamId) {
List<Note> notes = noteFinder.findAllByMemberIdAndTeamId(memberId, teamId);
notes.forEach(Note::deleteMemberDependency);
}

private Team createTeam(final TeamCreateRequest request, final University univ) {
return Team.of(request, univ);
}

private MemberTeamManager createMemberTeamManager(final Member member, final Team team, final Position position) {
return MemberTeamManager.of(member, team, position);
}

private void checkIsAdmin(final long memberId, final long teamId) {
MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamIdOrElseThrow(memberId, teamId);
if (!memberTeamManager.getPosition().equals(ADMIN)) {
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
throw new TeamException(INVALID_AUTHORIZATION_DELETE);
}
}

private MemberTeamManager checkIsNotAdmin(final long memberId, final long teamId) {
MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamIdOrElseThrow(memberId, teamId);
if (memberTeamManager.getPosition().equals(ADMIN)) {
throw new TeamException(TOO_HIGH_AUTHORIZATION);
Chan531 marked this conversation as resolved.
Show resolved Hide resolved
}
return memberTeamManager;
}
}