์ญ๊ฒฝ๋งค ์๋น์ค์ ๋ฉ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ ๋๋ค. ๊ฒฝ๋งคยท์ ์ฐฐยท๋ฆฌ๋ทฐ ๋ฑ ํต์ฌ ๋๋ฉ์ธ CRUD์ ํจ๊ป AI ์๋ด ์ฑ๋ด, ์ ์ ๊ฐ ์ค์๊ฐ ์ฑํ , ๋ชจ๋ํฐ๋ง์ ๋ด๋นํฉ๋๋ค.
EventBridge Scheduler
โ (๊ฒฝ๋งค ์์/์ข
๋ฃ 5๋ถ ์ ํธ๋ฆฌ๊ฑฐ)
โผ
auction-lambda
โ RDS ์ํ ๋ณ๊ฒฝ + Redis Pub/Sub ๋ฐํ
โผ
Redis auction-events
โ
โผ
auction (๋ฉ์ธ ์๋ฒ) โโ Elasticsearch ๋ํ๋จผํธ ๋๊ธฐํ
โโโ pgvector ์๋ฒ ๋ฉ ๋๊ธฐํ (๋์ฐฐ ์)
ํด๋ผ์ด์ธํธ
โ POST /api/chat/rooms/{roomId}/messages
โผ
AiController (SSE text/event-stream)
โ
โผ
AiService โโ Redis ์ปจํ
์คํธ ์บ์ ์กฐํ (์ต๊ทผ N๊ฐ ๋ฉ์์ง)
โ
โผ
ChatClient (DeepSeek V3)
โ Tool Calling ํ๋จ
โโโ AuctionTools (PostgreSQL ์กฐํ)
โโโ RAG (pgvector ์ ์ฌ๋ ๊ฒ์)
โ
โผ
SSE ์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ: TOKEN โ DONE (์ฒซ ๋ฉ์์ง ์ TOPIC ํฌํจ)
READY โโโบ ACTIVE โโโบ DONE (๋์ฐฐ)
โ โโโโบ NO_BID (์ ์ฐฐ)
โโโโบ CANCELLED (READY ์ํ + ์์ 10๋ถ ์ ๊น์ง)
- EventBridge Scheduler๋ก ์์/์ข ๋ฃ ์ค์ผ์ค ์๋ ๋ฑ๋ก
- Elasticsearch + PostgreSQL ์ด์ค ๊ฒ์ (Nori ํ๊ตญ์ด ํํ์ ๋ถ์), ES ์ฅ์ ์ PostgreSQL fallback
max_priceAPI ์๋ต ๋ ธ์ถ ๊ธ์ง (ํ๋งค์์๊ฒ ์ต๋ ํฌ๋ง๊ฐ ์จ๊น)
- Redisson ๋ถ์ฐ๋ฝ์ผ๋ก ๋์ ์ ์ฐฐ ๊ฒฝํฉ ๋ฐฉ์ง (์์ฐจ ์ฒ๋ฆฌ)
- ํ์ฌ ์ต์ ๊ฐ๋ณด๋ค ๋ฎ์ ๊ฐ๊ฒฉ๋ง ๋ฑ๋ก ๊ฐ๋ฅ,
max_price์ด๊ณผ ๋ถ๊ฐ - ๊ฒฝ๋งค ์ํ enum ์ธ์ ์ข ๋ฃ ์๊ฐ๊ณผ ํ์ฌ ์๊ฐ ๋น๊ต๋ก ์ด์ค ๊ฒ์ฆ
SSE ์คํธ๋ฆฌ๋ฐ์ผ๋ก ์ค์๊ฐ ์๋ต์ ์์ ํ๋ฉฐ, Tool Calling๊ณผ RAG๋ฅผ ํตํด DB์ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ต๋ณํฉ๋๋ค.
| Tool | ์ญํ | ๋ฐฉ์ |
|---|---|---|
getBidsByAuctionId |
๊ฒฝ๋งค ์ ์ฐฐ ํํฉ ยท ์ต์ ๊ฐ ยท ๊ฒฝ์ ๋ถ์ | PostgreSQL |
getRecentAuctionResults |
์ํ ์์ธ ยท ๋์ฐฐ ์ด๋ ฅ ์กฐํ | PostgreSQL |
getSellerStats |
ํ๋งค์ ์ข ํฉ ์ ๋ขฐ๋ (๋์ฐฐ ํ์, ํ๊ท ํ์ ) | PostgreSQL |
getSellerReviewInsights |
ํ๋งค์ ํ๊ธฐ ํค์๋ ๋ถ์ | RAG (pgvector) |
getMyAuctions |
๋ด๊ฐ ๋ฑ๋กํ ๊ฒฝ๋งค ํํฉ ยท ํ์ฌ ์ต์ ๊ฐ | PostgreSQL |
getMyBids |
๋ด๊ฐ ์ ์ฐฐํ ๊ฒฝ๋งค ํํฉ ยท 1์ ์ฌ๋ถ | PostgreSQL |
getAuctionStatsByCategory |
์นดํ ๊ณ ๋ฆฌ๋ณ ๋์ฐฐ ํต๊ณ ยท ์์ธ ๋ถ์ | PostgreSQL |
searchAuctionDescriptions |
๋์ฐฐ ๊ฒฝ๋งค ์ํ ์ค๋ช ์๋ฏธ ๊ฒ์ | RAG (pgvector) |
RAG ๊ตฌํ ํฌ์ธํธ
- ํ๊ธฐ RAG: HyDE(๊ฐ์ ๋ฌธ์ ์์ฑ) + Contextual Retrieval + ๊ฐ์ฑ ๋ฐฉํฅ score ํํฐ
- ๊ฒฝ๋งค ์ค๋ช RAG: Lambda Pub/Sub ํ์ดํ๋ผ์ธ์ผ๋ก ๋์ฐฐ ์ ์๋ ์๋ฒ ๋ฉ ์ ์ฅ
- ๋์ฐฐ ํ ๊ตฌ๋งค์-ํ๋งค์ 1:1 ์ฑํ ๋ฐฉ ์๋ ์์ฑ (Redis Pub/Sub ์ด๋ฒคํธ ์์ )
- WebSocket + STOMP + SockJS, Redis Pub/Sub ๋ธ๋ก์ปค๋ก ๋ค์ค ์๋ฒ ์ธ์คํด์ค ๊ฐ ๋ฉ์์ง ๊ณต์
- ๋์ฐฐ ๊ฒฝ๋งค ๋น์ฌ์(๊ตฌ๋งค์/ํ๋งค์)๋ง ์์ฑ ๊ฐ๋ฅ, ๋ณตํฉ ์ ๋ํฌ ์ ์ฝ
(reviewer_id, reviewee_id, auction_id) - S3 Presigned PUT URL ๋ฐ๊ธ (10๋ถ TTL) โ CloudFront URL๋ก ๋ฐํ
- ๋ฆฌ๋ทฐ ์ ์ฅ ์ pgvector ์๋ฒ ๋ฉ ์๋ ์ฐ๋
- Spring Actuator๋ก JVM ๋ฉํธ๋ฆญ ๋ ธ์ถ (ํฌํธ 9001, ์ฑ ํฌํธ 8080๊ณผ ๋ถ๋ฆฌ)
- Grafana Alloy ์ฌ์ด๋์นด๊ฐ scrape โ Amazon Managed Prometheus(AMP) remote_write
- AWS IAM ์ญํ ๊ธฐ๋ฐ SigV4 ์ธ์ฆ (Access Key ์์)
- Amazon Managed Grafana(AMG)์์ JVM, HTTP ์์ฒญ ํํฉ ์ค์๊ฐ ์๊ฐํ
com.example.auction/
โโโ common/
โ โโโ config/ # Security, Redis, QueryDSL, WebSocket, Spring AI, pgvector
โ โโโ dto/ # BaseResponse, PageResponse
โ โโโ entity/ # BaseEntity (์์ฑ์ผ, ์์ ์ผ, ์ญ์ ์ผ)
โ โโโ exception/ # GlobalExceptionHandler, ServiceErrorException
โ
โโโ domain/
โโโ auth/ # ํ์๊ฐ์
, ๋ก๊ทธ์ธ, ํ ํฐ ๊ฐฑ์ , ์์
๋ก๊ทธ์ธ
โโโ user/ # ๋ง์ดํ์ด์ง, ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ, ํ์ ํํด
โโโ auction/ # ๊ฒฝ๋งค CRUD, ๊ฒ์ (ES + PostgreSQL), EventBridge ์ฐ๋
โ โโโ result/ # ๋์ฐฐ ๊ฒฐ๊ณผ ์กฐํ
โ โโโ search/ # Elasticsearch ๋ํ๋จผํธ, ๊ฒ์ ์๋น์ค
โโโ bid/ # ์
์ฐฐ ์์ฑ (๋ถ์ฐ๋ฝ), ์
์ฐฐ ์กฐํ
โโโ category/ # ์นดํ
๊ณ ๋ฆฌ ํธ๋ฆฌ ์กฐํ, ๊ด๋ฆฌ์ CRUD
โโโ review/ # ๋ฆฌ๋ทฐ CRUD, S3 Presigned URL, RAG ์๋ฒ ๋ฉ ์ฐ๋
โโโ chat/ # AI ์ฑํ
๋ฐฉ CRUD, ๋ฉ์์ง ๋ชฉ๋ก (์ปค์ ํ์ด์ง), Redis ์ปจํ
์คํธ
โโโ ai/ # SSE ์คํธ๋ฆฌ๋ฐ, Tool Calling 8์ข
, RAG 2์ข
, ์๋ฒ ๋ฉ ์๋น์ค
โโโ userchat/ # ์ ์ ๊ฐ ์ค์๊ฐ ์ฑํ
(WebSocket + Redis Pub/Sub)
โโโ notification/ # Redis Pub/Sub ์๋ฆผ ๋ฐํ
| ๋ณ์๋ช | ์ค๋ช | ํ์ |
|---|---|---|
POSTGRES_URL |
PostgreSQL JDBC URL | โ |
POSTGRES_USERNAME |
DB ์ฌ์ฉ์๋ช | โ |
POSTGRES_PASSWORD |
DB ๋น๋ฐ๋ฒํธ | โ |
REDIS_HOST |
Redis ํธ์คํธ | โ |
ELASTICSEARCH_URIS |
Elasticsearch URI | โ |
ELASTICSEARCH_PASSWORD |
Elasticsearch ๋น๋ฐ๋ฒํธ | โ |
JWT_SECRET |
JWT ์๋ช ํค (32์ ์ด์) | โ |
ADMIN_SECRET_KEY |
๊ด๋ฆฌ์ ๊ณ์ ์์ฑ ํค | โ |
DEEPSEEK_API_KEY |
DeepSeek V3 ์ฑํ API ํค | โ |
OPENAI_API_KEY |
OpenAI ์๋ฒ ๋ฉ API ํค | โ |
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET |
Google OAuth2 | โ |
KAKAO_CLIENT_ID / KAKAO_CLIENT_SECRET |
Kakao OAuth2 | โ |
NAVER_CLIENT_ID / NAVER_CLIENT_SECRET |
Naver OAuth2 | โ |
LAMBDA_ARN |
๊ฒฝ๋งค ์ํ ์๋ํ Lambda ARN | โ |
ROLE_ARN |
EventBridge ์คํ ์ญํ ARN | โ |
S3_BUCKET_NAME |
๋ฆฌ๋ทฐ ์ด๋ฏธ์ง S3 ๋ฒํท๋ช | โ |
CLOUDFRONT_DOMAIN |
๋ฆฌ๋ทฐ ์ด๋ฏธ์ง CDN ๋๋ฉ์ธ | โ |
AWS ๊ด๋ จ ๋ณ์(
LAMBDA_ARN,S3_BUCKET_NAME๋ฑ)๋ ๋ก์ปฌ ์คํ ์ ์ค์ ํ์ง ์์๋ ๋ฉ๋๋ค.
- Java 21
- Docker / Docker Compose
ํ๋ก์ ํธ ๋ฃจํธ์ .env ํ์ผ์ ์์ฑํฉ๋๋ค.
POSTGRES_DATABASE=auction
POSTGRES_USERNAME=postgres
POSTGRES_PASSWORD=your_password
POSTGRES_URL=jdbc:postgresql://localhost:5432/auction
REDIS_HOST=localhost
ELASTICSEARCH_PASSWORD=your_es_password
ELASTICSEARCH_URIS=http://localhost:9200
JWT_SECRET=your_jwt_secret_key_min_32_chars
ADMIN_SECRET_KEY=your_admin_secret_key
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
KAKAO_CLIENT_ID=your_kakao_client_id
KAKAO_CLIENT_SECRET=your_kakao_client_secret
NAVER_CLIENT_ID=your_naver_client_id
NAVER_CLIENT_SECRET=your_naver_client_secret
DEEPSEEK_API_KEY=your_deepseek_api_key
OPENAI_API_KEY=your_openai_api_keydocker compose up -d postgres redis elasticsearchElasticsearch ๊ธฐ๋์ ์ฝ 30์ด~1๋ถ ์์๋ฉ๋๋ค.
docker compose ps๋ก ์ํ๋ฅผ ํ์ธํ์ธ์.
./gradlew bootRun --args='--spring.profiles.active=dev'์๋ฒ๊ฐ ๋จ๋ฉด http://localhost:8080 ์ผ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.