Skip to content
ย 
ย 

Latest commit

ย 

History

37 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

โœจ ํ”„๋ก ํŠธ์—”๋“œ ์ฃผ์š” ๊ธฐ๋Šฅ (Key Frontend Features)

  • โœ… ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ๊ณ„์ • ๊ด€๋ฆฌ

    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 ์ง€์›


โš™๏ธ ๊ธฐ์ˆ  ์Šคํƒ (Tech Stack)

Frontend Core

Routing & Server State

Real-time Communication

Code Quality & Deployment


๐Ÿค– ํ”„๋ก ํŠธ์—”๋“œ ์•„ํ‚คํ…์ฒ˜ (Frontend System Architecture)

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
Loading

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ (Project Structure)

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 ์ปดํฌ๋„ŒํŠธ

๐Ÿ” ์ธ์ฆ ๊ตฌ์กฐ (Authentication)

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
Loading

์ธ์ฆ ์ฒ˜๋ฆฌ ํ๋ฆ„

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์ด ๋งŒ๋ฃŒ๋˜๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿถ ๋ฐ˜๋ ค๋™๋ฌผ ๋ฐ ๊ฐ€์กฑ ๊ด€๋ฆฌ (Pet & Family Management)

๋ฐ˜๋ ค๋™๋ฌผ ํ”„๋กœํ•„๊ณผ ๊ฐ€์กฑ ๊ตฌ์„ฑ์›์„ ํ•˜๋‚˜์˜ ๋งˆ์ด๋„๋„ ํ™”๋ฉด์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

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[์‚ฌ์šฉ์ž ์ฐจ๋‹จ ๊ด€๋ฆฌ]
Loading

์ œ๊ณต ๊ธฐ๋Šฅ

๊ตฌ๋ถ„ ์ฃผ์š” ๊ธฐ๋Šฅ
๋ฐ˜๋ ค๋™๋ฌผ ๊ธฐ๋ณธ ์ •๋ณด ์ด๋ฆ„, ์ข…, ํ’ˆ์ข…, ์„ฑ๋ณ„, ์ƒ๋…„์›”์ผ ๋“ฑ ํ”„๋กœํ•„ ๊ด€๋ฆฌ
ํ”„๋กœํ•„ ์ด๋ฏธ์ง€ ์ด๋ฏธ์ง€ ์„ ํƒ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ, ํŒŒ์ผ ํฌ๊ธฐ ๋ฐ ํ™•์žฅ์ž ๊ฒ€์ฆ
๋ชธ๋ฌด๊ฒŒ ๊ธฐ๋ก ๋‚ ์งœ๋ณ„ ๋ชธ๋ฌด๊ฒŒ ๋“ฑ๋ก, ์กฐํšŒ, ์ˆ˜์ • ๋ฐ ์‚ญ์ œ
ํŠน์ด์‚ฌํ•ญ ์•Œ๋ ˆ๋ฅด๊ธฐ, ์งˆํ™˜, ๋ณต์šฉ ์•ฝ ๋“ฑ ํŠน์ด์‚ฌํ•ญ ๊ด€๋ฆฌ
๊ฐ€์กฑ ์ดˆ๋Œ€ ์ดˆ๋Œ€ ์ฝ”๋“œ ์ƒ์„ฑ ๋ฐ ์ดˆ๋Œ€ ์ฝ”๋“œ ๊ธฐ๋ฐ˜ ์ฐธ์—ฌ ์‹ ์ฒญ
๊ฐ€์กฑ ๊ถŒํ•œ ์ฐธ์—ฌ ์‹ ์ฒญ ์Šน์ธยท๊ฑฐ์ ˆ ๋ฐ ๊ฐ€์กฑ ๊ตฌ์„ฑ์› ๊ด€๋ฆฌ

๐Ÿฉบ AI ๊ฑด๊ฐ• ๋ฆฌํฌํŠธ (AI Health Report)

๋ฉ”์ธ ํ™”๋ฉด์—์„œ ๋ฐ˜๋ ค๋™๋ฌผ์„ ์„ ํƒํ•˜๋ฉด ํ•ด๋‹น ๋ฐ˜๋ ค๋™๋ฌผ์˜ ์ตœ์‹  ๊ฑด๊ฐ• ๋ฆฌํฌํŠธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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
Loading

ํ™”๋ฉด ์ฒ˜๋ฆฌ

  • ๋“ฑ๋ก๋œ ์—ฌ๋Ÿฌ ๋ฐ˜๋ ค๋™๋ฌผ ์ค‘ ์กฐํšŒํ•  ๋ฐ˜๋ ค๋™๋ฌผ์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ ํƒ๋œ ๋ฐ˜๋ ค๋™๋ฌผ์˜ ์ตœ์‹  ๊ฑด๊ฐ• ๋ถ„์„ ๋ฆฌํฌํŠธ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • JSON ํ˜•ํƒœ์˜ ๋ฆฌํฌํŠธ ์‘๋‹ต์—์„œ ์š”์•ฝ ๋‚ด์šฉ๊ณผ ๊ถŒ์žฅ ์‚ฌํ•ญ์„ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ์กฐํšŒ ์ค‘์—๋Š” Skeleton UI๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ๋นˆ ์ƒํƒœ ๋ฐ ์žฌ์‹œ๋„ UI๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ ์‹ค์‹œ๊ฐ„ ์œ„์น˜ ๋ฐ ์ง€์˜คํŽœ์Šค (Real-time Location & Geo-fencing)

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
Loading

์šธํƒ€๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ

๊ธฐ๋Šฅ ์„ค๋ช…
์šธํƒ€๋ฆฌ ์ƒ์„ฑ ๋ฐ˜๋ ค๋™๋ฌผ, ์ค‘์‹ฌ ์ขŒํ‘œ, ๋ฐ˜๊ฒฝ, ์šธํƒ€๋ฆฌ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์—ฌ ์•ˆ์ „ ๊ตฌ์—ญ ์ƒ์„ฑ
์šธํƒ€๋ฆฌ ์กฐํšŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฐ˜๋ ค๋™๋ฌผ์˜ ์šธํƒ€๋ฆฌ ๊ฒฝ๊ณ„ ๋ชฉ๋ก ์กฐํšŒ
์šธํƒ€๋ฆฌ ์ˆ˜์ • ์šธํƒ€๋ฆฌ ์ด๋ฆ„, ์ค‘์‹ฌ ์ขŒํ‘œ ๋ฐ ๋ฐ˜๊ฒฝ ์ˆ˜์ •
ํ™œ์„ฑ ์ƒํƒœ ๋ณ€๊ฒฝ ์šธํƒ€๋ฆฌ ๊ฐ์ง€ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™” ๋ฐ ๋น„ํ™œ์„ฑํ™”
์‹ค์‹œ๊ฐ„ ์œ„์น˜ ๋ฐ˜๋ ค๋™๋ฌผ๋ณ„ WebSocket Topic์„ ๊ตฌ๋…ํ•˜์—ฌ ํ˜„์žฌ ์œ„์น˜ ํ‘œ์‹œ
์ดํƒˆ ์ƒํƒœ ์„œ๋ฒ„๊ฐ€ ํŒ์ •ํ•œ ์šธํƒ€๋ฆฌ ๋‚ด๋ถ€ยท์™ธ๋ถ€ ์ƒํƒœ๋ฅผ UI์— ํ‘œ์‹œ

๐Ÿ’ฌ ์ปค๋ฎค๋‹ˆํ‹ฐ (Community)

์‚ฌ์šฉ์ž ๊ฐ„ ๋ฐ˜๋ ค๋™๋ฌผ ์ •๋ณด์™€ ๊ฒฝํ—˜์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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[๋ฐ˜์‘ํ•œ ๊ฒŒ์‹œ๊ธ€]
Loading

์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฐ์ดํ„ฐ

๊ตฌ๋ถ„ ์ฒ˜๋ฆฌ ๋ฐฉ์‹
๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ์™€ ํฌ๊ธฐ๋ฅผ ์ „๋‹ฌํ•˜์—ฌ ๋ชฉ๋ก ์กฐํšŒ
๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ ๊ฒŒ์‹œ๊ธ€ ID๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ƒ์„ธ ๋ฐ์ดํ„ฐ ์กฐํšŒ
๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ์ œ๋ชฉ, ๋‚ด์šฉ ๋ฐ ์ด๋ฏธ์ง€ URL์„ ์ „๋‹ฌํ•˜์—ฌ ๋“ฑ๋ก
์ž„์‹œ ์ €์žฅ Session Key๋ฅผ Local Storage์— ์ €์žฅํ•˜์—ฌ ์ž‘์„ฑ ๋‚ด์šฉ ๋ณต๊ตฌ
๋Œ“๊ธ€ ๊ฒŒ์‹œ๊ธ€๋ณ„ ๋Œ“๊ธ€ ๋ชฉ๋ก ์กฐํšŒ ๋ฐ ๋Œ“๊ธ€ ์ž‘์„ฑ
๋ฐ˜์‘ ์ข‹์•„์š”ยท์‹ซ์–ด์š” ์ƒํƒœ ๋ณ€๊ฒฝ ํ›„ ๊ด€๋ จ Query ๊ฐฑ์‹ 
๋‚ด ํ™œ๋™ ์ž‘์„ฑ ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€ ๋ฐ ๋ฐ˜์‘ ๋‚ด์—ญ ์กฐํšŒ

๐Ÿ”„ ๋ฐ์ดํ„ฐ ๋ฐ ์ƒํƒœ ๊ด€๋ฆฌ (Data & State Management)

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 ๊ด€๋ฆฌ

๐Ÿš€ CI ๋ฐ ๋ฐฐํฌ ๊ตฌ์กฐ (CI & Deployment)

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[ํ”„๋ก ํŠธ์—”๋“œ ์„œ๋น„์Šค ๋ฐฐํฌ]
Loading

CI ๊ฒ€์ฆ ๊ณผ์ •

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 ์„œ๋ฒ„ ๊ธฐ๋ณธ ์ฃผ์†Œ

๐Ÿค Conventions

์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๋Š” ์›ํ™œํ•œ ํ˜‘์—…์„ ์œ„ํ•ด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.


๐Ÿ“Š ํ”„๋ก ํŠธ์—”๋“œ ์ฐธ๊ณ ์ž๋ฃŒ ์ถœ์ฒ˜ (Reference)

๐Ÿ‘‰๐Ÿป React ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป TypeScript ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป Vite ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป Tailwind CSS ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป React Router ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป TanStack Query ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป Axios ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป STOMP.js ๊ณต์‹ ๋ฌธ์„œ ๐Ÿ‘‰๐Ÿป Vercel ๊ณต์‹ ๋ฌธ์„œ


๐Ÿ’โ€โ™‚๏ธ ํŒ€์› ์†Œ๊ฐœ (Team Members)

์กฐ์ˆ˜๋นˆ ํ”„๋กœํ•„
์กฐ์ˆ˜๋นˆ

About

๐Ÿพ DoDo ํ”„๋ก ํŠธ์—”๋“œ ๋ ˆํฌ ๐Ÿพ

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages