ํฉ์ด์ง ์ฅํ๊ธ ์ ๋ณด๋ฅผ ํ๊ณณ์, ๋์๊ฒ ๋ง๋ ์ฅํ๊ธ๋ง ๊ณจ๋ผ์ฃผ๋ ์ฅํ๊ธ ํ๋ ์ดํ ํ๋ซํผ WishConnect ๋ฐ๋ก๊ฐ๊ธฐ ยท API ์๋ฒ
๋ํ์์ด ์ฅํ๊ธ์ ๋์น๋ ์ด์ ๋ ์ ๋ณด๊ฐ ์์ด์๊ฐ ์๋๋ผ ๋๋ฌด ํฉ์ด์ ธ ์์ด์์ ๋๋ค. WishConnect๋ ํ๊ตญ์ฅํ์ฌ๋จ ๊ณต๊ณต๋ฐ์ดํฐ์ ์ ๊ตญ ๋ํ ์ฅํ๊ณต์ง๋ฅผ ๋งค์ผ ์๋ ์์งยท์ ์ ํ๊ณ , ์ฌ์ฉ์์ ํ์ ยท์๋ยท๊ด์ฌ๋ถ์ผ์ ๋ง๋ ๊ณต๊ณ ๋ง ์ถ๋ ค์ ๋ณด์ฌ์ค๋๋ค. ์ง์๊น์ง ์ด์ด์ง๋๋ก ๋ง๊ฐ ์๋ฆผ, ์คํฌ๋ฉ ์์นด์ด๋น, AI ์๊ธฐ์๊ฐ์ ์์ฑ, ๋ฉด์ ์ค๋น๊น์ง ํ ํ๋ฆ์ผ๋ก ๋ฌถ์์ต๋๋ค.
- ๐ ์ ์ถ ์๋ฃ (ERD ยท API ๋ช ์ธ์ ยท ์ํคํ ์ฒ)
- ๐ฑ Developers
- ๐ Services
- ๐ ERD
- ๐ API ๋ช ์ธ์
- ๐ป Architecture & Deploy
- ๐ง Tech Stack
- ๐งฑ ํ๋ก์ ํธ ๊ตฌ์กฐ
- โ๏ธ Getting Started
| ์๋ฃ | ์์น |
|---|---|
| ERD | ๋ฐ๋ก๊ฐ๊ธฐ โ ยท ์๋ณธ ์ด๋ฏธ์ง |
| API ๋ช ์ธ์ | ๋ฐ๋ก๊ฐ๊ธฐ โ ยท Notion ๋ช ์ธ์ (๊ณต๊ฐ) |
| ์ํคํ ์ฒ ๋ค์ด์ด๊ทธ๋จ | ๋ฐ๋ก๊ฐ๊ธฐ โ ยท ์๋ณธ ์ด๋ฏธ์ง |
| ํ์ | ์ญํ | ์ฃผ์ ์ ๋ฌด |
|---|---|---|
![]() ์ค๊ธฐ์ฐฌ |
BE (๋ฆฌ๋) |
|
![]() ํ์ข ํ |
BE |
|
![]() hahahanjihun |
BE |
|
| ajm6238 | BE |
|
๐ ์ธ์ฆ ยท ์จ๋ณด๋ฉ
- LOCAL ํ์๊ฐ์ (์ด๋ฉ์ผ 6์๋ฆฌ ์ธ์ฆ์ฝ๋, AWS SES) + ์นด์นด์ค / ๊ตฌ๊ธ / ๋ค์ด๋ฒ ์์ ๋ก๊ทธ์ธ 3์ข
- ๋ชจ๋ ๋์ผํ ์์ฒด JWT๋ฅผ ๋ฐ๊ธํ๊ณ
(loginType, providerId)๋ก ๊ณ์ ์ ๊ตฌ๋ถํฉ๋๋ค. - ์จ๋ณด๋ฉ 4๋จ๊ณ โ ๊ธฐ๋ณธ์ ๋ณด โ ํ์ ์ ๋ณด โ ๊ฐ๊ตฌ์ ๋ณดยท๊ด์ฌ์ฌ โ ์๋ฃ. ๋จ๊ณ๋ณ ์ ์ฅ์ด๋ผ ์ด์ด์ ์งํํ ์ ์์ต๋๋ค.
๐ ์ฅํ๊ธ ํ๋ ์ดํ ยท ๊ฒ์
- ์จ๋ณด๋ฉ์์ ๋ฐ์ ํ์ ยท์๋๋ถ์ยท๊ฑฐ์ฃผ์ง์ญยท๊ด์ฌ๋ถ์ผ๋ก ์กฐ๊ฑด์ ํ์ ํด ์๊ฒฉ์ด ๋๋ ๊ณต๊ณ ๋ง ํ๋ ์ดํ ํฉ๋๋ค.
- ์์ธ ํ๋ฉด์์ ์กฐ๊ฑด๋ณ ์ถฉ์กฑ/๋ฏธ์ถฉ์กฑ ํ์ ๊ณผ ์ถ์ฒ ์ด์ ๋ฅผ ํจ๊ป ๋ด๋ ค์ค๋๋ค.
- ํค์๋ยท์นดํ ๊ณ ๋ฆฌยท์ ๋ ฌ(๋ง๊ฐ์๋ฐ/์ต์ /๊ธ์ก/์ ํ๋) ๊ฒ์, ์ถ์ฒ ๊ฒ์์ด, ์๋ณ ์ผ์ ๋ฌ๋ ฅ์ ์ ๊ณตํฉ๋๋ค.
- ํ๊ตญ์ฅํ์ฌ๋จ ๊ณต๊ณต API + ์ ๊ตญ ๋ํ ์ฅํ๊ณต์ง ํฌ๋กค๋ง์ ๋งค์ผ ๋ฐฐ์น๋ก ์์งํ๊ณ , LLM์ผ๋ก ์๊ฒฉ์กฐ๊ฑด์ ๊ตฌ์กฐํํฉ๋๋ค.
๐ ์์นด์ด๋น ยท ์๋ฆผ
- ๊ด์ฌ ๊ณต๊ณ ๋ฅผ ์คํฌ๋ฉํด ์งํ ์ํ์ D-Day๋ก ๊ด๋ฆฌํฉ๋๋ค.
- ๋ง๊ฐ ์๋ฐ, ์ ๊ท ๋ง์ถค ์ฅํ๊ธ, ์์ฑ ์ค ์ง์์ ์ด์ด์ฐ๊ธฐ๋ฅผ ์๋ฆผ์ผํฐ๋ก ๋ณด๋ด๊ณ ์ ํ๋ณ๋ก ์ผ๊ณ ๋ ์ ์์ต๋๋ค.
โ๏ธ AI ์๊ธฐ์๊ฐ์ ยท ๋ฉด์ ์ค๋น
- ๊ณต๊ณ ๋ณธ๋ฌธ์์ ๊ทธ ์ฅํ๊ธ์ ์ค์ ๋ฌธํญ์ ๋ฝ์๋ด๊ณ , ์์ผ๋ฉด ๊ธฐ๋ณธ ๋ฌธํญ์ผ๋ก ๋์ฒดํฉ๋๋ค.
- STEP 1 ์ฌ์ ์ธํฐ๋ทฐ โ STEP 2 ์ด์ ์์ฑยท์์ ยท์ ์ฅ โ ์๋ฃ์ 3๋จ๊ณ๋ก ์งํํฉ๋๋ค.
- ๋ฉด์ ์ด ์๋ ์ฅํ๊ธ์ ์์ ์ง๋ฌธ๊ณผ ์ง๋ฌธ์๋ยท๋ต๋ณ Tipยท์์๋ต๋ณยท๊ตฌ์ฑ๊ฐ์ด๋๋ฅผ ํจ๊ป ์์ฑํฉ๋๋ค.
๐ก ์ธ์ฌ์ดํธ
- ์ฅํ๊ธ ํ๊ธฐยท์ ๋ณดยทํ ์ฝํ ์ธ ๋ฅผ ์ธ๋ถ์์ ์์งํด ์นดํ ๊ณ ๋ฆฌยท์ถ์ฒยทํ๊ทธ๋ก ํ์ํฉ๋๋ค.
๐ ๊ด๋ฆฌ์ ์ฝ์
- ์์ง ํํฉยท์ด์ ํ์งยทํ์ฑ ์คํจ ์๋ณธ ํ์ธ, ์๊ธฐ ๋ฑ๋ก/์์ , ์์ ์ผ๊ด ๋ฐ์, ์ค๋ฑ๋ก ์ ๊ณ ์ฒ๋ฆฌ, ๊ฐ์ฌ ๋ก๊ทธ.
- ๊ด๋ฆฌ์ ํ๋ฉด์ ์ธํฐ๋ท์ ์ด์ง ์๊ณ SSH ํฐ๋๋ก๋ง ์ ๊ทผํฉ๋๋ค. (deploy/README.md)
42๊ฐ ์ํฐํฐ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค. ์ฌ์ฉ์(usersยทuser_profile)๋ฅผ ์ค์ฌ์ผ๋ก ์ฅํ๊ธ(scholarshipยทraw_scholarshipยทscholarship_condition),
์ง์์(essayยทessay_questionยทessay_answerยทai_interview), ์์นด์ด๋น(scrap), ์๋ฆผ(notification), ์ธ์ฌ์ดํธ(insight) ๋๋ฉ์ธ์ด ์ฐ๊ฒฐ๋ฉ๋๋ค.
์ด๋ฏธ์ง๊ฐ ์๊ฒ ๋ณด์ด๋ฉด ํด๋ฆญํด์ ์๋ณธ ํฌ๊ธฐ๋ก ํ์ธํ ์ ์์ต๋๋ค. โ docs/images/erd.png
- ๐ Notion API ๋ช ์ธ์ (๊ณตํต ๊ท์น ยท ๋๋ฉ์ธ๋ณ ์์ธ Request/Response ยท ์คํจ ์ผ์ด์ค) โ https://app.notion.com/p/API-a480adbca4ca824ba1ce810b83a1e6e7
- Swagger UI โ
/swagger-ui/index.html(Swagger ๋ ๋ก์ปฌยท์ด์ ๋ชจ๋ ADMIN ๊ถํ ๋ค์ ์์ต๋๋ค./admin/login.html์์ ๊ด๋ฆฌ์ ๋ก๊ทธ์ธ ํ ์ ๊ทผํ์ธ์. ์ธ๋ถ ์ด๋์ ์ Notion ๋ช ์ธ์๋ฅผ ์ฌ์ฉํด ์ฃผ์ธ์.)
| ํญ๋ชฉ | ๊ท์น |
|---|---|
| Base URL | https://api.wish-connect.com (๋ชจ๋ ์๋ํฌ์ธํธ๋ /api/v1 ํ์) |
| ์ธ์ฆ | Authorization: Bearer {accessToken} โ Access Token 30๋ถ / Refresh Token 14์ผ(Redis ์ ์ฅ) |
| ์๋ต ํฌ๋งท | ๋ชจ๋ ์๋ต์ ApiResponse<T> { success, data, message } ๋ก ๊ฐ์ |
| ์๋ฌ ์ฒ๋ฆฌ | CustomException + ErrorCode enum, ์ ์ญ @RestControllerAdvice |
| ํ์ด์ง๋ค์ด์ | page(1๋ถํฐ), size ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ |
| ๋ค์ด๋ฐ | ๋ฆฌ์์ค๋ ์๋ฌธ์ ๋ณต์ํ, ์์ฒญ DTO ~Request / ์๋ต DTO ~Response, ์ํ๊ฐ์ ๋๋ฌธ์ Enum |
๐ ์ธ์ฆ (Auth)
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| LOCAL ํ์๊ฐ์ | POST | /api/v1/auth/signup |
| LOCAL ๋ก๊ทธ์ธ | POST | /api/v1/auth/login |
| ๋ก๊ทธ์์ | POST | /api/v1/auth/logout |
| ํ ํฐ ์ฌ๋ฐ๊ธ | POST | /api/v1/auth/refresh |
| ์นด์นด์ค / ๊ตฌ๊ธ / ๋ค์ด๋ฒ ๋ก๊ทธ์ธ | POST | /api/v1/auth/{kakao|google|naver}/login |
| ์ด๋ฉ์ผ ์ค๋ณต ํ์ธ | GET | /api/v1/auth/email/check |
| ์ด๋ฉ์ผ ์ธ์ฆ์ฝ๋ ๋ฐ์ก | POST | /api/v1/auth/email/verification-code |
| ์ด๋ฉ์ผ ์ธ์ฆ์ฝ๋ ํ์ธ | POST | /api/v1/auth/email/verify |
| ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ์์ฒญ | POST | /api/v1/auth/password/reset-request |
| ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ์ฝ๋ ํ์ธ | POST | /api/v1/auth/password/verify |
| ๋น๋ฐ๋ฒํธ ์ฌ์ค์ | POST | /api/v1/auth/password/reset |
| ๋ก๊ทธ์ธ ์์ด๋ ์ค๋ณต ํ์ธ | GET | /api/v1/auth/login-id/check |
| ์์ด๋ ์ฐพ๊ธฐ ์์ฒญ / ํ์ธ | POST | /api/v1/auth/login-id/find-request, /find |
๐ ์จ๋ณด๋ฉ ยท ํ๋กํ (Onboarding)
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| ๋ด ํ๋กํ ์กฐํ | GET | /api/v1/users/me/profile |
| STEP 1 ๊ธฐ๋ณธ ์ ๋ณด ์ ์ฅ | PUT | /api/v1/users/me/profile/basic |
| STEP 2 ํ์ ์ ๋ณด ์ ์ฅ | PUT | /api/v1/users/me/profile/academic |
| STEP 3 ๊ฐ๊ตฌ ์ ๋ณดยท๊ด์ฌ์ฌ ์ ์ฅ | PUT | /api/v1/users/me/profile/household |
| STEP 4 ์จ๋ณด๋ฉ ์๋ฃ | POST | /api/v1/users/me/profile/complete |
| ํ๊ต ๊ฒ์ (์๋์์ฑ) | GET | /api/v1/universities/search |
| ์ ๊ณต ๊ฒ์ | GET | /api/v1/majors/search |
| ์๋ / ์๊ตฐ๊ตฌ ๋ชฉ๋ก | GET | /api/v1/regions, /api/v1/regions/{regionId}/children |
๐ค ๋ง์ดํ์ด์ง (MyPage)
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| ๋ด ์ ๋ณด ์กฐํ | GET | /api/v1/users/me |
| ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ | PATCH | /api/v1/users/me/password |
| ์ด๋ฉ์ผ ์ค๋ณต ํ์ธ | POST | /api/v1/users/me/email/check |
| ์ด๋ฉ์ผ ๋ณ๊ฒฝ ์ธ์ฆ์ฝ๋ ๋ฐ์ก / ํ์ธ | POST | /api/v1/users/me/email/verification, /email/verify |
| ์ด๋ฉ์ผ ๋ณ๊ฒฝ | PATCH | /api/v1/users/me/email |
| ํ์ ํํด (soft delete) | DELETE | /api/v1/users/me |
๐ ์ฅํ๊ธ (Scholarship)
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| ๋ง์ถค ์ถ์ฒ ๋ชฉ๋ก (๋ฉ์ธ) | GET | /api/v1/scholarships/curated |
| ์ฅํ๊ธ ๊ฒ์ | GET | /api/v1/scholarships/search |
| ์ถ์ฒ ๊ฒ์์ด | GET | /api/v1/scholarships/search/popular-keywords |
| ์ฅํ๊ธ ์์ธ | GET | /api/v1/scholarships/{scholarshipId} |
| ์ฅํ๊ธ ์ผ์ ๋ฌ๋ ฅ | GET | /api/v1/scholarships/calendar |
| ํ ์ฅํ๊ธ ์์ ์์ฝ | GET | /api/v1/scholarships/home-summary |
| ์ถ์ฒ ๋ ธ์ถยทํด๋ฆญ ๊ธฐ๋ก | POST | /api/v1/scholarships/events |
| ์ค๋ฑ๋ก ์ ๊ณ / ๋ด ์ ๊ณ ๋ชฉ๋ก | POST / GET | /api/v1/scholarships/{scholarshipId}/reports, /my-reports |
| ๋ฉด์ ์์ ์ง๋ฌธ ์กฐํยท์์ฑยท์ญ์ | GET / POST / DELETE | /api/v1/scholarships/{scholarshipId}/interview-questions |
๐ ์์นด์ด๋น (Archive)
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| ์์นด์ด๋น ๋ชฉ๋ก ์กฐํ | GET | /api/v1/archive |
| ์ฅํ๊ธ ์คํฌ๋ฉ | POST | /api/v1/archive/{scholarshipId}/scrap |
| ์คํฌ๋ฉ ํด์ | DELETE | /api/v1/archive/{scholarshipId}/scrap |
โ๏ธ AI ์๊ธฐ์๊ฐ์ (Application)
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| ์ง์์ ๋ชฉ๋ก ์กฐํ | GET | /api/v1/applications |
| ์ง์์ ์์ฑ ์์ | POST | /api/v1/applications |
| ์ง์์ ํตํฉ ์์ธ ์กฐํ | GET | /api/v1/applications/{applicationId} |
| ์ฅํ๊ธ ๋ง์ถค ๋ฌธํญ ์์ฑ | POST | /api/v1/applications/{applicationId}/questions/generate |
| STEP 1 ์ฌ์ ์ธํฐ๋ทฐ | POST | /api/v1/applications/{applicationId}/questions/{questionId}/interview |
| STEP 2 ๋ต๋ณ ๊ด๋ฆฌ (draft/save/confirm) | PUT | /api/v1/applications/{applicationId}/questions/{questionId}/answer |
| ๋ฉด์ ์ค๋น ์๋ฃ ์กฐํ / ์์๋ต๋ณ ์์ฑ | GET / POST | /api/v1/applications/{applicationId}/interview-prep |
๐ ์๋ฆผ (Notification) ยท ๐ก ์ธ์ฌ์ดํธ (Insight) ยท ๐ฎ ๋ฌธ์
| ๊ธฐ๋ฅ | ๋ฉ์๋ | ์๋ํฌ์ธํธ |
|---|---|---|
| ์๋ฆผ ๋ชฉ๋ก | GET | /api/v1/notifications |
| ์๋ฆผ ์ฝ์ ์ฒ๋ฆฌ | PUT / PATCH | /api/v1/notifications/{notificationId}/read |
| ์๋ฆผ ์ ์ฒด ์ญ์ | DELETE | /api/v1/notifications |
| ์๋ฆผ ์ค์ ์กฐํ / ๋ณ๊ฒฝ | GET / PUT | /api/v1/notifications/settings |
| ์ธ์ฌ์ดํธ ๋ชฉ๋ก ์กฐํ | GET | /api/v1/insights |
| ์ฝํ ์ธ ์ด์ฉ ๋ฌธ์ ์ ์ | POST | /api/v1/content-inquiries |
๐ ๊ด๋ฆฌ์ (ADMIN ์ ์ฉ)
ROLE_ADMIN ํ ํฐ์ด ์์ด์ผ ํธ์ถํ ์ ์์ต๋๋ค.
| ์์ญ | ์๋ํฌ์ธํธ |
|---|---|
| ๊ด๋ฆฌ์ ์ธ์ฆ | /api/v1/admin/auth/login, /logout |
| ๋ฐ์ดํฐ ํํฉยท์์ง ์๋ณธยท์ด์ ํ์ง | /api/v1/scholarships/admin/** |
| ์์งยท๋ณด์ยทํ์ฑ ๋ฐฐ์น ์๋ ์คํ | /api/v1/scholarships/{sync|collect|enrich|parse|conditions}/** |
| ์ค๋ณต ์ฅํ๊ธ ํ์งยท๋ณํฉ ์น์ธ | /api/v1/scholarships/merge/** |
| ์ฅํ๊ธ ์๊ธฐ ๋ฑ๋กยท์์ ยท์ญ์ , ์์ ์ผ๊ด ๋ฐ์ | /api/v1/scholarships/manual/**, /admin/manual-excel |
| ์ค๋ฑ๋ก ์ ๊ณ ์ฒ๋ฆฌ | /api/v1/scholarships/reports/** |
| ์ฝํ ์ธ ๋ฌธ์ ์ฒ๋ฆฌ | /api/v1/admin/content-inquiries/** |
| ๋ฐฐ์น ์คํ ์ด๋ ฅ ยท ์์คํ ์ํ ยท ๊ฐ์ฌ ๋ก๊ทธ | /api/v1/admin/jobs, /admin/system/**, /admin/audit-log |
| ํ๊ตยท์ ๊ณต ๋๊ธฐํ, ์ธ์ฌ์ดํธ ์์ง | /api/v1/universities/sync, /api/v1/insights/sync |
| ๊ตฌ์ฑ | ๋ด์ฉ |
|---|---|
| CI/CD | GitHub Actions โ main push ์ build ยท test โ jar SCP โ SSH ์ฌ๊ธฐ๋ |
| Compute | AWS EC2 (Ubuntu, ap-northeast-2) ยท systemd wishconnect.service ยท -Xms512m -Xmx1g |
| Web | Nginx :443 (Let's Encrypt) โ Spring Boot :8080 ๋ฆฌ๋ฒ์ค ํ๋ก์ |
| DB | AWS RDS PostgreSQL |
| Cache | Redis (EC2 ๋ก์ปฌ) โ Refresh Token, ์ด๋ฉ์ผ ์ธ์ฆ์ฝ๋ TTL, ๋ถ์ฐ ๋ฝ |
| Storage / Mail | AWS S3 (ํฌ์คํฐยท์ฒจ๋ถ ์ด๋ฏธ์ง) ยท AWS SES (์ธ์ฆ ๋ฉ์ผ) |
| DNS | Route 53 โ wish-connect.com(Vercel, FE) / api.wish-connect.com(EC2, BE) |
| External | Anthropic Claude, ์นด์นด์คยท๊ตฌ๊ธยท๋ค์ด๋ฒ OAuth, ๋ค์ด๋ฒ ๊ฒ์, ํ๊ตญ์ฅํ์ฌ๋จ ๊ณต๊ณต API, ํ์ ์ ๋ณด API, ๋ํ ๊ณต์ง ํฌ๋กค๋ง |
์ด์ ์๋ฒ ์ค์ (systemdยทlogrotateยท์ค์ยท๊ด๋ฆฌ์ SSH ํฐ๋)์ deploy/README.md์ ์ ๋ฆฌ๋์ด ์์ต๋๋ค.
| ๊ตฌ๋ถ | ๊ธฐ์ |
|---|---|
| Language | Java 17 |
| Framework | Spring Boot 3.3.5 (Web, Data JPA, Security, Validation, Mail, Actuator) |
| Database | PostgreSQL ยท Redis |
| Auth | Spring Security + JWT (jjwt 0.12.6) ยท OAuth 2.0 (Kakao / Google / Naver) |
| AI | Anthropic Claude Java SDK |
| Docs | springdoc-openapi (Swagger UI) + therapi-runtime-javadoc |
| Infra | AWS EC2 ยท RDS ยท S3 ยท SES ยท Route 53 ยท Nginx ยท GitHub Actions |
| Etc | Jsoup(ํฌ๋กค๋ง) ยท Apache POI(์์ ) ยท AWS SDK v2 ยท Lombok |
src/main/java/com/wishconnect
โโโ domain
โ โโโ auth # ํ์๊ฐ์
ยท๋ก๊ทธ์ธยท์์
ยทํ ํฐยท์ด๋ฉ์ผ ์ธ์ฆ
โ โโโ user # ๋ง์ดํ์ด์งยทํ๋กํยท์จ๋ณด๋ฉ
โ โโโ scholarship # ์์งยท์ ์ ยทํ๋ ์ดํ
ยท๊ฒ์ยท์์ธยท์ ๊ณ ยท๊ด๋ฆฌ์
โ โโโ application # AI ์๊ธฐ์๊ฐ์(์ธํฐ๋ทฐยท์ด์ยท๋ฉด์ ์ค๋น)
โ โโโ archive # ์คํฌ๋ฉ ์์นด์ด๋น
โ โโโ notification # ์๋ฆผ์ผํฐยท์ค์ ยท์ค์ผ์ค๋ฌ
โ โโโ insight # ์ธ์ฌ์ดํธ ์ฝํ
์ธ ์์งยท์กฐํ
โ โโโ inquiry # ์ฝํ
์ธ ์ด์ฉ ๋ฌธ์
โ โโโ search # ์ถ์ฒ ๊ฒ์์ด
โ โโโ common # ์ง์ญยทํ๊ตยท์ ๊ณต ๋ง์คํฐ
โโโ global
โโโ config # Security, CORS, Swagger, Scheduling
โโโ jwt # ํ ํฐ ๋ฐ๊ธยท๊ฒ์ฆ ํํฐ
โโโ exception # CustomException ยท ErrorCode ยท ์ ์ญ ํธ๋ค๋ฌ
โโโ lock # ๋ฐฐ์น ๋ถ์ฐ ๋ฝ
โโโ audit # ๊ด๋ฆฌ์ ๊ฐ์ฌ ๋ก๊ทธ
โโโ operation # ๋ฐฐ์น ์คํ ์ด๋ ฅยท์์คํ
์ํ
โโโ common # ApiResponse ๋ฑ ๊ณตํต ์๋ต
โโโ util
- Java ํ์ผ 417๊ฐ ยท ์ํฐํฐ 42๊ฐ ยท ํ ์คํธ ํด๋์ค 78๊ฐ
๋ค์ด๋ฒ ์์น์ด๋๋ฐ์ด์ ์น๋ง์คํฐ ๊ฐ์ด๋๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ง์ท๋ค. ๊ณต๊ณ ๋ ๋งค์ผ ์์ง ๋ฐฐ์น๋ก ๊ฐ๋ฆฌ๋ฏ๋ก ์ ์ ํ์ผ ๋์ DB ๋ฅผ ์ฝ์ด ์ฆ์์์ ๋ง๋ ๋ค.
| ์๋ํฌ์ธํธ | ๋ด์ฉ |
|---|---|
GET /sitemap.xml |
๊ณ ์ ํ์ด์ง + ์ฅํ๊ธ ์์ธ URL. ๋ชจ์ง ์ค priority 0.8, ๋ง๊ฐ๋ถ 0.3 |
GET /robots.txt |
๋ค์ด๋ฒ ๊ฒ์๋ก๋ด(Yeti) ํ์ฉ, ๊ด๋ฆฌ์ยทAPI ๊ฒฝ๋ก ์ฐจ๋จ, Sitemap: ์์น ๋ช
์ |
๋ ๋ค ์ธ์ฆ ์์ด ์ด๋ ค ์๊ณ (ํฌ๋กค๋ฌ๋ ํ ํฐ์ด ์๋ค), ๊ฒฐ๊ณผ๋ ์๋ฒ์์ 1์๊ฐ ์บ์ํ๋ค.
์ค์ ์ app.sitemap.* / app.robots.* (application.yml).
ํ๋ก ํธ ๋ผ์ฐํ
์ด ๋ฐ๋๋ฉด SITEMAP_SCHOLARSHIP_PATH / SITEMAP_STATIC_PATHS ํ๊ฒฝ๋ณ์๋ง ๊ณ ์น๋ฉด ๋๋ค.
๊ฐ์ด๋์์ ์งํจ ๊ฒ:
- URL ๋๋ฉ์ธ ์ผ์น โ ์ฌ์ดํธ๋งต ๋ด URL ์ด ์์ ํ์ธํ ํธ์คํธ์ ๋ค๋ฅด๊ฑฐ๋ ์๋๊ฒฝ๋ก๋ฉด ๋ค์ด๋ฒ๊ฐ ํต์งธ๋ก ๋ฒ๋ฆฐ๋ค.
๊ทธ๋์
app.sitemap.base-url์ ์ ๋์ฃผ์๋ง ํ์ฉํ๊ณ , ์๋๋ฉด ๊ธฐ๋ ์์ ์ ์์ธ๋ก ๋ง๋๋ค. www ์ ๋ฌด๊น์ง ์์น์ด๋๋ฐ์ด์ ์ ๋ฑ๋กํ ํธ์คํธ์ ๋๊ฐ์ด ๋ง์ถฐ์ผ ํ๋ค. - ์ฉ๋ยท๊ฑด์ ์ํ โ 10MB ๋ฏธ๋ง, ํ ํ์ผ๋น 50,000 URL ๋ฏธ๋ง. ์ํ์ ๋ฟ์ผ๋ฉด WARN ๋ก๊ทธ๋ฅผ ๋จ๊ธด๋ค.
- ์๋ต ์๋ โ ํผ๋๊ฐ ๋๋ฆฌ๋ฉด ์ ์ถ์ด ์ ํ๋๋ฏ๋ก ์์ฑ ๊ฒฐ๊ณผ๋ฅผ ์บ์ํ๋ค.
lastmodโ ๋ค์ด๋ฒ ์์์ ๊ฐ์ W3C Datetime(2026-08-18T01:13:19+09:00).- ๋ชจ๋ URL ์๋ก ๊ถ์ฅ โ ๋ง๊ฐ ๊ณต๊ณ ๋ ์์ธ ํ์ด์ง๊ฐ ์ด์ ์์ผ๋ฏ๋ก ๋ด๋
priority๋ฅผ ๋ฎ์ถ๋ค (SITEMAP_INCLUDE_CLOSED=false๋ก ์ ์ธ ๊ฐ๋ฅ). - robots.txt ๋
text/plain+ 2xx โ HTML ๋ก ๋๊ฐ๋ฉด ๊ท์น์ด ๋ฌด์๋๊ณ , 5xx ๋ฉด ์ฌ์ดํธ ์ ์ฒด๊ฐ ์์ง ์ฐจ๋จ์ผ๋ก ํด์๋๋ค. Yeti ๊ทธ๋ฃน์๋ ๊ฐ์ ๊ท์น์ ๋ฐ๋ณตํด ์ ๋๋ค(ํ์ค์ ๊ฐ์ฅ ๊ตฌ์ฒด์ ์ธ ๊ทธ๋ฃน ํ๋๋ง ์ ์ฉ๋๊ธฐ ๋๋ฌธ).
โ ๏ธ ๋จ์ ์์ ์ ๋ฐฑ์๋ ๋ฐ์ ์๋ค.
- ํ๋ก ํธ/nginx ํ๋ก์ โ ๋ ํ์ผ ๋ชจ๋ ์ฌ์ดํธ ๋ฃจํธ์ ์์ด์ผ ํ๋ค.
https://wish-connect.com/sitemap.xml,/robots.txt์์ฒญ์ ์ด ์๋ํฌ์ธํธ๋ก rewrite ํด์ผ ํ๋ค. robots.txt ๊ท์น์ ํธ์คํธ๋ณ๋ก ์ ์ฉ๋๋ฏ๋ก API ๋๋ฉ์ธ์๋ง ์์ผ๋ฉด ํ๋ก ํธ ์์ง์๋ ์๋ฌด ์ํฅ์ด ์๋ค.- ์์น์ด๋๋ฐ์ด์ ๋ฑ๋ก โ ์ฌ์ดํธ ๋ฑ๋ก โ ์์ ํ์ธ(meta ํ๊ทธ ๋๋ HTML ํ์ผ) โ "์์ฒญ-์ฌ์ดํธ๋งต ์ ์ถ".
- ํ๋ก ํธ HTML ๋งํฌ์ โ ํ์ด์ง๋ณ
titleยทmeta description, ํ์ค<a href>๋งํฌ,noindex/nofollow๋ฏธ์ฌ์ฉ. ์ฝํ ์ธ ๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ๋ก๋ง ๊ทธ๋ฆฌ๋ฉด ์์ง๋์ง ์์ผ๋ฏ๋ก ์์ธ ํ์ด์ง๋ SSR ์ด์ด์ผ ํ๋ค.RSS ํผ๋๋ ๋ง๋ค์ง ์์๋ค. ๊ฐ์ด๋๋ "๋ณธ๋ฌธ์ ๋ด์์ผ ํด์ URL ์ ๋ง์ด ๋ฃ๊ธฐ ์ด๋ ค์ฐ๋ ์ฌ์ดํธ๋งต์ ์ฐ์ ํ์ฉ"ํ๋ผ๊ณ ๊ถํ๋ค.




