Skip to content

Commit

Permalink
feat: add some api of workspace (#2)
Browse files Browse the repository at this point in the history
* feat: add api of creating workspace

* style: move file

* feat: add api of joining workspace and seeing workspace password

* refactor: modify status code of exception handling

* feat: add api of matching workspace password

* refactor: modify fixtures

* refactor: move responsibility for mapping value of query param from enum to converter

* feat: add api of seeing workspaces joined

* feat: add api(not fully) of seeing all workspaces

* feat: add api of starting workspace

* test: supplement test of joining in workspace

* feat: add api of leaving workspace

* style: reformatting
  • Loading branch information
aiaiaiai1 authored Jun 28, 2024
1 parent 09bf470 commit 012e16d
Show file tree
Hide file tree
Showing 51 changed files with 2,009 additions and 242 deletions.
100 changes: 84 additions & 16 deletions src/main/java/gymmi/controller/WorkspaceController.java
Original file line number Diff line number Diff line change
@@ -1,42 +1,110 @@
package gymmi.controller;

import gymmi.entity.User;
import gymmi.entity.WorkspaceStatus;
import gymmi.global.Logined;
import gymmi.request.CreatingWorkspaceRequest;
import gymmi.request.JoiningWorkspaceRequest;
import gymmi.request.MatchingWorkspacePasswordRequest;
import gymmi.response.IdResponse;
import gymmi.response.JoinedWorkspaceResponse;
import gymmi.response.MatchingWorkspacePasswordResponse;
import gymmi.response.WorkspacePasswordResponse;
import gymmi.response.WorkspaceResponse;
import gymmi.service.WorkspaceService;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class WorkspaceController {

private final WorkspaceService workspaceService;

@PostMapping("/workspaces")
public ResponseEntity<Void> createWorkspace() {
return null;
public ResponseEntity<IdResponse> createWorkspace(
@Logined User user,
@Validated @RequestBody CreatingWorkspaceRequest request
) {
Long workspaceId = workspaceService.createWorkspace(user, request);
return ResponseEntity.ok().body(new IdResponse(workspaceId));
}

@GetMapping("/workspaces1")
public ResponseEntity<Void> seeJoinedWorkspaces() {
return null;
@PostMapping("/workspaces/{workspaceId}/join")
public ResponseEntity<Void> joinWorkspace(
@Logined User user,
@Validated @RequestBody JoiningWorkspaceRequest request,
@PathVariable Long workspaceId
) {
workspaceService.joinWorkspace(user, workspaceId, request);
return ResponseEntity.ok().build();
}

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

@PostMapping("/workspaces/{workspaceId}/join")
public ResponseEntity<Void> joinWorkspaces() {
return null;
@GetMapping("/workspaces/{workspaceId}/match-password")
public ResponseEntity<MatchingWorkspacePasswordResponse> matchWorkspacePassword(
// @Logined User user, login intercept 추가
@PathVariable Long workspaceId,
@Validated @RequestBody MatchingWorkspacePasswordRequest request
) {
MatchingWorkspacePasswordResponse response = workspaceService.matchesWorkspacePassword(workspaceId,
request.getPassword());
return ResponseEntity.ok().body(response);
}

@PostMapping("/workspaces/{workspaceId}/join/task")
public ResponseEntity<Void> writeTaskInWorkspace() {
return null;
@GetMapping("/workspaces/my")
public ResponseEntity<List<JoinedWorkspaceResponse>> seeJoinedWorkspaces(
@Logined User user,
@RequestParam("page") int pageNumber
) {
List<JoinedWorkspaceResponse> responses = workspaceService.getJoinedWorkspaces(user, pageNumber);
return ResponseEntity.ok().body(responses);
}

@GetMapping("/workspaces")
public ResponseEntity<List<WorkspaceResponse>> seeAllWorkspaces(
//@Logined User user,
@RequestParam(required = false) WorkspaceStatus status,
@RequestParam(required = false) String keyword,
@RequestParam(value = "page") int pageNumber
) {
List<WorkspaceResponse> responses = workspaceService.getAllWorkspaces();
return ResponseEntity.ok().body(responses);
}

@PatchMapping("/workspaces/{workspaceId}/start")
public ResponseEntity<Void> startWorkspace() {
return null;
public ResponseEntity<Void> startWorkspace(
@Logined User user,
@PathVariable Long workspaceId
) {
workspaceService.startWorkspace(user, workspaceId);
return ResponseEntity.ok().build();
}

@PostMapping("/workspaces/{workspaceId}/leave")
public ResponseEntity<Void> leaveWorkspace(
@Logined User user,
@PathVariable Long workspaceId
) {
workspaceService.leaveWorkspace(user, workspaceId);
return ResponseEntity.ok().build();
}

@GetMapping("/workspaces/{workspaceId}")
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/gymmi/entity/Contribution.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package gymmi.entity;

import jakarta.persistence.*;

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 java.time.LocalDateTime;

@Entity
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/gymmi/entity/Logined.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package gymmi.entity;

import jakarta.persistence.*;
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.OneToOne;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

Expand Down
20 changes: 19 additions & 1 deletion src/main/java/gymmi/entity/Mission.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
package gymmi.entity;

import jakarta.persistence.*;
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 lombok.AccessLevel;
import lombok.Builder;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Mission {

@Id
Expand All @@ -16,4 +27,11 @@ public class Mission {
@Column(nullable = false)
private String name;
private Integer score;

@Builder
public Mission(Workspace workspace, String name, Integer score) {
this.workspace = workspace;
this.name = name;
this.score = score;
}
}
24 changes: 23 additions & 1 deletion src/main/java/gymmi/entity/Task.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package gymmi.entity;

import jakarta.persistence.*;
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.Table;
import jakarta.persistence.UniqueConstraint;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "workspace_id"})})
public class Task {

@Id
Expand All @@ -22,4 +36,12 @@ public class Task {

@Column(nullable = false)
private boolean isPicked;

@Builder
public Task(Workspace workspace, User user, String name) {
this.workspace = workspace;
this.user = user;
this.name = name;
this.isPicked = false;
}
}
42 changes: 26 additions & 16 deletions src/main/java/gymmi/entity/User.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
package gymmi.entity;

import static gymmi.utils.Regexpressions.REGEX_숫자;
import static gymmi.utils.Regexpressions.REGEX_영어;
import static gymmi.utils.Regexpressions.REGEX_영어_숫자_만;
import static gymmi.utils.Regexpressions.REGEX_영어_한글_초성_숫자_만;
import static gymmi.utils.Regexpressions.SPECIAL_CHARACTER;

import gymmi.exception.InvalidPatternException;
import jakarta.persistence.*;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.regex.Pattern;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.mindrot.jbcrypt.BCrypt;

import java.util.regex.Pattern;

@Entity
@Table(name = "uuser")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(of = {"id"})
public class User {

private static final String SPECIAL_CHARACTER = "~!@#$%^&*()_+<>?:";
private static final Pattern REGEX_LOGIN_ID = Pattern.compile("^[a-zA-Z0-9]+$");
private static final Pattern REGEX_NICKNAME = Pattern.compile("^[ㄱ-ㅎ가-힣a-zA-Z0-9]+$");
private static final Pattern REGEX_EMAIL = Pattern.compile("^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]*$");
private static final Pattern REGEX_LOGIN_ID = REGEX_영어_숫자_만;
private static final Pattern REGEX_PASSWORD = Pattern.compile("^[a-zA-Z0-9" + SPECIAL_CHARACTER + "]+$");

private static final Pattern REGEX_ENGLISH = Pattern.compile("[a-zA-Z]");
private static final Pattern REGEX_NUMBER = Pattern.compile("[0-9]");

private static final Pattern REGEX_NICKNAME = REGEX_영어_한글_초성_숫자_만;
private static final Pattern REGEX_SPECIAL_CHARACTER = Pattern.compile("[" + SPECIAL_CHARACTER + "]");

private static final Pattern REGEX_EMAIL = Pattern.compile("^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]*$");

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down Expand Up @@ -57,10 +63,10 @@ private void validatePassword(String plainPassword) {
if (!REGEX_PASSWORD.matcher(plainPassword).matches()) {
throw new InvalidPatternException("비밀번호는 영문+숫자+특수문자 조합으로 구성해주세요.");
}
if (!REGEX_ENGLISH.matcher(plainPassword).find()) {
if (!REGEX_영어.matcher(plainPassword).find()) {
throw new InvalidPatternException("영문을 포함해주세요");
}
if (!REGEX_NUMBER.matcher(plainPassword).find()) {
if (!REGEX_숫자.matcher(plainPassword).find()) {
throw new InvalidPatternException("숫자를 포함해주세요.");
}
if (!REGEX_SPECIAL_CHARACTER.matcher(plainPassword).find()) {
Expand All @@ -77,10 +83,10 @@ private void validateLoginId(String loginId) {
if (!REGEX_LOGIN_ID.matcher(loginId).matches()) {
throw new InvalidPatternException("아이디는 영문+숫자 조합으로 구성해주세요.");
}
if (!REGEX_ENGLISH.matcher(loginId).find()) {
if (!REGEX_영어.matcher(loginId).find()) {
throw new InvalidPatternException("영문을 포함해주세요");
}
if (!REGEX_NUMBER.matcher(loginId).find()) {
if (!REGEX_숫자.matcher(loginId).find()) {
throw new InvalidPatternException("숫자를 포함해주세요.");
}
}
Expand All @@ -101,4 +107,8 @@ public boolean canAuthenticate(String loginId, String plainPassword) {
public Long getId() {
return id;
}

public String getNickname() {
return nickname;
}
}
27 changes: 26 additions & 1 deletion src/main/java/gymmi/entity/Worker.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
package gymmi.entity;


import jakarta.persistence.*;
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.Table;
import jakarta.persistence.UniqueConstraint;
import java.time.LocalDateTime;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"user_id", "workspace_id"})})
public class Worker {

@Id
Expand All @@ -21,4 +36,14 @@ public class Worker {
@Column(nullable = false)
private Integer score;

@Column(nullable = false, updatable = false)
private LocalDateTime createdAt;

@Builder
public Worker(User user, Workspace workspace) {
this.user = user;
this.workspace = workspace;
this.score = 0;
this.createdAt = LocalDateTime.now();
}
}
Loading

0 comments on commit 012e16d

Please sign in to comment.