2024.11.17 ~ 2024.11.27
- Python 3.11.X
- Django 4.2.X
- Vue 3.X
- Web Speech API์ MediaRecorder API๋ฅผ ํ์ฉํ์ฌ ์ฌ์ฉ์์ ์์ฑ์ ๋ น์ํ๊ณ ์ค์๊ฐ์ผ๋ก ํ ์คํธ๋ก ๋ณํํ๋ฉฐ, 5์ด๊ฐ์ ์์ฑ ๋ฐ์ดํฐ๋ฅผ ์์งํฉ๋๋ค. (back/moveis/views.py analyze_sentiment ์ฐธ๊ณ )
- ์์ง๋ ์์ฑ ๋ฐ์ดํฐ๋ ์๋ฒ๋ก ์ ์ก๋์ด ๊ฐ์ ๋ถ์(sentiment analysis)์ ์ํํ๊ณ , ๋ถ์๋ ๊ฐ์ ์ ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ํ๋ฅผ ์ถ์ฒํฉ๋๋ค. (back/moveis/views.py recommend_movies ์ฐธ๊ณ )
- ๋ถ์ ๊ฒฐ๊ณผ๋ ํ๋ก ํธ์๋์์ ์บ๋ฌ์ ํํ๋ก ํ์๋๋ฉฐ, localStorage๋ฅผ ํตํด ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ์ฌ ํ์ด์ง ์๋ก๊ณ ์นจ ์์๋ ์ด์ ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ์ ์งํฉ๋๋ค. (front/src/views/movies/SearchView.vue ์ฐธ๊ณ )
- ๋ก๊ทธ์ธ ์
- ๋ก๊ทธ์ธ ํ
- ์ฌ์, ์ฐํ๊ธฐ ์ํ ๊ด๋ฆฌ
- ๋ฆฌ๋ทฐ ์กฐํ(์ต์ ์/์ข์์์ ์ ๋ ฌ), ์์ฑ, ์ข์์ ๋ฒํผ
- ๋ฆฌ๋ทฐ ์์ , ์ญ์ , ์ข์์ ๊ด๋ฆฌ
- ํ์ ์ ๋ณด ์์ (ํ๋กํ ์ด๋ฏธ์ง, ๋๋ค์, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ)
- ์ ๋ชฉ์ผ๋ก ๊ฒ์
- ์์ฑ ์ธ์์ผ๋ก ๊ฐ์ ๋ถ์ ํ ์ฅ๋ฅด ๊ธฐ๋ฐ์ผ๋ก ์ํ ์ถ์ฒ (ํ๋ฉด ์ฌ์ง์ ์ถํ ์ ๋ก๋ ์์ )
[๋ฏผ์ฃผ]
- ํผ๊ทธ๋ง&์ปดํฌ๋ํธ ๊ตฌ์กฐ ์์ฑ - ๋ก๊ทธ์ธ, ํ์๊ฐ์
[์ฐ์ง]
- ERD ์ค๊ณ
[๋ฏผ์ฃผ]
- DB - ์ด๊ธฐ ์ํ, ์ฅ๋ฅด ๋ฐ์ดํฐ ์์ฑ
- ํผ๊ทธ๋ง&์ปดํฌ๋ํธ ๊ตฌ์กฐ ์์ฑ - ํ
[์ฐ์ง]
- ํ๋ก์ ํธ ์์ฑ
- ๋ก๊ทธ์ธ,ํ์๊ฐ์ ํ๋ก ํธ
[๋ฏผ์ฃผ]
- HomeView - ํ๋ก ํธ, ๋ฐฑ์๋
- ํผ๊ทธ๋ง&์ปดํฌ๋ํธ ๊ตฌ์กฐ๋ ์์ฑ - ์ปค๋ฎค๋ํฐ, ์ํ ์์ธ ์ ๋ณด, ํ๋กํ
[์ฐ์ง]
- ํ์๊ฐ์ ๋ฐฑ์ค๋
- ERD ์์
[๋ฏผ์ฃผ]
- HomeView ๋ง๋ฌด๋ฆฌ
- Navbar - ํ๋ก ํธ, ๋ฐฑ์๋
[์ฐ์ง]
- LoginView - ๋ก๊ทธ์ธ ๊ตฌํ
- Navbar - ๋ฉ์ธํ๋ฉด์ ๋ก๊ทธ์ธ๋๊ฑฐ ๋์ฐ๊ธฐ
[๋ฏผ์ฃผ]
- MovieDetail - ์ํ ์ ๋ณด, ์๊ณ ํธ ํ๋ก ํธ
- MovieDetail - ์ํ ์ ๋ณด, ์๊ณ ํธ ๋ฐฑ์๋
- DB - fixtures ๋ฐ์ดํฐ ์์
[์ฐ์ง]
- UpdateView - ํ์์ ๋ณด ์์
- ProfileVIew - ํ๋กํ ํ๋ก ํธ,๋ฐฑ์ค๋
[๋ฏผ์ฃผ]
- MovieDetail - ์ฐํ๊ธฐ, ์์ฒญ ์ํ ํ๋ก ํธ
- MovieDetail - ์ฐํ๊ธฐ, ์์ฒญ ์ํ ๋ฐฑ์๋
[์ฐ์ง]
- ์์ฑ API ๋๊ณ ์ค๊ธฐ, ์ฐ๊ฒฐ
- UpdateView - ํ๋กํ ์ฌ์ง ์์
[๋ฏผ์ฃผ]
- SearchView - URL ์ฟผ๋ฆฌ ์ฒ๋ฆฌ
[์ฐ์ง]
- ์์ฑ์ธ์ ์ค์๊ฐ์ผ๋ก ์์ฑ, ์คํฌ๋กค
[๋ฏผ์ฃผ]
- ReviewReadCard - ํ๋ก ํธ, ๋ฐฑ์๋
- ReviewCreateCard - ํ๋ก ํธ, ๋ฐฑ์๋
[์ฐ์ง]
- SearchView - ์์ฑ์ธ์ ์ค๋ฅ ํด๊ฒฐ
- ProfileView - css ์์
[๋ฏผ์ฃผ]
- SearchView - URL ์ฟผ๋ฆฌ ์ฒ๋ฆฌ ์ฌ์์
- ReviewUDCard - ํ๋ก ํธ, ๋ฐฑ์๋
[์ฐ์ง]
- HomeView - ๊ฒ์์ฐฝ ์์
- HomeView - ๊ฒ์์ฐฝ css ์์
[๋ฏผ์ฃผ]
- DB - ์ด๊ธฐ ๋ฐ์ดํฐ ์์
- MovieDetail - ์๊ณ ํธ ๋งํฌ ์์
- HomeView - MovieCard css ์์ (์ ๋ ฌ ์์ )
[์ฐ์ง]
- DB - ์ด๊ธฐ ๋ฐ์ดํฐ ์์
- ReviewCard - css ์์
- Navbar - ์๊ณ ์ถ๊ฐ
- PPT ์์
์ต์ข ๋ฐํ
[๋ฏผ์ฃผ]
HomeView.vue์์ SearchView.vue๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์กด์ฌ
- router์ params๋ฅผ ์ฌ์ฉ
1-1. ๋จผ์ ๋ผ์ฐํฐ ์ค์ ์ ์์ ํฉ๋๋ค:
{ path: '/search/:searchData?', // optional parameter name: 'Search', component: SearchView }1-2. HomeView.vue๋ฅผ ์์ ํฉ๋๋ค:
router.push({ name: 'Search', params: { searchData: btoa(JSON.stringify(searchData)) // base64๋ก ์ธ์ฝ๋ฉ }, replace: true // URL ํ์คํ ๋ฆฌ๋ฅผ ๋จ๊ธฐ์ง ์์ });1-3. SearchView.vue์์ params๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํฉ๋๋ค:
onMounted(() => { if (route.params.searchData) { const searchData = JSON.parse(atob(route.params.searchData)); // base64 ๋์ฝ๋ฉ transcript.value = searchData.transcript; sentiment.value = searchData.sentiment; movies.value = searchData.movies; } });
- router.push ์์ replace: true์ ํจ๊ป query๋ฅผ ์ฌ์ฉํ ํ, ์ฆ์ query๋ฅผ ์ ๊ฑฐ
2-1. router ์ค์ ์ props: true ์ถ๊ฐ
router.push({ name: 'Search', query: { transcript: data.transcript, sentiment: data.sentiment_score, movies: JSON.stringify(data.movies) }, replace: true }).then(() => { // query ์ ๊ฑฐ router.replace({ name: 'Search' }); });์์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์๋ ๋ฐ์ดํฐ๊ฐ ์์ ํ ๋ก๋๋๊ธฐ ์ ์ query๊ฐ ์ ๊ฑฐ๋์ด ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง๋ ๋ฌธ์ ๊ฐ ์์์.
- HomeView.vue๋ ๊ธฐ์กด ๊ทธ๋๋ก ์ ์ง
- SearchView.vue์์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ ํ URL์ ์ ๋ฆฌํฉ๋๋ค:
onMounted(() => { // URL์ query params์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ const queryTranscript = route.query.transcript; const querySentiment = route.query.sentiment; const queryMovies = route.query.movies; if (queryTranscript && querySentiment && queryMovies) { // ๋ฐ์ดํฐ ์ค์ transcript.value = queryTranscript; sentiment.value = Number(querySentiment); movies.value = JSON.parse(queryMovies); // ๋ฐ์ดํฐ ์ค์ ํ URL ์ ๋ฆฌ router.replace({ path: '/search' }); } });์ด๋ ๊ฒ ํ๋ฉด:
- SearchView๊ฐ ๋ง์ดํธ๋ ๋ ๋จผ์ query ํ๋ผ๋ฏธํฐ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค
- ๋ฐ์ดํฐ๋ฅผ ์ปดํฌ๋ํธ์ ์ํ๋ก ์ค์ ํฉ๋๋ค
- ๊ทธ ํ์ URL์ ๊น๋ํ๊ฒ ์ ๋ฆฌํฉ๋๋ค
- ์ดํ ์๋ก์ด ๊ฒ์๋ ์ ์์ ์ผ๋ก ๋์ํฉ๋๋ค
์์ ๋ฐฉ๋ฒ๋๋ก ํ๋๋ฐ JSON ํ์ฑ ์๋ฌ๊ฐ ๋ฐ์ํ์ฌ claude-3.5-sonnet ๋ชจ๋ธ์ ํ์ฉํ cursor๊ฐ ์๋ ค์ค ์ฝ๋๋ก ์์
์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ์ฒ๋ฆฌ ํ ๊นจ๋ํ URL๋ก ๋ณ๊ฒฝ (SearchView.vue onMounted ์ฐธ๊ณ )
- LoginView -ํ์๊ฐ์ ์ ๋ ๊ณ์ ์๋ฌ ์ฒ๋ฆฌ
- SignupView - ID ์ค๋ณต ์ฒ๋ฆฌ (์ด๋ฏธ ๊ฐ์ ๋ ๊ณ์ ๊ตฌ๋ถ)
- ์ฌ์ฉ์ ID๋ Email ํ๋ ์๋ก ๋ฐ๊พธ๊ธฐ
- ์์ ๋ก๊ทธ์ธ
๊น๋ฏผ์ฃผ
์๋ก์ด ์ธ์ด์ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก์ ํธ๋ฅผ ์ ์ํ๋ค๋ณด๋ ์๊ฐ๋ณด๋ค ์ด๋ ค์ ๋ ๋ถ๋ถ๋ ๋ง๊ณ ๋ป๋๋ก ์๋ํ์ง ์์ ๋ง๋งํ๋ ์๊ฐ๋ ๋ง์์ง๋ง, ์ข์ ํ์๊ณผ AI ํด(Special thanks to Cursor...) ๋๋ถ์ ํ๋ก์ ํธ๋ฅผ ๋๊น์ง ์์ฑํ ์ ์์์ต๋๋ค. ์ด๋ฒ ํ๋ก์ ํธ๊ฐ ์์ผ๋ก ์์ ํ์
๊ณผ ๊ฐ๋ฐ์๋ก์์ ์ปค๋ฆฌ์ด์ ์ด์์ ๋ค์ง๋ ๊ณ๊ธฐ๊ฐ ๋ ๊ฒ ๊ฐ์ ๋ฟ๋ฏํ๊ณ ์๋ฏธ ์๋ ์๊ฐ์ด์์ต๋๋ค.
์ต์ฐ์ง
API๋ฅผ ํ์ฉํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๊ณผ์ ์์ ์ด๋ ค์์ด ์์์ง๋ง ๋ฌธ์ ํด๊ฒฐ์ ํตํด ๋ง์ ์ง์์ ์ต๋ํ ์ ์์์ต๋๋ค. ํ์๊ณผ์ ์ํํ ํ์
์ ํตํด ํ๋ก์ ํธ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์์ํ๋ ํฐ ์ฑ์ทจ๊ฐ์ ๋๋ ์ ์์์ต๋๋ค. ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ํตํด ์ด์ ๋ณด๋ค ๋ ๊น์ด ์๋ ๊ฒฝํ์ ์์ ์ ์์๊ณ , ์ค๋ฌด ์ญ๋๊ณผ ํ์
๋ฅ๋ ฅ์ ํ์ธต ๊ฐํํ ์ ์์์ต๋๋ค.










