Skip to content

Latest commit

ย 

History

240 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ›๏ธ MUSINSSAK (Spring Boot + React)

์„ค๊ณ„๊ฐ€ ๋ช…ํ™•ํ•˜๋ฉด, "์ฝ”๋“œ๋ฅผ ์น˜๋Š” ํ–‰์œ„" ๋Š” ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๋Š” "์ˆ˜๋‹จ" ์ด ๋œ๋‹ค.

์„ค๊ณ„๊ฐ€ ๋ช…ํ™•ํ•˜์ง€ ์•Š์œผ๋ฉด, "์ฝ”๋“œ๋ฅผ ์น˜๋Š” ํ–‰์œ„" ๋Š” ๋ถˆํ•„์š”ํ•œ "๋…ธ๋™" ์ด ๋œ๋‹ค.

๐Ÿ“– ์›น ์„œ๋น„์Šค ๊ฐœ์š”

์†Œ๊ฐœ
๋ฌด์‹ ์‚ญ(MUSINSSAK)์€ ๋ฌด์‹ ์‚ฌ ํ™ˆํŽ˜์ด์ง€๋ฅผ ๋ชจ๋ฐฉํ•˜์—ฌ ๊ตฌํ˜„ํ•œ ์ด์ปค๋จธ์Šค ์‡ผํ•‘๋ชฐ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๋Š” ํฌ๋กค๋งํ•œ ์ƒํ’ˆ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒํ’ˆ ์„ ํƒ โ†’ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ โ†’ ์ฃผ๋ฌธ โ†’ ๊ฒฐ์ œ๊นŒ์ง€์˜ ํ๋ฆ„์„ ๊ฒฝํ—˜,

์ถ”๊ฐ€๋กœ AI ์ฑ—๋ด‡ ์ถ”์ฒœ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๊ฐœ์ธํ™”๋œ ์ƒํ’ˆ ์ถ”์ฒœ๊ณผ ๊ตฌ๋งค ์ง€์›์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ๊ธฐ๊ฐ„
2025.07.18(๊ธˆ) ~ ์ง„ํ–‰ ์ค‘

๊ฐœ๋ฐœ ์ธ์›
AI 1๋ช…, ๋ฐฑ์—”๋“œ 2๋ช…, ํ”„๋ก ํŠธ์—”๋“œ 2๋ช…


๐Ÿ”ง BE ๊ธฐ์ˆ  ์Šคํƒ

์˜์—ญ ๊ตฌ๋ถ„ ๊ธฐ์ˆ  ๋„๊ตฌ ์„ ์ • ์ด์œ  ์‚ฌ์šฉ์ฒ˜
์–ธ์–ด &
ํ”„๋ ˆ์ž„์›Œํฌ
Java 17, Spring Boot 3.5.3 ์ตœ์‹  LTS ๊ธฐ๋ฐ˜์˜ ์•ˆ์ •์„ฑ๊ณผ ํ’๋ถ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” Spring Boot ์„ ํƒ - REST API ์„œ๋ฒ„ ๊ฐœ๋ฐœ
- ์ „์ž์ƒ๊ฑฐ๋ž˜ ๋„๋ฉ”์ธ ๋กœ์ง ๊ตฌํ˜„
ORM/JPA Spring Data JPA, QueryDSL JPA๋กœ CRUD ๋‹จ์ˆœํ™”, QueryDSL๋กœ
๋ฌดํ•œ ์Šคํฌ๋กค(์ปค์„œ ๊ธฐ๋ฐ˜) ํŽ˜์ด์ง• ๋ฐ ๋™์  ์ฟผ๋ฆฌ ๊ตฌํ˜„
- ์ƒํ’ˆ ๊ฒ€์ƒ‰/์กฐํšŒ API
- ์นดํ…Œ๊ณ ๋ฆฌ/๋ธŒ๋žœ๋“œ ์ •๋ ฌยทํ•„ํ„ฐ๋ง
DB MySQL 8.0 RDBMS ์ค‘ ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๊ฐ€์žฅ ๋งŽ์€ MySQL์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. - ์ƒํ’ˆ ๊ฒ€์ƒ‰/์กฐํšŒ API
- ์นดํ…Œ๊ณ ๋ฆฌ/๋ธŒ๋žœ๋“œ ์ •๋ ฌยทํ•„ํ„ฐ๋ง
DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ Flyway DB ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ๋ฒ„์ „ ๊ด€๋ฆฌ, ํ˜‘์—… ์ถฉ๋Œ ์ตœ์†Œํ™” - V1__init.sql ๊ธฐ๋ฐ˜ ํ…Œ์ด๋ธ” ์ƒ์„ฑ
- ๋ฐฐํฌ ์‹œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ž๋™ ์ ์šฉ
์บ์‹œ/์„ธ์…˜
๊ด€๋ฆฌ
Redis 7.0 In-Memory ๊ธฐ๋ฐ˜์œผ๋กœ ์„ธ์…˜/ํ† ํฐ
์ €์žฅ ๋ฐ ๋ถ„์‚ฐ ๋ฝ ์ œ๊ณต
- Refresh Token ์ €์žฅยท๊ฒ€์ฆ
- ๋กœ๊ทธ์•„์›ƒ ์‹œ ํ† ํฐ ์‚ญ์ œ
- ์ฃผ๋ฌธ ๋™์‹œ์„ฑ ์ œ์–ด ๋ฝ
๋ฉ”์‹œ์ง• &
์ด๋ฒคํŠธ
(์ง„ํ–‰์ค‘)
Apache Kafka + Zookeeper ๋Œ€๊ทœ๋ชจ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐ ๋น„๋™๊ธฐ ํ™•์žฅ์„ฑ ํ™•๋ณด - ๊ฒฐ์ œ ์™„๋ฃŒ
โ†’ ์ฃผ๋ฌธ ํ™•์ • ์ด๋ฒคํŠธ ๋ฐœํ–‰
- ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
๋ณด์•ˆ &
์ธ์ฆ
Spring Security + JJWT JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ/์ธ๊ฐ€๋กœ ๋ฌด์ƒํƒœ ์•„ํ‚คํ…์ฒ˜ ๊ตฌํ˜„ - ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ API
- Access/Refresh
โ†’ Token ๋ฐœ๊ธ‰ ๋ฐ ๊ฒ€์ฆ
API ๋ฌธ์„œํ™” Springdoc (Swagger UI) API ํ…Œ์ŠคํŠธ ๋ฐ ๋ฌธ์„œํ™”๋ฅผ ๋น ๋ฅด๊ฒŒ ์ง€์› - /swagger-ui.html์„ ํ†ตํ•œ
๊ฐœ๋ฐœ/QA ํ˜‘์—…
ํด๋ผ์šฐ๋“œ/
๋ฐฐํฌ
(์ง„ํ–‰์ค‘)
GitHub Actions, Docker Compose, AWS EC2 GitHub Actions๋กœ CI/CD ์ž๋™ํ™”, Docker Compose๋กœ ํ™˜๊ฒฝ ์ผ๊ด€์„ฑ ํ™•๋ณด, AWS EC2 ํ”„๋ฆฌํ‹ฐ์–ด๋กœ ๋น„์šฉ ์ ˆ๊ฐ - main ๋ธŒ๋žœ์น˜ ํ‘ธ์‹œ ์‹œ
์ž๋™ ๋นŒ๋“œ/๋ฐฐํฌ
- BE/DB/Redis/Kafka๋ฅผ Docker Compose๋กœ ๊ด€๋ฆฌ
- AWS EC2์— ๋ฐฐํฌ
๋ชจ๋‹ˆํ„ฐ๋ง
(์ง„ํ–‰์ค‘)
Prometheus + Grafana ๋ฉ”ํŠธ๋ฆญ ๊ธฐ๋ฐ˜ WAS ์„ฑ๋Šฅ/์•ˆ์ •์„ฑ ๋ชจ๋‹ˆํ„ฐ๋ง - Spring Boot Actuator + Micrometer โ†’ /actuator/prometheus ์ˆ˜์ง‘
- Docker Compose ๋ถ„๋ฆฌ(infra/monitoring)๋กœ ๋…๋ฆฝ ๊ธฐ๋™
- ๋Œ€์‹œ๋ณด๋“œ: RPS(30s), p95(1m), 5xx ์—๋Ÿฌ์œจ, Tomcat Thread Util, Hikari Util/Pending, Top5 RPSยทp95 by URI
- ์šด์˜: Actuator 8081(๋‚ด๋ถ€๋ง), ๊ฐœ๋ฐœ: 8080
ํ™˜๊ฒฝ ๋ณ€์ˆ˜
๊ด€๋ฆฌ
.env ๋ฏผ๊ฐ ์ •๋ณด ๋ณ„๋„ ๊ด€๋ฆฌ๋กœ ๋ณด์•ˆ ๊ฐ•ํ™” - DB ๊ณ„์ •, JWT Secret,
Kakao API Key ๊ด€๋ฆฌ
ํ”„๋ก ํŠธ์—”๋“œ React(ts), Vite, Axios ๋น ๋ฅธ ๋ฒˆ๋“ค๋ง(Vite)๊ณผ ๊ฐ„๋‹จํ•œ API ํ˜ธ์ถœ(Axios)๋กœ ํšจ์œจ์ ์ธ UI/๋ฐ์ดํ„ฐ ์—ฐ๋™ - API ํ˜ธ์ถœ
๋นŒ๋“œ ๋„๊ตฌ Gradle ์˜์กด์„ฑ ๊ด€๋ฆฌ ๋ฐ ๋นŒ๋“œ ์ž๋™ํ™” - Spring Boot ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ/ํ…Œ์ŠคํŠธ/๋ฐฐํฌ
ํ…Œ์ŠคํŠธ/ํ˜‘์—… Postman, GitHub PR API ํ…Œ์ŠคํŠธ ๋ฐ ํ˜‘์—… ํ‘œ์ค€ํ™” - API ์‹œ๋‚˜๋ฆฌ์˜ค ํ…Œ์ŠคํŠธ
- ๋ธŒ๋žœ์น˜ ์ „๋žต & ์ฝ”๋“œ ๋ฆฌ๋ทฐ

Scouter APM โ†’ Prometheus+Grafana ์ „ํ™˜ ์ด์œ : ์ปค์Šคํ…€ ์ง€ํ‘œ/๋Œ€์‹œ๋ณด๋“œ ๊ตฌ์„ฑ์˜ ์œ ์—ฐ์„ฑ, CI/CDยท๋กœ์ปฌ ๋ถ„๋ฆฌ ๊ธฐ๋™, ์ปค๋ฎค๋‹ˆํ‹ฐ ๋Œ€์‹œ๋ณด๋“œ/์ƒํƒœ๊ณ„ ํ™œ์šฉ.


๐Ÿ“Š ER ๋‹ค์ด์–ด๊ทธ๋žจ

  1. ER ๋‹ค์ด์–ด๊ทธ๋žจ ๋งํฌ(ํด๋ฆญ)
image

์š”์•ฝ

  • ์ด ํ…Œ์ด๋ธ” 34๊ฐœ, ์™ธ๋ž˜ํ‚ค 42๊ฐœ
  • ํ•ต์‹ฌ ์ถ•: users โ†’ orders โ†’ order_items โ†’ products โ†’ payments

๋„๋ฉ”์ธ๋ณ„ ๊ตฌ์„ฑ

  • ํšŒ์›/๊ณ„์ • (4): ์‚ฌ์šฉ์ž/์ฃผ์†Œ/ํŒŒ์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ ๊ด€๋ฆฌ
  • ๋ธŒ๋žœ๋“œยท์นดํ…Œ๊ณ ๋ฆฌยท์ƒํ’ˆ (6): ์ƒํ’ˆ/์˜ต์…˜/์ด๋ฏธ์ง€/๋ฐฐ์†ก์ •์ฑ…
  • ๊ด€์‹ฌยท์ตœ๊ทผยท์žฅ๋ฐ”๊ตฌ๋‹ˆ (4): ์ฐœ/์ตœ๊ทผ ๋ณธ/์žฅ๋ฐ”๊ตฌ๋‹ˆ
  • ์ฃผ๋ฌธยท์žฌ๊ณ  (4): ์ฃผ๋ฌธ/์ฃผ๋ฌธ์ƒํ’ˆ/๋ฐฐ์†ก/์žฌ๊ณ ์˜ˆ์•ฝ
  • ๊ฒฐ์ œ (4): ๊ฒฐ์ œ/์นด๋“œ/์นด์นด์˜คํŽ˜์ด/์•„์ž„ํฌํŠธ
  • ๋ฆฌ๋ทฐยท๋ฌธ์˜ (7): ๋ฆฌ๋ทฐ/๋ฌธ์˜/์ƒํ’ˆ๋ฌธ์˜
  • ์ฟ ํฐยท์ ๋ฆฝ๊ธˆ (5): ์ฟ ํฐ/์‚ฌ์šฉ๋‚ด์—ญ/์ ๋ฆฝ๊ธˆ/์ด๋ ฅ

๐Ÿ”จ ์„œ๋ฒ„ ์•„ํ‚คํ…์ฒ˜ (๊ฐœ๋ฐœ/์šด์˜ ๊ตฌ์กฐ ์ง„ํ–‰์ค‘)

Dev (Local ยท Docker Compose)

  • ๊ฒฝ๋กœ: React Dev Server โ†’ Spring Boot App โ†’ Docker(Compose) โ†’ MySQL / Redis / Kafka / ZK / Scouter
  • ๋ชฉ์ : ํ™˜๊ฒฝ ์žฌํ˜„์„ฑ, ๋กœ์ปฌ ์ผ๊ด„ ๊ธฐ๋™, Kafka-UI & Scouter๋กœ ๊ฐ€์‹œ์„ฑ ํ™•๋ณด
  • AI Server (๋กœ์ปฌ): Spring Boot App โ†’ (Docker ๋„คํŠธ์›Œํฌ ๋‚ด๋ถ€) โ†’ ai-server:8000
    • WebClient baseUrl: http://ai-server:8000 (Compose ์„œ๋น„์Šค๋ช… ์‚ฌ์šฉ)
    • docker-compose.yml์— ai-server ์„œ๋น„์Šค ์ถ”๊ฐ€ ๋ฐ app์˜ depends_on: [ai-server] ์„ค์ •
    • /api/chat์€ permitAll ์œ ์ง€, AI๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ์ƒํ’ˆ ID ์ˆœ์„œ ๋ณด์กด ํ›„ DB ์กฐํšŒยท์‘๋‹ต ์กฐ๋ฆฝ
image

Prod (AWS)

  • ๊ฒฝ๋กœ: CloudFront+S3 โ†’ Nginx/ALB โ†’ EC2(App) โ†’ RDS / Redis / Kafka
  • FE: CloudFront+S3๋กœ ์ •์  ํŒŒ์ผ(CSS/JS/์ด๋ฏธ์ง€ ๋“ฑ)์„ CDN ์บ์‹ฑํ•ด ์ „์†ก ์†๋„ ์ตœ์ ํ™”
  • Nginx/ALB: API ์š”์ฒญ์„ ๋ฐ›์•„ EC2(App) ์ธ์Šคํ„ด์Šค๋กœ ํŠธ๋ž˜ํ”ฝ ๋ถ„์‚ฐ ์ฒ˜๋ฆฌ
  • BE: EC2 ์ปจํ…Œ์ด๋„ˆ์—์„œ Spring Boot ์‹คํ–‰
  • DB/์บ์‹œ/๋ฉ”์‹œ์ง•: ์ดˆ๊ธฐ์—” EC2+Compose๋กœ ์‹œ์ž‘ โ†’ ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€ ์‹œ RDS / ElastiCache / MSK๋กœ ํ™•์žฅ
  • AI Server: EC2(App) โ†’ (๋‚ด๋ถ€ ํ†ต์‹ ) โ†’ EC2(AI, Python FastAPI/Flask)
    • Java ๋ฐฑ์—”๋“œ๊ฐ€ WebClient๋กœ AI ์„œ๋ฒ„์— ์งˆ์˜ โ†’ ์ถ”์ฒœ ์ƒํ’ˆ ID ๋ฆฌ์ŠคํŠธ ์ˆ˜์‹  โ†’ DB ์กฐํšŒ๋กœ ์ตœ์ข… ์‘๋‹ต ์กฐ๋ฆฝ
    • ์™ธ๋ถ€ ๊ณต๊ฐœ ์—†์Œ(ํผ๋ธ”๋ฆญ ํŠธ๋ž˜ํ”ฝ ์ฐจ๋‹จ), ALB๋Š” App๋งŒ ๋…ธ์ถœ, AI๋Š” ํ”„๋ผ์ด๋น— ์„œ๋ธŒ๋„ท/๋ณด์•ˆ๊ทธ๋ฃน ํ—ˆ์šฉ์œผ๋กœ ๋‚ด๋ถ€ ํ˜ธ์ถœ๋งŒ
image

๋ฐฐํฌ (CI/CD)

  • GitHub Actions๋กœ ๋นŒ๋“œ โ†’ Docker ์ด๋ฏธ์ง€ ํ‘ธ์‹œ โ†’ EC2 ์ž๋™ ๋ฐฐํฌ
  • ์ธํ”„๋ผ ์ƒ์„ฑ/์„ค์ •์€ ์ฝ˜์†” ๋˜๋Š” IaC(Terraform ๋“ฑ)๋กœ ๊ด€๋ฆฌ

์š”์•ฝ: Dev๋Š” ๊ฐ„๋‹จํžˆ ํ•œ ๋ฒˆ์— ๋„์›Œ ๊ฐœ๋ฐœ, Prod๋Š” CDNยท๋กœ๋“œ๋ฐธ๋Ÿฐ์„œยท๋งค๋‹ˆ์ง€๋“œ ์„œ๋น„์Šค๋กœ ์•ˆ์ •์„ฑ๊ณผ ํ™•์žฅ์„ฑ ๊ฐ•ํ™”


๐Ÿ“‚ Git ์ „๋žต & ์ปจ๋ฒค์…˜

ํ˜‘์—… ๋ฐฉ์‹, ์ปค๋ฐ‹ ์ปจ๋ฒค์…˜

Git Flow

  • main: ์šด์˜ ๋ธŒ๋žœ์น˜
  • dev: ๊ฐœ๋ฐœ ํ†ตํ•ฉ ๋ธŒ๋žœ์น˜
  • feature/*: ๊ธฐ๋Šฅ ๋‹จ์œ„ ๋ธŒ๋žœ์น˜ โ†’ dev ๋จธ์ง€
  • dev โ†’ main: ํŒ€์žฅ ์Šน์ธ ํ›„ ๋จธ์ง€

Commit Message

  • feat: ๊ธฐ๋Šฅ ์ถ”๊ฐ€
  • fix: ๋ฒ„๊ทธ ์ˆ˜์ •
  • docs: ๋ฌธ์„œ ์ˆ˜์ •
  • style: ์ฝ”๋“œ ์Šคํƒ€์ผ/UI
  • refactor: ๋ฆฌํŒฉํ† ๋ง
  • test: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ
  • chore: ์„ค์ •/๋นŒ๋“œ ์ž‘์—…

๐Ÿ“Œ ์ฃผ์š” ๊ตฌํ˜„ ๋‚ด์šฉ

ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ƒ์„ธ (JWT ์ธ์ฆ, ์ƒํ’ˆ ์กฐํšŒ, ๊ฒฐ์ œ ๋“ฑ)

1. ์ธ์ฆ/์ธ๊ฐ€ (JWT + Redis)

  • Access (~15๋ถ„) / Refresh (~14์ผ) ๊ตฌ์กฐ
  • Refresh ํ† ํฐ์€ Redis์— ์ €์žฅ (RT:{userId})
  • /api/auth/refresh: Access ์žฌ๋ฐœ๊ธ‰
  • /api/auth/logout: Redis Refresh ์‚ญ์ œ + ์ฟ ํ‚ค ๋งŒ๋ฃŒ
  • ์‹คํŒจ ์‘๋‹ต ํ†ต์ผ
    { "status": 401, "code": "AUTH_REQUIRED", "message": "๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค." }

2. ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

  • ErrorCode: ์ƒํƒœยท์ฝ”๋“œยท๋ฉ”์‹œ์ง€ ์ •์˜
  • BusinessException: ์„œ๋น„์Šค์—์„œ throw
  • GlobalExceptionHandler: JSON ์‘๋‹ต์œผ๋กœ ๋ณ€ํ™˜

3. ์ƒํ’ˆ ์ƒ์„ธ ์กฐํšŒ ๋ฐ ์นดํ…Œ๊ณ ๋ฆฌ ํŽ˜์ด์ง€

  • ์ƒํ’ˆ + ๋ธŒ๋žœ๋“œ + ์ด๋ฏธ์ง€ + ์˜ต์…˜ + ๋ฆฌ๋ทฐ ์ง‘๊ณ„
  • Facade ํŒจํ„ด ์ ์šฉ
    • Service: ์กฐํšŒ ๊ทœ์น™, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
    • Facade: DTO ์กฐ๋ฆฝ
  • QueryDSL๋กœ ์ •๋ ฌ/ํŽ˜์ด์ง• ์ตœ์ ํ™”

4. ์นด์นด์˜ค ์ฃผ์†Œ๊ฒ€์ƒ‰ API

  • REST API ํ‚ค โ†’ .env ๊ด€๋ฆฌ
  • RestTemplate Client โ†’ Service โ†’ Controller ๋ถ„๋ฆฌ
  • ์‘๋‹ต DTO: ๋„๋กœ๋ช…, ์ง€๋ฒˆ, ์šฐํŽธ๋ฒˆํ˜ธ, ๊ฑด๋ฌผ๋ช… ๋“ฑ ๋ณ€ํ™˜

5. ๊ฒฐ์ œ

  • ์นด๋“œ์‚ฌ ์ธ์ฆ โ†’ ์„œ๋ฒ„ ์‘๋‹ต โ†’ PortOne(์•„์ž„ํฌํŠธ) ์—ฐ๋™
  • ๊ธฐ๋Šฅ: ๊ฒฐ์ œ / ์ทจ์†Œ / ํ™˜๋ถˆ
  • ๋ณด์•ˆ ๋ฐ ์ƒํƒœ ๋™๊ธฐํ™” ๊ณ ๋ ค

6. ์ฑ—๋ด‡ API (AI ์„œ๋ฒ„ ์—ฐ๋™)

  • Public API(POST /api/chat) ์ œ๊ณต โ†’ ๋กœ๊ทธ์ธ ์—†์ด ์ด์šฉ ๊ฐ€๋Šฅ
  • ChatService: AI ์„œ๋ฒ„ ํ˜ธ์ถœ โ†’ ์ƒํ’ˆ DB ์กฐํšŒ โ†’ ์‘๋‹ต ์กฐ๋ฆฝ
  • ์ˆœ์„œ ๋ณด์žฅ: AI ์ถ”์ฒœ ์ƒํ’ˆ ID ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•ด DB ๊ฒฐ๊ณผ๋ฅผ ์žฌ์ •๋ ฌ
  • WebClient ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ํ†ต์‹ ์œผ๋กœ Python AI ์„œ๋ฒ„์™€ ์—ฐ๋™
  • ์‘๋‹ต ์˜ˆ์‹œ:
    {
      "chatbotMessage": "์—ฌํ–‰๊ฐˆ ๋•Œ ์“ธ๋งŒํ•œ ๊ฐ€๋ฐฉ์„ ์ถ”์ฒœํ•ด๋“œ๋ฆด๊ฒŒ์š”.",
      "recommendedProducts": [ ... ]
    }
    

7. ํ”„๋ก ํŠธ์—”๋“œ ๊ตฌ์กฐ (Atomic Design)

src/
 โ”œโ”€ api/              # API ํ˜ธ์ถœ ํ•จ์ˆ˜
 โ”œโ”€ components/
 โ”‚   โ”œโ”€ atoms/        # input, button ๋“ฑ ์ตœ์†Œ ๋‹จ์œ„
 โ”‚   โ”œโ”€ molecules/    # ์ฃผ์†Œ ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ ๋“ฑ
 โ”‚   โ”œโ”€ organisms/    # atoms + molecules ์กฐํ•ฉ (๋ชจ๋‹ฌ ๋“ฑ)
 โ”‚   โ”œโ”€ templates/    # ๋ ˆ์ด์•„์›ƒ/์„น์…˜ ๋‹จ์œ„
 โ”œโ”€ pages/            # ํ™”๋ฉด ๋‹จ์œ„

๐Ÿ”ฅ BE ์ฑŒ๋ฆฐ์ง€ & ํ•ด๊ฒฐ (๋ฌธ์ œ ์ƒํ™ฉ๊ณผ ํ•ด๊ฒฐ ๊ณผ์ • (์„ฑ๋Šฅ, ๋™์‹œ์„ฑ, ๋ณด์•ˆ ๋“ฑ) ์ง„ํ–‰ ์ค‘)

Scouter

image

Prometheus, Grafana

ํ”„๋กœ๋ฉ”ํ…Œ์šฐ์Šคยท๊ทธ๋ผํŒŒ๋‚˜๋กœ ์ง€ํ‘œ ํ™•์ธ โ†’ ๋ฆฌํŒฉํ† ๋ง์œผ๋กœ ๊ทธ๋ž˜ํ”„ ๊ฐœ์„ (ํด๋ฆญ)

image
  • Prometheus + Grafana ๊ธฐ๋ฐ˜ ๋ชจ๋‹ˆํ„ฐ๋ง๋กœ ์ „ํ™˜ํ•˜์—ฌ ์„ฑ๋Šฅ ๋ถ„์„ ์ง„ํ–‰ (Spring Boot Actuator + Micrometer, /actuator/prometheus)
  • ๋ถ€ํ•˜ ํ…Œ์ŠคํŠธ ์ค‘ RPS, p95, 5xx, Tomcat Thread Util, Hikari Util/Pending ์ง€ํ‘œ๋กœ ๋ณ‘๋ชฉ ์‹๋ณ„ โ†’ ๊ฐœ์„  ์•„์ด๋””์–ด ์ •๋ฆฌ/์ ์šฉ
  • ์ง„ํ–‰ ์ƒํ™ฉ์€ Grafana ๋Œ€์‹œ๋ณด๋“œ ์บก์ฒ˜(์ „/ํ›„ ๋น„๊ต ๊ทธ๋ž˜ํ”„)์™€ ํ•จ๊ป˜ ์—…๋ฐ์ดํŠธ ์˜ˆ์ •

๐Ÿ“‚ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

musinssak/
โ”œโ”€ api/                          # ์™ธ๋ถ€ ๋…ธ์ถœ ๋ ˆ์ด์–ด (์ž…ยท์ถœ๋ ฅ ๊ฒฝ๊ณ„)
โ”‚  โ”œโ”€ <domain>/                  # ์˜ˆ: product, order, auth ...
โ”‚  โ”‚  โ”œโ”€ dto/                    # ์š”์ฒญ/์‘๋‹ต DTO
โ”‚  โ”‚  โ””โ”€ facade/                 # ์œ ์ฆˆ์ผ€์ด์Šค ์กฐํ•ฉ/ํ๋ฆ„ ์กฐ์ •
โ”‚  โ””โ”€ <domain>Controller.java    # ๊ฐ ๋„๋ฉ”์ธ ์ปจํŠธ๋กค๋Ÿฌ
โ”‚
โ”œโ”€ common/                       # ์ „์—ญ ๊ณตํ†ต ๋ชจ๋“ˆ
โ”‚  โ”œโ”€ exception/                 # ErrorCode, ์˜ˆ์™ธ ๊ณ„์ธต, ๊ธ€๋กœ๋ฒŒ ํ•ธ๋“ค๋Ÿฌ
โ”‚  โ””โ”€ web/                       # ๊ณตํ†ต ์‘๋‹ต/ํ•„ํ„ฐ/๋ฆฌ์กธ๋ฒ„ ๋“ฑ ์›น ์œ ํ‹ธ
โ”‚
โ”œโ”€ domain/                       # ํ•ต์‹ฌ ๋„๋ฉ”์ธ (๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™)
โ”‚  โ”œโ”€ <domain>/
โ”‚  โ”‚  โ”œโ”€ entity/                 # JPA ์—”ํ‹ฐํ‹ฐ(์• ๊ทธ๋ฆฌ๊ฒŒ์ž‡ ๋ฃจํŠธ ์ค‘์‹ฌ)
โ”‚  โ”‚  โ”œโ”€ repository/             # JPA/QueryDSL ๋ฆฌํฌ์ง€ํ† ๋ฆฌ (๋„๋ฉ”์ธ ๊ด€์ )
โ”‚  โ”‚  โ””โ”€ service/                # ๋„๋ฉ”์ธ ์„œ๋น„์Šค(ํŠธ๋žœ์žญ์…˜, ์ •ํ•ฉ์„ฑ)
โ”‚  โ””โ”€ ...
โ”‚
โ”œโ”€ infra/                        # ์™ธ๋ถ€ ์‹œ์Šคํ…œ ์–ด๋Œ‘ํ„ฐ (๊ตฌํ˜„ ์ƒ์„ธ)
โ”‚  โ”œโ”€ external/                  # ์นด์นด์˜ค ์ฃผ์†Œ๊ฒ€์ƒ‰ ๋“ฑ ์™ธ๋ถ€ API ํด๋ผ์ด์–ธํŠธ
โ”‚  โ”œโ”€ openapi/                   # Swagger/Springdoc(OpenAPI) ์„ค์ •/๊ทธ๋ฃนํ™”
โ”‚  โ”œโ”€ security/                  # JWT, Security ์„ค์ •/ํ•„ํ„ฐ/์ธ์ฆ ์ธํ”„๋ผ
โ”‚  โ””โ”€ test/                      # ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ๋ณด์กฐ(๋„์ปค/์Šฌ๋ผ์ด์Šค ๋“ฑ)
  • ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ: api(์ž…ยท์ถœ๋ ฅ) โ†” domain(๊ทœ์น™) โ†” infra(์™ธ๋ถ€/๊ตฌํ˜„)๋กœ ๋‚˜๋ˆ  ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ & ๊ต์ฒด ์šฉ์ด์„ฑ ํ™•๋ณด.
  • ๋„๋ฉ”์ธ ์ค‘์‹ฌ: ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์€ domain์— ์ง‘์ค‘(์—”ํ‹ฐํ‹ฐ/์„œ๋น„์Šค/๋ฆฌํฌ์ง€ํ† ๋ฆฌ), ์ปจํŠธ๋กค๋Ÿฌ๋Š” ์–‡๊ฒŒ ์œ ์ง€.
  • ํŒŒ์‚ฌ๋“œ ๋„์ž…: api//facade๊ฐ€ ์œ ์ฆˆ์ผ€์ด์Šค ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜๊ณผ DTO ์กฐ๋ฆฝ ๋‹ด๋‹น โ†’ ์„œ๋น„์Šค ๊ฐ„ ์ˆœํ™˜์ฐธ์กฐ ๋ฐฉ์ง€.
  • ์™ธ๋ถ€ ์—ฐ๋™ ์บก์Аํ™”: infra/external์— ์™ธ๋ถ€ API ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ชจ์•„ ์—๋Ÿฌ/์žฌ์‹œ๋„/DTO ๋งคํ•‘์„ ํ‘œ์ค€ํ™”.
  • ๋ฌธ์„œยท๋ณด์•ˆ ํ‘œ์ค€ํ™”: infra/openapi(API ๋ฌธ์„œ), infra/security(JWT/ํ•„ํ„ฐ)๋กœ ์ผ๊ด€๋œ ์ง„์ž…/๋ฌธ์„œ/์ธ์ฆ ์ฒด๊ณ„ ์ œ๊ณต.
  • ํ…Œ์ŠคํŠธ ์žฌํ˜„์„ฑ: infra/test๋กœ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ๋ณด์กฐ(๋„์ปค/์Šฌ๋ผ์ด์Šค) โ†’ ์•ˆ์ •์  ํšŒ๊ท€ ๊ฒ€์ฆ.

๐Ÿ“ ๊ธฐํƒ€ ์‚ฐ์ถœ๋ฌผ

  1. ๋…ธ์…˜ ๋งํฌ(ํด๋ฆญ)
image
  1. figma-Readdy(ํด๋ฆญ)
image
  1. miro ์š”๊ตฌ์‚ฌํ•ญ ๋ถ„์„(ํด๋ฆญ)
image
  1. API ๋ช…์„ธ์„œ(ํด๋ฆญ)
image
  1. dbdiagram(ํด๋ฆญ)
image
  1. swagger
image
  1. ์ž‘์—…๋ฆฌ์ŠคํŠธ ์—‘์…€(ํด๋ฆญ)
image
  1. Sequence Diagram
image (11)
  1. AI ์ฑ—๋ด‡ ์‹คํ–‰ ํ™”๋ฉด


๐Ÿ“‘ ๊ณต์œ /ํ•™์Šต ์ •๋ฆฌ

๊ณต์œ /ํ•™์Šต ์ •๋ฆฌ ๋งํฌ(ํด๋ฆญ)

  • ๊ฐœ๋ฐœ ํ™˜๊ฒฝ & ๋ฐฐํฌ

    • Docker + MySQL + Spring Boot + React ์—ฐ๋™
    • Flyway๋กœ DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ด€๋ฆฌ
    • Git ๋ธŒ๋žœ์น˜ ์ „๋žต & ์ปค๋ฐ‹ ์ปจ๋ฒค์…˜
    • GitHub Actions ๊ธฐ๋ฐ˜ CI/CD (์ง„ํ–‰ ์ค‘)
  • ๋ฐฑ์—”๋“œ ํ•ต์‹ฌ ๊ธฐ์ˆ 

    • Spring Data JPA + QueryDSL: ํ•œ ๋นˆ(Repository)ยท๋‘ ํƒ€๊นƒ ๊ตฌ์กฐ
    • ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ: ErrorCode โ†’ BusinessException โ†’ GlobalHandler
    • JWT ๊ธฐ๋ฐ˜ ์ธ์ฆ/์ธ๊ฐ€ + Redis Refresh Token
    • ์นด์นด์˜ค ์ฃผ์†Œ๊ฒ€์ƒ‰ API ์—ฐ๋™
  • ํ”„๋ก ํŠธ/ํ™˜๊ฒฝ ์„ค์ •

    • Vite ํ™˜๊ฒฝ ๋ณ€์ˆ˜(VITE_ ์ ‘๋‘์‚ฌ) ํƒ€์ž… ์•ˆ์ •์„ฑ ํ™•๋ณด
    • React ํ”„๋กœ์ ํŠธ ์‹คํ–‰/์—ฐ๋™ ํ™•์ธ
  • ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์‚ฌ๋ก€

    • ์ƒํ’ˆ ์ƒ์„ธ ์กฐํšŒ (๋ธŒ๋žœ๋“œยท์˜ต์…˜ยท๋ฆฌ๋ทฐ ์ง‘๊ณ„ + Facade ํŒจํ„ด)
    • Swagger(OpenAPI) ๋ฌธ์„œํ™” (Code-First ๋ฐฉ์‹)
    • ๋ชจ๋‹ˆํ„ฐ๋ง: Scouter APM (์ง„ํ–‰ ์ค‘)
  • ๊ธฐํƒ€

    • DIP ์›์น™ ์ •๋ฆฌ (์—”ํ‹ฐํ‹ฐยท๋ ˆํฌ์ง€ํ† ๋ฆฌยท์„œ๋น„์Šค ์ฐธ์กฐ ๊ตฌ์กฐ)
    • Postman์œผ๋กœ JWT API ํ…Œ์ŠคํŠธ
    • ChatGPT ํ”„๋กฌํ”„ํŠธ ํ•™์Šต ํ™œ์šฉ

โœ… ํ•ต์‹ฌ ์š”์•ฝ

  • ๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„ (DDD): ์—”ํ‹ฐํ‹ฐ/์„œ๋น„์Šค/ํŒŒ์‚ฌ๋“œ ์—ญํ•  ๋ถ„๋ฆฌ
  • ์•ˆ์ •์ ์ธ ์ธ์ฆ ๊ตฌ์กฐ: JWT + Redis ๊ธฐ๋ฐ˜ ํ† ํฐ ๊ด€๋ฆฌ
  • ์‹ค๋ฌดํ˜• ์•„ํ‚คํ…์ฒ˜: Docker, Flyway, QueryDSL, ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
  • ํ”„๋ก ํŠธ/๋ฐฑ์—”๋“œ ์—ฐ๋™: React + Spring Boot + REST API

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages