Skip to content

VibeCodeEval/BE-VibeCodeEval

Repository files navigation

BE-VibeCodeEval

AI 기반 μ½”λ”© ν…ŒμŠ€νŠΈ 평가 ν”Œλž«νΌ β€” Spring Boot λ°±μ—”λ“œ μ„œλ²„

μ‹€μ‹œκ°„ μ‹œν—˜ 관리, AI 채점 연동, WebSocket λΈŒλ‘œλ“œμΊμŠ€νŠΈ, SSE μŠ€νŠΈλ¦¬λ°μ„ λ‹΄λ‹Ήν•©λ‹ˆλ‹€.


Java Spring Boot PostgreSQL Redis

Docker Swagger Gradle License


λͺ©μ°¨


πŸ›  기술 μŠ€νƒ

λΆ„λ₯˜ 기술
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

πŸ— μ•„ν‚€ν…μ²˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        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 κ°œμš”

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 ──────►│
  β”‚  { 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_URL PostgreSQL JDBC URL jdbc:postgresql://localhost:5432/ai_vibe_coding_test
SPRING_DATASOURCE_USERNAME DB μ‚¬μš©μžλͺ… postgres
SPRING_DATASOURCE_PASSWORD DB λΉ„λ°€λ²ˆν˜Έ password
SPRING_REDIS_HOST Redis 호슀트 localhost
SPRING_REDIS_PORT Redis 포트 6379
JWT_SECRET JWT μ„œλͺ… ν‚€ (256bit+) your-secret-key
JWT_ACCESS_EXPIRATION Access Token 만료 (ms) 3600000
JWT_REFRESH_EXPIRATION Refresh Token 만료 (ms) 604800000
JASYPT_ENCRYPTOR_PASSWORD μ„€μ • 파일 μ•”ν˜Έν™” ν‚€ jasypt-password
AI_SERVER_URL AI Worker μ£Όμ†Œ http://localhost:8001

πŸ”— κ΄€λ ¨ λ ˆν¬μ§€ν† λ¦¬

레포 μ„€λͺ…
FE-VibeCodeEval Next.js ν”„λ‘ νŠΈμ—”λ“œ (User / Admin / Master UI)
AI-VibeCodeEval FastAPI + LangGraph AI 채점 μ›Œμ»€

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages