diff --git a/README.md b/README.md index 32b27d1..f6be721 100644 --- a/README.md +++ b/README.md @@ -1 +1,465 @@ -# CStar 백엔드 레포지토리 +# 🍭 CStar 백엔드 레포지토리 + +
+ + + +

컴퓨터 공학 퀴즈 웹 애플리케이션 프로젝트 입니다.

+ + 📒 팀 노션 | + 🎨 프론트엔드 레포지토리 | + 🎨 이슈 & PR 관리 +
+ +

+ +## 1. 기술 스택 +- 백엔드 + - Kotlin 1.9.24 + - SpringBoot 3.3.2 + - JUnit + - MySQL 8.0.35 + - Redis 7.2 + - WebSocket + - Docker + - GitHub Actions + - AWS + +

+ +## 2. 프로젝트 구조 + +### 1. 아키텍처 + + +

+### 2. 패키지 구조 + +``` +기본경로 : main ──> kotlin ──> yjh ──> cstar + +main... +├── cstar +│ ├── auth +│ ├── category +│ ├── common +│ ├── config +│ ├── engine +│ ├── game +│ ├── application +│ ├── domain +│ ├── infrastructure +│ ├── presentation +│ ├── member +│ ├── quiz +│ ├── room +│ ├── util +│ ├── websocket +│ │ +│ ├── CstarApplication.kt +│ +test... +├── devtoon + ├── engine + ├── game + ├── jpa + ├── member + ├── quiz + ├── redis + ├── room + ├── websocket + ├── IntegrationTest.kt +``` +### main +- auth : 인증 도메인을 구현한다 +- category : 퀴즈의 카테고리 도메인을 구현한다 +- common : 모든 도메인에서 공통적으로 사용하는 기능(공통 예외, 공통 응답, 예외 핸들러 등)을 포함한다 +- config : 설정 파일을 정의한다 +- engine : 실시간 게임 로직을 구현한다 +- member : 회원 도메인을 구현한다 +- quiz : 퀴즈 도메인을 구현한다 +- room : 게임방 도메인을 구현한다 +- util : 공통 유틸 클래스를 정의한다(redis util) +- websocket : 웹소켓 핸들러 및 Stomp Message 컨트롤러를 정의한다 + +### test +- 도메인별로 테스트가 정의되어 있다 + - application : 데이터베이스와 연동된 서비스 계층 통합 테스트 작성 + - concurrency : 동시성 문제 테스트 작성 + - domain : 도메인별 핵심 비즈니스 로직 단위 테스트 작성 + - IntegrationTest.kt 통합 테스트 관련 공통 추상 클래스 + +

+ + +## 3. 개발 환경 구축 +- back-end 와 front-end 서버를 로컬환경에서 실행시키고 테스트할 수 있습니다. +- 아래의 단계에 따라 로컬환경에서 순차적으로 실행하면 됩니다. +- docker를 컨테이너로 애플리케이션을 실행시키기 때문에 docker가 설치되어 있어야 합니다. + +### 1. 프로젝트 클론 +``` +git clone https://github.com/FreakPeople/freak-CStar-backend.git +``` + +### 2. 도커 컴포즈 명령어 실행 +- 터미널의 프로젝트 최상위 디렉토리에서 아래의 명령어를 실행합니다. +``` +cd docker +docker-compose up -d +``` + +### 3. 테스트 실행 +- mac os 환경 +``` +./gradlew clean test +``` +- window 환경 +``` +gradlew clean test +``` + +

+ + +## 4. ERD 다이어그램 +
+ erd +
+ +

+ +## 5. API 명세서 + +### 인증 API +
+로그인 + +`POST /v1/authenticate` +``` +Request +{ + "email" : "string", + "password" : "string" +} +``` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "string" + } +} +``` +--- +
+ +### 회원 API +
+회원 등록 + +`POST /v1/members` + +``` +Request +{ + "name" : "string", + "password" : "string", + "nickname" : "string" +} +``` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : int +} +``` +--- +
+
+내 정보 조회 + +`GET /v1/members/me` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "id": int, + "email": "string", + "nickname": "string", + "createdAt": "YYYY-MM-DDTHH:MM:SS", + "updatedAt": "YYYY-MM-DDTHH:MM:SS" + } +} +``` +--- +
+ +### 퀴즈 API +
+퀴즈 등록 + +`POST /v1/quizzes` + +``` +Request +{ + "question" : "string", + "answer" : "string", + "categoryId" : int +} +``` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : int +} +``` +--- +
+
+카테고리별 퀴즈 조회 + +`GET /v1/quizzes` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "totalPages": int, + "totalElements": int, + "first": boolean, + "last": boolean, + "size": int, + "content": [ + { + "writerId": int, + "question": "strign", + "answer": "string", + "categoryId": int + }, + .... +} +``` +--- +
+
+회원이 생성한 퀴즈 조회 + +`GET /v1/quizzes/filter?quizFilterType=created` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "totalPages": int, + "totalElements": int, + "first": boolean, + "last": boolean, + "size": int, + "content": [ + { + "writerId": int, + "question": "string", + "answer": "string", + "categoryId": int + } + ], + ... +} +``` +--- +
+
+회원이 시도한 퀴즈 조회 (푼 문제 + 풀지 못한 문제) + +`GET /v1/quizzes/filter?quizFilterType=attempted` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "totalPages": int, + "totalElements": int, + "first": boolean, + "last": boolean, + "size": int, + "content": [ + { + "writerId": int, + "question": "string", + "answer": "string", + "categoryId": int + } + ], + ... +} +``` +--- +
+ +### 게임 API +
+게임 생성 + +`POST /v1/games` + +``` +Request +{ + "roomId": int, + "quizCategoryId" : int, + "totalQuestions" : int +} +``` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : null +} +``` +--- +
+ +### 게임방 API +
+게임방 생성 + +`POST /v1/rooms` + +``` +Request +{ + "maxCapacity" : int +} +``` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : int +} +``` +--- +
+
+게임방 단건 조회 + +`GET /v1/rooms/{id}` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "id": int, + "maxCapacity": int, + "currCapacity": int, + "status": "string", + "createdAt": "YYYY-MM-DDTHH:MM:SS", + "updatedAt": "YYYY-MM-DDTHH:MM:SS", + "deletedAt": null + } +} +``` +--- +
+
+게임방 전체 조회 + +`GET /v1/rooms` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : { + "totalPages": int, + "totalElements": int, + "first": boolean, + "last": boolean, + "size": int, + "content": [ + { + "id": int, + "maxCapacity": int, + "currCapacity": int, + "status": "string", + "createdAt": "YYYY-MM-DDTHH:MM:SS", + "updatedAt": "YYYY-MM-DDTHH:MM:SS", + "deletedAt": null + }, + ... +} +``` +--- +
+
+게임방 참여 요청 + +`POST /v1/rooms/{id}` + +``` +Response / 200 OK +{ + "status" : "string", + "code" : int + "message" : "string", + "data" : int +} +``` + +--- +
+ +

+ +## 6. 화면 구성 + +https://github.com/user-attachments/assets/9be8b1de-274b-4e2d-999c-ae23b4056851 + +

+ + +## 7. 팀원 +| BackEnd | BackEnd | +|:----------------------------------------------------------------------------:|:-----------------------------------------------------------------------------:| +| | | +| [황유정](https://github.com/youjungHwang) | [정지훈](https://github.com/Jeongjjuna) | +