Skip to content

Commit

Permalink
feat: add some api of workspace (#4) (#7)
Browse files Browse the repository at this point in the history
* feat: complete the workspace when it exceeds goal score

* feat: add api of opening task box in workspace + drawing task in service

* feat: change api of seeing password of workspace to seeing introduction of workspace

* feat: add api of editing description of workspace
  • Loading branch information
aiaiaiai1 authored Jul 6, 2024
1 parent 5b1d16b commit 9e73459
Show file tree
Hide file tree
Showing 18 changed files with 457 additions and 115 deletions.
28 changes: 22 additions & 6 deletions src/main/java/gymmi/controller/WorkspaceController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import gymmi.entity.WorkspaceStatus;
import gymmi.global.Logined;
import gymmi.request.CreatingWorkspaceRequest;
import gymmi.request.EditingDescriptionOfWorkspaceRequest;
import gymmi.request.JoiningWorkspaceRequest;
import gymmi.request.MatchingWorkspacePasswordRequest;
import gymmi.request.WorkingMissionInWorkspaceRequest;
Expand All @@ -13,8 +14,9 @@
import gymmi.response.JoinedWorkspaceResponse;
import gymmi.response.MatchingWorkspacePasswordResponse;
import gymmi.response.MissionResponse;
import gymmi.response.OpeningTasksBoxResponse;
import gymmi.response.WorkingScoreResponse;
import gymmi.response.WorkspacePasswordResponse;
import gymmi.response.WorkspaceIntroductionResponse;
import gymmi.response.WorkspaceResponse;
import gymmi.service.WorkspaceService;
import java.util.List;
Expand All @@ -25,6 +27,7 @@
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
Expand Down Expand Up @@ -54,12 +57,12 @@ public ResponseEntity<Void> joinWorkspace(
return ResponseEntity.ok().build();
}

@GetMapping("/workspaces/{workspaceId}/password")
public ResponseEntity<WorkspacePasswordResponse> seeWorkspacePassword(
@GetMapping("/workspaces/{workspaceId}/introduction")
public ResponseEntity<WorkspaceIntroductionResponse> seeWorkspaceIntroduction(
@Logined User user,
@PathVariable Long workspaceId
) {
WorkspacePasswordResponse response = workspaceService.getWorkspacePassword(user, workspaceId);
WorkspaceIntroductionResponse response = workspaceService.getWorkspaceIntroduction(user, workspaceId);
return ResponseEntity.ok().body(response);
}

Expand Down Expand Up @@ -152,8 +155,21 @@ public ResponseEntity<List<ContributedWorkingResponse>> seeSumOfWorkingsInWorksp
}

@GetMapping("/workspaces/{workspaceId}/tasks")
public ResponseEntity<Void> openTasksBoxInWorkspace() {
return null;
public ResponseEntity<OpeningTasksBoxResponse> openTasksBoxInWorkspace(
@Logined User user,
@PathVariable Long workspaceId
) {
OpeningTasksBoxResponse response = workspaceService.openTaskBoxInWorkspace(user, workspaceId);
return ResponseEntity.ok().body(response);
}

@PutMapping("/workspaces/{workspaceId}/edit")
public ResponseEntity<Void> editDescriptionOfWorkspace(
@Logined User user,
@PathVariable Long workspaceId,
@RequestBody EditingDescriptionOfWorkspaceRequest request
) {
workspaceService.editDescription(user, workspaceId, request);
return ResponseEntity.ok().build();
}
}
32 changes: 29 additions & 3 deletions src/main/java/gymmi/entity/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class Task {

@JoinColumn(name = "user_id", nullable = false)
@ManyToOne(fetch = FetchType.LAZY)
private User user;
private User register;

@Column(nullable = false)
private String name;
Expand All @@ -38,10 +38,36 @@ public class Task {
private boolean isPicked;

@Builder
public Task(Workspace workspace, User user, String name) {
public Task(Workspace workspace, User register, String name) {
this.workspace = workspace;
this.user = user;
this.register = register;
this.name = name;
this.isPicked = false;
}

public boolean isPicked() {
return isPicked;
}

public void changeToPicked() {
this.isPicked = true;
}

public boolean isRegisteredBy(User user) {
return this.register.equals(user);
}

public Long getId() {
return id;
}

public String getName() {
return name;
}

public User getRegister() {
return register;
}
}


6 changes: 5 additions & 1 deletion src/main/java/gymmi/entity/Worker.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ public Integer getContributedScore() {
return contributedScore;
}

public double getContributedPercent() {
return Math.round((double) contributedScore / workspace.getGoalScore() * 100 * 100) / 100;
}

public void addWorkingScore(Integer workingScore) {
contributedScore += workingScore;
}

public WorkingRecord doMission(Mission mission, Integer count) {
if (!this.workspace.isRegisteredMission(mission)) {
if (!this.workspace.hasMission(mission)) {
throw new NotFoundResourcesException("해당 미션이 존재하지 않아요.");
}
return WorkingRecord.builder()
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/gymmi/entity/Workspace.java
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,18 @@ public boolean isInProgress() {
return this.status == WorkspaceStatus.IN_PROGRESS;
}

public boolean isRegisteredMission(Mission mission) {
public boolean hasMission(Mission mission) {
return this.equals(mission.getWorkspace());
}

public boolean isPreparing() {
return this.status == WorkspaceStatus.PREPARING;
}

public boolean isCompleted() {
return this.status == WorkspaceStatus.COMPLETED;
}

public boolean isFull(Integer headCount) {
return this.headCount <= headCount;
}
Expand All @@ -152,6 +156,14 @@ public boolean isCreatedBy(User user) {
return this.creator.equals(user);
}

public boolean achieves(int achievementScore) {
return this.goalScore <= achievementScore;
}

public void complete() {
this.status = WorkspaceStatus.COMPLETED;
}

public void start() {
this.status = WorkspaceStatus.IN_PROGRESS;
}
Expand Down Expand Up @@ -184,6 +196,10 @@ public Integer getGoalScore() {
return goalScore;
}

public void editDescription(String description) {
this.description = validateDescription(description);
}

public Integer getHeadCount() {
return headCount;
}
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/gymmi/exception/ServerLogicFaultException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package gymmi.exception;

public class ServerLogicFaultException extends GymmiException {

public static final String ERROR_CODE = "SERVER_LOGIC_FAULT";
public static final String ERROR_DESCRIPTION = "서버 내 로직에서 결함이 생긴 경우";

public ServerLogicFaultException(String message) {
super(message, ERROR_CODE, ERROR_DESCRIPTION);
}
}
8 changes: 6 additions & 2 deletions src/main/java/gymmi/repository/TaskRepository.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package gymmi.repository;

import gymmi.entity.Task;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

public interface TaskRepository extends JpaRepository<Task, Long> {

@Query("select t from Task t where t.user.id = :userId and t.workspace.id = :workspaceId")
@Query("select t from Task t where t.register.id = :userId and t.workspace.id = :workspaceId")
Optional<Task> findByUserIdAndWorkspaceId(Long userId, Long workspaceId);

@Query("select t from Task t where t.workspace.id = :workspaceId")
List<Task> getAllByWorkspaceId(Long workspaceId);

@Modifying(clearAutomatically = true)
@Query("delete from Task t where t.user.id = :userId and t.workspace.id = :workspaceId")
@Query("delete from Task t where t.register.id = :userId and t.workspace.id = :workspaceId")
void deleteByUserIdAndWorkspaceId(Long userId, Long workspaceId);
}
4 changes: 2 additions & 2 deletions src/main/java/gymmi/repository/WorkerRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public interface WorkerRepository extends JpaRepository<Worker, Long> {
@Query("delete from Worker w where w.user.id = :userId and w.workspace.id = :workspaceId")
void deleteByUserIdAndWorkspaceId(Long userId, Long workspaceId);

@Query("select w from Worker w join w.workspace ws where ws.id = :workspaceId")
List<Worker> getAllByWorkspaceId(Long workspaceId);
@Query("select w from Worker w join w.workspace ws where ws.id = :workspaceId order by w.contributedScore desc, w.user.id asc")
List<Worker> getAllByWorkspaceIdOrderByContributedScore(Long workspaceId);

// boolean으로 가능?? ->
// @Query(value = "select * from worker w", nativeQuery = true)
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/gymmi/repository/WorkspaceRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ default Workspace getWorkspaceById(Long id) {


@Query("select sum(w.contributedScore) from Workspace ws inner join Worker w on ws.id = w.workspace.id where ws.id = :workspaceId")
Integer getAchievementScore(Long workspaceId);
int getAchievementScore(Long workspaceId);

@Query("select ws from Workspace ws")
List<Workspace> getAllWorkspaces();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package gymmi.request;

import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class EditingDescriptionOfWorkspaceRequest {

private String description;

public EditingDescriptionOfWorkspaceRequest(String description) {
this.description = description;
}
}
2 changes: 1 addition & 1 deletion src/main/java/gymmi/response/MissionResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PROTECTED) // for test
public class MissionResponse {

private Long id;
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/gymmi/response/OpeningTasksBoxResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package gymmi.response;

import gymmi.entity.Task;
import gymmi.exception.ServerLogicFaultException;
import java.util.List;
import lombok.Getter;

@Getter
public class OpeningTasksBoxResponse {

private final TaskDTO pickedTask;
private final List<TaskDTO> tasks;

public OpeningTasksBoxResponse(List<Task> tasks) {
this.pickedTask = getPickedTask(tasks);
this.tasks = getTask(tasks);
}

private List<TaskDTO> getTask(List<Task> tasks) {
return tasks.stream()
.map(t -> new TaskDTO(t.getId(), t.getName(), t.getRegister().getNickname()))
.toList();
}

private TaskDTO getPickedTask(List<Task> tasks) {
return tasks.stream()
.filter(t -> t.isPicked())
.findFirst()
.map(t -> new TaskDTO(t.getId(), t.getName(), t.getRegister().getNickname()))
.orElseThrow(() -> new ServerLogicFaultException("picked task is not exist: " + this.getClass()));
}

}
17 changes: 17 additions & 0 deletions src/main/java/gymmi/response/TaskDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package gymmi.response;

import lombok.Getter;

@Getter
public class TaskDTO {

private final Long id;
private final String task;
private final String nickname;

public TaskDTO(Long id, String task, String nickname) {
this.id = id;
this.task = task;
this.nickname = nickname;
}
}
18 changes: 18 additions & 0 deletions src/main/java/gymmi/response/WorkspaceIntroductionResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package gymmi.response;

import gymmi.entity.Workspace;
import lombok.Getter;

@Getter
public class WorkspaceIntroductionResponse {

private final String password;
private final String description;
private final String tag;

public WorkspaceIntroductionResponse(Workspace workspace) {
this.password = workspace.getPassword();
this.description = workspace.getDescription();
this.tag = workspace.getTag();
}
}
13 changes: 0 additions & 13 deletions src/main/java/gymmi/response/WorkspacePasswordResponse.java

This file was deleted.

46 changes: 46 additions & 0 deletions src/main/java/gymmi/service/TaskDraw.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package gymmi.service;

import gymmi.entity.Task;
import gymmi.entity.User;
import gymmi.entity.Worker;
import gymmi.exception.ServerLogicFaultException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;

public class TaskDraw {

// 기여퍼센트 + 2 * 등수(reversed)
private final List<Task> tasks;

public TaskDraw(List<Task> tasks) {
this.tasks = new ArrayList<>(tasks);
}

private Task findBy(User user) {
return tasks.stream()
.filter(t -> t.isRegisteredBy(user))
.findFirst()
.orElseThrow(() -> new ServerLogicFaultException("task is not exist: " + this.getClass()));
}

private Task findBy(Long id) {
return tasks.stream()
.filter(t -> t.getId().equals(id))
.findFirst()
.orElseThrow(() -> new ServerLogicFaultException("task is not exist: " + this.getClass()));
}

public Task pickOneAmong(List<Worker> workers, List<Integer> ranks) {
List<Long> box = new ArrayList<>();
for (int i = 0; i < workers.size(); i++) {
int score = (int) Math.round(workers.get(i).getContributedPercent()) + 2 * (ranks.size() - ranks.get(i));
for (int j = 0; j < score; j++) {
box.add(findBy(workers.get(i).getUser()).getId());
}
}
SecureRandom random = new SecureRandom();
Long taskId = box.get(random.nextInt(0, box.size()));
return findBy(taskId);
}
}
Loading

0 comments on commit 9e73459

Please sign in to comment.