Skip to content

Commit

Permalink
feat: add api of reading a workspace result
Browse files Browse the repository at this point in the history
- add method to drawing a winner and a loser of workspace
  • Loading branch information
aiaiaiai1 committed Jan 7, 2025
1 parent 8164065 commit b90a641
Show file tree
Hide file tree
Showing 12 changed files with 337 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public enum ErrorCode {
NOT_CONSISTENT_WORKERS_COUNT("워크스페이스 인원이 잘못 되었습니다.", 500),
NOT_CONSISTENT_MISSIONS_COUNT("미션 수가 잘못 되었습니다.", 500),
ALREADY_ACTIVATED_WORKSPACE("이미 진행중이거나 종료된 워크스페이스 입니다.", 400),
NOT_COMPLETED_WORKSPACE("종료되지 않은 워크스페이스 입니다.", 400),
EXIST_WORKERS_EXCLUDE_CREATOR("방장 이외에 참여자가 존재합니다.", 400),
BELOW_MINIMUM_WORKER("최소 인원인 2명을 채워주세요.", 400),
EXCEED_MAX_JOINED_WORKSPACE("워크스페이스는 5개까지 참여 가능합니다.(완료된 워크스페이스 제외)", 400),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,13 @@ public ResponseEntity<List<ObjectionAlarmResponse>> terminateObjections(
return ResponseEntity.ok().build();
}

@GetMapping("/workspaces/{workspaceId}/result")
public ResponseEntity<List<ObjectionAlarmResponse>> readWorkspaceResult(
@Logined User user,
@PathVariable Long workspaceId
) {
workspaceCommandService.getWorkspaceResult(user, workspaceId);
return ResponseEntity.ok().build();
}

}
47 changes: 47 additions & 0 deletions src/main/java/gymmi/workspace/domain/WorkspaceDrawManger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package gymmi.workspace.domain;

import gymmi.exceptionhandler.exception.InvalidStateException;
import gymmi.exceptionhandler.message.ErrorCode;
import gymmi.workspace.domain.entity.Worker;
import gymmi.workspace.domain.entity.Workspace;
import gymmi.workspace.domain.entity.WorkspaceResult;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class WorkspaceDrawManger {

private final List<Worker> workers;
private final Workspace workspace;

public WorkspaceDrawManger(Workspace workspace, List<Worker> workers) {
if (!workspace.isCompleted()) {
throw new InvalidStateException(ErrorCode.NOT_COMPLETED_WORKSPACE);
}
this.workers = new ArrayList<>(workers);
this.workspace = workspace;
workers.sort(Comparator.comparing(Worker::getContributedScore).reversed());
}

public WorkspaceResult draw() {
Worker first = workers.get(0);
Worker last = workers.get(workers.size() - 1);
Worker winner = pickOneInTie(first);
Worker loser = pickOneInTie(last);
WorkspaceResult workspaceResult = new WorkspaceResult(workspace, winner, loser);
workspace.changeStatusTo(WorkspaceStatus.FULLY_COMPLETED);
return workspaceResult;
}

private Worker pickOneInTie(Worker worker) {
List<Worker> tieWorkers = workers.stream()
.filter(w -> w.isTie(worker))
.collect(Collectors.toList());
Collections.shuffle(tieWorkers);
return tieWorkers.get(0);
}

}
31 changes: 14 additions & 17 deletions src/main/java/gymmi/workspace/domain/entity/Worker.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,8 @@

import gymmi.entity.TimeEntity;
import gymmi.entity.User;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
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 jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.UniqueConstraint;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
Expand Down Expand Up @@ -64,4 +49,16 @@ public boolean isJoinedIn(Workspace workspace) {
public String getNickname() {
return user.getNickname();
}

public boolean isTie(Worker worker) {
return this.contributedScore.equals(worker.getContributedScore());
}

@Override
public String toString() {
return "Worker{" +
"id=" + id +
", contributedScore=" + contributedScore +
'}';
}
}
38 changes: 38 additions & 0 deletions src/main/java/gymmi/workspace/domain/entity/WorkspaceResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package gymmi.workspace.domain.entity;

import gymmi.exceptionhandler.exception.InvalidRangeException;
import gymmi.exceptionhandler.exception.NotHavePermissionException;
import gymmi.exceptionhandler.message.ErrorCode;
import gymmi.workspace.domain.entity.Worker;
import gymmi.workspace.domain.entity.Workspace;
import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(of = {"id"})
public class WorkspaceResult {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@JoinColumn(name = "workspace_id", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
private Workspace workspace;

@JoinColumn(name = "winner_id", nullable = false)
@ManyToOne(fetch = FetchType.EAGER)
private Worker winner;

@JoinColumn(name = "loser_id", nullable = false)
@ManyToOne(fetch = FetchType.EAGER)
private Worker loser;

public WorkspaceResult(Workspace workspace, Worker winner, Worker loser) {
this.workspace = workspace;
this.winner = winner;
this.loser = loser;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gymmi.workspace.repository;

import gymmi.exceptionhandler.legacy.NotFoundResourcesException;
import gymmi.workspace.domain.entity.WorkspaceResult;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.Optional;

public interface WorkspaceResultRepository extends JpaRepository<WorkspaceResult, Long> {

default WorkspaceResult getByWorkspaceId(Long workspaceId) {
WorkspaceResult workspaceResult = findByWorkspaceId(workspaceId)
.orElseThrow(() -> new NotFoundResourcesException("해당 결과가 존재하지 않아요."));
return workspaceResult;
}

@Query("select w from WorkspaceResult w where w.workspace.id =:workspaceId")
Optional<WorkspaceResult> findByWorkspaceId(Long workspaceId);
}
21 changes: 21 additions & 0 deletions src/main/java/gymmi/workspace/response/WorkerResultResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gymmi.workspace.response;

import gymmi.workspace.domain.entity.Worker;
import lombok.Builder;
import lombok.Getter;

@Getter
public class WorkerResultResponse {

private final String name;
private final Integer contributeScore;
private final Integer rank;

@Builder
public WorkerResultResponse(Worker worker, Integer rank) {
this.name = worker.getNickname();
this.contributeScore = worker.getContributedScore();
this.rank = rank;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package gymmi.workspace.response;

import gymmi.workspace.domain.entity.Worker;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
public class WorkspaceResultResponse {

private final String task;
private final List<WorkerResultResponse> workers;

public WorkspaceResultResponse(String task, List<Worker> workers) {
this.task = task;
this.workers = getWorkerResultResponse(workers);
}

private List<WorkerResultResponse> getWorkerResultResponse(List<Worker> workers) {
List<WorkerResultResponse> workerResultResponse = new ArrayList<>();
for (int i = 0; i < workers.size(); i++) {
workerResultResponse.add(new WorkerResultResponse(workers.get(i), i + 1));
}
return workerResultResponse;
}
}
40 changes: 34 additions & 6 deletions src/main/java/gymmi/workspace/service/WorkspaceCommandService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@
import gymmi.workspace.domain.entity.*;
import gymmi.workspace.repository.*;
import gymmi.workspace.request.*;
import gymmi.workspace.response.WorkspaceResultResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;

@Service
@RequiredArgsConstructor
Expand All @@ -35,6 +33,7 @@ public class WorkspaceCommandService {
private final FavoriteMissionRepository favoriteMissionRepository;
private final ObjectionRepository objectionRepository;
private final VoteRepository voteRepository;
private final WorkspaceResultRepository workspaceResultRepository;

private final S3Service s3Service;
private final PhotoFeedService photoFeedService;
Expand Down Expand Up @@ -167,7 +166,7 @@ public void editIntroduction(
Worker worker = workerRepository.getByUserIdAndWorkspaceId(loginedUser.getId(), workspace.getId());

WorkspaceEditManager workspaceEditManager = new WorkspaceEditManager(workspace, worker);
workspaceEditManager.edit(request.getDescription(), request.getTag(),request.getTask());
workspaceEditManager.edit(request.getDescription(), request.getTag(), request.getTask());
}

public void toggleRegistrationOfFavoriteMission(User loginedUser, Long workspaceId, Long missionId) {
Expand Down Expand Up @@ -236,7 +235,7 @@ private void rejectWorkoutHistory(ObjectionManager objectionManager, WorkoutHist

public void terminateExpiredObjection(User loginedUser, Long workspaceId) {
Workspace workspace = workspaceRepository.getWorkspaceById(workspaceId);
validateIfWorkerIsInWorkspace(loginedUser.getId(), workspaceId);
validateIfWorkerIsInWorkspace(loginedUser.getId(), workspace.getId());
List<Objection> expiredObjections = objectionRepository.getExpiredObjections(workspace.getId());
List<Worker> workers = workerRepository.getAllByWorkspaceId(workspace.getId());

Expand All @@ -251,5 +250,34 @@ public void terminateExpiredObjection(User loginedUser, Long workspaceId) {
}
}

public WorkspaceResultResponse getWorkspaceResult(User loginedUser, Long workspaceId) {
Workspace workspace = workspaceRepository.getWorkspaceById(workspaceId);
validateIfWorkerIsInWorkspace(loginedUser.getId(), workspace.getId());
List<Worker> workers = workerRepository.getAllByWorkspaceId(workspace.getId());

if (workspace.isFullyCompleted()) {
WorkspaceResult workspaceResult = workspaceResultRepository.getByWorkspaceId(workspace.getId());
return getWorkspaceResultResponse(workspace, workers, workspaceResult);
}

WorkspaceDrawManger workspaceDrawManger = new WorkspaceDrawManger(workspace, workers);
WorkspaceResult workspaceResult = workspaceDrawManger.draw();

workspaceResultRepository.save(workspaceResult);
return getWorkspaceResultResponse(workspace, workers, workspaceResult);
}

private WorkspaceResultResponse getWorkspaceResultResponse(Workspace workspace, List<Worker> workers, WorkspaceResult workspaceResult) {
List<Worker> result = sortResult(workspaceResult.getWinner(), workspaceResult.getLoser(), workers);
return new WorkspaceResultResponse(workspace.getTask(), result);
}

private List<Worker> sortResult(Worker winner, Worker loser, List<Worker> workers) {
LinkedList<Worker> result = new LinkedList<>(workers);
result.remove(winner);
result.remove(loser);
result.addFirst(winner);
result.addLast(loser);
return result;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
alter table vote
add column automatic boolean not null;

alter table worker drop foreign key worker_ibfk_1;
alter table worker drop column task_id;

drop table task;

alter table workspace
add column task varchar(255) not null;

create table workspace_task
(
id bigint not null auto_increment primary key,
workspace_id bigint not null,
winner_id bigint not null,
loser_id bigint not null,
created_at timestamp(3) not null,
last_modified_at timestamp(3) not null,
foreign key (workspace_id) references worker (id),
foreign key (winner_id) references worker (id),
foreign key (loser_id) references worker (id)
);
Loading

0 comments on commit b90a641

Please sign in to comment.