From c7656717677511e1cfdaf70a0c442b970237c479 Mon Sep 17 00:00:00 2001 From: ydking0911 Date: Sat, 6 Jun 2026 14:07:00 +0900 Subject: [PATCH] docs: README changed --- README.md | 193 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 112 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index 2b33d97..6610cf4 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,65 @@ +
+ # BE-VibeCodeEval -AI 기반 코딩 테스트 평가 플랫폼의 **Spring Boot 백엔드 서버**입니다. +### AI 기반 코딩 테스트 평가 플랫폼 — Spring Boot 백엔드 서버 + 실시간 시험 관리, AI 채점 연동, WebSocket 브로드캐스트, SSE 스트리밍을 담당합니다. -[![Java](https://img.shields.io/badge/Java-17-007396?style=flat-square&logo=openjdk&logoColor=white)](https://openjdk.org/) -[![Spring Boot](https://img.shields.io/badge/Spring_Boot-3.2.0-6DB33F?style=flat-square&logo=springboot&logoColor=white)](https://spring.io/projects/spring-boot) -[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15-4169E1?style=flat-square&logo=postgresql&logoColor=white)](https://www.postgresql.org/) -[![Redis](https://img.shields.io/badge/Redis-7-DC382D?style=flat-square&logo=redis&logoColor=white)](https://redis.io/) -[![Docker](https://img.shields.io/badge/Docker-Compose-2496ED?style=flat-square&logo=docker&logoColor=white)](https://www.docker.com/) -[![Swagger](https://img.shields.io/badge/Swagger-OpenAPI_3-85EA2D?style=flat-square&logo=swagger&logoColor=black)](https://swagger.io/) -[![License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square)](LICENSE) +
+ +[![Java](https://img.shields.io/badge/Java-17-007396?style=for-the-badge&logo=openjdk&logoColor=white)](https://openjdk.org/) +[![Spring Boot](https://img.shields.io/badge/Spring_Boot-3.2.0-6DB33F?style=for-the-badge&logo=springboot&logoColor=white)](https://spring.io/projects/spring-boot) +[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15-4169E1?style=for-the-badge&logo=postgresql&logoColor=white)](https://www.postgresql.org/) +[![Redis](https://img.shields.io/badge/Redis-7-DC382D?style=for-the-badge&logo=redis&logoColor=white)](https://redis.io/) + +[![Docker](https://img.shields.io/badge/Docker-Compose-2496ED?style=for-the-badge&logo=docker&logoColor=white)](https://www.docker.com/) +[![Swagger](https://img.shields.io/badge/Swagger-OpenAPI_3-85EA2D?style=for-the-badge&logo=swagger&logoColor=black)](https://swagger.io/) +[![Gradle](https://img.shields.io/badge/Gradle-8.5-02303A?style=for-the-badge&logo=gradle&logoColor=white)](https://gradle.org/) +[![License](https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge)](LICENSE) + +
--- ## 목차 -- [기술 스택](#기술-스택) -- [아키텍처](#아키텍처) -- [프로젝트 구조](#프로젝트-구조) -- [주요 기능](#주요-기능) -- [API 개요](#api-개요) -- [인증 플로우](#인증-플로우) -- [실시간 통신](#실시간-통신) -- [시작하기](#시작하기) -- [환경 변수](#환경-변수) +- [기술 스택](#-기술-스택) +- [아키텍처](#-아키텍처) +- [프로젝트 구조](#-프로젝트-구조) +- [주요 기능](#-주요-기능) +- [API 개요](#-api-개요) +- [인증 플로우](#-인증-플로우) +- [실시간 통신](#-실시간-통신) +- [시작하기](#-시작하기) +- [환경 변수](#-환경-변수) --- -## 기술 스택 +## 🛠 기술 스택 + +
| 분류 | 기술 | -|------|------| -| Language | Java 17 | -| Framework | Spring Boot 3.2.0 | -| Security | Spring Security + JWT (HttpOnly Cookie) | -| Database | PostgreSQL 15 (JPA / Hibernate) | -| Cache | Redis 7 (Lettuce) | -| Real-time | STOMP WebSocket, SSE | -| API Docs | Springdoc OpenAPI (Swagger UI) | -| ID Generation | TSID (hypersistence-utils) | -| Config Encryption | Jasypt | -| Monitoring | Micrometer + Prometheus | -| Build | Gradle 8.5 | -| Container | Docker + Docker Compose | +|:----:|:-----| +| **Language** | Java 17 | +| **Framework** | Spring Boot 3.2.0 | +| **Security** | Spring Security + JWT (HttpOnly Cookie) | +| **Database** | PostgreSQL 15 (JPA / Hibernate) | +| **Cache** | Redis 7 (Lettuce) | +| **Real-time** | STOMP WebSocket, SSE | +| **API Docs** | Springdoc OpenAPI (Swagger UI) | +| **ID Generation** | TSID (hypersistence-utils) | +| **Config Encryption** | Jasypt | +| **Monitoring** | Micrometer + Prometheus | +| **Build** | Gradle 8.5 | +| **Container** | Docker + Docker Compose | + +
--- -## 아키텍처 +## 🏗 아키텍처 ``` ┌─────────────────────────────────────────────────────────────┐ @@ -72,6 +85,8 @@ AI 기반 코딩 테스트 평가 플랫폼의 **Spring Boot 백엔드 서버** └─────────────┘ ``` +
+ ### 도메인 구성 (Clean Architecture) ``` @@ -85,12 +100,12 @@ domain/ └── admin # 관리자 · 마스터 운영 ``` -각 도메인은 `ui → application → domain → infrastructure` 레이어로 분리되며, +각 도메인은 `ui → application → domain → infrastructure` 레이어로 분리되며, UseCase 단위로 비즈니스 로직이 구성됩니다. --- -## 프로젝트 구조 +## 📁 프로젝트 구조 ``` src/main/java/com/yd/vibecode/ @@ -115,38 +130,44 @@ src/main/java/com/yd/vibecode/ --- -## 주요 기능 +## ✨ 주요 기능 + +### 🔐 인증 / 인가 + +- **참가자 입장** — Entry Code + 이름 + 전화번호로 JWT 발급 (회원가입 불필요) +- **관리자 로그인** — ID/PW 기반 Access Token + Refresh Token 발급 +- **토큰 저장** — HttpOnly 쿠키 전달 (XSS 방지) +- **토큰 로테이션** — Refresh Token 재발급 시 기존 토큰 즉시 무효화 +- **블랙리스트** — 로그아웃된 Access Token을 Redis에 등록하여 재사용 차단 +- **STOMP 인증 우회** — WebSocket은 HttpOnly 쿠키 접근 불가 → body로 토큰 전달 후 `StompPrincipalInterceptor`에서 검증 -### 인증 / 인가 -- **참가자 입장**: Entry Code + 이름 + 전화번호로 JWT 발급 (회원가입 불필요) -- **관리자 로그인**: ID/PW 기반 Access Token + Refresh Token 발급 -- **토큰 저장**: HttpOnly 쿠키 전달 (XSS 방지) -- **토큰 로테이션**: Refresh Token 재발급 시 기존 토큰 즉시 무효화 -- **블랙리스트**: 로그아웃된 Access Token을 Redis에 등록하여 재사용 차단 -- **STOMP 인증 우회**: WebSocket은 HttpOnly 쿠키 접근 불가 → body로 토큰 전달 후 `StompPrincipalInterceptor`에서 검증 +### 📝 시험 관리 -### 시험 관리 - 시험 생성·시작·종료 (관리자) - 시험 상태 실시간 조회 (타이머 동기화) - 참가자 세션 정보 조회 -- 코드 드래프트 자동 저장 (PUT `/api/exams/{id}/code-draft`) +- 코드 드래프트 자동 저장 (`PUT /api/exams/{id}/code-draft`) + +### 🤖 코드 제출 · AI 채점 -### 코드 제출 · AI 채점 - 제출 접수 후 **202 Accepted** 즉시 응답 (비동기 처리) - **Outbox Poller**로 Redis 이벤트를 AI Worker에 전달 - AI 채점 완료 시 Callback 수신 (`POST /api/callbacks/ai/**`) - 채점 결과를 **SSE 스트림**으로 관리자에게 실시간 전송 -### 실시간 통신 -- **STOMP WebSocket** (`/ws`): 시험 상태 변경 브로드캐스트 -- **SSE** (`/api/admin/submissions/{id}/stream`): 채점 진행 스트리밍 +### 📡 실시간 통신 + +- **STOMP WebSocket** (`/ws`) — 시험 상태 변경 브로드캐스트 +- **SSE** (`/api/admin/submissions/{id}/stream`) — 채점 진행 스트리밍 + +### 💬 AI 채팅 연동 -### AI 채팅 연동 - 참가자 채팅 메시지 저장 → AI Worker로 전달 - 대화 이력 조회 - 토큰 사용량 추적 및 제한 -### 관리자 / 마스터 +### 🧑‍💼 관리자 / 마스터 + - 관리자 계정 CRUD, 입장 코드 생성·관리 - 실시간 참가자 현황 보드 - 제출 상세 조회 (루브릭·코드 포함) @@ -155,32 +176,36 @@ src/main/java/com/yd/vibecode/ --- -## API 개요 +## 📖 API 개요 + +
| Method | Path | 설명 | 권한 | -|--------|------|------|------| -| POST | `/api/auth/enter` | 참가자 입장 (JWT 발급) | Public | -| POST | `/api/auth/admin/login` | 관리자 로그인 | Public | -| POST | `/api/auth/admin/logout` | 로그아웃 | ADMIN | -| POST | `/api/auth/admin/reissue` | 토큰 재발급 | Cookie | -| GET | `/api/auth/me` | 내 정보 조회 | Any | -| GET | `/api/exams/{id}/state` | 시험 상태 조회 | USER | -| GET | `/api/exams/{id}/participants/me` | 참가자 세션 조회 | USER | -| POST | `/api/exams/{id}/submissions` | 코드 제출 (202) | USER | -| GET/PUT | `/api/exams/{id}/code-draft` | 코드 드래프트 | USER | -| GET | `/api/submissions/{id}` | 제출 상세 (본인) | USER | -| POST | `/api/chat/messages` | 채팅 메시지 저장 | USER | -| GET | `/api/chat/history` | 채팅 이력 조회 | Any | -| GET | `/api/problems` | 문제 목록 조회 | USER | -| GET | `/api/admin/**` | 관리자 전용 API | ADMIN/MASTER | -| POST | `/api/callbacks/ai/**` | AI 채점 결과 수신 | Internal | -| GET | `/api/admin/submissions/{id}/stream` | 채점 결과 SSE | ADMIN | - -> Swagger UI: `http://localhost:8080/swagger-ui/index.html` +|:------:|:-----|:-----|:----:| +| `POST` | `/api/auth/enter` | 참가자 입장 (JWT 발급) | Public | +| `POST` | `/api/auth/admin/login` | 관리자 로그인 | Public | +| `POST` | `/api/auth/admin/logout` | 로그아웃 | ADMIN | +| `POST` | `/api/auth/admin/reissue` | 토큰 재발급 | Cookie | +| `GET` | `/api/auth/me` | 내 정보 조회 | Any | +| `GET` | `/api/exams/{id}/state` | 시험 상태 조회 | USER | +| `GET` | `/api/exams/{id}/participants/me` | 참가자 세션 조회 | USER | +| `POST` | `/api/exams/{id}/submissions` | 코드 제출 (202) | USER | +| `GET/PUT` | `/api/exams/{id}/code-draft` | 코드 드래프트 | USER | +| `GET` | `/api/submissions/{id}` | 제출 상세 (본인) | USER | +| `POST` | `/api/chat/messages` | 채팅 메시지 저장 | USER | +| `GET` | `/api/chat/history` | 채팅 이력 조회 | Any | +| `GET` | `/api/problems` | 문제 목록 조회 | USER | +| `GET` | `/api/admin/**` | 관리자 전용 API | ADMIN/MASTER | +| `POST` | `/api/callbacks/ai/**` | AI 채점 결과 수신 | Internal | +| `GET` | `/api/admin/submissions/{id}/stream` | 채점 결과 SSE | ADMIN | + +
+ +> **Swagger UI** — `http://localhost:8080/swagger-ui/index.html` --- -## 인증 플로우 +## 🔑 인증 플로우 ``` 참가자 서버 @@ -207,7 +232,7 @@ src/main/java/com/yd/vibecode/ --- -## 실시간 통신 +## 📡 실시간 통신 ### STOMP WebSocket @@ -233,7 +258,7 @@ GET /api/admin/submissions/{submissionId}/stream --- -## 시작하기 +## 🚀 시작하기 ### 사전 요구사항 @@ -249,7 +274,7 @@ docker compose up -d # 2. 애플리케이션 실행 ./gradlew bootRun -# 서버: http://localhost:8080 +# 서버: http://localhost:8080 # Swagger: http://localhost:8080/swagger-ui/index.html ``` @@ -268,10 +293,12 @@ docker compose -f docker-compose.prod.yml up -d --- -## 환경 변수 +## ⚙️ 환경 변수 + +
| 변수 | 설명 | 예시 | -|------|------|------| +|:-----|:-----|:-----| | `SPRING_DATASOURCE_URL` | PostgreSQL JDBC URL | `jdbc:postgresql://localhost:5432/ai_vibe_coding_test` | | `SPRING_DATASOURCE_USERNAME` | DB 사용자명 | `postgres` | | `SPRING_DATASOURCE_PASSWORD` | DB 비밀번호 | `password` | @@ -283,17 +310,21 @@ docker compose -f docker-compose.prod.yml up -d | `JASYPT_ENCRYPTOR_PASSWORD` | 설정 파일 암호화 키 | `jasypt-password` | | `AI_SERVER_URL` | AI Worker 주소 | `http://localhost:8001` | +
+ --- -## 관련 레포지토리 +## 🔗 관련 레포지토리 + +
| 레포 | 설명 | -|------|------| +|:----:|:-----| | [FE-VibeCodeEval](../FE-VibeCodeEval) | Next.js 프론트엔드 (User / Admin / Master UI) | | [AI-VibeCodeEval](../AI-VibeCodeEval) | FastAPI + LangGraph AI 채점 워커 | ---- +
-## 전체 인프라 아키텍처 +
-전체 시스템 구성도(Mermaid)는 [`docs/architecture.md`](../docs/architecture.md)를 참조하세요. +> 전체 시스템 구성도(Mermaid)는 [`docs/architecture.md`](../docs/architecture.md)를 참조하세요.