์ถ์ต์ ์๊ฐ์๊ฐ ๊ธฐ๋กํ๊ณ ๊ณต์ ํ๋ ์์น ๊ธฐ๋ฐ ์ฌ์ง SNS ํ๋ซํผ
Momentory๋ ์ฌ์ง์ ํตํด ์ถ์ต์ ๊ธฐ๋กํ๊ณ , ์ง์ญ ๊ธฐ๋ฐ ์คํฌํ๋ฅผ ์์งํ๋ฉฐ, ์บ๋ฆญํฐ๋ฅผ ์ฑ์ฅ์ํค๋ ์์ ํ๋ซํผ์ ๋๋ค. ์ฌ์ฉ์๋ ์ฌํ์ง์์ ์ฐ์ ์ฌ์ง์ ์ ๋ก๋ํ๊ณ , ์ง์ญ ์คํฌํ์ ๋ฌธํ ์คํฌํ๋ฅผ ์์งํ๋ฉฐ, ํฌ์ธํธ๋ฅผ ํ๋ํ์ฌ ์บ๋ฆญํฐ๋ฅผ ๊พธ๋ฐ ์ ์์ต๋๋ค.
- ์ฌ์ง ์ ๋ก๋ ๋ฐ ์์น ์ ๋ณด ์๋ ์ถ์ถ
- ์จ๋ฒ๋ณ ์ฌ์ง ๊ด๋ฆฌ ๋ฐ ๊ณต์
- ์ฌ์ง ๊ณต๊ฐ/๋น๊ณต๊ฐ ์ค์
- ์ปค์ ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์
- GPS ๊ธฐ๋ฐ ์ง์ญ ์คํฌํ ์๋ ์์ง
- ๋ฌธํ์์ค ๊ทผ์ฒ ์ฌ์ง ์ดฌ์ ์ ๋ฌธํ ์คํฌํ ํ๋
- ์ค๋ณต ์คํฌํ ์๋ ํํฐ๋ง
- Tour API ์ฐ๋ ๋ฌธํ์์ค ์ ๋ณด ์ ๊ณต
- ํ๋๋ณ ํฌ์ธํธ ํ๋ (์ฌ์ง ์ ๋ก๋, ์ข์์, ํ๋ก์ฐ ๋ฑ)
- ์ผ์ผ ์ ํ์ผ๋ก ๊ณต์ ํ ํฌ์ธํธ ์์คํ
- ๋์ ํฌ์ธํธ ๊ธฐ๋ฐ ๋ ๋ฒจ ์๋ ๊ณ์ฐ
- ๋ ๋ฒจ์ ์ ๋ณด๋์ค ํฌ์ธํธ ์ง๊ธ
- ๋์์ฑ ์ ์ด๋ก ์ค๋ณต ๋ณด์ ๋ฐฉ์ง
- ๋ค์ํ ์บ๋ฆญํฐ ํ์ (๊ณ ์์ด, ๊ฐ์์ง ๋ฑ)
- ํฌ์ธํธ๋ก ์์ดํ ๊ตฌ๋งค ๋ฐ ์บ๋ฆญํฐ ์ปค์คํฐ๋ง์ด์ง
- ์์, ํ์ , ํจ๊ณผ, ์ฅ์ ์นดํ ๊ณ ๋ฆฌ๋ณ ์์ดํ ์ฅ์ฐฉ
- ๋ ๋ฒจ์ ๋ฐ๋ฅธ ์บ๋ฆญํฐ ์ฑ์ฅ
- ํฌ์ธํธ๋ฅผ ์๋นํ์ฌ ๋ฃฐ๋ ์คํ
- ์ง์ญ ์คํฌํ ์ธ์ฆ์ผ๋ก ์ถ๊ฐ ๋ณด์ ํ๋
- ํ๋ฅ ๊ธฐ๋ฐ ๋ฆฌ์๋ ์์คํ
- ํ๋ก์ฐ/ํ๋ก์ ์์คํ
- ์ฌ์ฉ์ ํ๋กํ ์กฐํ ๋ฐ ๊ด๋ฆฌ
- ์ข์์ ๋ฐ ๋๊ธ ๊ธฐ๋ฅ
- ์ค์๊ฐ ์๋ฆผ (WebSocket)
- ๋ ๋ฒจ์ , ํ๋ก์ฐ, ์ข์์ ๋ฑ ๋ค์ํ ์๋ฆผ ํ์
- ์๋ฆผ ์ค์ ๊ด๋ฆฌ
- JWT ๊ธฐ๋ฐ ์ธ์ฆ
- ์นด์นด์ค ์์ ๋ก๊ทธ์ธ
- ์ด๋ฉ์ผ ์ธ์ฆ (ํ์๊ฐ์ ์)
- Refresh Token ์๋ ๊ฐฑ์
- Java 17
- Spring Boot 3.3.4
- Spring Data JPA - ORM ๋ฐ ๋ฐ์ดํฐ ์ ๊ทผ
- QueryDSL - ํ์ ์์ ํ ์ฟผ๋ฆฌ ์์ฑ
- Spring Security - ์ธ์ฆ ๋ฐ ๊ถํ ๊ด๋ฆฌ
- JWT - ํ ํฐ ๊ธฐ๋ฐ ์ธ์ฆ
- OAuth2 - ์นด์นด์ค ์์ ๋ก๊ทธ์ธ
- MySQL 8 - ๋ฉ์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค
- Hibernate - JPA ๊ตฌํ์ฒด
- AWS S3 - ์ด๋ฏธ์ง ํ์ผ ์คํ ๋ฆฌ์ง
- WebSocket - ์ค์๊ฐ ์๋ฆผ
- SpringDoc OpenAPI (Swagger) - API ๋ฌธ์ ์๋ํ
- ์นด์นด์ค ๋งต API - ์์น ์ ๋ณด ๋ณํ
- Tour API - ๋ฌธํ์์ค ์ ๋ณด
src/main/java/com/example/momentory
โโโ domain
โ โโโ auth # ์ธ์ฆ/์ธ๊ฐ
โ โโโ user # ์ฌ์ฉ์ ๊ด๋ฆฌ
โ โโโ photo # ์ฌ์ง ๊ด๋ฆฌ
โ โโโ album # ์จ๋ฒ ๊ด๋ฆฌ
โ โโโ character # ์บ๋ฆญํฐ ์์คํ
โ โโโ point # ํฌ์ธํธ ์์คํ
โ โโโ stamp # ์คํฌํ ์์ง
โ โโโ map # ์ง์ญ/์ง๋ ๊ธฐ๋ฅ
โ โโโ roulette # ๋ฃฐ๋ ๊ฒ์
โ โโโ community # ์ปค๋ฎค๋ํฐ ๊ธฐ๋ฅ
โ โโโ notification # ์๋ฆผ
โ โโโ home # ํ ํ๋ฉด
โ โโโ file # ํ์ผ ์
๋ก๋ (S3)
โ โโโ tag # ํ๊ทธ ์์คํ
โโโ global
โโโ config # ์ค์
โโโ security # ๋ณด์ ์ค์
โโโ exception # ์์ธ ์ฒ๋ฆฌ
โโโ common # ๊ณตํต ์ ํธ๋ฆฌํฐ
- Java 17 ์ด์
- MySQL 8.0 ์ด์
- Gradle 7.0 ์ด์
ํ๋ก์ ํธ ๋ฃจํธ์ .env ํ์ผ์ ์์ฑํ๊ณ ๋ค์ ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํฉ๋๋ค:
# Database
DB_URL=jdbc:mysql://localhost:3306/momentory
DB_USERNAME=your_db_username
DB_PASSWORD=your_db_password
# JWT
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRATION=86400000
REFRESH_TOKEN_EXPIRATION=604800000
# AWS S3
AWS_ACCESS_KEY=your_aws_access_key
AWS_SECRET_KEY=your_aws_secret_key
AWS_REGION=ap-northeast-2
AWS_BUCKET=your_bucket_name
# Kakao OAuth
KAKAO_CLIENT_ID=your_kakao_client_id
KAKAO_CLIENT_SECRET=your_kakao_client_secret
# Email
APP_EMAIL[email protected]
APP_PASSWORD=your_email_app_password
# Kakao Map API
KAKAO_REST_API_KEY=your_kakao_rest_api_key
# Tour API
TOUR_API_KEY=your_tour_api_key# ํ๋ก์ ํธ ํด๋ก
git clone https://github.com/your-username/momentory-backend.git
cd momentory-backend
# ์์กด์ฑ ์ค์น ๋ฐ ๋น๋
./gradlew clean build
# ์ ํ๋ฆฌ์ผ์ด์
์คํ
./gradlew bootRun์๋ฒ๋ ๊ธฐ๋ณธ์ ์ผ๋ก http://localhost:8080์์ ์คํ๋ฉ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์คํ ํ Swagger UI์์ API ๋ฌธ์๋ฅผ ํ์ธํ ์ ์์ต๋๋ค:
http://localhost:8080/swagger-ui/index.html
POST /api/auth/signup- ํ์๊ฐ์POST /api/auth/signin- ๋ก๊ทธ์ธPOST /api/auth/refresh- ํ ํฐ ๊ฐฑ์GET /login/oauth2/code/kakao- ์นด์นด์ค ๋ก๊ทธ์ธ ์ฝ๋ฐฑ
POST /api/photos- ์ฌ์ง ์ ๋ก๋GET /api/photos/{photoId}- ์ฌ์ง ์กฐํPUT /api/photos/{photoId}- ์ฌ์ง ์์ DELETE /api/photos/{photoId}- ์ฌ์ง ์ญ์
GET /api/stamps- ๋ด ์คํฌํ ๋ชฉ๋ก ์กฐํPOST /api/stamps/cultural- ๋ฌธํ ์คํฌํ ํ๋
GET /api/characters/current- ํ์ฌ ์บ๋ฆญํฐ ์กฐํPOST /api/characters- ์บ๋ฆญํฐ ์์ฑPOST /api/characters/{characterId}/select- ์บ๋ฆญํฐ ์ ํPOST /api/characters/{characterId}/equip/{itemId}- ์์ดํ ์ฅ์ฐฉ
GET /api/points- ํฌ์ธํธ ์กฐํGET /api/points/history- ํฌ์ธํธ ๋ด์ญ ์กฐํ
์ฃผ์ ํ ์ด๋ธ:
users- ์ฌ์ฉ์ ์ ๋ณดuser_profiles- ์ฌ์ฉ์ ํ๋กํphotos- ์ฌ์ง ์ ๋ณดalbums- ์จ๋ฒcharacters- ์บ๋ฆญํฐitems- ์์ดํ user_items- ์ฌ์ฉ์ ๋ณด์ ์์ดํ stamps- ์คํฌํpoint_histories- ํฌ์ธํธ ๋ด์ญlevel_up_histories- ๋ ๋ฒจ์ ์ด๋ ฅ (์ค๋ณต ๋ฐฉ์ง)notifications- ์๋ฆผ
๋ ๋ฒจ์ ๋ณด์ ์ค๋ณต ๋ฐฉ์ง
// level_up_histories ํ
์ด๋ธ์ (user_id, reached_level) ์ ๋ํฌ ์ ์ฝ์กฐ๊ฑด
// ๋์์ฑ ๋ฌธ์ ๋ DataIntegrityViolationException์ผ๋ก ์ฒ๋ฆฌ๋ฌธํ ์คํฌํ ์ค๋ณต ๋ฐฉ์ง
// ์ด๋ฏธ ๋ฐ์ ์คํฌํ๋ hasNearbyCulturalSpots = false
boolean alreadyHasStamp = stampRepository.existsByUserAndSpotName(user, spotName);์ผ์ผ ์ ํ
- ์ฌ์ง ์ ๋ก๋: 3ํ/์ผ
- ์ข์์: 50ํ/์ผ
- ํ๋ก์ฐ: 20ํ/์ผ
ํฌ์ธํธ ์ข ๋ฅ
- ํ์๊ฐ์ : 500p
- ์ฌ์ง ์ ๋ก๋: 50p
- ๋ ๋ฒจ์ : 200p
- ์ข์์ ๋ฐ๊ธฐ: 5p
- ํ๋ก์ ์ฆ๊ฐ: 10p
- ๋ฃฐ๋ ์ธ์ฆ: 500p
๋ ๋ฒจ์ ๋์ ํฌ์ธํธ ๊ธฐ๋ฐ์ผ๋ก ์๋ ๊ณ์ฐ:
- ๋ ๋ฒจ 1: 0p
- ๋ ๋ฒจ 2: 100p
- ๋ ๋ฒจ 3: 300p
- ๋ ๋ฒจ N:
100 * (N-1) * N / 2
- JWT ๊ธฐ๋ฐ Stateless ์ธ์ฆ
- Refresh Token์ผ๋ก ๋ณด์์ฑ ๊ฐํ
- CORS ์ค์ ์ผ๋ก ํ์ฉ๋ ์ถ์ฒ๋ง ์ ๊ทผ ๊ฐ๋ฅ
- SQL Injection ๋ฐฉ์ง (Prepared Statement)
- XSS ๋ฐฉ์ง (์ ๋ ฅ ๊ฒ์ฆ)
spring:
profiles:
active: local
jpa:
hibernate:
ddl-auto: update
show-sql: true./gradlew clean
./gradlew build --refresh-dependencies- MySQL ์๋ฒ ์คํ ํ์ธ
.envํ์ผ์ DB ์ค์ ํ์ธ- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑ ํ์ธ:
CREATE DATABASE momentory;
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License.
ํ๋ก์ ํธ ๊ด๋ จ ๋ฌธ์: [email protected]
โญ Star this repository if you find it helpful!