๊ธฐ์ ๋ฉด์ ๋ถํฐ ์ด๋ ฅ์ ๊ธฐ๋ฐ ๊ฐ์ธํ ๋ฉด์ , ํ์ ํ์ต ํ๋ฆ๊น์ง ์ฐ๊ฒฐํ๋ AI ์ธํฐ๋ทฐ ํ๋ซํผ
"์ด ์ง๋ฌธ์ด ์ ๋ง ๋ด ๊ฒฝํ์ ๋ณด๊ณ ๋์จ ๊ฑธ๊น?"
๋ง์ ๋ฉด์ ์ค๋น ์๋น์ค๋ ๋จ์ํ ์ง๋ฌธ ์์ฑ์์ ๋ฉ์ถฅ๋๋ค.
VlaInter๋ ์ค์ ์ค๋น ํ๋ฆ์ด ๋๊ธฐ์ง ์๋๋ก ์ง๋ฌธ ์์ฑ, ๋ต๋ณ ํ๊ฐ, ๋ฌธ์ ๋ถ์, ํ์ต ๋ณต๊ธฐ๊น์ง ํ ํ๋ฆ์ผ๋ก ์ฐ๊ฒฐํฉ๋๋ค.
- ๊ธฐ์ ์คํ ๊ธฐ๋ฐ ์ค์ ๋ฉด์
- ์ด๋ ฅ์/์๊ธฐ์๊ฐ์/ํฌํธํด๋ฆฌ์ค ๊ธฐ๋ฐ ๊ฐ์ธํ ์ง๋ฌธ
- ํ์ ๊ณผ๋ชฉ/์๋ฃ ๊ธฐ๋ฐ ์์ฝ, ์ํ, ์ค๋ต๋ ธํธ
- AI ๋ชจ๋ฒ ๋ต์ ์์ฑ๊ณผ ํผ๋๋ฐฑ
- ์ธ์ ์ ์ฅ ๋ฐ ๋ณต๊ธฐ ๊ธฐ๋ฅ
- ์ง๋ฌด์ ๊ธฐ์ ์คํ ๊ธฐ๋ฐ ์ง๋ฌธ ์์ฑ
- ๋ต๋ณ ์ ์ถ ํ AI ๋ชจ๋ฒ ๋ต์๊ณผ ํผ๋๋ฐฑ ์ ๊ณต
- ์ ์ฅ ์ง๋ฌธ๊ณผ ์ง๋ฌธ ์ธํธ ๊ด๋ฆฌ
- ์ธ์ ๊ฒฐ๊ณผ์ ์ด๋ ฅ ์กฐํ
- ์ด๋ ฅ์, ์๊ธฐ์๊ฐ์, ํฌํธํด๋ฆฌ์ค ์ ๋ก๋
- ๋ฌธ์ ๊ธฐ๋ฐ ์ง๋ฌธ ์์ฑ๊ณผ ๋ฉด์ ์ธ์ ์์
- ๊ฒฝํ ์ค์ฌ ๋ง์ถค ์ง๋ฌธ ์ฐ์ต
- ๋ต๋ณ ํ๊ฐ์ ์ด๋ ฅ ๊ด๋ฆฌ
- ๊ณผ๋ชฉ ์์ฑ๊ณผ ํ์ ์ ๋ณด ๊ธฐ๋ฐ ํ์ต ์ง์
- ๊ฐ์ ์๋ฃ ์ ๋ก๋์ ์ ํ๋ธ ์๋ฃ ์์ฝ
- ์ํ ์ธ์ ์์ฑ๊ณผ ์ ์ถ
- ์ค๋ต๋ ธํธ, ์์ฝ ๋ฌธ์, ๋ณต์ต ํ๋ฆ ์ ๊ณต
- ๊ด๋ฆฌ์ ์ฝ์
- ์ง๋ฌธ/์นดํ ๊ณ ๋ฆฌ/์ฌ์ดํธ ์ค์ ์ด์
- ํฌ์ธํธ ์ถฉ์ ๊ณผ ํจ์น๋ ธํธ ํ์ธ
- ์ฌ์ฉ์ ๋ฌธ์ ๋ฐ ๋ฆฌํฌํธ ์ ์ ํ๋ฆ
VlaInter ํ๋ก ํธ์๋๋ React + Vite ๊ธฐ๋ฐ SPA๋ก, ์ทจ์ ์ค๋น์์ฉ AI ๋ฉด์ ์ฐ์ต ํ๋ฆ๊ณผ ๋ํ์์ฉ ํ์ต ๋ณด์กฐ ํ๋ฆ์ ํ๋์ ์ฑ ์์์ ํจ๊ป ์ ๊ณตํฉ๋๋ค.
์ ์ด๋ฏธ์ง๋ ๋ก์ปฌ Vite ๊ฐ๋ฐ ์๋ฒ ๊ธฐ์ค ๊ณต๊ฐ ํ๋ฉด์ ์บก์ฒํ ์์์ ๋๋ค.
- ์ทจ์ค์ ๋ชจ๋ ๋๋ฉ, ์๋น์ค ์๊ฐ, ํ์๊ฐ์ /๋ก๊ทธ์ธ, ์นด์นด์ค ๋ก๊ทธ์ธ
- ๋ฌธ์ ๊ธฐ๋ฐ ๋ชจ์๋ฉด์ ์์, ๊ธฐ์ ์ง๋ฌธ ์ฐ์ต, ์ธ์ ๊ฒฐ๊ณผ/ํ์คํ ๋ฆฌ ์กฐํ
- ์ ์ฅ ์ง๋ฌธ, ์ง๋ฌธ ์ธํธ, ๋ฌธ์ ์ ๋ก๋, ํฌ์ธํธ ์ถฉ์ UI
- ๋ํ์ ๋ชจ๋ ๋๋ฉ, ๊ณผ๋ชฉ ๊ด๋ฆฌ, ์๋ฃ ์ ๋ก๋, ์ํ ์ธ์ , ์ค๋ต๋ ธํธ
- ๋ง์ดํ์ด์ง์์ ํ๋กํ, ์๋น์ค ๋ชจ๋, ํ์ ์ ๋ณด, Gemini API Key, ํฌ์ธํธ ์ด๋ ฅ ๊ด๋ฆฌ
- ๊ด๋ฆฌ์ ์ฝ์์์ ํ์, ์ง๋ฌธ/์นดํ ๊ณ ๋ฆฌ, ์ด์ ์ค์ , ํจ์น๋ ธํธ, KPI ํ์ธ
| ๊ตฌ๋ถ | ์ฌ์ฉ ๊ธฐ์ |
|---|---|
| Framework | React 19, Vite 7 |
| Routing | React Router DOM 6 |
| UI / Motion | CSS, Tailwind ์ ํธ๋ฆฌํฐ ์คํ์ผ, Framer Motion |
| Utilities | html2canvas, jsPDF, react-icons |
| Auth Integration | Cookie-based session, Kakao OAuth |
| Build / Lint | Vite, ESLint |
| ๊ตฌ์ญ | ์ฃผ์ ๊ฒฝ๋ก | ์ค๋ช |
|---|---|---|
| ๊ณต๊ฐ ํ๋ฉด | /, /campus, /about, /terms, /privacy |
๋๋ฉ๊ณผ ์๊ฐ, ์ฝ๊ด/์ ์ฑ |
| ์ธ์ฆ ํ๋ฉด | /login, /join, /password/forgot, /auth/kakao/callback |
๋ก๊ทธ์ธ, ํ์๊ฐ์ , ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ |
| ๊ณตํต ์ง์ ์ | /content, /content/service-mode, /content/mypage |
๋ก๊ทธ์ธ ํ ์๋น์ค ๋ชจ๋ ๋ถ๊ธฐ์ ๊ณตํต ์ค์ |
| ์ทจ์ค์ ๋ชจ๋ | /content/interview, /content/tech-practice, /content/files, /content/question-sets ๋ฑ |
๋ฉด์ /์ง๋ฌธ/๋ฌธ์/๊ฒฐ์ ํ๋ฆ |
| ๋ํ์ ๋ชจ๋ | /content/student, /content/student/courses/:courseId, /content/student/sessions/:sessionId |
๊ณผ๋ชฉ/์๋ฃ/์ํ/์ค๋ต๋ ธํธ |
| ๊ด๋ฆฌ์ | /content/admin |
์ด์์ ์ ์ฉ ์ฝ์ |
- ๊ณต๊ฐ ๋๋ฉ ๋๋ ๋ก๊ทธ์ธ ํ๋ฉด์์ ์ธ์ฆ
/content์ง์ ์ ํ๋กํ์serviceMode๋ฅผ ํ์ธ- ์ทจ์ค์์ด๋ฉด
/content/interview, ๋ํ์์ด๋ฉด/content/student, ๋ฏธ์ ํ์ด๋ฉด/content/service-mode๋ก ์ด๋ - ์ทจ์ค์ ์ฃผ์ ํ๋ฉด์ ์ผ๋ถ ๊ธฐ๋ฅ์์ Gemini API Key ๋ฑ๋ก์ด ํ์
git pull ๋๋ ํด๋ก ์งํ ์๋ ์์๋๋ก ์งํํ๋ฉด ๋ฉ๋๋ค.
๋ชจ๋
ธ๋ ํฌ ๋ฃจํธ์์ ์์ํ๋ค๋ฉด ๋จผ์ cd vlainter_FE/vlainter๋ก ์ด๋ํ ๋ค ์๋ ๋ช
๋ น์ ์คํํ์ธ์.
cp .env.example .envํ์ ํญ๋ชฉ:
VITE_API_BASE_URLVITE_KAKAO_CLIENT_IDVITE_KAKAO_AUTH_URIVITE_KAKAO_REDIRECT_URI
์ ํ ํญ๋ชฉ:
VITE_PORTONE_PG
npm installnpm run dev๊ธฐ๋ณธ ๊ฐ๋ฐ ์ฃผ์๋ http://localhost:5173์
๋๋ค.
npm run build
npm run preview| ๋ณ์ | ์ค๋ช |
|---|---|
VITE_API_BASE_URL |
๋ฐฑ์๋ API ๊ธฐ๋ณธ ์ฃผ์. ๊ธฐ๋ณธ๊ฐ์ http://localhost:8080 |
VITE_KAKAO_CLIENT_ID |
์นด์นด์ค OAuth ํด๋ผ์ด์ธํธ ID |
VITE_KAKAO_AUTH_URI |
์นด์นด์ค ์ธ์ฆ ํ์ด์ง ์ฃผ์ |
VITE_KAKAO_REDIRECT_URI |
์นด์นด์ค ๋ก๊ทธ์ธ ์๋ฃ ํ ๋ณต๊ทํ ํ๋ก ํธ ์ฃผ์ |
VITE_PORTONE_PG |
ํฌ์ธํธ ๊ฒฐ์ ์ ์ฌ์ฉํ PG ์ฝ๋. ๋ฏธ์ค์ ์ html5_inicis |
- ๋ชจ๋ API ์์ฒญ์ ๊ธฐ๋ณธ์ ์ผ๋ก
VITE_API_BASE_URL์ ๊ธฐ์ค์ผ๋ก ํธ์ถํฉ๋๋ค. - ์ธ์ฆ ๋ฐฉ์์ Bearer token ํค๋๊ฐ ์๋๋ผ
credentials: include๊ธฐ๋ฐ ์ฟ ํค ์ธ์ ์ ๋๋ค. 401์ด ๋ฐ์ํ๋ฉด/api/auth/refresh๋ฅผ ํตํด ์ธ์ ๊ฐฑ์ ์ ํ ๋ฒ ๋ ์๋ํฉ๋๋ค.- ๋ณดํธ ํ๋ฉด ์ง์
์
BrowserSessionGuard๊ฐ ํ๋กํ ์กฐํ๋ก ๋ธ๋ผ์ฐ์ ์ธ์ ์ ํจ์ฑ์ ํ์ธํฉ๋๋ค. - ์ทจ์ค์ ์ฃผ์ ํ๋ฉด์
GeminiApiKeyGuard๊ฐ ํ ๋ฒ ๋ ํ์ธํ๋ฏ๋ก, ๋ก๊ทธ์ธ ํ์๋ Gemini API Key ๋ฏธ๋ฑ๋ก ์ํ๋ฉด ์ ํ๋ ์ ์์ต๋๋ค.
src
โโโ assets # ๋ก๊ณ , ์์ด์ฝ, ์ด๋ฏธ์ง
โโโ components # ๊ณตํต UI, Guard, Sidebar, Modal
โโโ hooks # ์ฌ์ฌ์ฉ ํ
โโโ lib # API ํด๋ผ์ด์ธํธ, ์ธ์
/๋๋ฉ์ธ ์ ํธ
โโโ pages
โ โโโ auth # ๋ก๊ทธ์ธ, ํ์๊ฐ์
, ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ
โ โโโ content # ์ทจ์ค์/ํ์/๊ด๋ฆฌ์ ๋ณดํธ ํ๋ฉด
โ โโโ *.jsx # ๊ณต๊ฐ ํ์ด์ง, ์ ์ฑ
ํ์ด์ง
โโโ App.jsx # ์ ์ฒด ๋ผ์ฐํ
์ ์
โโโ main.jsx # ์ฑ ์ํธ๋ฆฌํฌ์ธํธ
npm run lint
npm run build์ถ๊ฐ ์๋ ๊ฒ์ฆ ๊ถ์ฅ ํญ๋ชฉ:
/๋๋ฉ ๋ก๋/loginํผ ๋ ๋๋ง/campus๋๋ฉ ๋ก๋- ๋ก๊ทธ์ธ ํ
/content์๋น์ค ๋ชจ๋ ๋ถ๊ธฐ ํ์ธ - Gemini API Key ๋ฏธ๋ฑ๋ก ์ํ์์ ์ทจ์ค์ ๋ณดํธ ํ๋ฉด ์ง์ ์ ์ฝ ํ์ธ
- ํ๋ก ํธ ์ ์ฉ ํ ์คํธ ๋ฌ๋๋ ์์ง ๊ตฌ์ฑ๋์ด ์์ง ์์ต๋๋ค.
- ๋ฐ๋ผ์ ์๋ ๊ฒ์ฆ ๊ธฐ์ค์ ํ์ฌ
lint + build์ค์ฌ์ ๋๋ค. - ๋ณดํธ ํ๋ฉด์ ๊น๊ฒ ๊ฒ์ฆํ๋ ค๋ฉด ๋ฐฑ์๋๊ฐ ํจ๊ป ์คํ ์ค์ด์ด์ผ ํฉ๋๋ค.
- ๊ด๋ฆฌ์ ํ๋ฉด ์บก์ฒ๋ ๊ณต์ ์ ํ์ ์ ๋ณด, ์ ์ ์ด๋ ฅ, ๊ฒฐ์ ๋ฐ์ดํฐ๋ ๋ฐ๋์ ๋ง์คํนํด์ผ ํฉ๋๋ค.
- ๋ผ์ฐํ ์ ์ค์ฌ์ src/App.jsx์ ๋๋ค.
/content์ง์ ๋ถ๊ธฐ ๋ก์ง์ src/pages/content/ContentEntryPage.jsx์์ ํ์ธํ ์ ์์ต๋๋ค.- API ํด๋ผ์ด์ธํธ์ refresh ๋ก์ง์ src/lib/apiClient.js์์ ํ์ธํ ์ ์์ต๋๋ค.


