๐ŸŽฌ ๋งํฌ๋กœ ๊ณต์œ ํ•˜๋Š” ๋‚ด ์˜ํ™” ์œ„์‹œ๋ฆฌ์ŠคํŠธ, movieshelf ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ์†Œ๊ฐœ

JEONGYUJINยท2025๋…„ 5์›” 22์ผ

์š”์ฆ˜ OTT ๋„ˆ๋ฌด ๋น„์‹ธ์ง€ ์•Š๋‚˜์š”?
์ €๋Š” ๋ณด๊ณ  ์‹ถ์€ ์˜ํ™”๋‚˜ ๋“œ๋ผ๋งˆ๊ฐ€ ์ •๋ง ๋งŽ์€ ์‚ฌ๋žŒ์ด์—ˆ๋Š”๋ฐ, ์ด๊ฒƒ์ €๊ฒƒ ์ •๊ธฐ ๊ตฌ๋…ํ•˜๊ธฐ์—” ๋ถ€๋‹ด๋ผ์„œ ํ•œ๋™์•ˆ ์ฐธ๋‹ค๊ฐ€ ์š”์ฆ˜ ๋ชฐ์•„์„œ ๋ณด๊ณ  ์žˆ์–ด์š”.

๊ทธ ์™€์ค‘์— ์นœ๊ตฌ๋“คํ•œํ…Œ ์˜ํ™” ์ถ”์ฒœ์„ ์ •๋ง ๋งŽ์ด ๋ฐ›์•˜๋Š”๋ฐ์š”,
๊ฐ€๋งŒํžˆ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๋“œ๋ผ๋งˆ๋‚˜ ๋ฎค์ง€์ปฌ๋ณด๋‹ค๋„ '์˜ํ™”'๊ฐ€ ๊ฐ€์žฅ ์ทจํ–ฅ์„ ๋“œ๋Ÿฌ๋‚ด๋Š” ์ฝ˜ํ…์ธ  ๊ฐ™๋”๋ผ๊ณ ์š”.

  • ๋“œ๋ผ๋งˆ๋Š” ๋ณด๋‹ค ๋ณด๋ฉด ์ •๋“ค์–ด์„œ ๋ณด๊ฒŒ ๋˜๊ณ ,
  • ๋ฎค์ง€์ปฌ์€ ์žฅ๋ฅด๋‚˜ ๋น„์šฉ ๋•Œ๋ฌธ์— ์ ‘๊ทผ์ด ์กฐ๊ธˆ ์ œํ•œ๋˜๋Š”๋ฐ,
  • ์˜ํ™”๋Š” ๋‚ด ์ทจํ–ฅ์— ๋”ฑ ๋งž๋Š” ์ž‘ํ’ˆ์„ ๊ณ ๋ฅด๊ณ , ์ถ”์ฒœํ•˜๊ณ , ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ ๊ฐ™์•˜์–ด์š”.

๊ทธ๋ž˜์„œ ๋ฌธ๋“ ์ด๋Ÿฐ ์ƒ๊ฐ์ด ๋“ค์—ˆ์–ด์š”.

"๋ณด๊ณ  ์‹ถ์€ ์˜ํ™” ๋ฆฌ์ŠคํŠธ, ๊ทธ๋ƒฅ ๋งํฌ ํ•˜๋‚˜๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉด ์•ˆ ๋ ๊นŒ?"

๊ทธ๋ž˜์„œ ์ง์ ‘ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
๋กœ๊ทธ์ธ ์—†์ด ๋ˆ„๊ตฌ๋‚˜ ์œ„์‹œ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค๊ณ , URL๋งŒ์œผ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์›น์•ฑ! โ†’ movieshelf ๐ŸŽž๏ธ


๐Ÿ’ก When2meet์—์„œ ์˜๊ฐ์„ ๋ฐ›์•˜์–ด์š”

ํšŒ์˜ ์‹œ๊ฐ„ ์กฐ์œจํ•  ๋•Œ ์ž์ฃผ ์“ฐ๋Š” ์„œ๋น„์Šค์ธ [When2meet]์„ ๋– ์˜ฌ๋ ธ์Šต๋‹ˆ๋‹ค.
ํšŒ์›๊ฐ€์ž…๋„ ํ•„์š” ์—†๊ณ , ๋งํฌ๋งŒ์œผ๋กœ ์‚ฌ๋žŒ๋“ค์ด ์ฐธ์—ฌํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๊ฐ€ ๋„ˆ๋ฌด ๋งˆ์Œ์— ๋“ค์—ˆ๊ฑฐ๋“ ์š”.

ํ•ญ๋ชฉWhen2meet ๊ตฌ์กฐ ์„ค๋ช…movieshelf์—์„œ์˜ ์ ์šฉ ๋ฐฉ์‹
์ธ์ฆ ๋ฐฉ์‹๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ์—†์Œ, ์ฐธ์—ฌ์ž ์ด๋ฆ„๋งŒ ์ž…๋ ฅ๋กœ๊ทธ์ธ ์—†์Œ, ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ ์‹œ UUID ๋ฐœ๊ธ‰
์ ‘๊ทผ ๋ฐฉ์‹๊ณ ์œ  URL์„ ํ†ตํ•ด ์ฐธ์—ฌ (์˜ˆ: when2meet.com/?123abc)movieshelf.store/view/:id ํ˜•์‹์˜ ๋งํฌ๋กœ ๊ณต์œ 
๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์‹œ๊ฐ„ ์„ ํƒ์€ 2์ฐจ์› ๊ทธ๋ฆฌ๋“œ ๋ฐฐ์—ด๋กœ ํ‘œํ˜„, ์„œ๋ฒ„์— ์ฆ‰์‹œ ๋ฐ˜์˜๋จ์˜ํ™” ์„ ํƒ ๋ฆฌ์ŠคํŠธ๋ฅผ JSON ํ˜•ํƒœ๋กœ ์ €์žฅ, ์ž๋™ ์ €์žฅ ์˜ˆ์ •
์ €์žฅ ๋ฐฉ์‹์ €์žฅ ๋ฒ„ํŠผ ์—†์ด ์ž…๋ ฅ ์‹œ ์ž๋™ ๋ฐ˜์˜ (auto-save)onChange ์‹œ debounce ํ›„ ์ €์žฅ API ํ˜ธ์ถœ ๊ตฌ์กฐ ์„ค๊ณ„ ์ค‘
์ˆ˜์ • ์ธ์ฆ ๋ฐฉ์‹์ด๋ฆ„+๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ์‹œ ์ˆ˜์ • ๊ฐ€๋Šฅ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์„ ํƒ์‚ฌํ•ญ์œผ๋กœ, bcrypt๋ฅผ ์ด์šฉํ•ด ํ•ด์‹œ ์ €์žฅ ์˜ˆ์ •
๋ฐ์ดํ„ฐ ๊ณต์œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ ์„ ํƒ ์‹œ๊ฐ„๊ณผ ๊ฒน์น˜๋Š” ์‹œ๊ฐ„ ์‹œ๊ฐํ™”์ถ”ํ›„ WebSocket ๋„์ž…์œผ๋กœ ์‹ค์‹œ๊ฐ„ ์˜ํ™” ์ถ”๊ฐ€ ๋ฐ˜์˜ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ์˜ˆ์ •

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

movieshelf/
โ”œโ”€โ”€ backend/        โ† Node + Express (Wishlist ๊ด€๋ฆฌ API)
โ””โ”€โ”€ frontend/       โ† React + Vite + Tailwind (UI ๊ตฌ์„ฑ)

๐Ÿ“ฆ backend/

๊ฐ„๋‹จํ•œ API ์„œ๋ฒ„์˜ˆ์š”.
๋กœ๊ทธ์ธ์€ ์—†๊ณ , ๊ฐ ์œ„์‹œ๋ฆฌ์ŠคํŠธ์— UUID ๊ฐ™์€ ๊ณ ์œ  ID๋งŒ ๋ถ€์—ฌํ•ด์„œ ๊ตฌ๋ถ„ํ•ด์š”.

์ฃผ์š” ๊ธฐ๋Šฅ์€ ์•„๋ž˜ 3๊ฐ€์ง€์ž…๋‹ˆ๋‹ค

  • ์œ„์‹œ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
  • ์˜ํ™” ๊ฒ€์ƒ‰ (TMDB API ํ™œ์šฉ)
  • ํŠน์ • ๋ฆฌ์ŠคํŠธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ & ์ˆ˜์ •ํ•˜๊ธฐ

ํด๋” ๊ตฌ์กฐ๋„ ๊ธฐ๋Šฅ ์ค‘์‹ฌ์œผ๋กœ ๋‹จ์ˆœํ™”ํ–ˆ์–ด์š”

โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ controllers/        โ† ์š”์ฒญ ์ฒ˜๋ฆฌ
โ”‚   โ”œโ”€โ”€ services/           โ† TMDB ์—ฐ๋™, ๋กœ์ง ์ฒ˜๋ฆฌ
โ”‚   โ”œโ”€โ”€ models/             โ† ํƒ€์ž… ์ •์˜
โ”‚   โ”œโ”€โ”€ routes/             โ† API ์—”๋“œํฌ์ธํŠธ
โ”‚   โ”œโ”€โ”€ utils/              โ† UUID ์ƒ์„ฑ ๋“ฑ ์œ ํ‹ธ ํ•จ์ˆ˜

ํ˜„์žฌ๋Š” wishlists.json์— ์ €์žฅํ•˜์ง€๋งŒ,
์ดํ›„์—๋Š” Firebase๋‚˜ PostgreSQL๋กœ ์ด์ „ํ•  ์˜ˆ์ •์ด์—์š”.

๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์„ ํƒ์ ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๊ณ , ๋‚˜์ค‘์— ์ˆ˜์ • ๊ถŒํ•œ์„ ์œ„ํ•ด bcrypt hash๋กœ ์ €์žฅํ•  ์˜ˆ์ •์ด์—์š”.

๐ŸŽจ frontend/

Vite ๊ธฐ๋ฐ˜ React ํ”„๋กœ์ ํŠธ์— Tailwind CSS๋ฅผ ์ž…ํ˜”์–ด์š”.
ํŽ˜์ด์ง€๋Š” ์ด 3๊ฐœ๋กœ ๊ตฌ์„ฑ๋ผ ์žˆ์–ด์š”.

ํŽ˜์ด์ง€๊ฒฝ๋กœ์„ค๋ช…
์ƒ์„ฑํ•˜๊ธฐ/create์ƒˆ๋กœ์šด ์œ„์‹œ๋ฆฌ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ
๋ณด๊ธฐ/view/:id๊ณต์œ ๋ฐ›์€ ๋งํฌ๋กœ ๋ฆฌ์ŠคํŠธ ํ™•์ธ
์ˆ˜์ •ํ•˜๊ธฐ/edit/:id๋‚ด ๋ฆฌ์ŠคํŠธ ๋‹ค์‹œ ํŽธ์ง‘ํ•˜๊ธฐ

์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ๋„ ์‹ฌํ”Œํ•˜๊ฒŒ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค

โ”œโ”€โ”€ components/
โ”‚   โ”œโ”€โ”€ MovieList.tsx       โ† ์ €์žฅ๋œ ์˜ํ™” ๋ชฉ๋ก ์ถœ๋ ฅ
โ”‚   โ”œโ”€โ”€ MovieSearch.tsx     โ† ์˜ํ™” ๊ฒ€์ƒ‰์ฐฝ + ๊ฒฐ๊ณผ
โ”‚   โ””โ”€โ”€ Wishlist.tsx        โ† ์ €์žฅ/์ˆ˜์ • ์ „์ฒด UI ๊ตฌ์„ฑ

๐Ÿง  ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„์—์„œ ์‹ ๊ฒฝ ์“ด ์ 

  1. ํšŒ์›๊ฐ€์ž… ์—†๋Š” ๊ตฌ์กฐ (When2meet ๋ฐฉ์‹)
    โ†’ ๋ˆ„๊ตฌ๋‚˜ ๋งํฌ๋งŒ์œผ๋กœ ์ฐธ์—ฌ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๊ตฌ์„ฑ
  2. ์„ ํƒ์  ๋น„๋ฐ€๋ฒˆํ˜ธ ์„ค์ •
    โ†’ ์ต๋ช…์„ฑ๊ณผ ํŽธ์˜์„ฑ ๋ชจ๋‘ ๊ณ ๋ ค
  3. ์ฆ‰์‹œ ์ €์žฅ UX
    โ†’ ์ €์žฅ ๋ฒ„ํŠผ ์—†์ด ๋ฐ”๋กœ ๋ฐ˜์˜๋˜๋„๋ก debounce + auto-save ๊ตฌ์กฐ ๊ตฌํ˜„ ์ค‘

๐Ÿ›ฃ๏ธ ์•ž์œผ๋กœ์˜ ๊ณ„ํš

  • DB ์—ฐ๋™: wishlists.json โ†’ Firebase or PostgreSQL
  • WebSocket ๋„์ž…: ์‹ค์‹œ๊ฐ„ ๋™๊ธฐํ™” ๊ธฐ๋Šฅ
  • ๊ณต์œ  ๋ฏธ๋ฆฌ๋ณด๊ธฐ: Open Graph ํƒœ๊ทธ๋กœ ์ธ๋„ค์ผ ์ž๋™ ์ƒ์„ฑ
  • ๋‹คํฌ๋ชจ๋“œ ์ง€์›: Tailwind ํ…Œ๋งˆ ์ „ํ™˜

๐Ÿ’ฌ ๋งˆ๋ฌด๋ฆฌ

์นœ๊ตฌ๋“ค์ด๋ž‘, ํ˜น์€ ์ปคํ”Œ๋ผ๋ฆฌ ๋ณด๊ณ  ์‹ถ์€ ์˜ํ™”๋ฅผ ์ •๋ฆฌํ•˜๊ณ  ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต๊ฐ„.
movieshelf๋Š” ๊ทธ๋Ÿฐ ๋„๊ตฌ๊ฐ€ ๋˜๊ธธ ๋ฐ”๋ผ๋Š” ๋งˆ์Œ์—์„œ ์‹œ์ž‘๋์Šต๋‹ˆ๋‹ค.

์•„์ง MVP์ง€๋งŒ, ๋‹จ์ˆœํ•œ ๊ตฌ์กฐ ๋•๋ถ„์— ๊ธˆ๋ฐฉ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ํ™•์žฅํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”.
๋น„์Šทํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์œผ์‹  ๋ถ„๋“ค๊ป˜๋„ ๋„์›€์ด ๋˜๊ธธ ๋ฐ”๋ผ๋ฉฐ ๊ตฌ์กฐ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค ๐Ÿ™Œ

๐Ÿ” ๋‹ค์Œ ๊ธ€ | ์‚ฌ์šฉํ•œ ๊ธฐ์ˆ ๊ณผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ •๋ฆฌ

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” ์ „๋ฐ˜์ ์ธ ๊ธฐํš๊ณผ ๊ตฌ์กฐ ์œ„์ฃผ๋กœ ์†Œ๊ฐœํ–ˆ์ง€๋งŒ, ๋‹ค์Œ ๊ธ€์—์„œ๋Š” ์‹ค์ œ ๊ฐœ๋ฐœ์— ์‚ฌ์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ์กฐ๊ธˆ ๋” ๊ณต๋ถ€ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

  • TMDB API๋กœ ์˜ํ™” ๊ฒ€์ƒ‰ํ•˜๊ธฐ (axios, dotenv)
  • ๊ณ ์œ  URL ์ƒ์„ฑ (nanoid)
  • ์˜ํ™” ํฌ์Šคํ„ฐ ์ž๋™ ๊ฐ€์ ธ์˜ค๊ธฐ (posterSearch.service.ts)
  • Tailwind๋กœ UI ๋น ๋ฅด๊ฒŒ ๊ตฌ์„ฑํ•œ ๋ฐฉ์‹
  • Vite + React ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์ตœ์ ํ™”

๋‹ค์Œ ๊ธ€์—์„  ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์„ ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด๋ฉด์„œ ์™œ ์„ ํƒํ–ˆ๋Š”์ง€,
์–ด๋–ป๊ฒŒ ๋” ๋‚˜์€ ๋ฐฉ์‹์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋งํ•  ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผ์„ ๊ณต์œ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

profile
์ผ๋‹จ ํ•˜๊ณ  ๋ณด์ž (ํŽ ๋ฆฌ์ปจ์  ๋งˆ์ธ๋“œ ใ… ใ… )

0๊ฐœ์˜ ๋Œ“๊ธ€