Skip to content

Repository files navigation

BE-VibeCodeEval

AI 기반 코딩 테스트 평가 플랫폼 — Spring Boot 백엔드 서버

실시간 시험 관리, AI 채점 연동, WebSocket 브로드캐스트, SSE 스트리밍을 담당합니다.


JavaSpring BootPostgreSQLRedis

DockerSwaggerGradleLicense


목차


🛠 기술 스택

분류기술
LanguageJava 17
FrameworkSpring Boot 3.2.0
SecuritySpring Security + JWT (HttpOnly Cookie)
DatabasePostgreSQL 15 (JPA / Hibernate)
CacheRedis 7 (Lettuce)
Real-timeSTOMP WebSocket, SSE
API DocsSpringdoc OpenAPI (Swagger UI)
ID GenerationTSID (hypersistence-utils)
Config EncryptionJasypt
MonitoringMicrometer + Prometheus
BuildGradle 8.5
ContainerDocker + Docker Compose

🏗 아키텍처

┌─────────────────────────────────────────────────────────────┐
│ Cloudflare │
│ DNS · CDN · WAF · SSL/TLS │
└────────────────────────┬────────────────────────────────────┘
│ HTTPS / WSS
┌────▼────┐
│ Nginx │ :443 → :8080 / :8001
└────┬────┘
┌─────────────┼─────────────┐
│ │ │
┌──────▼──────┐ │ ┌──────▼──────┐
│ BE Server │ │ │ AI Worker │
│ Spring Boot │◄─────┘ │ FastAPI │
│ :8080 │◄────────────│ :8001 │
└──────┬──────┘ Callback └─────────────┘
│
┌──────┴──────┐
│ Data Layer │
│ PostgreSQL │
│ Redis │
└─────────────┘

도메인 구성 (Clean Architecture)

domain/
├── auth # 인증·인가 (JWT, 토큰 재발급)
├── exam # 시험 세션 관리
├── submission # 코드 제출 · Outbox Poller
├── chat # AI 채팅 · 토큰 사용량
├── problem # 문제 CRUD
├── statistics # 통계 집계
└── admin # 관리자 · 마스터 운영

각 도메인은 ui → application → domain → infrastructure 레이어로 분리되며, UseCase 단위로 비즈니스 로직이 구성됩니다.


📁 프로젝트 구조

src/main/java/com/yd/vibecode/
├── VibecodeApplication.java
├── domain/
│ ├── admin/ # 관리자 계정·보드·메트릭·시험 관리
│ ├── auth/ # 로그인·로그아웃·토큰 재발급
│ ├── chat/ # 채팅 저장·조회·AI 콜백
│ ├── exam/ # 시험 상태·참가자 세션
│ ├── problem/ # 문제 조회
│ ├── statistics/ # 통계
│ └── submission/ # 제출·스트리밍·내부 처리
└── global/
├── config/ # Web, JPA, Redis, WebSocket, Async
├── security/ # SecurityConfig, JWT, STOMP Interceptor
├── interceptor/ # JWT Blacklist, Cookie Handshake
├── swagger/ # API 명세 인터페이스
├── exception/ # 전역 예외 처리
├── annotation/ # @CurrentUser, @AccessToken 등
└── util/ # CookieUtils, SecureRandomGenerator

✨ 주요 기능

🔐 인증 / 인가

  • 참가자 입장 — 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)

🤖 코드 제출 · AI 채점

  • 제출 접수 후 202 Accepted 즉시 응답 (비동기 처리)
  • Outbox Poller로 Redis 이벤트를 AI Worker에 전달
  • AI 채점 완료 시 Callback 수신 (POST /api/callbacks/ai/**)
  • 채점 결과를 SSE 스트림으로 관리자에게 실시간 전송

📡 실시간 통신

  • STOMP WebSocket (/ws) — 시험 상태 변경 브로드캐스트
  • SSE (/api/admin/submissions/{id}/stream) — 채점 진행 스트리밍

💬 AI 채팅 연동

  • 참가자 채팅 메시지 저장 → AI Worker로 전달
  • 대화 이력 조회
  • 토큰 사용량 추적 및 제한

🧑‍💼 관리자 / 마스터

  • 관리자 계정 CRUD, 입장 코드 생성·관리
  • 실시간 참가자 현황 보드
  • 제출 상세 조회 (루브릭·코드 포함)
  • 시스템 메트릭, 활동 로그
  • 플랫폼 전역 설정 (시험 시간, 토큰 제한, 데이터 보관 정책)

📖 API 개요

MethodPath설명권한
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/**관리자 전용 APIADMIN/MASTER
POST/api/callbacks/ai/**AI 채점 결과 수신Internal
GET/api/admin/submissions/{id}/stream채점 결과 SSEADMIN

Swagger UIhttp://localhost:8080/swagger-ui/index.html


🔑 인증 플로우

참가자 서버
│ │
├─ POST /api/auth/enter ──────►│
│ { entryCode, name, phone } │
│◄─────────────────────────────┤ Set-Cookie: accessToken (HttpOnly)
│ { accessToken } │ (body 포함: STOMP 인증용)
│ │
│ STOMP Connect │
├─ connectHeaders: { │
│ Authorization: Bearer ... │
│ } ──────────────────────────►│ StompPrincipalInterceptor 검증
│ │
관리자
│
├─ POST /api/auth/admin/login ─►│
│◄─────────────────────────────┤ Set-Cookie: accessToken, refreshToken (HttpOnly)
│ │
├─ POST /api/auth/admin/reissue►│ refreshToken 검증 + 로테이션
│◄─────────────────────────────┤ 새 accessToken, refreshToken 발급

📡 실시간 통신

STOMP WebSocket

ws://host/ws
SUBSCRIBE /topic/exams/{examId}/state
→ 시험 시작·종료·상태 변경 브로드캐스트
SUBSCRIBE /topic/exams/{examId}/submissions
→ 신규 제출 알림 (관리자 보드)

SSE (Server-Sent Events)

GET /api/admin/submissions/{submissionId}/stream
← data: {"status":"JUDGING","score":null}
← data: {"status":"COMPLETED","score":85}
← event: close

🚀 시작하기

사전 요구사항

  • Java 17+
  • Docker & Docker Compose

로컬 실행

# 1. 인프라 기동 (PostgreSQL + Redis)
docker compose up -d
# 2. 애플리케이션 실행
./gradlew bootRun
# 서버: http://localhost:8080# Swagger: http://localhost:8080/swagger-ui/index.html

Docker 빌드

docker build -t be-vibecodeeval .
docker run -p 8080:8080 be-vibecodeeval

프로덕션 배포

docker compose -f docker-compose.prod.yml up -d

⚙️ 환경 변수

변수설명예시
SPRING_DATASOURCE_URLPostgreSQL JDBC URLjdbc:postgresql://localhost:5432/ai_vibe_coding_test
SPRING_DATASOURCE_USERNAMEDB 사용자명postgres
SPRING_DATASOURCE_PASSWORDDB 비밀번호password
SPRING_REDIS_HOSTRedis 호스트localhost
SPRING_REDIS_PORTRedis 포트6379
JWT_SECRETJWT 서명 키 (256bit+)your-secret-key
JWT_ACCESS_EXPIRATIONAccess Token 만료 (ms)3600000
JWT_REFRESH_EXPIRATIONRefresh Token 만료 (ms)604800000
JASYPT_ENCRYPTOR_PASSWORD설정 파일 암호화 키jasypt-password
AI_SERVER_URLAI Worker 주소http://localhost:8001

🔗 관련 레포지토리

레포설명
FE-VibeCodeEvalNext.js 프론트엔드 (User / Admin / Master UI)
AI-VibeCodeEvalFastAPI + LangGraph AI 채점 워커

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages