Skip to content

[FEAT] Main branch merge #112

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

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f7cb8b9
[FIX] 손님호출/입장처리 로직 오류 수정
kyuung09 Feb 6, 2023
cfe62ed
[FIX] 손님호출/입장처리 로직 오류 수정
kyuung09 Feb 6, 2023
8e8add6
[FIX] 손님호출/입장처리 로직 오류 수정
kyuung09 Feb 6, 2023
c42b9b1
REFACTOR: WaitingService 예외처리 및 사용하지 않는 코드 제거
hongdangmoo49 Feb 6, 2023
e64149a
Merge pull request #100 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 6, 2023
7586f62
Merge pull request #101 from pirate99-FinalProject/feature/AdminLogin…
kyuung09 Feb 6, 2023
59fa0b0
Update gradle.yml
kyuung09 Feb 6, 2023
0dca458
[FIX] console log 일부 제거
kyuung09 Feb 6, 2023
b470f71
Merge pull request #102 from pirate99-FinalProject/feature/AdminLogin…
kyuung09 Feb 6, 2023
09d3459
REFACTOR: StoreService.leaveStore 코드 수정
hongdangmoo49 Feb 6, 2023
865a2e1
Merge pull request #103 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 6, 2023
74fbc63
REFACTOR: StoreService.leaveStore 코드 수정
hongdangmoo49 Feb 6, 2023
767c68f
FIX: 사용자 호출기능 수정
hongdangmoo49 Feb 6, 2023
fb0655c
Merge branch 'develop' into feature/waiting16
hongdangmoo49 Feb 6, 2023
4978632
Merge pull request #104 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 6, 2023
c8f2946
FIX: 사용자 호출기능 수정
hongdangmoo49 Feb 6, 2023
336d52a
Merge remote-tracking branch 'origin/feature/waiting16' into feature/…
hongdangmoo49 Feb 6, 2023
110464d
Merge pull request #105 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 6, 2023
7ae5aea
FIX: 대기자 인원 제한 설정 쿼리메소드 수정
hongdangmoo49 Feb 6, 2023
51e8520
Merge pull request #106 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 6, 2023
d313a68
Refactoring: Waiting Service Refeactoring (Transactional delete from …
developjisung Feb 7, 2023
757f1ad
Merge pull request #107 from pirate99-FinalProject/feature/Refactorin…
developjisung Feb 7, 2023
14f4cb2
REFACTOR: WaitingStatus 상태값 (퇴장) 추가 및 leaveStore에 적용
hongdangmoo49 Feb 7, 2023
247cab5
Merge branch 'develop' into feature/waiting16
hongdangmoo49 Feb 7, 2023
1dee9dd
Merge pull request #108 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 7, 2023
b232790
Update README.md
kyuung09 Feb 7, 2023
55925bf
Update README.md
kyuung09 Feb 7, 2023
bbf876b
Update README.md
kyuung09 Feb 7, 2023
cd13de5
Update README.md
kyuung09 Feb 7, 2023
225a88a
REFACTOR: WaitingService, StoreService, UserService, ReviewService 예외처리
hongdangmoo49 Feb 8, 2023
e68702d
Merge branch 'develop' into feature/waiting16
hongdangmoo49 Feb 8, 2023
738fcaa
Merge pull request #109 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 8, 2023
d22ccec
[FIX] console log 제거
kyuung09 Feb 9, 2023
e519e4b
Merge pull request #110 from pirate99-FinalProject/feature/index
kyuung09 Feb 9, 2023
15a697e
REFACTOR: WaitingService.createWaiter lock 임대시간 수정
hongdangmoo49 Feb 9, 2023
67ee181
Merge remote-tracking branch 'origin/feature/waiting16' into feature/…
hongdangmoo49 Feb 9, 2023
c35a4c5
Merge pull request #111 from pirate99-FinalProject/feature/waiting16
hongdangmoo49 Feb 9, 2023
ce40020
Update README.md
kyuung09 Feb 10, 2023
7dd0c6c
Merge branch 'main' into develop
kyuung09 Feb 14, 2023
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
3 changes: 2 additions & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

name: Java CI with Gradle

pull_request:
on:
pull_request:
branches: [ "develop" ]


Expand Down
169 changes: 114 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,155 @@
![image](https://user-images.githubusercontent.com/117708164/216932548-af5766aa-a9a5-4d02-ba3f-49467c3fb956.png)

# PIN Table 🍽
### Pin-Table은, 대용량 위치 데이터를 활용한 위치 검색과 스토어 웨이팅 신청을 제공하는 서비스 입니다.
### 대용량 위치 데이터를 활용한 위치 검색과 스토어 웨이팅 신청을 제공하는 서비스 입니다.

- 위치 데이터를 활용한 장소 위치 검색을 할 수 있어요 🙆🏻
- 가고싶은 식당을 검색하고, 현재 웨이팅 현황 및 웨이팅 신청을 할 수 있어요 ❗️

#

## 📍 Index
## Pin-Table 기록지

1. [프로젝트 소개](#1-프로젝트-소개-)
2. [기술 스택](#2-기술-스택-)
3. [기능 명세](#3-기능-명세-)
4. [시연 영상](#4-시연영상-)
5. [서비스 아키텍처](#5-서비스-아키텍처-)
6. [ERD](#6-erd-)
7. [API](#7-api-)
#
[📘 핀테이블 브로슈어](https://www.notion.so/PIN-TABLE-3985986345c640969a8a8a5c3cabb3e1)<br>
[📗 핀테이블 Notion](https://speckle-apple-b3b.notion.site/Pin-Table-d4c37b30fd804199b3392045c0080129)

## 1. 프로젝트 소개 📢
- 설명 : Challenge Team3 | Pin-Table 프로젝트
- 기간 : 2022.12.30 ~ 2022.02.09
#
## 프로젝트 소개 📢
- 설명 :
- 프로젝트 목표 :
- 대용량 장소 데이터를 활용한 검색 및 예약 서비스 플랫폼
- 프로젝트 이름 :
- Pin-Table
- 구현 기능 및 핵심 목표 :
- 검색 시스템 + 웨이팅 서비스를 접목하여 검색부터 예약까지 가능하도록 구현하였습니다.
- **약 1000만건의** 데이터 조회 1초~3초
- 기간 :
- 2022.12.30 ~ 2022.02.09
- 팀원 : <br>

| - | NAME | GITHUB |
| - | 이름 | GITHUB |
|--|--|--|
| BE | 김규리 | https://github.com/kyuung09 |
| BE | 김규리🔰 | https://github.com/kyuung09 |
| BE | 이상훈 | https://github.com/leemeo3 |
| BE | 신승호 | https://github.com/hongdangmoo49 |
| BE | 황지성 | https://github.com/developjisung |

#

## 2. 기술 스택 🔨
## 기술 스택 🔨
<div align=center>
<img src="https://img.shields.io/badge/java-02569B?style=for-the-badge&logo=java&logoColor=white">
<img src="https://img.shields.io/badge/spring-6DB33F?style=for-the-badge&logo=spring&logoColor=white">
<img src="https://img.shields.io/badge/mysql-4479A1?style=for-the-badge&logo=mysql&logoColor=white">
<img src="https://img.shields.io/badge/jpa-181717?style=for-the-badge&logo=jpa&logoColor=white">
<img src="https://img.shields.io/badge/amazon aws-F8DC75?style=for-the-badge&logo=amazonaws&logoColor=white">
<img src="https://img.shields.io/badge/amazon rds-61DAFB?style=for-the-badge&logo=amazonrds&logoColor=white">
<img src="https://img.shields.io/badge/amazon s3-E34F26?style=for-the-badge&logo=amazons3&logoColor=white">
<br>

<img src="https://img.shields.io/badge/axios-61DAFB?style=for-the-badge&logo=axios&logoColor=black">
<img src="https://img.shields.io/badge/html5-E34F26?style=for-the-badge&logo=html5&logoColor=white">
<img src="https://img.shields.io/badge/css-1572B6?style=for-the-badge&logo=css&logoColor=white">
<img src="https://img.shields.io/badge/javascript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black">
<img src="https://img.shields.io/badge/amazon s3-E34F26?style=for-the-badge&logo=amazons3&logoColor=white">
<br>
<img src="https://img.shields.io/badge/java-007396?style=for-the-badge&logo=java&logoColor=white">
<img src="https://img.shields.io/badge/springboot-6DB33F?style=for-the-badge&logo=springboot&logoColor=white">
<img src="https://img.shields.io/badge/Springjpa-4FC08D?style=for-the-badge&logo=jpa&logoColor=white">
<img src="https://img.shields.io/badge/gradle-02303A?style=for-the-badge&logo=gradle&logoColor=white">
<img src="https://img.shields.io/badge/python-3776AB?style=for-the-badge&logo=python&logoColor=white">
<br>

<img src="https://img.shields.io/badge/html5-E34F26?style=for-the-badge&logo=html5&logoColor=white">
<img src="https://img.shields.io/badge/javascript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black">
<img src="https://img.shields.io/badge/css-1572B6?style=for-the-badge&logo=css3&logoColor=white">
<img src="https://img.shields.io/badge/axios-61DAFB?style=for-the-badge&logo=axios&logoColor=black">
<img src="https://img.shields.io/badge/Thymeleaf-339933?style=for-the-badge&logo=Thymeleaf&logoColor=white">
<br>

<img src="https://img.shields.io/badge/amazonaws-232F3E?style=for-the-badge&logo=amazonaws&logoColor=white">
<img src="https://img.shields.io/badge/amazon rds-61DAFB?style=for-the-badge&logo=amazonrds&logoColor=white">
<img src="https://img.shields.io/badge/amazon s3-E34F26?style=for-the-badge&logo=amazons3&logoColor=white">
<img src="https://img.shields.io/badge/redis-DD0031?style=for-the-badge&logo=redis&logoColor=white">
<img src="https://img.shields.io/badge/github action-000000?style=for-the-badge&logo=githubaction&logoColor=white">
<img src="https://img.shields.io/badge/mysql-4479A1?style=for-the-badge&logo=mysql&logoColor=white">


<br>
<img src="https://img.shields.io/badge/elasticsearch-4053D6?style=for-the-badge&logo=elasticsearch&logoColor=white">
<img src="https://img.shields.io/badge/logstash-FCC624?style=for-the-badge&logo=logstash&logoColor=black">
<img src="https://img.shields.io/badge/kibana-DD0031?style=for-the-badge&logo=kibana&logoColor=white">
<img src="https://img.shields.io/badge/junit5-F05032?style=for-the-badge&logo=junit5&logoColor=white">
<img src="https://img.shields.io/badge/jmeter-000000?style=for-the-badge&logo=jmeter&logoColor=white">
</div>

#

## 3. 기능 명세 🗂
<details>
<summary> 주요 기능 🖋 </summary>
<div markdown="1">
## 주요 기능 소개 🗂

(1) 장소 검색
| 장소 검색 | 예약(웨이팅) 시스템 |
|:------:|:------:|
| ![검색빠르게](https://user-images.githubusercontent.com/117708164/217257406-1717d3d7-5384-49d6-9fe5-67e3087a5ce4.gif) | ![웨이팅등록2배속](https://user-images.githubusercontent.com/117708164/217257762-10912785-2722-4dd9-938d-10a768b9d117.gif) |
|- 장소 검색<br> - 카테고리 필터 검색<br> - 랭킹 조회<br> |- 스토어 웨이팅 신청<br> - 스토어 현황 조회<br> - 사용자 유효성(메일) 인증 및 메일 호출|

- 장소 검색 기능
- 카테고리 필터 검색 기능
- 검색어 지정 검색 (가게 이름 / 도로명 주소 / 업종)
- 랭킹 조회(평점 4점 이상 / 평점 높은 순 / 리뷰 1000개 이상 / 리뷰 높은 순)
- Elastic Search + Nori 형태소 분석기를 이용한 빠르고 정확한 검색 기능 제공

| 장소 리뷰 기능 | 관리자페이지 |
|:------:|:------:|
| ![리뷰빠르게](https://user-images.githubusercontent.com/117708164/217258004-0e90f7d1-751f-480c-be8d-5cb66902d211.gif) |![](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/ace974d9-7b6f-4fd0-9433-82f2ed524571/ezgif.com-gif-maker_%284%29.gif?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20230207%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20230207T133119Z&X-Amz-Expires=86400&X-Amz-Signature=6f7007409b140efa46b329d72a035f2c2122c118029733af550f0f3dae4078ad&X-Amz-SignedHeaders=host&response-content-disposition=filename%3D%22ezgif.com-gif-maker%2520%284%29.gif%22&x-id=GetObject)|
|- 장소 리뷰 작성 및 조회 기능<br> - 리뷰 등록 시 스토어 정보 갱신(별점, 리뷰 갯수)<br>|- 웨이팅 현황 확인<br> - 웨이팅 호출(이메일)<br>|

#
## 시연영상 🎥
[시연영상 바로가기](https://www.youtube.com/watch?v=HmiIVvJn6I8&t=21s)

#
## 서비스 아키텍처 🎨
![image](https://user-images.githubusercontent.com/117708164/216933029-f5c882eb-daec-4216-a27c-56822226726f.png)

#
## ERD 👨🏻‍💻
<details>
<summary> 펼쳐보기 </summary>
<div markdown="1">

![image](https://user-images.githubusercontent.com/117708164/216933200-78984f6c-6653-46ea-bf1f-ee8900e5c2bf.png)

</div>
</details>

(2) 예약(웨이팅) 시스템
#
## API 💬
[Swagger API 바로가기](https://pintable.co.kr/swagger-ui/index.html?urls.primaryName=store#/store-controller/createStoreUsingPOST)

- 스토어 웨이팅 신청 기능
- 스토어 현황 조회 기능
- 사용자 유효성(메일) 인증 및 메일 호출 기능
#
## 트러블슈팅 🐞

(3) 장소 리뷰 기능
<details>
<summary> 데이터 수집 </summary>
<div markdown="1">
<br>
(1) 공공 API를 이용한 대용량 장소 데이터 수집<br>
- 공공 데이터 포털에서 제공하는 전국 음식점/카페의 파일 데이터 수집 (약 650만건)<br>

- 장소 리뷰 작성 및 조회 기능
- 리뷰 등록 시 스토어 정보 갱신(별점, 리뷰 갯수) 기능
<br>
(2) 장소 데이터 1차 가공<br>
- 공공 데이터 포털에서 수집한 데이터 중 불필요 컬럼 및 폐업 장소 데이터 제거 (약 200만건)<br>

<br>
(3) 네이버 플레이스 웹 크롤링을 통한 추가 데이터 수집<br>
- 웹크롤링(Python + 셀레니움)을 이용하여 리뷰 갯수/ 블로그 리뷰 / 별점 정보 등 추가 데이터 수집<br>
- 네이버 플레이스 크롤링 시 특정 횟수 이상 반복 시도시 차단되는 경우가 발생하였고, 아래 과정을 통해 해결<br>
👉 https://www.notion.so/404-Not-Found-9ec37cc4600545e7972663f4d9d06364<br>
<br>
(4) Faker 라이브러리를 이용한 리뷰/사용자 데이터 생성<br>
- Faker 라이브러리를 이용하여 약 600만건의 리뷰/사용자 데이터 생성<br>
<br>
</div>
</details>

## 4. 시연영상 🎥
[시연영상 바로가기](https://www.youtube.com/watch?v=iY3YxFOawYs)
<details>
<summary> 검색 성능 향상 </summary>
<div markdown="1">
🔎 검색 성능 개선 자세히 보기 : https://www.notion.so/PIN-TABLE-98c3a7dbb1324630a3a300575b2f7782<br>
ㄴ( 🥹 열심히했는데 봐주실꺼죠? 🥹)

## 5. 서비스 아키텍처 🎨
![image](https://user-images.githubusercontent.com/117708164/216933029-f5c882eb-daec-4216-a27c-56822226726f.png)
</div>
</details>

## 6. ERD 👨🏻‍💻
![image](https://user-images.githubusercontent.com/117708164/216933200-78984f6c-6653-46ea-bf1f-ee8900e5c2bf.png)

## 7. API 💬
[API명세서 바로가기 Swagger](https://pintable.co.kr/swagger-ui/index.html?urls.primaryName=store#/store-controller/createStoreUsingPOST)

## 8. 트러블슈팅 🐞

<details>
<summary> 동시성 제어 </summary>
<div markdown="1">
🧲 동시성 제어 자세히 보기 : https://www.notion.so/PIN-TABLE-721fb45b91454dda8255e0de4ac757ca
)
</div>
</details>
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
@Getter
@NoArgsConstructor
public class MsgResponseDto {
private int statusCode;
private String msg;
protected int statusCode;
protected String msg;

public MsgResponseDto(SuccessCode successCode) {
this.msg = successCode.getMessage();
Expand All @@ -23,15 +23,6 @@ public MsgResponseDto(int statusCode, String msg) {
this.msg = msg;
this.statusCode = statusCode;
}

public MsgResponseDto(CustomException customException) {
this.msg = customException.getMsg();
this.statusCode = customException.getStatusCode();
}
public MsgResponseDto(MethodArgumentNotValidException ex) {
this.msg = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();
this.statusCode = HttpStatus.BAD_REQUEST.value();
}
public MsgResponseDto(ErrorCode errorCode) {
this.msg = errorCode.getMessage();
this.statusCode = errorCode.getHttpStatus().value();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.example.pirate99_final.global.exception;

import lombok.Getter;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;

@Getter
public class CustomException extends RuntimeException{
Expand All @@ -19,5 +21,13 @@ public CustomException(int statusCode, String msg) {
this.msg = msg; // 안내 문구
this.statusCode = statusCode; // 상태 코드
}
public CustomException(int statusCode, ErrorCode errorCode) {
this.msg = msg; // 안내 문구
this.statusCode = statusCode; // 상태 코드
}
public CustomException(MethodArgumentNotValidException ex) {
this.msg = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();
this.statusCode = HttpStatus.BAD_REQUEST.value();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,21 @@
@RequiredArgsConstructor
public enum ErrorCode {

LOGIN_ERROR(HttpStatus.BAD_REQUEST, "로그인에 실패했습니다."),
SIGN_UP_ERROR(HttpStatus.BAD_REQUEST, "회원가입에 실패했습니다."),
NOT_FOUND_ID_ERROR(HttpStatus.OK, "해당하는 ID가 없습니다."),

NOT_FOUND_USER_ERROR(HttpStatus.OK, "해당하는 사용자를 찾을 수 없습니다."),
DUPLICATE_USER_ERROR(HttpStatus.OK, "이미 존재하는 회원입니다."),

WAITING_POST_ERROR(HttpStatus.BAD_REQUEST, "대기자 명단 등록에 실패했습니다."),
WRONG_PASSWORD_ERROR(HttpStatus.OK, "잘못된 비밀번호입니다."),
WAITING_DELETE_ERROR(HttpStatus.BAD_REQUEST, "대기자 명단 삭제에 실패했습니다."), // error code 대신 status code 200과 error message 를 함께 보낸다.


NOT_ENOUGH_TABLE(HttpStatus.OK, "빈 자리가 없습니다. 예약 등록 부탁드립니다."),
WRONG_LIMIT_WAITING_ERROR(HttpStatus.OK, "인원 제한 설정 값은 현재 대기자 인원보다 적을 수 없습니다."),

STORE_POST_ERROR(HttpStatus.BAD_REQUEST, "점포 등록에 실패했습니다."),
STORE_DELETE_ERROR(HttpStatus.BAD_REQUEST, "점포 삭제에 실패했습니다."),
NOT_FOUND_STORE_STATUS_ERROR(HttpStatus.BAD_REQUEST, "해당하는 상호 상태가 없습니다."),
NOT_FOUND_STORE_ERROR(HttpStatus.OK, "해당하는 상호명이 없습니다."),

REVIEW_POST_ERROR(HttpStatus.BAD_REQUEST, "리뷰 등록에 실패했습니다."),
REVIEW_DELETE_ERROR(HttpStatus.OK, "리뷰 삭제에 실패했습니다."),
NOT_FOUND_REVIEW_ERROR(HttpStatus.OK, "해당하는 리뷰가 없습니다."),

ALREADY_IN_QUEUE(HttpStatus.OK, "이미 대기열에 존재합니다."),

ALREADY_LEAVING(HttpStatus.OK, "이미 퇴장한 손님입니다."),

ALREADY_EATING(HttpStatus.OK, "이미 식사 중인 손님입니다."),
LIMIT_QUEUE_EXCEEDED(HttpStatus.OK, "제한 대기열 초과");


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public MsgResponseDto createReview(@PathVariable Long storeId, @RequestBody Revi

// DB select one
@GetMapping("/review/{storeId}/{reviewId}")
public ReviewResponseDto getReview(@PathVariable Long storeId, @PathVariable Long reviewId){return reviewService.getReview(storeId, reviewId);}
public MsgResponseDto getReview(@PathVariable Long storeId, @PathVariable Long reviewId){return reviewService.getReview(storeId, reviewId);}

// DB delete
@DeleteMapping("/review/{storeId}/{reviewId}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.example.pirate99_final.review.dto;

import com.example.pirate99_final.global.MsgResponseDto;
import com.example.pirate99_final.review.entity.Review;
import lombok.Getter;

@Getter
public class ReviewResponseDto {
public class ReviewResponseDto extends MsgResponseDto {
private Long reviewId;
private String username;
private String content;
Expand Down
Loading