Hodl_Server๋ ์ฌ์ฉ์์ ์ฝ๋ฌผ ๋ณต์ฉ ๊ด๋ฆฌ์ ๊ฑด๊ฐ ๊ธฐ๋ก์ ์ํ ๋ชจ๋ฐ์ผ ์ฑ์ ๋ฐฑ์๋ ์๋ฒ์ ๋๋ค. ์ฌ์ฉ์๊ฐ ์ฝ๋ฌผ์ ๋ฑ๋กํ๊ณ ๋ณต์ฉ ์ผ์ ์ ๊ด๋ฆฌํ๋ฉฐ, ์๋ฉด, ์ด๋, ํ๋น ๋ ธ์ถ, ์ฆ์ ๋ฑ์ ๊ฑด๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋กํ ์ ์๋ RESTful API๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ์ฝ๋ฌผ ๊ด๋ฆฌ: ์ฝ๋ฌผ ๋ฑ๋ก, ๋ณต์ฉ ์ผ์ ๊ด๋ฆฌ, ๋ณต์ฉ ๊ธฐ๋ก
- ๊ฑด๊ฐ ๊ธฐ๋ก: ์๋ฉด, ์ด๋, ํ๋น ๋ ธ์ถ, ์ฆ์ ๊ธฐ๋ก
- ์๋ฆผ ์์คํ : Firebase Cloud Messaging์ ํตํ ํธ์ ์๋ฆผ
- ์ฌ์ฉ์ ๊ด๋ฆฌ: ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ํ๋กํ ๊ด๋ฆฌ
- ์ฑํ ๊ธฐ๋ฐ UX: ๋จ๊ณ๋ณ ์ฑํ ์ธํฐํ์ด์ค๋ฅผ ํตํ ์ง๊ด์ ์ธ ์ฝ๋ฌผ ๋ฑ๋ก
graph TB
subgraph "Client Layer"
A[Mobile App]
end
subgraph "Web Server Layer"
B[Nginx - Reverse Proxy]
end
subgraph "Application Layer"
C[Spring Boot Application]
D[JWT Authentication]
E[Firebase Cloud Messaging]
end
subgraph "Data Layer"
F[MySQL Database]
G[AWS RDS]
end
subgraph "Infrastructure"
H[AWS EC2 - Linux]
I[AWS RDS - MySQL]
end
A -->|HTTPS| B
B -->|HTTP| C
C --> D
C --> E
C -->|JDBC| F
F --> G
C --> H
G --> I
style A fill:#e1f5fe
style B fill:#fff3e0
style C fill:#f3e5f5
style D fill:#e8f5e8
style E fill:#fff8e1
style F fill:#fce4ec
style G fill:#f1f8e9
style H fill:#e0f2f1
style I fill:#fafafa
sequenceDiagram
participant Client as Mobile App
participant Nginx as Nginx Server
participant Spring as Spring Boot
participant DB as MySQL Database
participant FCM as Firebase Cloud Messaging
Client->>Nginx: HTTPS Request
Nginx->>Spring: HTTP Request (Reverse Proxy)
Spring->>Spring: JWT Authentication
Spring->>DB: Database Query
DB->>Spring: Query Result
Spring->>FCM: Push Notification (if needed)
FCM->>Client: Push Notification
Spring->>Nginx: HTTP Response
Nginx->>Client: HTTPS Response
| ๋ ์ด์ด | ๊ตฌ์ฑ ์์ | ์ญํ | ๊ธฐ์ ์คํ |
|---|---|---|---|
| Client Layer | Mobile App | ์ฌ์ฉ์ ์ธํฐํ์ด์ค | React Native / Flutter |
| Web Server Layer | Nginx | ๋ฆฌ๋ฒ์ค ํ๋ก์, ๋ก๋ ๋ฐธ๋ฐ์ | Nginx |
| Application Layer | Spring Boot | ๋น์ฆ๋์ค ๋ก์ง ์ฒ๋ฆฌ | Spring Boot 2.4.2 |
| Application Layer | JWT Authentication | ์ธ์ฆ ๋ฐ ๊ถํ ๊ด๋ฆฌ | JWT |
| Application Layer | Firebase Cloud Messaging | ํธ์ ์๋ฆผ ์๋น์ค | Firebase FCM |
| Data Layer | MySQL Database | ๋ฐ์ดํฐ ์ ์ฅ ๋ฐ ๊ด๋ฆฌ | MySQL 8.0 |
| Infrastructure | AWS EC2 | ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ | Amazon EC2 (Linux) |
| Infrastructure | AWS RDS | ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ | Amazon RDS (MySQL) |
- Framework: Spring Boot 2.4.2
- Language: Java 8
- Build Tool: Gradle
- Database: MySQL 8.0
- ORM: Spring JDBC Template
- Authentication: JWT (JSON Web Token)
- Push Notification: Firebase Cloud Messaging
- Email Service: JavaMail API
- Security: Spring Security (๊ธฐ๋ณธ ์ค์ )
- Cloud Platform: AWS
- Server: EC2 (Linux)
- Web Server: Nginx
- Database: RDS (MySQL)
- Load Balancer: Nginx (Reverse Proxy)
- IDE: IntelliJ IDEA
- Version Control: Git
- API Testing: Postman
- Database Management: MySQL Workbench
Hodl_Server/
โโโ src/
โ โโโ main/
โ โ โโโ java/shop/hodl/kkonggi/
โ โ โ โโโ config/ # ์ค์ ํด๋์ค
โ โ โ โ โโโ BaseException.java
โ โ โ โ โโโ BaseResponse.java
โ โ โ โ โโโ BaseResponseStatus.java
โ โ โ โ โโโ Constant.java
โ โ โ โโโ src/
โ โ โ โ โโโ user/ # ์ฌ์ฉ์ ๊ด๋ฆฌ
โ โ โ โ โ โโโ UserController.java
โ โ โ โ โ โโโ UserService.java
โ โ โ โ โ โโโ UserProvider.java
โ โ โ โ โ โโโ UserDao.java
โ โ โ โ โ โโโ model/
โ โ โ โ โโโ medicine/ # ์ฝ๋ฌผ ๊ด๋ฆฌ
โ โ โ โ โ โโโ MedicineController.java
โ โ โ โ โ โโโ MedicineService.java
โ โ โ โ โ โโโ MedicineProvider.java
โ โ โ โ โ โโโ MedicineDao.java
โ โ โ โ โ โโโ model/
โ โ โ โ โโโ record/ # ๊ฑด๊ฐ ๊ธฐ๋ก
โ โ โ โ โ โโโ medicine/ # ์ฝ๋ฌผ ๋ณต์ฉ ๊ธฐ๋ก
โ โ โ โ โ โโโ sleep/ # ์๋ฉด ๊ธฐ๋ก
โ โ โ โ โ โโโ exercise/ # ์ด๋ ๊ธฐ๋ก
โ โ โ โ โ โโโ sun/ # ํ๋น ๊ธฐ๋ก
โ โ โ โ โ โโโ symptom/ # ์ฆ์ ๊ธฐ๋ก
โ โ โ โ โโโ notification/ # ์๋ฆผ ๊ด๋ฆฌ
โ โ โ โ โโโ push/ # ํธ์ ์๋ฆผ
โ โ โ โ โโโ email/ # ์ด๋ฉ์ผ ์๋น์ค
โ โ โ โ โโโ firebase/ # Firebase ์ฐ๋
โ โ โ โ โโโ data/ # ๊ณต์ง์ฌํญ, ๋ฒ์ ๊ด๋ฆฌ
โ โ โ โ โโโ store/ # ์คํ ์ด ์ ๋ณด
โ โ โ โโโ utils/ # ์ ํธ๋ฆฌํฐ ํด๋์ค
โ โ โ โ โโโ JwtService.java
โ โ โ โ โโโ AES128.java
โ โ โ โ โโโ ValidationRegex.java
โ โ โ โโโ WebSecurityConfig.java # ๋ณด์ ์ค์
โ โ โโโ resources/
โ โ โโโ templates/
โ โ โ โโโ mail.html # ์ด๋ฉ์ผ ํ
ํ๋ฆฟ
โ โ โโโ logback-spring.xml # ๋ก๊ทธ ์ค์
โ โโโ test/ # ํ
์คํธ ์ฝ๋
โโโ build.gradle # Gradle ์ค์
โโโ gradlew
โโโ README.md
- ์ด๋ฉ์ผ ์ธ์ฆ: ํ์๊ฐ์ ์ ์ด๋ฉ์ผ ์ธ์ฆ ์ฝ๋ ๋ฐ์ก
- JWT ํ ํฐ: ๋ก๊ทธ์ธ ์ฑ๊ณต ์ 1๋ ์ ํจํ JWT ํ ํฐ ๋ฐ๊ธ
- ๋น๋ฐ๋ฒํธ ์ํธํ: AES128 ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋น๋ฐ๋ฒํธ ์ํธํ
- ๋๋ค์, ์๋ ์์ผ, ์ฑ๋ณ ์ ๋ณด ๊ด๋ฆฌ
- ์ฑํ ๊ธฐ๋ฐ ๋๋ค์ ์ค์ ํ๋ก์ธ์ค
API ์๋ํฌ์ธํธ:
POST /app/v1/users # ํ์๊ฐ์
POST /app/v1/users/logIn # ๋ก๊ทธ์ธ
GET /app/v1/users/{userIdx} # ํ๋กํ ์กฐํ
PATCH /app/v1/users/{userIdx} # ํ๋กํ ์์
์ฑํ ๊ธฐ๋ฐ์ ๋จ๊ณ๋ณ ์ฝ๋ฌผ ๋ฑ๋ก ์์คํ :
- ์ฝ๋ฌผ๋ช ์ ๋ ฅ โ 2. ๋ณต์ฉ ์ฃผ๊ธฐ ์ค์ โ 3. ์์์ผ ์ค์ โ 4. ์ข ๋ฃ์ผ ์ค์ โ 5. ๋ณต์ฉ ์๊ฐ ์ค์
- ์์ผ๋ณ ๋ณต์ฉ ์ค์ (์~์ผ)
- ์๊ฐ๋๋ณ ๋ณต์ฉ ์ค์ (์๋ฒฝ, ์์นจ, ์ ์ฌ, ์ ๋ , ์๊ธฐ์ )
- ๋ณต์ฉ๋ ๋ฐ ๋ฉ๋ชจ ๊ด๋ฆฌ
API ์๋ํฌ์ธํธ:
GET /app/v1/users/medicine/input # ์ฝ๋ฌผ ๋ฑ๋ก ์์
GET /app/v1/users/medicine/name # ์ฝ๋ฌผ๋ช
์
๋ ฅ
GET /app/v1/users/medicine/cycle # ๋ณต์ฉ ์ฃผ๊ธฐ ์ค์
GET /app/v1/users/medicine/start # ์์์ผ ์ค์
GET /app/v1/users/medicine/end # ์ข
๋ฃ์ผ ์ค์
GET /app/v1/users/medicine/time # ๋ณต์ฉ ์๊ฐ ์ค์
POST /app/v1/users/medicine # ์ฝ๋ฌผ ๋ฑ๋ก
GET /app/v1/users/medicine # ์ฝ๋ฌผ ๋ชฉ๋ก ์กฐํ
PUT /app/v1/users/medicine/{medicineIdx} # ์ฝ๋ฌผ ์์
DELETE /app/v1/users/medicine/{medicineIdx} # ์ฝ๋ฌผ ์ญ์
- ์ผ๋ณ, ์๊ฐ๋๋ณ ๋ณต์ฉ ์ฌ๋ถ ๊ธฐ๋ก
- ๋ณต์ฉ๋, ๋ณต์ฉ ์๊ฐ, ๋ฉ๋ชจ ๊ด๋ฆฌ
- ์ ์ฒด ์ฝ๋ฌผ ์ผ๊ด ๋ณต์ฉ ๊ธฐ๋ก ๊ธฐ๋ฅ
- ์๋ฉด ์๊ฐ, ๊ธฐ์ ์๊ฐ ๊ธฐ๋ก
- ์๋ฉด ํ์ง ๋ฐ ์๋ฉด ๊ด๋ จ ๋ฉ๋ชจ
- ์๋ฉด ํจํด ๋ถ์
- ์ด๋ ์์ ์๊ฐ, ์ด ์ด๋ ์๊ฐ
- ์ด๋ ๊ฐ๋ ๋ฐ ์ด๋ ์ข ๋ฅ
- ์ด๋ ๊ด๋ จ ๋ฉ๋ชจ
- ์ผ์ธ ํ๋ ์์ ์๊ฐ, ์ด ํ๋ ์๊ฐ
- ํ๋น ๋ ธ์ถ ๊ด๋ จ ๋ฉ๋ชจ
- ์ฒด๊ณ์ ์ธ ์ฆ์ ์ฒดํฌ๋ฆฌ์คํธ
- ๋ถ์์ฉ ๋ฐ ์ฆ์ ๊ธฐ๋ก
- ์ฆ์ ๊ทธ๋ฃน๋ณ ๋ถ๋ฅ
API ์๋ํฌ์ธํธ:
# ์ฝ๋ฌผ ๋ณต์ฉ ๊ธฐ๋ก
GET /app/v1/users/record/medicine
POST /app/v1/users/record/medicine/all
PATCH /app/v1/users/record/medicine/all
# ์๋ฉด ๊ธฐ๋ก
GET /app/v1/users/record/sleep
POST /app/v1/users/record/sleep
PATCH /app/v1/users/record/sleep
# ์ด๋ ๊ธฐ๋ก
GET /app/v1/users/record/exercise
POST /app/v1/users/record/exercise
PATCH /app/v1/users/record/exercise
# ํ๋น ๊ธฐ๋ก
GET /app/v1/users/record/sun
POST /app/v1/users/record/sun
PATCH /app/v1/users/record/sun
# ์ฆ์ ๊ธฐ๋ก
GET /app/v1/users/record/symptom
POST /app/v1/users/record/symptom
PATCH /app/v1/users/record/symptom
- Firebase Cloud Messaging ์ฐ๋
- ์ฝ๋ฌผ ๋ณต์ฉ ์๊ฐ ์๋ฆผ
- ์ค์ผ์ค๋ง ๊ธฐ๋ฐ ์๋ ์๋ฆผ ์ ์ก
- ์ฌ์ฉ์๋ณ ์๋ฆผ ์ค์ ๊ด๋ฆฌ
- ์๋น์ค ์๋ฆผ, ์ฝ๋ฌผ ์๋ฆผ, ์ด๋ฒคํธ ์๋ฆผ, ๋ง์ผํ ์๋ฆผ ๋ถ๋ฆฌ
- ์๊ฐ๋๋ณ ์ฝ๋ฌผ ์๋ฆผ ์ค์
- ๋๋ฐ์ด์ค ํ ํฐ ๊ด๋ฆฌ
API ์๋ํฌ์ธํธ:
GET /app/v1/users/notification # ์๋ฆผ ์ค์ ์กฐํ
PATCH /app/v1/users/notification # ์๋ฆผ ์ค์ ์์
GET /app/v1/users/notification/medicine # ์ฝ๋ฌผ ์๋ฆผ ์ค์ ์กฐํ
PATCH /app/v1/users/notification/medicine # ์ฝ๋ฌผ ์๋ฆผ ์ค์ ์์
PATCH /app/v1/users/notification/token # ๋๋ฐ์ด์ค ํ ํฐ ์
๋ฐ์ดํธ
- ์ฑ ๋ด ๊ณต์ง์ฌํญ ๊ด๋ฆฌ
- ๊ณต์ง์ฌํญ ๋ชฉ๋ก ๋ฐ ์์ธ ๋ด์ฉ ์กฐํ
- ์ฑ ๋ฒ์ ์ ๋ณด ๊ด๋ฆฌ
- ์ต์ ๋ฒ์ ์ ๋ณด ์กฐํ
API ์๋ํฌ์ธํธ:
GET /app/v1/data/noticeboard # ๊ณต์ง์ฌํญ ๋ชฉ๋ก
GET /app/v1/data/noticeboard/{idx} # ๊ณต์ง์ฌํญ ์์ธ
GET /app/v1/data/version # ์ฑ ๋ฒ์ ์ ๋ณด
- ํ ํฐ ์์ฑ: ๋ก๊ทธ์ธ ์ userIdx๋ฅผ ํฌํจํ JWT ํ ํฐ ์์ฑ
- ํ ํฐ ๊ฒ์ฆ: ๊ฐ API ์์ฒญ ์ X-ACCESS-TOKEN ํค๋์์ JWT ์ถ์ถ ๋ฐ ๊ฒ์ฆ
- ํ ํฐ ๋ง๋ฃ: 1๋ ์ ํจํ ํ ํฐ (๊ฐ์ ํ์: 30๋ถ-1์๊ฐ ๊ถ์ฅ)
- ๊ธฐ๋ณธ์ ์ธ Spring Security ์ค์
- CSRF ๋ณดํธ ๋นํ์ฑํ
- ์๋ JWT ์ธ์ฆ ๊ตฌํ
- AES128 ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ ๋น๋ฐ๋ฒํธ ์ํธํ
- ์ด๋ฉ์ผ ์ธ์ฆ ์ฝ๋ ์ํธํ
- Users: ์ฌ์ฉ์ ๊ธฐ๋ณธ ์ ๋ณด
- Authentication: ์ด๋ฉ์ผ ์ธ์ฆ ์ ๋ณด
- Medicine: ์ฝ๋ฌผ ์ ๋ณด
- MedicineTime: ์ฝ๋ฌผ ๋ณต์ฉ ์๊ฐ ์ค์
- MedicineRecord: ์ฝ๋ฌผ ๋ณต์ฉ ๊ธฐ๋ก
- SleepRecord: ์๋ฉด ๊ธฐ๋ก
- ExerciseRecord: ์ด๋ ๊ธฐ๋ก
- SunRecord: ํ๋น ๋ ธ์ถ ๊ธฐ๋ก
- SymptomRecord: ์ฆ์ ๊ธฐ๋ก
- Notification: ์๋ฆผ ์ค์
- DeviceToken: ๋๋ฐ์ด์ค ํ ํฐ
- EC2 ์ธ์คํด์ค: Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ํธ์คํ
- RDS MySQL: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ
- Nginx: ๋ฆฌ๋ฒ์ค ํ๋ก์ ๋ฐ ๋ก๋ ๋ฐธ๋ฐ์
- Security Groups: ๋คํธ์ํฌ ๋ณด์ ์ค์
- Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ๋น๋
- EC2 ์ธ์คํด์ค์ JAR ํ์ผ ์ ๋ก๋
- Nginx ์ค์ ์ ๋ฐ์ดํธ
- ์ ํ๋ฆฌ์ผ์ด์ ์ฌ์์
- JWT ๊ธฐ๋ฐ ์ธ์ฆ ์์คํ : ์ฌ์ฉ์ ์ธ์ฆ ๋ฐ ๊ถํ ๊ด๋ฆฌ
- Firebase ํธ์ ์๋ฆผ: ์ ์ ์ฝ๋ฌผ ๋ณต์ฉ ์๋ฆผ ์๋ ์ ์ก
- ์ด๋ฉ์ผ ์ธ์ฆ ์์คํ : ํ์๊ฐ์ ์ ์ด๋ฉ์ผ ์ธ์ฆ ์ฝ๋ ๋ฐ์ก
- ์ฑํ ๊ธฐ๋ฐ UX: ๋จ๊ณ๋ณ ์ฝ๋ฌผ ๋ฑ๋ก ํ๋ก์ธ์ค
- ์ค์ผ์ค๋ง ์์คํ : ๋งค๋ถ๋ง๋ค ์ฝ๋ฌผ ๋ณต์ฉ ์๊ฐ ์ฒดํฌ ๋ฐ ์๋ฆผ
- RESTful API: ์ฒด๊ณ์ ์ธ API ์ค๊ณ ๋ฐ ๊ตฌํ
- Java 8 ์ด์
- Gradle 6.x ์ด์
- MySQL 8.0 ์ด์
# ํ๋ก์ ํธ ํด๋ก
git clone [repository-url]
cd Hodl_Server
# ์์กด์ฑ ์ค์น
./gradlew build
# ์ ํ๋ฆฌ์ผ์ด์
์คํ
./gradlew bootRun# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/hodl_db
username: your_username
password: your_password
mail:
host: smtp.gmail.com
port: 587
username: [email protected]
password: your_app_password
# Firebase ์ค์
firebase:
service-account: path/to/serviceAccountKey.json- Postman์ ์ฌ์ฉํ API ์๋ํฌ์ธํธ ํ ์คํธ
- JWT ํ ํฐ ๊ธฐ๋ฐ ์ธ์ฆ ํ ์คํธ
- ๊ฐ ๊ธฐ๋ฅ๋ณ ํตํฉ ํ ์คํธ
- ์ฟผ๋ฆฌ ์ฑ๋ฅ ํ ์คํธ
- ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ํ ์คํธ
{
"isSuccess": true,
"code": 1000,
"message": "์์ฒญ์ ์ฑ๊ณตํ์์ต๋๋ค.",
"result": {
// ์ค์ ๋ฐ์ดํฐ
}
}- 1000: ์ฑ๊ณต
- 2000: ์์ฒญ ์ค๋ฅ (์ ๋ ฅ๊ฐ ๊ฒ์ฆ ์คํจ)
- 3000: ์๋ต ์ค๋ฅ (๋ฐ์ดํฐ ์กฐํ ์คํจ)
- 4000: ์๋ฒ ์ค๋ฅ (๋ฐ์ดํฐ๋ฒ ์ด์ค, ์๋ฒ ์ฐ๊ฒฐ ์คํจ)
- JWT ํ ํฐ ๋ง๋ฃ ์๊ฐ ๋จ์ถ (1๋ โ 30๋ถ-1์๊ฐ)
- ๋ฆฌํ๋ ์ ํ ํฐ ๊ตฌํ
- Spring Security JWT ํํฐ ๊ตฌํ
- ๋ฉ์๋ ๋ ๋ฒจ ๋ณด์ ์ ์ฉ
- ์บ์ฑ ์ ๋ต ๋์ (Redis)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฟผ๋ฆฌ ์ต์ ํ
- API ์๋ต ์๊ฐ ๊ฐ์
- ๋ค์ค ๋๋ฐ์ด์ค ๋ก๊ทธ์ธ ๊ด๋ฆฌ
- ํ ํฐ ๋ธ๋๋ฆฌ์คํธ ๊ตฌํ
- ๋ณด์ ๋ก๊ทธ ๊ธฐ๋ก
- Rate Limiting ๊ตฌํ
์ญํ : ๋ฐฑ์๋ ๊ฐ๋ฐ์ (ํ์คํ ๋ฐฑ์๋) ๋ด๋น ์์ญ:
- ์๋ฒ ๊ตฌ์ถ ๋ฐ ์ธํ๋ผ ์ค์ (AWS EC2, RDS, Nginx)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๊ณ ๋ฐ ๊ตฌ์ถ (MySQL)
- Spring Boot ๋ฐฑ์๋ API ๊ฐ๋ฐ
- JWT ์ธ์ฆ ์์คํ ๊ตฌํ
- Firebase ํธ์ ์๋ฆผ ์ฐ๋
- ์ด๋ฉ์ผ ์๋น์ค ๊ตฌํ
๊ธฐ์ ์คํ:
- Java, Spring Boot, MySQL, AWS, Nginx, JWT, Firebase
ํ๋ก์ ํธ ๊ธฐ๊ฐ: 2021.5 - 2021.8
ํ ๊ตฌ์ฑ: Hodl (์์: @Central-MakeUs)
GitHub: @ucans/Hodl_Server
์ด ํ๋ก์ ํธ๋ ๋ํ๊ต ํ๋ถ ๊ณผ์ ์์ ์งํํ ํ ํ๋ก์ ํธ๋ก, ์ค์ ์๋น์ค ๊ฐ๋ฐ ๊ฒฝํ์ ํตํด ๋ฐฑ์๋ ๊ฐ๋ฐ ์ญ๋์ ํฅ์์ํจ ํ๋ก์ ํธ์ ๋๋ค.