Skip to content

kusitms-bugi/FE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

362 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

GBGR (๊ฑฐ๋ถ€๊ธฐ๋ฆฐ)

์‹ค์‹œ๊ฐ„ ์›น์บ  ์ž์„ธ ์ธ์‹์„ ํ†ตํ•ด ๊ฑฐ๋ถ๋ชฉ๊ณผ ๊ฐ™์€ ์ž˜๋ชป๋œ ์ž์„ธ๋ฅผ ๊ต์ •ํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ํ†ต๊ณ„ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜๋Š” ๋ฐ์Šคํฌํƒ‘ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜

๊ฑฐ๋ถ€๊ธฐ๋ฆฐ ์•„์ด์ฝ˜


๐Ÿ”— ๋ฐ๋ชจ & ์ž๋ฃŒ


โœจ ํ•ต์‹ฌ ์š”์•ฝ (TL;DR)

  • ๋ฌธ์ œ ์ธ์‹: ์žฅ์‹œ๊ฐ„ ์ปดํ“จํ„ฐ ์‚ฌ์šฉ์œผ๋กœ ์ธํ•ด ๋ฌด์˜์‹์ ์œผ๋กœ ์ž์„ธ๊ฐ€ ํํŠธ๋Ÿฌ์ ธ ๊ฑฐ๋ถ๋ชฉ, ์–ด๊นจ ๋น„๋Œ€์นญ ๋“ฑ์˜ ๋ฌธ์ œ๋ฅผ ๊ฒช๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.
  • ํ•ต์‹ฌ ํ•ด๊ฒฐ ์ „๋žต:
    • ์›น์บ ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ์ž์„ธ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ถ„์„ํ•˜๊ณ  ์‹œ๊ฐ์ ์œผ๋กœ ํ”ผ๋“œ๋ฐฑํ•ฉ๋‹ˆ๋‹ค.
    • ์ž˜๋ชป๋œ ์ž์„ธ๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ์•Œ๋ฆผ์„ ๋ณด๋‚ด ์ฆ‰๊ฐ์ ์ธ ๊ต์ •์„ ์œ ๋„ํ•ฉ๋‹ˆ๋‹ค.
    • ์„ธ์…˜๋ณ„ ์ž์„ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ํ†ต๊ณ„ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์žฅ๊ธฐ์ ์ธ ์Šต๊ด€ ๊ฐœ์„ ์„ ๋•์Šต๋‹ˆ๋‹ค.
  • ํ”„๋ก ํŠธ์—”๋“œ ๊ธฐ์ˆ  ํฌ์ธํŠธ:
    • @mediapipe/tasks-vision์„ ํ™œ์šฉํ•˜์—ฌ ์›น์บ  ์˜์ƒ์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์‹ ์ฒด ํ‚คํฌ์ธํŠธ๋ฅผ ์ถ”์ถœํ•˜๊ณ  ์ž์„ธ๋ฅผ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค.
    • Zustand๋ฅผ ์‚ฌ์šฉํ•ด ์„ธ์…˜, ์•Œ๋ฆผ, ์นด๋ฉ”๋ผ ๋“ฑ ๋ณต์žกํ•œ ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • Recharts๋ฅผ ์ด์šฉํ•ด ์‚ฌ์šฉ์ž์˜ ์ž์„ธ ์ ์ˆ˜, ํŒจํ„ด ๋“ฑ ํ†ต๊ณ„ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•˜์—ฌ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • Electron์˜ IPC ํ†ต์‹ ์„ ํ™œ์šฉํ•˜์—ฌ ๋ฉ”์ธ ์œˆ๋„์šฐ์™€ ์œ„์ ฏ ๊ฐ„์˜ ์ƒํƒœ๋ฅผ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿงฉ ์ฃผ์š” ๊ธฐ๋Šฅ

  1. ์‹ค์‹œ๊ฐ„ ์ž์„ธ ๋ถ„์„ ๋ฐ ์œ„์ ฏ

    • ์„ค๋ช…: ์›น์บ ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ์ž์„ธ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ถ„์„ํ•˜๊ณ , MediaPipe๋ฅผ ํ™œ์šฉํ•ด ์‹ ์ฒด ํ‚คํฌ์ธํŠธ๋ฅผ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์ธ ํ™”๋ฉด๊ณผ ๋ฐ์Šคํฌํƒ‘ ์œ„์ ฏ์„ ํ†ตํ•ด ํ˜„์žฌ ์ž์„ธ ์ƒํƒœ(๊ฑฐ๋ถ๋ชฉ/๊ธฐ๋ฆฐ)๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ™•์ธํ•˜๊ณ  ์„ธ์…˜์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์ ฏ์€ ํ•ญ์ƒ ์œ„์— ํ‘œ์‹œ๋˜๋ฉฐ ํฌ๊ธฐ ์กฐ์ ˆ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ์ˆ  ํฌ์ธํŠธ: react-webcam, @mediapipe/tasks-vision, Electron BrowserWindow, PostureClassifier
    • ์ฃผ์š” ํŠน์ง•:
      • PI(Posture Index) ๊ณ„์‚ฐ์„ ํ†ตํ•œ ์ •๋Ÿ‰์  ์ž์„ธ ํ‰๊ฐ€
      • EMA(Exponential Moving Average) ์Šค๋ฌด๋”ฉ์œผ๋กœ ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ
      • ScoreProcessor๋ฅผ ํ†ตํ•œ ๋‹ค๋‹จ๊ณ„ ์Šค๋ฌด๋”ฉ (Moving Average โ†’ EMA(30) โ†’ EMA(70))
      • ํžˆ์Šคํ…Œ๋ฆฌ์‹œ์Šค ๋กœ์ง์œผ๋กœ ์ฑ„ํ„ฐ๋ง ๋ฐฉ์ง€ (enter_bad: 1.2, exit_bad: 0.8)
      • ์ •๋ฉด์„ฑ ๊ฒ€์‚ฌ(roll, centerRatio)๋กœ ์ธก์ • ์‹ ๋ขฐ๋„ ๋ณด์žฅ
      • ์œ„์ ฏ ๋…๋ฆฝ ๋™์ž‘: ๋ฉ”์ธ ์ฐฝ์ด ์—†์–ด๋„ ์œ„์ ฏ๋งŒ์œผ๋กœ ์ž์„ธ ํŒ์ • ๊ฐ€๋Šฅ
      • ์Šค๋งˆํŠธ ๋™๊ธฐํ™”: ๋ฉ”์ธ ์ฐฝ์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์œผ๋ฉด ์œ„์ ฏ์€ ํŒ์ •์„ ํ•˜์ง€ ์•Š๊ณ  ๋™๊ธฐํ™”๋งŒ ์ˆ˜ํ–‰
  2. ์บ˜๋ฆฌ๋ธŒ๋ ˆ์ด์…˜ ์‹œ์Šคํ…œ

    • ์„ค๋ช…: ์‚ฌ์šฉ์ž ๊ฐœ์ธ์˜ ์ •์ƒ ์ž์„ธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์„ค์ •ํ•˜๋Š” ์บ˜๋ฆฌ๋ธŒ๋ ˆ์ด์…˜ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ธก์ • ์ค‘ ๋ฐ๊ธฐ, ์ž์„ธ ์•ˆ์ •์„ฑ ๋“ฑ์„ ๊ฒ€์‚ฌํ•˜์—ฌ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ์ค€๊ฐ’์„ ํ™•๋ณดํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ์ˆ  ํฌ์ธํŠธ: trimmedStats (์ƒํ•˜ 5% ์ ˆ์‚ฌ ํ‰๊ท  ๋ฐ ํ‘œ์ค€ํŽธ์ฐจ), errorChecks (๋ฐ๊ธฐ/์•ˆ์ •์„ฑ ๊ฒ€์ฆ)
  3. ํ†ต๊ณ„ ๋Œ€์‹œ๋ณด๋“œ

    • ์„ค๋ช…: ์ผ๋ณ„, ์ฃผ๋ณ„ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž์„ธ ์ ์ˆ˜ ๋ณ€ํ™”, ์ฃผ์š” ์ž์„ธ ํŒจํ„ด, ์ถœ์„๋ฅ , ํ‰๊ท  ์ž์„ธ ์ ์ˆ˜, ๋ ˆ๋ฒจ ์ง„ํ–‰๋„ ๋“ฑ์„ ์‹œ๊ฐ์ ์œผ๋กœ ๋ถ„์„ํ•ฉ๋‹ˆ๋‹ค. Recharts๋ฅผ ํ™œ์šฉํ•œ ๋‹ค์–‘ํ•œ ์ฐจํŠธ๋กœ ์‚ฌ์šฉ์ž์˜ ์žฅ๊ธฐ์ ์ธ ์ž์„ธ ๊ฐœ์„  ์ถ”์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ธฐ์ˆ  ํฌ์ธํŠธ: TanStack Query (์„œ๋ฒ„ ๋ฐ์ดํ„ฐ ์บ์‹ฑ ๋ฐ ๋™๊ธฐํ™”), Recharts (์ฐจํŠธ ์‹œ๊ฐํ™”)
    • ์ฃผ์š” ํŒจ๋„:
      • ํ‰๊ท  ์ž์„ธ ์ ์ˆ˜ ๊ทธ๋ž˜ํ”„ (์‹œ๊ฐ„๋Œ€๋ณ„ ์ถ”์ด)
      • ์ž์„ธ ํŒจํ„ด ๋ถ„์„ (๊ฑฐ๋ถ๋ชฉ/๊ธฐ๋ฆฐ ๋น„์œจ)
      • ์ถœ์„๋ฅ  ๋ฐ ์—ฐ์† ์ถœ์„ ์ผ์ˆ˜
      • ๋ ˆ๋ฒจ ์ง„ํ–‰๋„ ๋ฐ ๋‹ฌ์„ฑ๋ฅ 
  4. ์ž์„ธ ๊ต์ • ์•Œ๋ฆผ

    • ์„ค๋ช…: ๊ฑฐ๋ถ๋ชฉ์ด๋‚˜ ๋น„๋Œ€์นญ ์ž์„ธ๊ฐ€ ์ผ์ • ์‹œ๊ฐ„ ์ด์ƒ ์ง€์†๋˜๋ฉด ๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ์„ ๋ณด๋‚ด ์‚ฌ์šฉ์ž๊ฐ€ ์ธ์ง€ํ•˜๊ณ  ๋ฐ”๋กœ์žก์„ ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค. ์•Œ๋ฆผ ๊ฐ•๋„์™€ ์ฃผ๊ธฐ๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ๊ธฐ์ˆ  ํฌ์ธํŠธ: Electron Notification API, useNotificationScheduler ํ›…, Zustand (์•Œ๋ฆผ ์ƒํƒœ ๊ด€๋ฆฌ)
  5. ์„ธ์…˜ ๊ด€๋ฆฌ

    • ์„ค๋ช…: ์ž์„ธ ์ธก์ • ์„ธ์…˜์„ ์‹œ์ž‘, ์ผ์‹œ์ •์ง€, ์žฌ๊ฐœ, ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ธ์…˜ ์ค‘ ์ˆ˜์ง‘๋œ ๋ฉ”ํŠธ๋ฆญ ๋ฐ์ดํ„ฐ๋Š” ์ฃผ๊ธฐ์ ์œผ๋กœ ์„œ๋ฒ„์— ์ €์žฅ๋˜๋ฉฐ, ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ ๋ฆฌํฌํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ์ˆ  ํฌ์ธํŠธ: useAutoMetricsSender (์ž๋™ ๋ฉ”ํŠธ๋ฆญ ์ „์†ก), useSessionCleanup (์„ธ์…˜ ์ •๋ฆฌ)

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ

Frontend

  • Framework: Electron, React
  • Language: TypeScript
  • State Management: Zustand, TanStack Query
  • Styling: Tailwind CSS
  • Build/Bundle: Vite
  • Pose Detection: @mediapipe/tasks-vision

ํ˜‘์—… & ๊ธฐํƒ€

  • Version Control: Git, GitHub
  • CI: GitHub Actions
  • Package Manager: pnpm
  • Linting & Formatting: Biome
  • Form Validation: react-hook-form, zod
  • Animation: framer-motion
  • Routing: react-router-dom

๐Ÿ“ ๊ฐœ๋ฐœ ๊ทœ์•ฝ

  • ํ”„๋กœ์ ํŠธ ํ—Œ๋ฒ•: .specify/memory/constitution.md
  • Renderer๋Š” Node/Electron API์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ , preload contextBridge ๊ณ„์•ฝ์„ ํ†ตํ•ด์„œ๋งŒ ์‹œ์Šคํ…œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Renderer ๊ตฌ์กฐ๋Š” FSD ๋ ˆ์ด์–ด ๊ทœ์น™์„ ๋”ฐ๋ฅด๋ฉฐ, ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๋Š” Zustand, ์„œ๋ฒ„ ์ƒํƒœ๋Š” TanStack Query๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋จธ์ง€ ๊ธฐ์ค€์€ Biome check, TypeScript typecheck, build ๊ฒ€์ฆ ํ†ต๊ณผ์ž…๋‹ˆ๋‹ค.
  • ํƒœ๊ทธ ๋ฆด๋ฆฌ์ฆˆ๋Š” vX.Y.Z ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋ฉฐ macOS/Windows ๋นŒ๋“œ์™€ ์—…๋ฐ์ดํŠธ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์—…๋กœ๋“œ๊ฐ€ ๋ชจ๋‘ ์™„๋ฃŒ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“ˆ Google Analytics (GA4)

ํ˜„์žฌ ์•ฑ์˜ ๋ถ„์„ ์ด๋ฒคํŠธ๋Š” Renderer์—์„œ GA SDK๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ , ์•„๋ž˜ ๊ฒฝ๋กœ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

renderer logEvent -> preload contextBridge -> ipc -> main -> GA4 Measurement Protocol

ํ•„์ˆ˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜ (๋ฃจํŠธ .env)

GA4_MEASUREMENT_ID=G-XXXXXXXXXX
GA4_API_SECRET=YOUR_API_SECRET
GA4_DEBUG_MP=true
  • GA4_API_SECRET์€ Main ํ”„๋กœ์„ธ์Šค์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ Renderer ๋ฒˆ๋“ค์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ž๋™ page_view/URL ๊ธฐ๋ฐ˜ ์ถ”์ ์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ํผ๋„/ํ•ต์‹ฌ ํ–‰๋™ ์ด๋ฒคํŠธ๋งŒ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

DebugView ํ™•์ธ

  • GA4_DEBUG_MP=true์ผ ๋•Œ:
    • mp/collect ์ „์†ก ์‹œ debug_mode๊ฐ€ ํฌํ•จ๋˜์–ด DebugView ํ™•์ธ ๊ฐ€๋Šฅ
    • debug/mp/collect ๊ฒ€์ฆ ์‘๋‹ต์ด ๋ฉ”์ธ ํ„ฐ๋ฏธ๋„์— ์ถœ๋ ฅ๋จ

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

Electron ํ”„๋กœ์ ํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ Main Process, Preload Scripts, Renderer Process ์„ธ ๊ฐ€์ง€ ํ”„๋กœ์„ธ์Šค๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” Vite๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๋นŒ๋“œํ•˜๊ณ , TypeScript์™€ React๋ฅผ ํ™œ์šฉํ•œ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ  ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ:

  • electron-vite-react - Electron Vite React ํ…œํ”Œ๋ฆฟ
  • electron-vite - Vite ๊ธฐ๋ฐ˜ Electron ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ
  • electron-react-boilerplate - Webpack ๊ธฐ๋ฐ˜ Electron + React ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ
  • vite-electron-builder - Vite + Electron Builder ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ
src/
โ”œโ”€โ”€ main/           # Electron ๋ฉ”์ธ ํ”„๋กœ์„ธ์Šค
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ”œโ”€โ”€ index.ts              # IPC ํ•ธ๋“ค๋Ÿฌ ๋ฐ ์•ฑ ์ดˆ๊ธฐํ™”
โ”‚       โ”œโ”€โ”€ mainWindow.ts        # ๋ฉ”์ธ ์œˆ๋„์šฐ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ
โ”‚       โ”œโ”€โ”€ widgetWindow.ts      # ์œ„์ ฏ ์œˆ๋„์šฐ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ
โ”‚       โ””โ”€โ”€ notificationHandlers.ts  # ์•Œ๋ฆผ ๊ด€๋ จ ํ•ธ๋“ค๋Ÿฌ
โ”œโ”€โ”€ preload/        # Electron ํ”„๋ฆฌ๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ
โ”‚   โ””โ”€โ”€ src/
โ”‚       โ””โ”€โ”€ index.ts             # Context Bridge API ๋…ธ์ถœ
โ””โ”€โ”€ renderer/       # React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ (UI)
    โ””โ”€โ”€ src/
        โ”œโ”€โ”€ api/                  # API ์š”์ฒญ ๊ด€๋ จ ํ›… (TanStack Query)
        โ”‚   โ”œโ”€โ”€ dashboard/        # ๋Œ€์‹œ๋ณด๋“œ ๋ฐ์ดํ„ฐ ์ฟผ๋ฆฌ
        โ”‚   โ”œโ”€โ”€ session/          # ์„ธ์…˜ ๊ด€๋ฆฌ ๋ฎคํ…Œ์ด์…˜
        โ”‚   โ””โ”€โ”€ login/            # ์ธ์ฆ ๊ด€๋ จ
        โ”œโ”€โ”€ assets/               # ์ด๋ฏธ์ง€, ํฐํŠธ ๋“ฑ ์ •์  ์—์…‹
        โ”œโ”€โ”€ entities/             # ๋น„์ฆˆ๋‹ˆ์Šค ์—”ํ‹ฐํ‹ฐ (FSD ์•„ํ‚คํ…์ฒ˜)
        โ”‚   โ””โ”€โ”€ posture/          # ์ž์„ธ ๋ถ„์„ ์—”ํ‹ฐํ‹ฐ
        โ”‚       โ””โ”€โ”€ lib/
        โ”‚           โ”œโ”€โ”€ PostureClassifier.ts    # ์ž์„ธ ๋ถ„๋ฅ˜ ์—”์ง„
        โ”‚           โ”œโ”€โ”€ ScoreProcessor.ts       # ์ ์ˆ˜ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ
        โ”‚           โ”œโ”€โ”€ calculations.ts         # PI ๊ณ„์‚ฐ, EMA ์Šค๋ฌด๋”ฉ
        โ”‚           โ””โ”€โ”€ errorChecks.ts          # ์บ˜๋ฆฌ๋ธŒ๋ ˆ์ด์…˜ ๊ฒ€์ฆ
        โ”‚   โ”œโ”€โ”€ Button/           # ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ
        โ”‚   โ”œโ”€โ”€ Modal/            # ๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ
        โ”‚   โ””โ”€โ”€ ...
        โ”œโ”€โ”€ hooks/                # ์ปค์Šคํ…€ ํ›…
        โ”‚   โ”œโ”€โ”€ useNotificationScheduler.ts  # ์•Œ๋ฆผ ์Šค์ผ€์ค„๋ง
        โ”‚   โ”œโ”€โ”€ useAutoMetricsSender.ts      # ์ž๋™ ๋ฉ”ํŠธ๋ฆญ ์ „์†ก
        โ”‚   โ””โ”€โ”€ useWidget.ts                 # ์œ„์ ฏ ์ƒํƒœ ๊ด€๋ฆฌ
        โ”œโ”€โ”€ layout/               # ํŽ˜์ด์ง€ ๋ ˆ์ด์•„์›ƒ ์ปดํฌ๋„ŒํŠธ
        โ”œโ”€โ”€ pages/                # ๋ผ์šฐํŒ… ๋‹จ์œ„ ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ
        โ”‚   โ”œโ”€โ”€ Main/             # ๋ฉ”์ธ ๋Œ€์‹œ๋ณด๋“œ ํŽ˜์ด์ง€
        โ”‚   โ”œโ”€โ”€ Widget/          # ์œ„์ ฏ ํŽ˜์ด์ง€
        โ”‚   โ”œโ”€โ”€ Calibration/     # ์บ˜๋ฆฌ๋ธŒ๋ ˆ์ด์…˜ ํŽ˜์ด์ง€
        โ”‚   โ””โ”€โ”€ ...
        โ”œโ”€โ”€ store/                # Zustand ์ „์—ญ ์Šคํ† ์–ด
        โ”‚   โ”œโ”€โ”€ usePostureStore.ts    # ์ž์„ธ ์ƒํƒœ ๊ด€๋ฆฌ
        โ”‚   โ”œโ”€โ”€ useCameraStore.ts     # ์นด๋ฉ”๋ผ ์ƒํƒœ ๊ด€๋ฆฌ
        โ”‚   โ””โ”€โ”€ useNotificationStore.ts  # ์•Œ๋ฆผ ์„ค์ • ๊ด€๋ฆฌ
        โ”œโ”€โ”€ styles/               # ์ „์—ญ ์Šคํƒ€์ผ ๋ฐ Tailwind ์„ค์ •
        โ”œโ”€โ”€ types/                # ๊ณต์šฉ ํƒ€์ž… ์ •์˜
        โ””โ”€โ”€ utils/                # ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜
  • ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„: ํŽ˜์ด์ง€(Pages)๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ฐ์ดํ„ฐ ํŽ˜์นญ์„ ๋‹ด๋‹นํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ(Components)๋Š” UI ํ‘œํ˜„์— ์ง‘์ค‘ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์ง€ํ–ฅํ•ฉ๋‹ˆ๋‹ค. pose-detection ํด๋”์—๋Š” ์ž์„ธ ์ธ์‹ ๊ด€๋ จ ํ•ต์‹ฌ ๋กœ์ง์ด ํด๋ž˜์Šค ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋””์ž์ธ ์‹œ์Šคํ…œ: Button, Modal, TextField, ToggleSwitch ๋“ฑ ํ•ต์‹ฌ UI๋ฅผ ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค์–ด ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์˜€์Šต๋‹ˆ๋‹ค. clsx์™€ tailwind-merge๋ฅผ ํ™œ์šฉํ•ด ์กฐ๊ฑด๋ถ€ ์Šคํƒ€์ผ๋ง์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ƒํƒœ ๊ด€๋ฆฌ ์ „๋žต:
    • Zustand๋กœ ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ(์ž์„ธ, ์นด๋ฉ”๋ผ, ์•Œ๋ฆผ ์„ค์ •) ๊ด€๋ฆฌ
    • TanStack Query๋กœ ์„œ๋ฒ„ ์ƒํƒœ ์บ์‹ฑ ๋ฐ ๋™๊ธฐํ™”
    • ์œ„์ ฏ๊ณผ ๋ฉ”์ธ ์œˆ๋„์šฐ ๊ฐ„ ๋™๊ธฐํ™”๋Š” localStorage์˜ storage ์ด๋ฒคํŠธ ํ™œ์šฉ

๐Ÿš€ ์‹คํ–‰ ๋ฐฉ๋ฒ•

# 1. ์˜์กด์„ฑ ์„ค์น˜
pnpm install

# 2. ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰ (๋ฉ”์ธ + ๋ Œ๋”๋Ÿฌ ๋™์‹œ ์‹คํ–‰)
pnpm dev

# 3. ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ
pnpm build

# 4. ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ๋กœ ์‹คํ–‰
pnpm start:prod

# 5. ํ”Œ๋žซํผ๋ณ„ ๋นŒ๋“œ
pnpm build:mac    # macOS ๋นŒ๋“œ
pnpm build:win    # Windows ๋นŒ๋“œ
pnpm build:all    # ๋ชจ๋“  ํ”Œ๋žซํผ ๋นŒ๋“œ

๐Ÿšข Release Flow

  • ๊ธฐ๋ณธ ๋ฐฐํฌ ๊ฒฝ๋กœ๋Š” main PR merge -> .github/workflows/auto-release.yml -> vX.Y.Z tag push -> Electron Release / Release Notes ์ˆœ์„œ์ž…๋‹ˆ๋‹ค.
  • ๋ฒ„์ „ ์ฆ๊ฐ€๋Š” PR label release:major, release:minor, release:patch ์ค‘ ์ •ํ™•ํžˆ ํ•˜๋‚˜๋กœ๋งŒ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.
  • ์ž๋™ ๋ฆด๋ฆฌ์ฆˆ ์‹œ์ž‘ ์ „ lint, typecheck, build ์ฒดํฌ๊ฐ€ ๋ชจ๋‘ ์„ฑ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • package.json ๋ฒ„์ „๊ณผ Git tag๋Š” ๊ฐ™์€ release prepare ์ปค๋ฐ‹์—์„œ ํ•จ๊ป˜ ๋™๊ธฐํ™”๋ฉ๋‹ˆ๋‹ค.
  • ์ˆ˜๋™ workflow_dispatch ๋ฆด๋ฆฌ์ฆˆ๋Š” auto_release_recovery, approved_hotfix, operator_intervention ์˜ˆ์™ธ ์‚ฌ์œ ๊ฐ€ ์žˆ์„ ๋•Œ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์šด์˜์ž ์ฒดํฌํฌ์ธํŠธ

  • Auto Release summary์—์„œ HEAD SHA, ๊ณ„์‚ฐ๋œ ๋ฒ„์ „, duplicate guard ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • Electron Release summary์—์„œ mac_release, win_release, updater_metadata ๋‹จ๊ณ„๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • partial_platform_release ๋˜๋Š” updater_metadata_incomplete๊ฐ€ ๋‚˜์˜ค๋ฉด ๋งˆ์ง€๋ง‰ ์•ˆ์ • ํƒœ๊ทธ ๊ธฐ์ค€์œผ๋กœ rollback ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฆด๋ฆฌ์ฆˆ ํšŒ๊ท€ ๊ฒ€์ฆ์€ pnpm run release:validate๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ๊ฐœ๋ฐœ ์˜๋„ & ๊ธฐ์ˆ ์  ๋„์ „

  • ๊ธฐ์ˆ ์  ๋„์ „ ๊ณผ์ œ:

    1. ์‹ค์‹œ๊ฐ„ ์˜์ƒ ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ: ์ €์‚ฌ์–‘ ์ปดํ“จํ„ฐ์—์„œ๋„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ์›น์บ  ์˜์ƒ ๋ถ„์„ ๊ณผ์ •์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.
    2. ๋‹ค์ค‘ ์œˆ๋„์šฐ ์ƒํƒœ ๊ด€๋ฆฌ: Electron์˜ ๋ฉ”์ธ ์œˆ๋„์šฐ์™€ ์œ„์ ฏ ์œˆ๋„์šฐ ๊ฐ„์˜ ์ƒํƒœ(์„ธ์…˜, ์‹œ๊ฐ„ ๋“ฑ)๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ๋™๊ธฐํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋ณต์žกํ–ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋ฉ”์ธ ์ฐฝ๊ณผ ์œ„์ ฏ์ด ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ํŒ์ •์„ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ƒํƒœ๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
    3. ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ˜ธํ™˜์„ฑ: macOS์™€ Windows ํ™˜๊ฒฝ ๋ชจ๋‘์—์„œ ์•ˆ์ •์ ์œผ๋กœ ๋นŒ๋“œ๋˜๊ณ  ์‹คํ–‰๋˜๋„๋ก electron-builder ์„ค์ •์„ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ•ด๊ฒฐ ๊ณผ์ •:

    1. ์„ฑ๋Šฅ ์ตœ์ ํ™”:
    • MediaPipe์˜ detectForVideo๋ฅผ ํ”„๋ ˆ์ž„๋ณ„๋กœ ํ˜ธ์ถœํ•˜์—ฌ ์ค‘๋ณต ์ฒ˜๋ฆฌ ๋ฐฉ์ง€
    • ScoreProcessor์˜ ๋‹ค๋‹จ๊ณ„ ์Šค๋ฌด๋”ฉ ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ๋…ธ์ด์ฆˆ ์ œ๊ฑฐ (Moving Average โ†’ EMA(30) โ†’ EMA(70))
    • ํžˆ์Šคํ…Œ๋ฆฌ์‹œ์Šค ๋กœ์ง์œผ๋กœ ์ฑ„ํ„ฐ๋ง ๋ฐฉ์ง€ํ•˜์—ฌ ์•ˆ์ •์ ์ธ ์ƒํƒœ ์ „ํ™˜
    • ์ ์ˆ˜ ํด๋žจํ•‘(-10 ~ 40)์œผ๋กœ ์ด์ƒ์น˜ ์ œ๊ฑฐ
    1. ๋‹ค์ค‘ ์œˆ๋„์šฐ ๋™๊ธฐํ™”:
    • ๋ฉ”์ธ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ค‘์•™ ํ—ˆ๋ธŒ๋กœ ์‚ผ์•„ ipcMain๊ณผ ipcRenderer๋ฅผ ํ†ตํ•ด ์œ„์ ฏ ์ฐฝ ์—ด๊ธฐ/๋‹ซ๊ธฐ ์ œ์–ด
    • ์œ„์ ฏ๊ณผ ๋ฉ”์ธ ์œˆ๋„์šฐ ๊ฐ„ ์ž์„ธ ์ƒํƒœ ๋™๊ธฐํ™”๋Š” localStorage์˜ storage ์ด๋ฒคํŠธ ํ™œ์šฉ (IPC ๋Œ€์‹  ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ณ  ์•ˆ์ •์ ์œผ๋กœ ๊ตฌํ˜„)
    • usePostureSyncWithLocalStorage ํ›…์œผ๋กœ ์œ„์ ฏ์—์„œ ๋ฉ”์ธ ์ฐฝ์˜ ์ƒํƒœ ๋ณ€๊ฒฝ ๊ฐ์ง€
    • ์Šค๋งˆํŠธ ํŒ์ • ์ „๋žต: ๋ฉ”์ธ ์ฐฝ์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์œผ๋ฉด ์œ„์ ฏ์€ ํŒ์ •์„ ํ•˜์ง€ ์•Š๊ณ  ๋ฉ”์ธ ์ฐฝ์˜ ๊ฒฐ๊ณผ๋งŒ ๋™๊ธฐํ™”๋ฐ›์Œ. ๋ฉ”์ธ ์ฐฝ์ด ์—†์œผ๋ฉด ์œ„์ ฏ์ด ๋…๋ฆฝ์ ์œผ๋กœ ํŒ์ • ์ˆ˜ํ–‰
    • ๋ฉ”์ธ ์ฐฝ ํ™œ์„ฑํ™” ์ƒํƒœ๋Š” localStorage์˜ ํƒ€์ž„์Šคํƒฌํ”„๋กœ ์ถ”์  (2์ดˆ ์ด๋‚ด ์—…๋ฐ์ดํŠธ๊ฐ€ ์—†์œผ๋ฉด ๋น„ํ™œ์„ฑํ™”๋กœ ๊ฐ„์ฃผ)
    1. ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ˜ธํ™˜์„ฑ:
    • GitHub Actions๋ฅผ ์ด์šฉํ•ด ๊ฐ๊ธฐ ๋‹ค๋ฅธ OS ํ™˜๊ฒฝ์˜ ๋นŒ๋“œ๋ฅผ ์ž๋™ํ™”
    • entitlements.mac.plist์— ์นด๋ฉ”๋ผ/๋งˆ์ดํฌ ๊ถŒํ•œ ๋ช…์‹œ
    • electron-builder ์„ค์ •์œผ๋กœ macOS (Intel/Apple Silicon) ๋ฐ Windows ๋นŒ๋“œ ์ง€์›

๐Ÿ‘ฅ ํŒ€ ๊ตฌ์„ฑ & ์—ญํ• 

ํ”„๋กœํ•„ ์—ญํ•  ์ด๋ฆ„ GitHub
์ตœํ˜ธ ํ”„๋กœํ•„ Frontend ์ตœํ˜ธ @choihooo
์ดํ™˜์„ ํ”„๋กœํ•„ Frontend ์ดํ™˜์„ @hwanseok1014
์†๋Œ€ํ˜„ ํ”„๋กœํ•„ Backend ์†๋Œ€ํ˜„ @son-daehyeon

Packages

 
 
 

Contributors