Skip to content

Latest commit

ย 

History

159 Commits

Folders and files

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

Repository files navigation

์ฐ๋จน Backend

์ƒˆ๋กœ์šด ์ทจํ–ฅ์„, ๊ฐ€๋ณ๊ฒŒ

20๋Œ€๋ฅผ ์œ„ํ•œ ๋งž์ถค ๋ฌธํ™”ํ™œ๋™ ์ถ”์ฒœ ์„œ๋น„์Šค


์ฐ๋จน ์„œ๋น„์Šค ์†Œ๊ฐœ

๐Ÿ“– ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

์ทจํ–ฅ๊ณผ ์ง€์—ญ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ƒˆ๋กœ์šด ๋ฌธํ™”ํ™œ๋™์„ ๋ฐœ๊ฒฌํ•˜๋Š” ์„œ๋น„์Šค, ์ฐ๋จน

์ฐ๋จน(JJICK-MEOK)์€ ์‚ฌ์šฉ์ž์˜ ๊ด€์‹ฌ ์ฃผ์ œ, ์ทจํ–ฅ ํƒœ๊ทธ, ํ™œ๋™ ์ง€์—ญ์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ฌธํ™”ยท์—ฌ๊ฐ€ ํ™œ๋™์„ ํƒ์ƒ‰ํ•˜๊ณ  ์ถ”์ฒœํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

  • ๊ด€์‹ฌ ์ง€์—ญยท์ฃผ์ œยท์ทจํ–ฅ์„ ์˜จ๋ณด๋”ฉ์—์„œ ์„ ํƒํ•˜๊ณ  ๊ฐœ์ธํ™” ์ถ”์ฒœ์— ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ํ™ˆ, ์นดํ…Œ๊ณ ๋ฆฌ, ๋งž์ถค ์ถ”์ฒœ, ์ฐœ, ์ƒ์„ธ ํŽ˜์ด์ง€์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด ๋‹จ์œ„ API๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ํ™œ๋™ ์œ ํ˜•ยท์นดํ…Œ๊ณ ๋ฆฌยท์ง€์—ญยทํ‚ค์›Œ๋“œยทํƒœ๊ทธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ™œ๋™์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํ•„ํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณต๊ณต API์™€ ์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์ˆ˜์ง‘ยท์ •๊ทœํ™”ํ•˜๊ณ , ๊ฒ€์ˆ˜๋œ ํ™œ๋™์„ ์ž๋™์œผ๋กœ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฐœ, ํ›„๊ธฐ, ํ™œ๋™ ์ด๋ฏธ์ง€์™€ ๊ด‘๊ณ ๋ฅผ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•ด ํƒ์ƒ‰ ๊ฒฝํ—˜์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ

๋ถ„๋ฅ˜ ๊ธฐ์ˆ 
Language Java
Framework Spring Boot Spring Security Spring Data JPA Spring AI
Database MySQL Redis Valkey
Migration Flyway
Auth OAuth2 JWT Google Kakao Naver
AI & External OpenAI Google Sheets Serper
Storage OCI Object Storage Local Storage
Docs Swagger Spring REST Docs
Test JUnit5 Mockito H2
Build & Deploy Gradle Docker Docker Compose GitHub Actions GHCR
Infra Oracle Cloud Caddy
Monitoring Prometheus Grafana Discord

๐Ÿ“ก ์•„ํ‚คํ…์ฒ˜

์ฐ๋จน OCI ๋ฐฐํฌ ์•„ํ‚คํ…์ฒ˜
  • React Native ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ Caddy๊ฐ€ HTTPS๋กœ ์ˆ˜์‹ ํ•˜๊ณ  Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์บ์‹œ๋Š” OCI Compute์˜ Docker Compose ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜์† ๋ฐ์ดํ„ฐ๋Š” Oracle MySQL Database Service, ํŒŒ์ผ์€ OCI Object Storage์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
  • GitHub Actions๊ฐ€ ์ด๋ฏธ์ง€๋ฅผ GHCR์— ๋ฐœํ–‰ํ•˜๊ณ  OCI Compute์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
  • Prometheus์™€ Grafana๋กœ ๋ฉ”ํŠธ๋ฆญ์„ ์‹œ๊ฐํ™”ํ•˜๊ณ  Discord Webhook์œผ๋กœ ์žฅ์•  ์•Œ๋ฆผ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ—‚๏ธ ERD

์ฐ๋จน ERD

์ƒ์„ธ ์ปฌ๋Ÿผ, ์ œ์•ฝ์กฐ๊ฑด๊ณผ ๊ด€๊ณ„ ์ •์˜๋Š” docs/current-entity-erd.dbml์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ

src/main/java/com/jjikmeok/app/
โ”œโ”€โ”€ AppApplication.java
โ”œโ”€โ”€ domain/
โ”‚   โ”œโ”€โ”€ activity/          # ํ™œ๋™ CRUDยท๊ฒ€์ƒ‰ยท์ถ”์ฒœ, ๊ณต๊ณต/๋ฏผ๊ฐ„ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐ ๋ฐœํ–‰
โ”‚   โ”œโ”€โ”€ advertisement/     # ๊ด‘๊ณ  ๋…ธ์ถœ ๋ฐ ๊ด€๋ฆฌ์ž CRUD
โ”‚   โ”œโ”€โ”€ ai/                # ์ˆ˜์ง‘ ํ›„๋ณด์˜ OpenAI ๊ธฐ๋ฐ˜ ๋ถ„์„
โ”‚   โ”œโ”€โ”€ auth/              # ๋กœ์ปฌ/OAuth ์ธ์ฆ, JWT, ์ด๋ฉ”์ผ ์ธ์ฆ, ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ •
โ”‚   โ”œโ”€โ”€ favorite/          # ์‚ฌ์šฉ์ž ํ™œ๋™ ์ฐœ
โ”‚   โ”œโ”€โ”€ image/             # ํ™œ๋™ ์ด๋ฏธ์ง€์™€ ๋…ธ์ถœ ์ˆœ์„œ ๊ด€๋ฆฌ
โ”‚   โ”œโ”€โ”€ onboarding/        # ๊ด€์‹ฌ ์ง€์—ญยท์ฃผ์ œยท์ทจํ–ฅ ์„ ํƒ ๋ฐ ์กฐํšŒ
โ”‚   โ”œโ”€โ”€ page/              # ํ™ˆยท์นดํ…Œ๊ณ ๋ฆฌยท๋งž์ถคยท์ฐœยท์ƒ์„ธ ํ™”๋ฉด ์กฐํ•ฉ API
โ”‚   โ”œโ”€โ”€ personalization/   # ์ทจํ–ฅ ์œ ํ˜• ๋ฐ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ๊ฐœ์ธํ™” ์ถ”์ฒœ
โ”‚   โ”œโ”€โ”€ region/            # ์‹œ/๋„ยท์‹œ/๊ตฐ/๊ตฌ ๊ณ„์ธตํ˜• ์ง€์—ญ ๊ด€๋ฆฌ
โ”‚   โ”œโ”€โ”€ review/            # ํ™œ๋™ ํ›„๊ธฐ CRUD
โ”‚   โ”œโ”€โ”€ tag/               # ํ™œ๋™ยท์ฃผ์ œยท์ทจํ–ฅ ํƒœ๊ทธ ์‚ฌ์ „ ๊ด€๋ฆฌ
โ”‚   โ””โ”€โ”€ user/              # ์‚ฌ์šฉ์ž ๊ณ„์ •๊ณผ ํ”„๋กœํ•„
โ””โ”€โ”€ global/
    โ”œโ”€โ”€ common/            # ๊ณตํ†ต ์‘๋‹ต, ์˜ˆ์™ธ, JPA ๊ฐ์‚ฌ ์—”ํ‹ฐํ‹ฐ
    โ”œโ”€โ”€ config/            # Security, CORS, Redis, Swagger, Async ์„ค์ •
    โ”œโ”€โ”€ infra/             # ๋ฉ”์ผ ๋ฐ Local/OCI Object Storage ์—ฐ๋™
    โ””โ”€โ”€ security/          # JWT ํ•„ํ„ฐยทํ† ํฐยท์ธ์ฆ/์ธ๊ฐ€ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

๐Ÿ”‘ ์ฃผ์š” ๊ธฐ๋Šฅ

์ธ์ฆ ๋ฐ ์‚ฌ์šฉ์ž

  • ์ด๋ฉ”์ผ ํšŒ์›๊ฐ€์ž…ยท๋กœ๊ทธ์ธ๊ณผ BCrypt ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”
  • Google, Kakao, Naver OAuth 2.0 ๋กœ๊ทธ์ธ
  • ์›น ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์™€ ๋ชจ๋ฐ”์ผ ๋”ฅ๋งํฌ๋ฅผ ์ง€์›ํ•˜๋Š” ์ผํšŒ์šฉ Handoff Token ๊ตํ™˜
  • JWT Access/Refresh Token ๋ฐœ๊ธ‰ยทํšŒ์ „ยท๋กœ๊ทธ์•„์›ƒ, Redis ๊ธฐ๋ฐ˜ Refresh Token ๊ฒ€์ฆ
  • ์ด๋ฉ”์ผ ์ธ์ฆ ์ฝ”๋“œ ๋ฐœ์†ก๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ •
  • ๋‹‰๋„ค์ž„, ์ƒ๋…„์›”์ผ, ์„ฑ๋ณ„, ์ƒํƒœ, ์•ฝ๊ด€ ๋™์˜๋ฅผ ํฌํ•จํ•œ ํ”„๋กœํ•„ ์ƒ์„ฑยท์กฐํšŒ

์˜จ๋ณด๋”ฉ ๋ฐ ๊ฐœ์ธํ™”

  • ๊ด€์‹ฌ ์ฃผ์ œ, ์ทจํ–ฅ ํƒœ๊ทธ, ํ™œ๋™ ์ง€์—ญ ์„ ํƒ ๋ฐ ์ „์ฒด ๊ต์ฒด ๋ฐฉ์‹ ์ˆ˜์ •
  • ๊ฐ€์ž… ์ƒํƒœ๋ฅผ ํ”„๋กœํ•„ ์™„๋ฃŒ์™€ ์˜จ๋ณด๋”ฉ ์™„๋ฃŒ ๋‹จ๊ณ„๋กœ ๊ด€๋ฆฌ
  • ์‚ฌ์šฉ์ž ์˜จ๋ณด๋”ฉ ํƒœ๊ทธ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ทจํ–ฅ ์œ ํ˜• ๋ถ„๋ฅ˜
  • ์ทจํ–ฅ ํƒœ๊ทธ ID ์ˆœ์„œ๋กœ ์‚ฌ์šฉ์žยทํ™œ๋™ ์ด์ง„ ๋ฒกํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„๋กœ ์ถ”์ฒœ ์ ์ˆ˜ ๊ณ„์‚ฐ
  • ๊ฐœ์ธํ™” ์ ์ˆ˜, ๋ชจ์ง‘ ๋งˆ๊ฐ์ผ, ์ฐœ ์—ฌ๋ถ€, ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•œ ๋งž์ถค ํ™œ๋™ ์ถ”์ฒœ

ํ™œ๋™ ํƒ์ƒ‰ ๋ฐ ํ™”๋ฉด ํ๋ ˆ์ด์…˜

  • ํ™œ๋™ ์œ ํ˜•, ์นดํ…Œ๊ณ ๋ฆฌ, ์ง€์—ญ, ํ‚ค์›Œ๋“œ, ํƒœ๊ทธ ๊ธฐ๋ฐ˜ ๊ฒ€์ƒ‰ยทํ•„ํ„ฐ๋ง
  • ๋ชจ์ง‘ ์ค‘์ด๊ณ  ์Šน์ธ๋œ ํ™œ๋™์„ ๋Œ€์ƒ์œผ๋กœ ์ตœ์‹ ์ˆœยท์ธ๊ธฐ์ˆœยท๋งˆ๊ฐ์ˆœ ์ •๋ ฌ
  • ์ƒ์„ธ ์กฐํšŒ ์‹œ ์กฐํšŒ์ˆ˜ ์ฆ๊ฐ€์™€ ์ง€์—ญยทํƒœ๊ทธยท์ด๋ฏธ์ง€ยท์ฐœ ์ƒํƒœ ์กฐํ•ฉ
  • ํ™ˆ์˜ ์ตœ์‹ /์ธ๊ธฐ ํ™œ๋™ ๋ฐ ์ทจํ–ฅ ํ๋ ˆ์ด์…˜, ์นดํ…Œ๊ณ ๋ฆฌยท๋งž์ถคยท์ฐœยท์ƒ์„ธ ํ™”๋ฉด API
  • ํ™œ๋™ ๊ธฐ๊ฐ„, ๋ชจ์ง‘ ๊ธฐ๊ฐ„, URL, ์Šน์ธ ์ƒํƒœ ๊ฒ€์ฆ๊ณผ ๊ด€๋ฆฌ์ž CRUD

ํ™œ๋™ ์ˆ˜์ง‘ ๋ฐ ๋ฐœํ–‰ ํŒŒ์ดํ”„๋ผ์ธ

  • KOPIS, ์ „์‹œ, ์„œ์šธ ๋ฌธํ™”ํ–‰์‚ฌ, ์„œ์šธ ๊ณต๊ณต์˜ˆ์•ฝ API ๋™๊ธฐํ™”
  • ์™ธ๋ถ€ ์‘๋‹ต์„ raw_activities์— ์›๋ณธ ๋ณด๊ด€ํ•œ ๋’ค ๊ณตํ†ต ํ™œ๋™ ๋ชจ๋ธ๋กœ ์ •๊ทœํ™”
  • Serper ๊ฒ€์ƒ‰, robots ์ •์ฑ… ํ™•์ธ, URL ํ’ˆ์งˆ ํ‰๊ฐ€, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ถ”์ถœ, ์ค‘๋ณต ์ œ๊ฑฐ
  • Spring AI/OpenAI๋ฅผ ์ด์šฉํ•œ Discovery ํ›„๋ณด ๋ถ„์„๊ณผ ํ™œ๋™ ์ •๋ณด ๊ตฌ์กฐํ™”
  • Google Sheets์— ์ˆ˜์ง‘ ํ›„๋ณด๋ฅผ ์ ์žฌํ•˜๊ณ  ๊ฒ€์ˆ˜ ์™„๋ฃŒ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋น„์Šค DB๋กœ ๋ฐœํ–‰
  • ๊ณต๊ณต ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐ Discovery ์ˆ˜์ง‘ยท๋ฐœํ–‰ ์Šค์ผ€์ค„๋Ÿฌ ์ œ๊ณต

์ฐœยทํ›„๊ธฐยท์ด๋ฏธ์ง€

  • ์‚ฌ์šฉ์ž๋ณ„ ํ™œ๋™ ์ฐœ ๋“ฑ๋กยท์กฐํšŒยท์‚ญ์ œ ๋ฐ ์ €์žฅ์ˆœยท๋งˆ๊ฐ์ˆœ ์ •๋ ฌ
  • ์‚ฌ์šฉ์ž๋‹น ํ™œ๋™๋ณ„ ํ•˜๋‚˜์˜ ํ›„๊ธฐ ์ž‘์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ ๋ฐ ํŽ˜์ด์ง€ ์กฐํšŒ
  • ํ™œ๋™๋ณ„ ๋‹ค์ค‘ ์ด๋ฏธ์ง€, ์ธ๋„ค์ผ ์—ฌ๋ถ€, ๋…ธ์ถœ ์ˆœ์„œ ๊ด€๋ฆฌ
  • ์ฐœยทํ›„๊ธฐ ์ˆ˜ ์ง‘๊ณ„์™€ ์ค‘๋ณต ๋“ฑ๋ก ๋ฐฉ์ง€

๊ด‘๊ณ  ๋ฐ ์šด์˜

  • ๋…ธ์ถœ ์œ„์น˜์™€ ๊ธฐ๊ฐ„์„ ๊ธฐ์ค€์œผ๋กœ ํ™œ์„ฑ ๊ด‘๊ณ  ์กฐํšŒ, ๊ด€๋ฆฌ์ž CRUD
  • Local File Storage์™€ OCI Object Storage๋ฅผ ํ™˜๊ฒฝ๋ณ„๋กœ ์„ ํƒ
  • Caddy ๊ธฐ๋ฐ˜ HTTPS ์ข…๋ฃŒ์™€ Docker Compose ๊ธฐ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ยท์บ์‹œ ์šด์˜
  • GitHub Actions๋ฅผ ํ†ตํ•œ Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ, GHCR ํ‘ธ์‹œ, OCI Compute ์ž๋™ ๋ฐฐํฌ
  • PrometheusยทGrafana ๋ชจ๋‹ˆํ„ฐ๋ง๊ณผ Discord Webhook ์žฅ์•  ์•Œ๋ฆผ ๊ตฌ์„ฑ

๐Ÿงช ํ…Œ์ŠคํŠธ

Controller, Service, Repository, Security, Storage, ๊ฐœ์ธํ™” ๊ณ„์‚ฐ ๋ฐ ์ˆ˜์ง‘ ํŒŒ์ดํ”„๋ผ์ธ์„ ์ค‘์‹ฌ์œผ๋กœ ๋‹จ์œ„ยทํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

# ์ „์ฒด ํ…Œ์ŠคํŠธ
./gradlew test

# ์ปดํŒŒ์ผ ๊ฒ€์ฆ
./gradlew compileJava

Swagger UI๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ํ›„ /swagger-ui/index.html์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

About

๐Ÿ˜‹ ์ฐ๋จน: 20๋Œ€๋ฅผ ์œ„ํ•œ ๋งž์ถค ์ทจ๋ฏธยท๋ฌธํ™”ํ™œ๋™ ์ถ”์ฒœ ์„œ๋น„์Šค - [Backend]

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages