-
โ ์ฌ์ฉ์ ์ธ์ฆ ๋ฐ ๊ณ์ ๊ด๋ฆฌ
Google/Naver OAuth2 ์์ ๋ก๊ทธ์ธ ๋ฐ ์ฝ๋ฐฑ ์ฒ๋ฆฌ
์ ๊ท ์ฌ์ฉ์์ ์ถ๊ฐ ์ ๋ณด ์ ๋ ฅ๊ณผ ๋๋ค์ ์ค๋ณต ํ์ธ
Access TokenยทRefresh Token ๊ธฐ๋ฐ ๋ก๊ทธ์ธ ์ํ ์ ์ง ๋ฐ ํ ํฐ ์ฌ๋ฐ๊ธ
๋ก๊ทธ์์, ํ์์ ๋ณด ์์ , ์ด๋ฉ์ผ ์ธ์ฆ ๊ธฐ๋ฐ ํ์ ํํด -
โ ๋ฉ์ธ ๋์๋ณด๋ ๋ฐ AI ๊ฑด๊ฐ ๋ฆฌํฌํธ
๋ฑ๋ก๋ ๋ฐ๋ ค๋๋ฌผ ์ ํํ ๋ฉ์ธ ๋์๋ณด๋ ์ ๊ณต
๋ฐ๋ ค๋๋ฌผ๋ณ ์ต์ AI ๊ฑด๊ฐ ๋ฆฌํฌํธ์ ๊ฑด๊ฐ ๊ด๋ฆฌ ๊ถ์ฅ ์ฌํญ ํ์
๋ฐ๋ ค๋๋ฌผ ๊ธฐ๋ณธ ์ ๋ณด, ๋ชธ๋ฌด๊ฒ, ๊ฒ์ง ์ผ์ ๋ฑ ์ฃผ์ ์ ๋ณด ์๊ฐํ
๊ณต์ง์ฌํญ, ์ธ๊ธฐ ๊ฒ์๊ธ ๋ฐ ์ฃผ์ ์๋น์ค ๋ฐ๋ก๊ฐ๊ธฐ ์ ๊ณต -
โ ๋ฐ๋ ค๋๋ฌผ ๋ฐ ๊ฐ์กฑ ๊ด๋ฆฌ
๋ฐ๋ ค๋๋ฌผ ๋ชฉ๋ก, ๋ฑ๋ก, ์์ธ ์กฐํ, ์ ๋ณด ์์ ํ๋ฉด
๋ฐ๋ ค๋๋ฌผ ํ๋กํ ์ด๋ฏธ์ง ์ ๋ก๋ ๋ฐ ํ์ผ ๊ฒ์ฆ
๋ชธ๋ฌด๊ฒ ๊ธฐ๋ก๊ณผ ํน์ด์ฌํญ ๋ฑ๋กยท์์ ยท์ญ์
๊ฐ์กฑ ์ด๋ ์ฝ๋ ๋ฐ๊ธ, ๊ฐ์กฑ ์ฐธ์ฌ ์ ์ฒญ ๋ฐ ๊ถํ ๊ด๋ฆฌ -
โ ์ฐ์ฑ ๋ฐ ์ค์๊ฐ ์์น ์ถ์
์ง๋ ๊ธฐ๋ฐ ๋ฐ๋ ค๋๋ฌผ ํ์ฌ ์์น ๋ฐ ์์ ๊ตฌ์ญ ์๊ฐํ
STOMP WebSocket์ ํ์ฉํ ์ค์๊ฐ ์์น ๋ฐ์ดํฐ ๊ตฌ๋
์ธํ๋ฆฌ ๋ด๋ถยท์ธ๋ถ ์ํ์ ์ค์ฌ์ ๊ธฐ์ค ๊ฑฐ๋ฆฌ ํ์
๋ฐ๋ ค๋๋ฌผ๋ณ ์์น ์ถ์ ๊ณผ ์ฐ๊ฒฐ ์ํ ๊ด๋ฆฌ -
โ ์ง์คํ์ค ์์ ๊ตฌ์ญ ๊ด๋ฆฌ
๋ฐ๋ ค๋๋ฌผ๋ณ ์์ ๊ตฌ์ญ ์์ฑ ๋ฐ ๊ฒฝ๊ณ ์กฐํ
์ธํ๋ฆฌ ์ด๋ฆ, ์ค์ฌ ์ขํ, ๋ฐ๊ฒฝ ์์
์์ ๊ตฌ์ญ ํ์ฑํยท๋นํ์ฑํ ์ํ ๊ด๋ฆฌ
์๋ฒ์์ ํ์ ํ ์ธํ๋ฆฌ ์ดํ ์ฌ๋ถ๋ฅผ ์ค์๊ฐ UI์ ๋ฐ์ -
โ ์ปค๋ฎค๋ํฐ
๊ฒ์๊ธ ๋ชฉ๋ก, ์์ธ ์กฐํ, ์์ฑ, ์์ , ์ญ์
๊ฒ์๊ธ ์ด๋ฏธ์ง ์ ๋ก๋ ๋ฐ ์์ฑ ์ค ์์ ์ ์ฅ
๋๊ธ ์์ฑยท์กฐํ์ ์ข์์ยท์ซ์ด์ ๋ฐ์ ๊ธฐ๋ฅ
์์ฑ ๊ฒ์๊ธ, ๋๊ธ, ๋ฐ์ ๋ฑ ๋ด ํ๋ ์กฐํ -
โ ์๋ฆผ ๋ฐ ์ฌ์ฉ์ ์ค์
์๋น์ค ์๋ฆผ ์์ ์ฌ๋ถ ์ค์
๋ง์ด๋๋ ๋ฉ๋ด๋ฅผ ํตํ ์ฌ์ฉ์ ์ค์ ๊ด๋ฆฌ
API ์ฒ๋ฆฌ ์ํ์ ๋ฐ๋ฅธ ์ฑ๊ณตยท์คํจ ๋ฉ์์ง์ ์ฌ์ฉ์ ํผ๋๋ฐฑ ์ ๊ณต -
โ ์ฌ์ฉ์ ๊ฒฝํ ๋ฐ ๋ฐ์ดํฐ ์ฒ๋ฆฌ
TanStack Query ๊ธฐ๋ฐ ์๋ฒ ์ํ ์บ์ฑ๊ณผ ๋ฐ์ดํฐ ๊ฐฑ์
๋ก๋ฉ Skeleton, ์ค๋ฅ ํ๋ฉด, ๋น ์ํ UI ๋ฐ ์ฌ์๋ ์ฒ๋ฆฌ
Axios ๊ณตํต ํด๋ผ์ด์ธํธ์ ์ธ์ฆ ์ธํฐ์ ํฐ๋ฅผ ํตํ API ์์ฒญ ๊ด๋ฆฌ
๋ฐ์ํ ๋ ์ด์์๊ณผ ๋ชจ๋ฐ์ผยท๋ฐ์คํฌํฑ ํ๋ฉด ๋์ -
โ ์ฝ๋ ํ์ง ๋ฐ ๋ฐฐํฌ ํ๊ฒฝ
ESLint์ Prettier ๊ธฐ๋ฐ ์ฝ๋ ํ์ง ๋ฐ ํฌ๋งท ๊ด๋ฆฌ
Husky์ lint-staged๋ฅผ ํ์ฉํ ์ปค๋ฐ ์ ์๋ ๊ฒ์ฌ
GitHub Actions ๊ธฐ๋ฐ Lint, Format Check, TypeScript Build ๊ฒ์ฆ
Vercel ๊ธฐ๋ฐ ํ๋ก ํธ์๋ ๋ฐฐํฌ ๋ฐ SPA Routing ์ง์
DoDo ํ๋ก ํธ์๋๋ ํ๋ฉด, ๋๋ฉ์ธ ๊ธฐ๋ฅ, ๊ณตํต ๋ชจ๋์ ์ฑ ์์ ๋ถ๋ฆฌํ ๊ณ์ธตํ ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋์ด ์์ต๋๋ค.
์ฌ์ฉ์์ ์์ฒญ์ React Router๋ฅผ ํตํด ํ์ด์ง๋ก ์ ๋ฌ๋๊ณ , ๊ฐ ํ์ด์ง๋ Feature ๊ณ์ธต์ API์ ์ํ ๊ด๋ฆฌ ๋ก์ง์ ์ฌ์ฉํฉ๋๋ค. ์๋ฒ ๋ฐ์ดํฐ๋ TanStack Query๋ก ๊ด๋ฆฌํ๋ฉฐ, Axios์ STOMP WebSocket์ ํตํด ๋ฐฑ์๋ ์๋ฒ์ ํต์ ํฉ๋๋ค.
flowchart TD
User[์ฌ์ฉ์] --> UI[React UI]
UI --> Router[React Router]
Router --> Guard[RequireAuth<br/>์ธ์ฆ ๋ณดํธ ๋ผ์ฐํธ]
Guard --> Pages[Pages]
Pages --> Features[Features<br/>๋๋ฉ์ธ ๊ธฐ๋ฅ]
Features --> Query[TanStack Query]
Features --> LocalState[React Local State]
Query --> Axios[Axios API Client]
Axios --> Interceptor[JWT ์ธ์ฆ ์ธํฐ์
ํฐ]
Interceptor --> Backend[Spring Boot Backend]
Features --> STOMP[STOMP WebSocket Client]
STOMP --> WebSocket[Spring WebSocket Server]
Backend --> QueryCache[Query Cache ๊ฐฑ์ ]
QueryCache --> UI
WebSocket --> LiveState[์ค์๊ฐ ์์น ์ํ ๊ฐฑ์ ]
LiveState --> UI
DoDo ํ๋ก ํธ์๋๋ app, pages, features, widgets, shared ๊ณ์ธต์ผ๋ก ์ฑ
์์ ๋ถ๋ฆฌํฉ๋๋ค.
๐ฆ src
โฃ ๐ app
โ โฃ ๐ guards # ์ธ์ฆ ์ฌ๋ถ์ ๋ฐ๋ฅธ ์ ๊ทผ ์ ์ด
โ โฃ ๐ layouts # ์ฑ ๋ฐ ์ธ์ฆ ํ์ด์ง ๊ณตํต ๋ ์ด์์
โ โฃ ๐ styles # ์ ์ญ ์คํ์ผ๊ณผ ๋์์ธ ํ ํฐ
โ โฃ ๐ App.tsx # ์ ํ๋ฆฌ์ผ์ด์
์ง์
์ปดํฌ๋ํธ
โ โ ๐ router.tsx # ์ ์ฒด ํ์ด์ง ๋ผ์ฐํ
์ค์
โ
โฃ ๐ pages
โ โฃ ๐ auth # ๋ก๊ทธ์ธ, OAuth ์ฝ๋ฐฑ, ํ์๊ฐ์
โ โฃ ๐ community # ์ปค๋ฎค๋ํฐ ๋ชฉ๋ก, ์์ธ, ์์ฑ, ์์ , ๋ด ํ๋
โ โฃ ๐ family # ๊ฐ์กฑ ์ด๋ ์ฐธ์ฌ
โ โฃ ๐ main # ๋ฉ์ธ ๋์๋ณด๋์ ๊ฑด๊ฐ ๋ฆฌํฌํธ
โ โฃ ๐ my # ์ฌ์ฉ์, ๋ฐ๋ ค๋๋ฌผ, ๋ชธ๋ฌด๊ฒ, ํน์ด์ฌํญ ๊ด๋ฆฌ
โ โฃ ๐ walk # ์ฐ์ฑ
์ง๋์ ์ค์๊ฐ ์์น ์ถ์
โ โ ๐ not-found # 404 ํ์ด์ง
โ
โฃ ๐ features
โ โฃ ๐ auth # ์์
๋ก๊ทธ์ธ, ํ ํฐ, ์ฌ์ฉ์ API
โ โฃ ๐ community # ๊ฒ์๊ธ, ๋๊ธ, ๋ฐ์ ๊ธฐ๋ฅ
โ โฃ ๐ family-management # ๋ฐ๋ ค๋๋ฌผ ๊ฐ์กฑ ๊ด๋ฆฌ
โ โ ๐ fence # ์ธํ๋ฆฌ์ ์ค์๊ฐ ์์น ๊ด๋ฆฌ
โ
โฃ ๐ widgets
โ โ ๐ header # ๊ณตํต ํค๋์ ๋ด๋น๊ฒ์ด์
โ
โ ๐ shared
โฃ ๐ api # Axios ํด๋ผ์ด์ธํธ์ ๊ณตํต API
โฃ ๐ assets # ์ด๋ฏธ์ง, ์์ด์ฝ, SVG ๋ฆฌ์์ค
โฃ ๐ lib
โ โฃ ๐ api # API ์ค๋ฅ ๋ฉ์์ง ์ฒ๋ฆฌ
โ โฃ ๐ auth # JWT ์ ์ฅ, ๋ง๋ฃ ํ์ธ, ์ฌ๋ฐ๊ธ
โ โฃ ๐ files # ์ด๋ฏธ์ง ์
๋ก๋ ๊ฒ์ฆ
โ โฃ ๐ react-query # QueryClient์ Query Key
โ โ ๐ socket # STOMP WebSocket ํด๋ผ์ด์ธํธ
โ ๐ ui # ๊ณตํต UI ์ปดํฌ๋ํธ
DoDo ํ๋ก ํธ์๋๋ Google๊ณผ Naver OAuth2 ๋ก๊ทธ์ธ ๋ฐ JWT ๊ธฐ๋ฐ ์ธ์ฆ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
flowchart TD
Login[๋ก๊ทธ์ธ ํ์ด์ง] --> Provider{์์
๋ก๊ทธ์ธ ์ ํ}
Provider --> Google[Google OAuth]
Provider --> Naver[Naver OAuth]
Google --> Callback[OAuth Callback]
Naver --> Callback
Callback --> Code[Authorization Code ์ถ์ถ]
Code --> Backend[๋ฐฑ์๋ ์์
๋ก๊ทธ์ธ API ์์ฒญ]
Backend --> Result{์๋ต ์ํ}
Result -->|200 ๊ธฐ์กด ์ฌ์ฉ์| Token[Access Token / Refresh Token ์ ์ฅ]
Result -->|202 ์ ๊ท ์ฌ์ฉ์| Signup[์ถ๊ฐ ์ ๋ณด ์
๋ ฅ]
Signup --> Nickname[๋๋ค์ ์ค๋ณต ํ์ธ]
Nickname --> Profile[ํ๋กํ ๋ฑ๋ก]
Profile --> Token
Token --> Protected[๋ณดํธ๋ ํ์ด์ง ์ ๊ทผ]
Protected --> Expired{Access Token ๋ง๋ฃ}
Expired -->|๋ง๋ฃ๋์ง ์์| Request[API ์์ฒญ ์ฒ๋ฆฌ]
Expired -->|๋ง๋ฃ๋จ| Refresh[Refresh Token์ผ๋ก ์ฌ๋ฐ๊ธ]
Refresh --> Request
1. ์ฌ์ฉ์๊ฐ Google ๋๋ Naver ๋ก๊ทธ์ธ์ ์ ํํฉ๋๋ค.
2. OAuth ์ธ์ฆ์ด ์๋ฃ๋๋ฉด ํ๋ก ํธ์๋ ์ฝ๋ฐฑ ํ์ด์ง๋ก Authorization Code๊ฐ ์ ๋ฌ๋ฉ๋๋ค.
3. ํ๋ก ํธ์๋๋ Provider์ Authorization Code๋ฅผ ๋ฐฑ์๋์ ์ ๋ฌํฉ๋๋ค.
4. ๊ธฐ์กด ํ์์ด๋ฉด Access Token๊ณผ Refresh Token์ ์ ์ฅํฉ๋๋ค.
5. ์ ๊ท ํ์์ด๋ฉด ์ถ๊ฐ ์ ๋ณด ์
๋ ฅ๊ณผ ๋๋ค์ ์ค๋ณต ํ์ธ์ ์งํํฉ๋๋ค.
6. ๋ณดํธ๋ ํ์ด์ง๋ RequireAuth๋ฅผ ํตํด Access Token ๋ณด์ ์ฌ๋ถ๋ฅผ ํ์ธํฉ๋๋ค.
7. Access Token์ด ๋ง๋ฃ๋๋ฉด Refresh Token์ ์ฌ์ฉํ์ฌ ํ ํฐ ์ฌ๋ฐ๊ธ์ ์์ฒญํฉ๋๋ค.
8. ์ฌ๋ฐ๊ธ์ ์คํจํ๊ฑฐ๋ Refresh Token์ด ๋ง๋ฃ๋๋ฉด ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
๋ฐ๋ ค๋๋ฌผ ํ๋กํ๊ณผ ๊ฐ์กฑ ๊ตฌ์ฑ์์ ํ๋์ ๋ง์ด๋๋ ํ๋ฉด์์ ๊ด๋ฆฌํฉ๋๋ค.
flowchart TD
MyDodo[๋ง์ด๋๋] --> PetList[๋ฐ๋ ค๋๋ฌผ ๋ชฉ๋ก]
MyDodo --> UserProfile[ํ์์ ๋ณด ๊ด๋ฆฌ]
MyDodo --> Family[๊ฐ์กฑ ๊ด๋ฆฌ]
PetList --> Register[๋ฐ๋ ค๋๋ฌผ ๋ฑ๋ก]
PetList --> Detail[๋ฐ๋ ค๋๋ฌผ ์์ธ]
Detail --> Edit[๊ธฐ๋ณธ ์ ๋ณด ์์ ]
Detail --> Weight[๋ชธ๋ฌด๊ฒ ๊ธฐ๋ก]
Detail --> Notes[ํน์ด์ฌํญ ๊ด๋ฆฌ]
Detail --> Invite[๊ฐ์กฑ ์ด๋ ์ฝ๋ ๋ฐ๊ธ]
Family --> Pending[์ฐธ์ฌ ์ ์ฒญ ๋ชฉ๋ก]
Pending --> Approve[์ ์ฒญ ์น์ธ]
Pending --> Reject[์ ์ฒญ ๊ฑฐ์ ]
Family --> Permission[๊ฐ์กฑ ๊ถํ ๊ด๋ฆฌ]
Family --> Block[์ฌ์ฉ์ ์ฐจ๋จ ๊ด๋ฆฌ]
| ๊ตฌ๋ถ | ์ฃผ์ ๊ธฐ๋ฅ |
|---|---|
| ๋ฐ๋ ค๋๋ฌผ ๊ธฐ๋ณธ ์ ๋ณด | ์ด๋ฆ, ์ข , ํ์ข , ์ฑ๋ณ, ์๋ ์์ผ ๋ฑ ํ๋กํ ๊ด๋ฆฌ |
| ํ๋กํ ์ด๋ฏธ์ง | ์ด๋ฏธ์ง ์ ํ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ, ํ์ผ ํฌ๊ธฐ ๋ฐ ํ์ฅ์ ๊ฒ์ฆ |
| ๋ชธ๋ฌด๊ฒ ๊ธฐ๋ก | ๋ ์ง๋ณ ๋ชธ๋ฌด๊ฒ ๋ฑ๋ก, ์กฐํ, ์์ ๋ฐ ์ญ์ |
| ํน์ด์ฌํญ | ์๋ ๋ฅด๊ธฐ, ์งํ, ๋ณต์ฉ ์ฝ ๋ฑ ํน์ด์ฌํญ ๊ด๋ฆฌ |
| ๊ฐ์กฑ ์ด๋ | ์ด๋ ์ฝ๋ ์์ฑ ๋ฐ ์ด๋ ์ฝ๋ ๊ธฐ๋ฐ ์ฐธ์ฌ ์ ์ฒญ |
| ๊ฐ์กฑ ๊ถํ | ์ฐธ์ฌ ์ ์ฒญ ์น์ธยท๊ฑฐ์ ๋ฐ ๊ฐ์กฑ ๊ตฌ์ฑ์ ๊ด๋ฆฌ |
๋ฉ์ธ ํ๋ฉด์์ ๋ฐ๋ ค๋๋ฌผ์ ์ ํํ๋ฉด ํด๋น ๋ฐ๋ ค๋๋ฌผ์ ์ต์ ๊ฑด๊ฐ ๋ฆฌํฌํธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
flowchart TD
MainAPI[๋ฉ์ธ API ์กฐํ] --> Profiles[๋ฐ๋ ค๋๋ฌผ ํ๋กํ ๋ชฉ๋ก]
MainAPI --> Reports[๊ฑด๊ฐ ๋ฆฌํฌํธ ๋ชฉ๋ก]
MainAPI --> Boards[๊ณต์ง ๋ฐ ์ธ๊ธฐ ๊ฒ์๊ธ]
Profiles --> Select[๋ฐ๋ ค๋๋ฌผ ์ ํ]
Select --> Match[์ ํํ ๋ฐ๋ ค๋๋ฌผ์ ์ต์ ๋ฆฌํฌํธ ํ์]
Reports --> Match
Match --> Parse[๋ฆฌํฌํธ ์๋ต ํ์ฑ]
Parse --> Summary[๊ฑด๊ฐ ์์ฝ ํ์]
Parse --> Recommendations[๊ฑด๊ฐ ๊ด๋ฆฌ ๊ถ์ฅ ์ฌํญ ํ์]
Summary --> Dashboard[๋ฉ์ธ ๋์๋ณด๋]
Recommendations --> Dashboard
Boards --> Dashboard
- ๋ฑ๋ก๋ ์ฌ๋ฌ ๋ฐ๋ ค๋๋ฌผ ์ค ์กฐํํ ๋ฐ๋ ค๋๋ฌผ์ ์ ํํ ์ ์์ต๋๋ค.
- ์ ํ๋ ๋ฐ๋ ค๋๋ฌผ์ ์ต์ ๊ฑด๊ฐ ๋ถ์ ๋ฆฌํฌํธ๋ฅผ ํ์ํฉ๋๋ค.
- JSON ํํ์ ๋ฆฌํฌํธ ์๋ต์์ ์์ฝ ๋ด์ฉ๊ณผ ๊ถ์ฅ ์ฌํญ์ ๋ถ๋ฆฌํฉ๋๋ค.
- ๋ฐ์ดํฐ ์กฐํ ์ค์๋ Skeleton UI๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๋ฐ์ดํฐ๊ฐ ์๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ๋น ์ํ ๋ฐ ์ฌ์๋ UI๋ฅผ ์ ๊ณตํฉ๋๋ค.
STOMP WebSocket์ผ๋ก ๋ฐ๋ ค๋๋ฌผ์ ์์น๋ฅผ ๊ตฌ๋ ํ๊ณ ์ง๋์ ์ค์๊ฐ์ผ๋ก ๋ฐ์ํฉ๋๋ค.
flowchart TD
WalkPage[์ฐ์ฑ
ํ์ด์ง] --> PetSelect[๋ฐ๋ ค๋๋ฌผ ์ ํ]
PetSelect --> FenceAPI[์ธํ๋ฆฌ ๊ฒฝ๊ณ REST API ์กฐํ]
PetSelect --> STOMP[STOMP WebSocket ์ฐ๊ฒฐ]
FenceAPI --> Boundary[์ธํ๋ฆฌ ์ค์ฌ๊ณผ ๋ฐ๊ฒฝ ํ์]
STOMP --> Subscribe["/sub/fence/location/{petId} ๊ตฌ๋
"]
Subscribe --> Location[์ค์๊ฐ ์์น ๋ฉ์์ง ์์ ]
Location --> Coordinate[์๋ยท๊ฒฝ๋ ๊ฐฑ์ ]
Location --> Inside[์ธํ๋ฆฌ ๋ด๋ถ ์ฌ๋ถ]
Location --> Distance[์ธํ๋ฆฌ ์ค์ฌ๊ณผ์ ๊ฑฐ๋ฆฌ]
Coordinate --> Map[์ง๋ ๋ง์ปค ๊ฐฑ์ ]
Inside --> Status[์์ ์ํ UI ๊ฐฑ์ ]
Distance --> Status
Boundary --> Map
| ๊ธฐ๋ฅ | ์ค๋ช |
|---|---|
| ์ธํ๋ฆฌ ์์ฑ | ๋ฐ๋ ค๋๋ฌผ, ์ค์ฌ ์ขํ, ๋ฐ๊ฒฝ, ์ธํ๋ฆฌ ์ด๋ฆ์ ์ ๋ ฅํ์ฌ ์์ ๊ตฌ์ญ ์์ฑ |
| ์ธํ๋ฆฌ ์กฐํ | ์ ๊ทผ ๊ฐ๋ฅํ ๋ฐ๋ ค๋๋ฌผ์ ์ธํ๋ฆฌ ๊ฒฝ๊ณ ๋ชฉ๋ก ์กฐํ |
| ์ธํ๋ฆฌ ์์ | ์ธํ๋ฆฌ ์ด๋ฆ, ์ค์ฌ ์ขํ ๋ฐ ๋ฐ๊ฒฝ ์์ |
| ํ์ฑ ์ํ ๋ณ๊ฒฝ | ์ธํ๋ฆฌ ๊ฐ์ง ๊ธฐ๋ฅ ํ์ฑํ ๋ฐ ๋นํ์ฑํ |
| ์ค์๊ฐ ์์น | ๋ฐ๋ ค๋๋ฌผ๋ณ WebSocket Topic์ ๊ตฌ๋ ํ์ฌ ํ์ฌ ์์น ํ์ |
| ์ดํ ์ํ | ์๋ฒ๊ฐ ํ์ ํ ์ธํ๋ฆฌ ๋ด๋ถยท์ธ๋ถ ์ํ๋ฅผ UI์ ํ์ |
์ฌ์ฉ์ ๊ฐ ๋ฐ๋ ค๋๋ฌผ ์ ๋ณด์ ๊ฒฝํ์ ๊ณต์ ํ ์ ์๋ ์ปค๋ฎค๋ํฐ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
flowchart TD
Community[์ปค๋ฎค๋ํฐ] --> List[๊ฒ์๊ธ ๋ชฉ๋ก]
List --> Detail[๊ฒ์๊ธ ์์ธ]
Community --> Create[๊ฒ์๊ธ ์์ฑ]
Create --> Image[์ด๋ฏธ์ง ์
๋ก๋]
Create --> Draft[์์ ์ ์ฅ]
Draft --> Restore[์์ฑ ๋ด์ฉ ๋ณต๊ตฌ]
Detail --> Edit[๊ฒ์๊ธ ์์ ]
Detail --> Delete[๊ฒ์๊ธ ์ญ์ ]
Detail --> Comment[๋๊ธ ์์ฑ ๋ฐ ์กฐํ]
Detail --> Reaction[์ข์์ยท์ซ์ด์ ๋ฐ์]
Community --> MyActivity[๋ด ํ๋]
MyActivity --> MyBoards[์์ฑ ๊ฒ์๊ธ]
MyActivity --> MyComments[์์ฑ ๋๊ธ]
MyActivity --> MyReactions[๋ฐ์ํ ๊ฒ์๊ธ]
| ๊ตฌ๋ถ | ์ฒ๋ฆฌ ๋ฐฉ์ |
|---|---|
| ๊ฒ์๊ธ ๋ชฉ๋ก | ํ์ด์ง ๋ฒํธ์ ํฌ๊ธฐ๋ฅผ ์ ๋ฌํ์ฌ ๋ชฉ๋ก ์กฐํ |
| ๊ฒ์๊ธ ์์ธ | ๊ฒ์๊ธ ID๋ฅผ ๊ธฐ์ค์ผ๋ก ์์ธ ๋ฐ์ดํฐ ์กฐํ |
| ๊ฒ์๊ธ ์์ฑ | ์ ๋ชฉ, ๋ด์ฉ ๋ฐ ์ด๋ฏธ์ง URL์ ์ ๋ฌํ์ฌ ๋ฑ๋ก |
| ์์ ์ ์ฅ | Session Key๋ฅผ Local Storage์ ์ ์ฅํ์ฌ ์์ฑ ๋ด์ฉ ๋ณต๊ตฌ |
| ๋๊ธ | ๊ฒ์๊ธ๋ณ ๋๊ธ ๋ชฉ๋ก ์กฐํ ๋ฐ ๋๊ธ ์์ฑ |
| ๋ฐ์ | ์ข์์ยท์ซ์ด์ ์ํ ๋ณ๊ฒฝ ํ ๊ด๋ จ Query ๊ฐฑ์ |
| ๋ด ํ๋ | ์์ฑ ๊ฒ์๊ธ, ๋๊ธ ๋ฐ ๋ฐ์ ๋ด์ญ ์กฐํ |
DoDo ํ๋ก ํธ์๋๋ ๋ณ๋์ ์ ์ญ ์ํ ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ์๋ฒ ์ํ์ ํ๋ฉด ์ํ์ ์ฑ๊ฒฉ์ ๋ฐ๋ผ ๊ด๋ฆฌ ๋ฐฉ์์ ๊ตฌ๋ถํฉ๋๋ค.
| ๊ตฌ๋ถ | ๊ธฐ์ | ์ญํ |
|---|---|---|
| Server State | TanStack Query | API ๋ฐ์ดํฐ ์กฐํ, ์บ์ฑ, ์ฌ์์ฒญ ๋ฐ Query ๋ฌดํจํ |
| API Client | Axios | REST API ์์ฒญ๊ณผ ๊ณตํต ์๋ต ์ฒ๋ฆฌ |
| Authentication | Axios Interceptor | JWT ์๋ ์ฒจ๋ถ, ํ ํฐ ์ฌ๋ฐ๊ธ ๋ฐ ์คํจ ์์ฒญ ์ฌ์๋ |
| Real-time State | STOMP.js | ์ค์๊ฐ ์์น ๋ฐ์ดํฐ ๊ตฌ๋ ๊ณผ ์ฐ๊ฒฐ ์ํ ๊ด๋ฆฌ |
| Routing | React Router | ํ์ด์ง ๋ผ์ฐํ , ๋์ ๊ฒฝ๋ก, ์ธ์ฆ ๋ณดํธ ๋ผ์ฐํธ |
| Local UI State | React Hooks | ๋ชจ๋ฌ, ์ ๋ ฅ ํผ, ์ ํ ์ํ ๋ฐ ํ๋ฉด ์ํ ๊ด๋ฆฌ |
| Draft Storage | Local Storage | ์ปค๋ฎค๋ํฐ ์์ ์ ์ฅ Session Key ๊ด๋ฆฌ |
DoDo ํ๋ก ํธ์๋๋ GitHub Actions๋ฅผ ํตํด ์ฝ๋ ํ์ง๊ณผ ๋น๋ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ๊ฒ์ฆํ๊ณ , Vercel ํ๊ฒฝ์์ ์๋น์ค๋ฅผ ๋ฐฐํฌํฉ๋๋ค.
flowchart TD
Git[GitHub Repository] --> Event{Git Event}
Event -->|develop Pull Request| Actions[GitHub Actions CI]
Event -->|develop Push| Actions
Actions --> Checkout[์ฝ๋ ์ฒดํฌ์์]
Checkout --> Node[Node.js 20 ์ค์ ]
Node --> Yarn[Yarn ์์กด์ฑ ์ค์น]
Yarn --> Lint[ESLint ๊ฒ์ฌ]
Lint --> Format[Prettier Format Check]
Format --> Build[TypeScript + Vite Build]
Build --> Result{๊ฒ์ฆ ๊ฒฐ๊ณผ}
Result -->|์ฑ๊ณต| Pass[CI ํต๊ณผ]
Result -->|์คํจ| Fail[Workflow ์คํจ]
Git --> Vercel[Vercel Build & Deployment]
Vercel --> SPA[SPA Rewrite ์ ์ฉ]
SPA --> Service[ํ๋ก ํธ์๋ ์๋น์ค ๋ฐฐํฌ]
1. develop ๋ธ๋์น Pull Request ๋๋ Push ์ Workflow๊ฐ ์คํ๋ฉ๋๋ค.
2. Node.js 20๊ณผ Yarn 1.22.22 ํ๊ฒฝ์ ์ค์ ํฉ๋๋ค.
3. yarn install --frozen-lockfile ๋ช
๋ น์ผ๋ก ์์กด์ฑ์ ์ค์นํฉ๋๋ค.
4. ESLint๋ฅผ ํตํด ์ฝ๋ ์ค๋ฅ์ ๊ท์น ์๋ฐ์ ๊ฒ์ฌํฉ๋๋ค.
5. Prettier๋ฅผ ํตํด ์ฝ๋ ํฌ๋งท์ ๊ฒ์ฌํฉ๋๋ค.
6. TypeScript ์ปดํ์ผ๊ณผ Vite Production Build๋ฅผ ์คํํฉ๋๋ค.
7. ๋ชจ๋ ๊ณผ์ ์ด ์ฑ๊ณตํด์ผ CI ๊ฒ์ฆ์ ํต๊ณผํฉ๋๋ค.
| ํ๊ฒฝ ๋ณ์ | ์ค๋ช |
|---|---|
VITE_API_BASE_URL |
Spring Boot ๋ฐฑ์๋ API ์๋ฒ ๊ธฐ๋ณธ ์ฃผ์ |
์ฐ๋ฆฌ ํ๋ก์ ํธ๋ ์ํํ ํ์ ์ ์ํด ์๋์ ๊ฐ์ ๊ท์น์ ๋ฐ๋ฆ ๋๋ค.
๐๐ป React ๊ณต์ ๋ฌธ์ ๐๐ป TypeScript ๊ณต์ ๋ฌธ์ ๐๐ป Vite ๊ณต์ ๋ฌธ์ ๐๐ป Tailwind CSS ๊ณต์ ๋ฌธ์ ๐๐ป React Router ๊ณต์ ๋ฌธ์ ๐๐ป TanStack Query ๊ณต์ ๋ฌธ์ ๐๐ป Axios ๊ณต์ ๋ฌธ์ ๐๐ป STOMP.js ๊ณต์ ๋ฌธ์ ๐๐ป Vercel ๊ณต์ ๋ฌธ์
![]() ์กฐ์๋น |
