๋งํฌ๋ค์ด ํธ์ง, ์์ฑ ์ ๋ ฅ(STT), OCR, ํ์ผ ์ ๋ก๋, ์์ ๋ก๊ทธ์ธ(๊ตฌ๊ธยท๋ค์ด๋ฒยท์นด์นด์ค)์ ๊ฐ์ถ ๋ ธํธ/์ง์ ๊ด๋ฆฌ์ฉ ํ๋ก ํธ์๋์ ๋๋ค. ๊ฐ๋ฐ ํธ์๋ฅผ ์ํด Vite(์น)์ Electron(๋ฐ์คํฌํฑ ์ ธ)์ ํจ๊ป ์ ๊ณตํฉ๋๋ค.
- ๊ธฐ์ ์คํ
- ํ๋ฉด
- ํต์ฌ ๊ธฐ๋ฅ
- ์ํคํ ์ฒ
- ๋ผ์ฐํ
- ๋ก์ปฌ ์คํ
- ํ๊ฒฝ ๋ณ์
- ํด๋ ๊ตฌ์กฐ
- API ํต์ ๊ท์ฝ
- ์ธ์ฆ/์จ๋ณด๋ฉ: ์์ด๋ยท๋น๋ฒ ๋ก๊ทธ์ธ, ์์ ๋ก๊ทธ์ธ(๊ตฌ๊ธ/๋ค์ด๋ฒ/์นด์นด์ค), ํ์๊ฐ์ ๋ผ์ฐํธ ์ ๊ณต.
- ๋ ธํธ ๋ฆฌ์คํธ: ํด๋๋ณ/์ ์ฒด ๋ณด๊ธฐ, ๊ฒ์ยทํํฐ, ์ฆ๊ฒจ์ฐพ๊ธฐ ํ ๊ธ, ์ต๊ทผ/์ฆ๊ฒจ์ฐพ๊ธฐ ํญ.
- ์๋ํฐ: Toast UI/Milkdown/Tiptap ์กฐํฉ์ผ๋ก ๋งํฌ๋ค์ด ํธ์งยท๋ฏธ๋ฆฌ๋ณด๊ธฐยทํ์ด๋ผ์ดํธ ์ง์.
- ํ์ผ ์ ๋ก๋: ์ด๋ฏธ์ง/ํ์ผ ๋๋๊ทธยท์ ํ ์ ๋ก๋ โ ์๋ ๋ ธํธ ์์ฑ ๋ฐ ๋ฏธ๋์ด ์๋ฒ ๋.
- ์์ฑ ์ ๋ ฅ(STT): Web Speech API ๊ธฐ๋ฐ ํ๊ตญ์ด ์ฐ์ ์ ๋ ฅ โ ํธ์ง๊ธฐ์ ์ค์๊ฐ ๋ฐ์.
- OCR: ์ด๋ฏธ์ง โ ํ ์คํธ ๋ณํ(API ์ฐ๋) ํ ์ ๋ ธํธ ์์ฑ ๋ฐ ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ.
- ์์ฝ/๋ฌธ์ ์์ฑ: ๋ฐฑ์๋ ์ฐ๋์ผ๋ก ๊ธด ๋ฌธ์ ์์ฝยท์์๋ฌธ์ ์๋ ์์ฑ ํ ๋ ธํธ ์ ์ฅ.
- ๋ ์ด์์: Sidebar/Topbar/Bottombar, ๋จ์ถ ์ก์ (ActionDock), ํ ์คํธ/์ํํ์.
flowchart LR
A[React + Vite]
B[Backend API]
G[Google OAuth]
N[Naver OAuth]
K[Kakao OAuth]
E[Electron Shell]
A --> B
A -. OAuth .-> G
A -. OAuth .-> N
A -. OAuth .-> K
E --> A
- ๊ณต๊ฐ:
/(๋ก๊ทธ์ธ) ยท/signupยท/homeยท/pricingยท/docs - ์์
์ฝ๋ฐฑ:
/naver/callbackยท/kakao/callback - ์ฑ:
/mainยท/main/:folderIdยท/notes/newยท/notes/:idยท/stt - ์ธ์ฆ ๊ฐ๋: ํ ํฐ ๋ฏธ๋ณด์ ์ ๋ณดํธ ๋ผ์ฐํธ ์ ๊ทผ ์
/๋ฆฌ๋ค์ด๋ ํธ
- Node.js 18+
# 1) Electron ์
ธ + ํด ์ค์น (๋ฃจํธ)
cd Frontend
npm i
# 2) React ์ฑ ์ค์น
cd react-app
npm i# Electron ์
ธ๊ณผ Vite dev ์๋ฒ ๋์ ์คํ
cd Frontend
npm run dev
# ๋๋: ์น๋ง ์คํ
cd Frontend/react-app
npm run dev # default: http://localhost:5174Frontend/react-app/.env
VITE_API_BASE_URL=http://localhost:8000
VITE_GOOGLE_CLIENT_ID=YOUR_GOOGLE_OAUTH_CLIENT_ID
VITE_NAVER_CLIENT_ID=YOUR_NAVER_CLIENT_ID
VITE_NAVER_REDIRECT_URI=http://localhost:5174/naver/callback
VITE_KAKAO_CLIENT_ID=YOUR_KAKAO_REST_API_KEYํ์ ํฌ์ธํธ
- JWT ์ ์ฅ:
localStorage.access_token์ ์ ์ฅ/์ฌ์ฉ - ๊ฐ๋ฐ ํฌํธ: Vite
5174ยท Electron์ด ํด๋น ์ฃผ์๋ฅผ ๋ก๋
Frontend/
โโโ main.js # Electron ์ง์
(๊ฐ๋ฐ ์
ธ ยท http://localhost:5174 ๋ก๋)
โโโ package.json # dev ์คํฌ๋ฆฝํธ(concurrently, wait-on, electron)
โโโ preload.js # (์ต์
) ํ๋ฆฌ๋ก๋ ์คํฌ๋ฆฝํธ
โโโ react-app/ # Vite ๊ธฐ๋ฐ React ์ฑ
โ โโโ src/
โ โ โโโ App.tsx # ๋ผ์ฐํ
์ํธ๋ฆฌ
โ โ โโโ main.tsx # ์ฑ ๋ถํธ์คํธ๋ฉ(Google OAuth Provider)
โ โ โโโ components/ # ๋ ์ด์์/ํด๋ฐ/์ฌ์ด๋๋ฐ/ํธ์ง๊ธฐ/๋ทฐ์ด ๋ฑ UI
โ โ โโโ screen/ # Login/Signup/Main/NoteDetail/NewNote/STT/Docs ๋ฑ
โ โ โโโ css/ # ํ๋ฉดยท์ปดํฌ๋ํธ ์คํ์ผ ๋ฐ ํ ํฐ
โ โ โโโ utils/ # fetch ๋ก๊ฑฐ, ์ ํธ
โ โโโ package.json # Vite, React, ์๋ํฐ ๊ด๋ จ ์์กด์ฑ
โโโ utils/
โโโ qg_service.py # (๊ฐ๋ฐ ๋ณด์กฐ) ๋ฌธ์ ์์ฑ API ์์ ์คํฌ๋ฆฝํธ
- ๋ฒ ์ด์ค URL:
VITE_API_BASE_URL - ์ธ์ฆ:
Authorization: Bearer <access_token>ํค๋ ์ฌ์ฉ - ์ฃผ์ ์๋ํฌ์ธํธ(์)
- ์ธ์ฆ:
POST /api/v1/login,POST /api/v1/login/google,POST /api/v1/register - ๋
ธํธ:
GET/POST/PUT/DELETE /api/v1/notes,POST /api/v1/notes/{id}/favorite - ์์ฝ:
POST /api/v1/notes/{id}/summarize_sync?longdoc=true - ํ์ผ:
POST /api/v1/files/upload,POST /api/v1/files/ocr?langs=kor+eng&max_pages=50
- ์ธ์ฆ:
์ฃผ์
- ๋ณธ ํ๋ก ํธ๋ ๋ฐฑ์๋ API์ ์ฐ๋๋์ด ๋์ํฉ๋๋ค.
VITE_API_BASE_URL๋ฐ OAuth ํด๋ผ์ด์ธํธ ์ค์ ์ด ์์ผ๋ฉด ์ผ๋ถ ๊ธฐ๋ฅ์ด ์ ํ๋ฉ๋๋ค. - Electron์ ๊ฐ๋ฐ ์ ธ ์ฉ๋๋ก๋ง ๊ตฌ์ฑ๋์ด ์์ผ๋ฉฐ ํจํค์ง ์ค์ ์ ํฌํจํ์ง ์์ต๋๋ค.







