|
| 1 | +# 온길 Backend |
| 2 | + |
| 3 | +**시니어를 위한 쇼핑 플랫폼, 온길의 백엔드 서버입니다.** |
| 4 | + |
| 5 | +<br/> |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | + |
| 15 | +[](https://github.com/IT-Cotato/12th-OnGil-BE/actions/workflows/ci-cd.yml) |
| 16 | + |
| 17 | +<div align="center"> |
| 18 | + |
| 19 | +<img src="src/main/resources/docs/banner.png" alt="OnGil Banner" width="100%"/> |
| 20 | + |
| 21 | +</div> |
| 22 | + |
| 23 | +<br/> |
| 24 | + |
| 25 | +## 📌 목차 |
| 26 | + |
| 27 | +- [프로젝트 소개](#-프로젝트-소개) |
| 28 | +- [주요 기능](#-주요-기능) |
| 29 | +- [기술 스택](#-기술-스택) |
| 30 | +- [시스템 아키텍처](#-시스템-아키텍처) |
| 31 | +- [프로젝트 구조](#-프로젝트-구조) |
| 32 | +- [시작하기](#-시작하기) |
| 33 | +- [환경 변수](#-환경-변수) |
| 34 | +- [API 문서](#-api-문서) |
| 35 | +- [커밋 컨벤션](#-커밋-컨벤션) |
| 36 | +- [팀원 소개](#-팀원-소개) |
| 37 | + |
| 38 | +<br/> |
| 39 | + |
| 40 | +## 🛍️ 프로젝트 소개 |
| 41 | + |
| 42 | +온길은 **시니어 사용자**의 접근성과 편의성을 최우선으로 설계된 커머스 플랫폼입니다. |
| 43 | + |
| 44 | +큰 글씨, 직관적인 탐색 흐름, 음성 검색 등 시니어 친화적 기능을 제공하며 |
| 45 | +상품 탐색부터 장바구니, 주문/결제, 리뷰, 마이페이지까지 하나의 흐름으로 연결됩니다. |
| 46 | + |
| 47 | +``` |
| 48 | +탐색 / 검색 → 장바구니 → 주문 / 결제 → 리뷰 / 마이페이지 |
| 49 | +``` |
| 50 | + |
| 51 | +<br/> |
| 52 | + |
| 53 | +## ✨ 주요 기능 |
| 54 | + |
| 55 | +**🔐 인증** |
| 56 | +- 이메일 / 비밀번호 로그인 |
| 57 | +- 카카오 · 구글 OAuth2 소셜 로그인 |
| 58 | +- JWT + Redis 기반 Refresh Token 관리 |
| 59 | + |
| 60 | +**🔍 검색** |
| 61 | +- Elasticsearch 풀텍스트 검색 (한국어 노리 형태소 분석기) |
| 62 | +- AI 기반 유사 상품 추천 (OpenAI) |
| 63 | +- 최근 검색어 저장 / 검색어 유사도 보정 (Apache Commons Text) |
| 64 | + |
| 65 | +**🛒 커머스** |
| 66 | +- 상품 목록 / 상세 / 카테고리 / 브랜드 조회 |
| 67 | +- 장바구니 담기 · 수정 · 삭제 |
| 68 | +- 주문 생성 · 목록 · 상세 · 취소 |
| 69 | + |
| 70 | +**⭐ 리뷰** |
| 71 | +- 단계형 리뷰 작성 (사이즈 / 소재 / 색상 등 항목별 답변) |
| 72 | +- AI 기반 리뷰 자동 생성 및 요약 |
| 73 | +- "도움돼요" 반응 토글 |
| 74 | + |
| 75 | +**🔔 알림** |
| 76 | +- 가격 할인 알림 등록 · 조회 (Price Alert) |
| 77 | +- SSE(Server-Sent Events) 기반 실시간 알림 전송 |
| 78 | +- Spring Scheduler로 30초 간격 가격 모니터링 |
| 79 | + |
| 80 | +**📰 매거진** |
| 81 | +- 시니어 관련 뉴스 자동 크롤링 (Jsoup + Spring Scheduler) |
| 82 | +- 매거진 북마크 · 댓글 · 댓글 좋아요 |
| 83 | + |
| 84 | +**👤 사용자** |
| 85 | +- 배송지 관리 (등록 · 수정 · 삭제 · 기본 설정) |
| 86 | +- 찜(위시리스트) 관리 |
| 87 | +- 프로필 이미지 업로드 (AWS S3) |
| 88 | +- 체형 정보 (키 · 몸무게 · 상의 · 하의 · 신발 사이즈) 입력 |
| 89 | + |
| 90 | +**🖥️ 어드민** |
| 91 | +- 상품 / 배너 / 광고 관리 |
| 92 | +- 상품 Elasticsearch 인덱싱 |
| 93 | + |
| 94 | +<br/> |
| 95 | + |
| 96 | +## 🛠 기술 스택 |
| 97 | + |
| 98 | +| Category | Stack | |
| 99 | +|----------|-------| |
| 100 | +| Language | Java 17 | |
| 101 | +| Framework | Spring Boot 3.3.5, Spring Security, Spring Data JPA | |
| 102 | +| Database | MySQL 8.0 (AWS RDS) | |
| 103 | +| Cache | Redis 7 (Refresh Token, 캐싱) | |
| 104 | +| Search | Elasticsearch 8.10 (노리 형태소 분석기) | |
| 105 | +| Storage | AWS S3 | |
| 106 | +| Auth | JWT, OAuth2 (Kakao, Google), FeignClient | |
| 107 | +| AI | OpenAI API (상품 추천, 리뷰 생성) | |
| 108 | +| Realtime | SSE (Server-Sent Events), WebSocket | |
| 109 | +| Crawling | Jsoup, Spring Scheduler | |
| 110 | +| Infra | AWS EC2, Docker Compose, Nginx, Let's Encrypt / Certbot | |
| 111 | +| CI/CD | GitHub Actions → Docker Hub → EC2 | |
| 112 | +| Docs | Swagger (springdoc-openapi) | |
| 113 | +| Etc | Apache Commons Text (검색어 유사도), CodeRabbit (AI 코드 리뷰) | |
| 114 | + |
| 115 | +<br/> |
| 116 | + |
| 117 | +## 🏗 시스템 아키텍처 |
| 118 | + |
| 119 | +<div align="center"> |
| 120 | + <img src="src/main/resources/docs/archit.png" alt="System Architecture" width="85%"/> |
| 121 | +</div> |
| 122 | + |
| 123 | +<br/> |
| 124 | + |
| 125 | +**인프라 요약** |
| 126 | +- **Nginx**: 리버스 프록시, HTTPS 종단 처리 |
| 127 | +- **Let's Encrypt + Certbot**: SSL 인증서 자동 발급 및 갱신 |
| 128 | +- **Spring Boot** (8080): 메인 애플리케이션 서버 |
| 129 | +- **Redis** (6379): Refresh Token 저장, 응답 캐싱 |
| 130 | +- **Elasticsearch** (9200): 상품 검색 인덱스 (노리 플러그인 적용) |
| 131 | +- **MySQL** (AWS RDS): 운영 데이터베이스 |
| 132 | +- **AWS S3**: 이미지 파일 저장소 |
| 133 | + |
| 134 | +**CI/CD 흐름** |
| 135 | +``` |
| 136 | +IntelliJ IDEA → GitHub → GitHub Actions → Docker Hub → EC2 Pull & Deploy |
| 137 | +``` |
| 138 | + |
| 139 | +<br/> |
| 140 | + |
| 141 | +## 📁 프로젝트 구조 |
| 142 | + |
| 143 | +``` |
| 144 | +src/main/java/com/ongil/backend/ |
| 145 | +├── domain/ |
| 146 | +│ ├── auth/ # 인증 (JWT, OAuth2 - Kakao/Google) |
| 147 | +│ ├── user/ # 회원 정보, 체형 정보 |
| 148 | +│ ├── product/ # 상품 조회, AI 소재 추천 |
| 149 | +│ ├── search/ # Elasticsearch 검색, AI 검색, 검색 로그 |
| 150 | +│ ├── cart/ # 장바구니 |
| 151 | +│ ├── order/ # 주문 |
| 152 | +│ ├── payment/ # 결제 |
| 153 | +│ ├── review/ # 리뷰 작성, AI 리뷰 생성 |
| 154 | +│ ├── wishlist/ # 찜 |
| 155 | +│ ├── address/ # 배송지 |
| 156 | +│ ├── pricealert/ # 가격 할인 알림 (Scheduler) |
| 157 | +│ ├── notification/ # SSE 실시간 알림 |
| 158 | +│ ├── magazine/ # 매거진 (크롤링, 댓글, 북마크) |
| 159 | +│ ├── brand/ # 브랜드 |
| 160 | +│ ├── category/ # 카테고리 |
| 161 | +│ ├── banner/ # 배너 |
| 162 | +│ ├── advertisement/ # 광고 |
| 163 | +│ └── admin/ # 어드민 |
| 164 | +└── global/ |
| 165 | + ├── config/ # Security, Redis, S3, WebSocket, Async 설정 |
| 166 | + ├── security/jwt/ # JWT 필터, 토큰 발급 |
| 167 | + ├── openai/ # OpenAI 클라이언트 |
| 168 | + └── common/ # 공통 응답, 예외, 유효성 검사 |
| 169 | +``` |
| 170 | + |
| 171 | +<br/> |
| 172 | + |
| 173 | +## 🚀 시작하기 |
| 174 | + |
| 175 | +### 사전 요구사항 |
| 176 | + |
| 177 | +```bash |
| 178 | +java --version # 17 이상 |
| 179 | +mysql --version # 8.0 이상 |
| 180 | +docker --version # Docker & Compose |
| 181 | +``` |
| 182 | + |
| 183 | +### 로컬 실행 |
| 184 | + |
| 185 | +```bash |
| 186 | +# 1. 클론 |
| 187 | +git clone https://github.com/IT-Cotato/12th-OnGil-BE.git |
| 188 | +cd 12th-OnGil-BE |
| 189 | + |
| 190 | +# 2. DB 생성 |
| 191 | +mysql -u root -p |
| 192 | +CREATE DATABASE ongil CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; |
| 193 | + |
| 194 | +# 3. 환경변수 설정 (.env 파일 생성) |
| 195 | + |
| 196 | +# 4. 실행 |
| 197 | +chmod +x ./gradlew |
| 198 | +./gradlew bootRun --args='--spring.profiles.active=local' |
| 199 | +``` |
| 200 | + |
| 201 | +### Docker Compose (전체 스택) |
| 202 | + |
| 203 | +```bash |
| 204 | +docker-compose up -d |
| 205 | +``` |
| 206 | + |
| 207 | +### 프로덕션 빌드 |
| 208 | + |
| 209 | +```bash |
| 210 | +./gradlew clean build -x test |
| 211 | +java -jar build/libs/backend-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod |
| 212 | +``` |
| 213 | + |
| 214 | +<br/> |
| 215 | + |
| 216 | +## 🔧 환경 변수 |
| 217 | + |
| 218 | +프로젝트 루트에 `.env` 파일을 생성합니다. |
| 219 | + |
| 220 | +| Key | 설명 | |
| 221 | +|-----|------| |
| 222 | +| `LOCAL_DB_URL` | 로컬 MySQL JDBC URL | |
| 223 | +| `LOCAL_DB_USERNAME` | 로컬 DB 사용자 | |
| 224 | +| `LOCAL_DB_PASSWORD` | 로컬 DB 비밀번호 | |
| 225 | +| `PROD_DB_URL` | 운영 MySQL JDBC URL | |
| 226 | +| `PROD_DB_USERNAME` | 운영 DB 사용자 | |
| 227 | +| `PROD_DB_PASSWORD` | 운영 DB 비밀번호 | |
| 228 | +| `JWT_SECRET` | JWT 서명 시크릿 키 (256bit 이상) | |
| 229 | +| `KAKAO_CLIENT_ID` | 카카오 OAuth 앱 키 | |
| 230 | +| `KAKAO_CLIENT_SECRET` | 카카오 OAuth 시크릿 | |
| 231 | +| `KAKAO_REDIRECT_URI` | 카카오 콜백 URI | |
| 232 | +| `GOOGLE_CLIENT_ID` | 구글 OAuth 클라이언트 ID | |
| 233 | +| `GOOGLE_CLIENT_SECRET` | 구글 OAuth 시크릿 | |
| 234 | +| `GOOGLE_REDIRECT_URI` | 구글 콜백 URI | |
| 235 | +| `OPENAI_API_KEY` | OpenAI API 키 | |
| 236 | +| `SPRING_DATA_REDIS_HOST` | Redis 호스트 | |
| 237 | +| `SPRING_DATA_REDIS_PORT` | Redis 포트 (기본: 6379) | |
| 238 | +| `SPRING_ELASTICSEARCH_URIS` | Elasticsearch URI | |
| 239 | +| `AWS_ACCESS_KEY` | AWS IAM 액세스 키 | |
| 240 | +| `AWS_SECRET_KEY` | AWS IAM 시크릿 키 | |
| 241 | +| `AWS_S3_BUCKET` | S3 버킷 이름 | |
| 242 | + |
| 243 | +<br/> |
| 244 | + |
| 245 | +## 📄 API 문서 |
| 246 | + |
| 247 | +서버 실행 후 Swagger UI에서 전체 API를 확인할 수 있습니다. |
| 248 | + |
| 249 | +``` |
| 250 | +http://localhost:8080/swagger-ui/index.html |
| 251 | +``` |
| 252 | + |
| 253 | +<br/> |
| 254 | + |
| 255 | +## 📝 커밋 컨벤션 |
| 256 | + |
| 257 | +``` |
| 258 | +feat : 새로운 기능 |
| 259 | +fix : 버그 수정 |
| 260 | +refactor: 코드 리팩토링 |
| 261 | +docs : 문서 수정 |
| 262 | +style : 포맷팅 |
| 263 | +test : 테스트 |
| 264 | +chore : 빌드 / 설정 |
| 265 | +``` |
| 266 | + |
| 267 | +```bash |
| 268 | +# 예시 |
| 269 | +feat: 가격 할인 알림 SSE 전송 구현 |
| 270 | +fix: 검색 결과 페이징 오류 수정 |
| 271 | +``` |
| 272 | + |
| 273 | +<br/> |
| 274 | + |
| 275 | +## 👥 팀원 소개 |
| 276 | + |
| 277 | +<table align="center"> |
| 278 | + <tr> |
| 279 | + <td align="center" width="160"> |
| 280 | + <a href="https://github.com/marshmallowing"> |
| 281 | + <img src="https://avatars.githubusercontent.com/u/114673063?v=4" width="100" height="100" style="border-radius:50%;" alt="정유진"/> |
| 282 | + </a> |
| 283 | + <br/> |
| 284 | + <a href="https://github.com/marshmallowing"><b>정유진</b></a> |
| 285 | + <br/> |
| 286 | + <sub>Backend Developer</sub> |
| 287 | + </td> |
| 288 | + <td align="center" width="160"> |
| 289 | + <a href="https://github.com/kangcheolung"> |
| 290 | + <img src="https://avatars.githubusercontent.com/u/112637112?v=4" width="100" height="100" style="border-radius:50%;" alt="강철웅"/> |
| 291 | + </a> |
| 292 | + <br/> |
| 293 | + <a href="https://github.com/kangcheolung"><b>강철웅</b></a> |
| 294 | + <br/> |
| 295 | + <sub>Backend Developer</sub> |
| 296 | + </td> |
| 297 | + <td align="center" width="160"> |
| 298 | + <a href="https://github.com/neibler"> |
| 299 | + <img src="https://avatars.githubusercontent.com/u/87866961?v=4" width="100" height="100" style="border-radius:50%;" alt="조형준"/> |
| 300 | + </a> |
| 301 | + <br/> |
| 302 | + <a href="https://github.com/neibler"><b>조형준</b></a> |
| 303 | + <br/> |
| 304 | + <sub>Backend Developer</sub> |
| 305 | + </td> |
| 306 | + </tr> |
| 307 | +</table> |
| 308 | + |
| 309 | +<br/> |
| 310 | + |
0 commit comments