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

[3 - 4단계 방탈출 예약 대기] 몰리(김지민) 미션 제출합니다. #145

Merged
merged 47 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
9a87d77
style: 요구사항에 맞게 프론트 코드 수정
jminkkk May 21, 2024
7e9b0a2
docs(README.md): 3단계 요구사항 작성
jminkkk May 21, 2024
240a588
docs(erd.png): 예약 대기 스키마 설계
jminkkk May 21, 2024
9c1c8e4
refactor(BaseEntity): 모든 엔티티들의 생성 시간, 수정 시간을 저장하는 BaseEntity 생성 및 상속
jminkkk May 21, 2024
748a835
feat(Waiting): 예약 대기에 대한 엔티티 구현
jminkkk May 21, 2024
bb347bd
docs(APISpecification): 예약 대기에 대한 API 명세 작성
jminkkk May 21, 2024
4e95421
test(WaitingRepositoryTest): 해당하는 회원, 예약과 동일한 예약 대기가 존재하는지에 대한 쿼리 테스트 작성
jminkkk May 21, 2024
76afc7c
feat(WaitingController): 예약 대기 생성 기능 구현
jminkkk May 21, 2024
889bf5c
feat(Waiting, Member): 회원에 대한 예약인지 묻는 메서드 추가
jminkkk May 21, 2024
53f3222
refactor(/exception): 401, 403 커스텀 예외 생성
jminkkk May 22, 2024
ad79650
feat(WaitingController): 예약 대기 취소 API 구현
jminkkk May 22, 2024
849e93c
feat(WaitingController): 예약 대기 조회 API 구현
jminkkk May 22, 2024
b129112
feat(AuthController): 로그아웃 API 구현
jminkkk May 22, 2024
812bf32
refactor(/dto/response): 메서드 인자 줄바꿈 통일
jminkkk May 22, 2024
ae5a7b3
refactor(GlobalExceptionHandler): 출력문 대신 logger로 변경
jminkkk May 22, 2024
76d67b4
refactor(/repository): repository로 getBy 메서드 위치 이동
jminkkk May 23, 2024
a4208dd
chore(data.sql): 예약 대기 더미 데이터 생성
jminkkk May 23, 2024
b0e1b60
docs(README.md): 4단계 요구사항 작성
jminkkk May 23, 2024
f36df96
feat(ReservationController): 에약 대기 승인 기능 구현
jminkkk May 23, 2024
78cd966
style(/js): 프론트 코드 추가
jminkkk May 23, 2024
357d743
feat(AdminController): 어드민 예약 대기 목록 조회 구현
jminkkk May 23, 2024
187c62a
feat(AdminController): 예약 대기 거절 구현
jminkkk May 23, 2024
f305922
refactor(/util): AbstractTestExecutionListener 구현, Test 어노테이션에 반영
jminkkk May 24, 2024
fa34e8b
refactor(AdminController): 관리자 예약 조회용 응답 dto 생성
jminkkk May 24, 2024
1efdb6e
refactor(/dto): 안 쓰는 dto 제거
jminkkk May 24, 2024
bc12273
test(AuthIntegrationTest): 로그아웃 테스트 추가
jminkkk May 24, 2024
fac9f7b
fix(JwtTokenProvider): 회원의 이름을 위한 클래임 이름 변경
jminkkk May 24, 2024
3b229f9
refactor(MemberController): 내 예약 조회 메서드 이름을 변
jminkkk May 24, 2024
b6aa788
style(/src): 불필요한 주석 제거
jminkkk May 24, 2024
6eae891
style(/js): 관리자의 예약 조회 API 프론트 코드에서 변경
jminkkk May 24, 2024
bfb60b6
fix(ReservationService): 예약 삭제 권한 로직 변경
jminkkk May 24, 2024
b41726a
test(ReservationServiceTest): 예약 관련 서비스 계층 테스트 추가
jminkkk May 24, 2024
16efd2b
refactor(CreateReservationRequest): 관리자에 의한 예약 추가 요청 dto 이름 변경
jminkkk May 24, 2024
c0fb37a
test(WaitingIntegrationTest): 예약 대기 거절 실패 테스트 추가
jminkkk May 24, 2024
7b19471
fix(WaitingService): 예약 삭제 시 업데이트를 위한 대기 삭제 메서드 추가
jminkkk May 24, 2024
2c580be
docs(APISpecification.md): API 명세 최신화
jminkkk May 24, 2024
1696466
fix(waiting.js): admin API 변경에 따른 프론트 코드 변경
jminkkk May 24, 2024
28998e2
refactor(ReservationTest): 테스트 메서드의 이름을 각 테스트 목적에 맞게 변경
jminkkk May 27, 2024
3524d8f
refactor(ReservationService): 예외 메시지를 자세하게 변경
jminkkk May 27, 2024
4eacd7b
refactor(WaitingService): 동일한 역할의 메서드를 통일
jminkkk May 27, 2024
1d84a9b
refactor(ReservationService): 메서드 명을 조금 더 추상화하여 수정
jminkkk May 27, 2024
5641fa7
refactor(MemberRepository): 예외 메세지를 내부에서 던지도록 변경
jminkkk May 27, 2024
68cf267
refactor(BaseEntity): 엔티티 컬럼에 updatable, nullable 조건 추가
jminkkk May 27, 2024
860d01a
refactor(/test/reservation/service): main과 동일하게 테스트 패키지 이동
jminkkk May 27, 2024
4d114c1
refactor(AdminWaitingController): 각 도메인의 책임에 맞게 위치를 변경 및 AdminWaiting…
jminkkk May 27, 2024
684cbeb
refactor(/src/test): 각 테스트 명을 통일성있게 전체 변경
jminkkk May 27, 2024
50b9ee3
style(/src): import 문 최적화
jminkkk May 27, 2024
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
215 changes: 182 additions & 33 deletions docs/APISpecification.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,65 +79,167 @@ Content-Type: application/json
```

</details>
<br>

## 예약
<details>
<summary> 내 예약 대기 조회 API </summary>

### 내 예약 대기 조회 API

#### Request

```http request
GET /members/waitings HTTP/1.1
```

#### Response

```
HTTP/1.1 200
[
{
"id": 1,
"name": "브라운",
"date": "2023-01-01",
"timeId": 1,
"themeId": 1
}
]
```
</details>

## 관리자

<details>
<summary> 예약 페이지 조회 API </summary>
<summary> 예약 목록 조회 API - 관리자 </summary>

### 예약 페이지 조회
### 예약 목록 조회 - 관리자

#### Request

```http request
GET /admin/reservation HTTP/1.1
GET /admin/reservations HTTP/1.1
```

#### Response

```
HTTP/1.1 200
Content-Type: application/json

[
{
"id": 1,
"name": "브라운",
"date": "2023-01-01",
"startAt": "10:00"
"theme": "레벨2 탈출"
}
]
```
</details>

<br>

<details>
<summary> 예약 목록 조회 API </summary>
<summary> 예약 추가 - 관리자 API </summary>

### 예약 목록 조회
### 예약 추가 - 관리자

#### Request

```http request
GET /reservations HTTP/1.1
POST /admin/reservations HTTP/1.1
content-type: application/json
cookie: token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwibmFtZSI6ImFkbWluIiwicm9sZSI6IkFETUlOIn0.cwnHsltFeEtOzMHs2Q5-ItawgvBZ140OyWecppNlLoI
host: localhost:8080

{
"date": "2024-03-01",
"themeId": 1,
"timeId": 1,
"memberId": 1
}
```

#### Response

```
HTTP/1.1 200
Content-Type: application/json
HTTP/1.1 201
Location: /reservation/{id}
```
</details>

<br>

<details>
<summary> 예약 대기 목록 조회 API - 관리자 </summary>

### 예약 대기 목록 조회 API

#### Request

```http request
GET /admin/waitings HTTP/1.1
```

#### Response

```
HTTP/1.1 200
[
{
"id": 1,
"name": "브라운",
"date": "2023-01-01",
"time": {
"id": 1,
"startAt": "10:00"
},
"theme": {
"id": 1,
"name": "레벨2 탈출",
"description": "우테코 레벨2를 탈출하는 내용입니다.",
"thumbnail": "https://i.pinimg.com/236x/6e/bc/46/6ebc461a94a49f9ea3b8bbe2204145d4.jpg"
}
"timeId": 1,
"themeId": 1
}
]
```
</details>
<br>


<details>
<summary> 예약 대기 거절 API </summary>

### 예약 대기 거절 API

#### Request

```http request
DELETE /admin/waitings/reject/{waitingId HTTP/1.1
```

#### Response

```
HTTP/1.1 204
```
</details>
<br>


## 예약

<details>
<summary> 예약 페이지 조회 API </summary>

### 예약 페이지 조회

#### Request

```http request
GET /admin/reservation HTTP/1.1
```

#### Response

```
HTTP/1.1 200
```
</details>

<br>

Expand Down Expand Up @@ -248,55 +350,80 @@ Location: /reservation/{id}
<br>

<details>
<summary> 예약 추가 - 관리자 API </summary>
<summary> 예약 취소 API </summary>

### 예약 추가 - 관리자
### 예약 취소

#### Request

```http request
POST /admin/reservations HTTP/1.1
DELETE /reservations/{id} HTTP/1.1
```

#### Response

```
HTTP/1.1 204
```

---
</details>

## 예약 대기

<details>
<summary> 예약 대기 생성 API </summary>

### 예약 대기 생성 API

#### Request

```http request
POST /waitings HTTP/1.1
content-type: application/json
cookie: token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwibmFtZSI6ImFkbWluIiwicm9sZSI6IkFETUlOIn0.cwnHsltFeEtOzMHs2Q5-ItawgvBZ140OyWecppNlLoI
host: localhost:8080

{
"date": "2024-03-01",
"themeId": 1,
"date": "2023-08-05",
"timeId": 1,
"memberId": 1
"themeId": 1
}
```

#### Response

```
HTTP/1.1 201
Location: /reservation/{id}
Location: /waitings/1

{
"waitingId": 1,
"date": "2023-08-05",
"timeId": 1,
"themeId": 1
}
```
</details>

<br>

<details>
<summary> 예약 취소 API </summary>
<summary> 예약 대기 취소 API </summary>

### 예약 취소
### 예약 대기 취소 API

#### Request

```http request
DELETE /reservations/{id} HTTP/1.1
DELETe /waitings/{waitingId} HTTP/1.1
```

#### Response

```
HTTP/1.1 204
```

---
</details>
<br>

## 시간

Expand Down Expand Up @@ -642,6 +769,28 @@ Set-Cookie: token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwibmFtZSI6ImFkbWluIiwicm9sZ

<br>

<details>
<summary> 로그아웃 API </summary>

### 로그아웃

#### Request

```http request
POST /logout HTTP/1.1
cookie: token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwibmFtZSI6ImFkbWluIiwicm9sZSI6IkFETUlOIn0.cwnHsltFeEtOzMHs2Q5-ItawgvBZ140OyWecppNlLoI; Path=/; HttpOnly
host: localhost:8080
```

#### Response

```http request
HTTP/1.1 204 OK
```
</details>

<br>

<details>
<summary> 인증 정보 조회 API </summary>

Expand Down
29 changes: 29 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# 요구사항 분석

## 예약 대기 정책

- 동일한 날짜, 시간, 테마의 예약이 존재할 경우, 사용자는 해당 예약에 대기를 요청할 수 있다.
- 사용자는 내 예약 조회 시 대기 중인 예약인 경우, 해당 대기의 순번을 확인할 수 있다.
- 사용자는 동일한 날짜, 시간, 테마의 예약이 불가능하다.
- 동일한 날짜, 시간의 다른 테마인 경우, 예약이 가능하다.
- 다른 날짜, 시간의 동일한 테마인 경우, 예약이 가능하다.
- 사용자는 대기가 예약으로 확정되기 전이라면, 예약 대기를 취소할 수 있다.

## 예약 취소
- 예약 취소 시, 해당 예약에 대해 우선순위가 높은 대기가 자동으로 예약된다.
- 관리자는 예약 대기를 거절할 수 있다.

## 3단계
- 예약 대기 요청 API 구현
- [x] 예약 대기 스키마 설계
- [x] 예약 대기 엔티티 구현
- [x] 예약 대기 요청 로직 구현
- [x] 예약 대기 취소 API 구현
- [x] 예약 조회 API 변경
- 예약 조회 시, 대기 목록을 포함한다.

## 4단계
- [x] 에약 대기 승인 기능 구현
- 예약 취소 API에서 대기 번호 1번인 대기가 예약이 되도록 변경
- [x] 예약 대기 거절 API 구현
- [x] 어드민 예약 대기 목록 조회 API 구현

---
## 1단계
- [x] gradle 의존성 추가
- [x] 엔티티 매핑
Expand Down
Binary file added docs/erd.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/main/java/roomescape/RoomescapeApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@ConfigurationPropertiesScan
@SpringBootApplication
@EnableJpaAuditing
public class RoomescapeApplication {
public static void main(String[] args) {
SpringApplication.run(RoomescapeApplication.class, args);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/roomescape/auth/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,10 @@ public ResponseEntity<GetAuthInfoResponse> getMemberAuthInfo(@AuthenticationPrin
GetAuthInfoResponse getAuthInfoResponse = authService.getMemberAuthInfo(authInfo);
return ResponseEntity.ok(getAuthInfoResponse);
}

@PostMapping("/logout")
public ResponseEntity<Void> logout(HttpServletResponse httpServletResponse) {
authorizationManager.removeAuthorization(httpServletResponse);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.springframework.web.servlet.HandlerInterceptor;
import roomescape.auth.core.token.TokenProvider;
import roomescape.auth.domain.AuthInfo;
import roomescape.common.exception.ForbiddenException;
import roomescape.common.exception.UnAuthorizationException;

public class AuthorizationInterceptor implements HandlerInterceptor {

Expand All @@ -26,14 +28,14 @@ public boolean preHandle(final HttpServletRequest request, final HttpServletResp

private void validatedTokeIsBlank(final String token) {
if (token == null || token.isBlank()) {
throw new SecurityException("회원의 인증 토큰 정보를 찾을 수 없습니다. 다시 로그인해주세요.");
throw new UnAuthorizationException("회원의 인증 토큰 정보를 찾을 수 없습니다. 다시 로그인해주세요.");
}
}

private void checkAdminAuthorization(final String token) {
AuthInfo authInfo = tokenProvider.extractAuthInfo(token);
if (authInfo.isNotAdmin()) {
throw new SecurityException("관리자 회원이 아닙니다. 관리자 권한이 필요한 기능입니다.");
throw new ForbiddenException("관리자 회원이 아닙니다. 관리자 권한이 필요한 기능입니다.");
}
}
}
Loading