๐ŸŽญ ์—ฐ๊ทน ๊ณต์—ฐ ํ›„๊ธฐ & ์‚ฌ์ง„ ๊ฐค๋Ÿฌ๋ฆฌ - ๊ด€๊ฐ์ด ๋งŒ๋“œ๋Š” ๊ณต์—ฐ ์•„์นด์ด๋ธŒ - ๋ฐ”์ด๋ธŒ์ฝ”๋”ฉ ๋ ˆ์‹œํ”ผ
์ž…๋ฌธ PHP Laravel AI: Claude

๐ŸŽญ ์—ฐ๊ทน ๊ณต์—ฐ ํ›„๊ธฐ & ์‚ฌ์ง„ ๊ฐค๋Ÿฌ๋ฆฌ - ๊ด€๊ฐ์ด ๋งŒ๋“œ๋Š” ๊ณต์—ฐ ์•„์นด์ด๋ธŒ

๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ช… theater-audience-review-gallery
์กฐํšŒ์ˆ˜ 89 0๊ฑด ์ œ์ถœ

๋ฌธ์ œ ์„ค๋ช…

๐ŸŽญ ์—ฐ๊ทน ๊ณต์—ฐ ํ›„๊ธฐ & ์‚ฌ์ง„ ๊ฐค๋Ÿฌ๋ฆฌ

๊ด€๊ฐ๋“ค์ด ์ง์ ‘ ๊ด€๋žŒํ•œ ์—ฐ๊ทน ๊ณต์—ฐ์˜ ํ›„๊ธฐ์™€ ์‚ฌ์ง„์„ ์—…๋กœ๋“œํ•˜์—ฌ ๊ณต์œ ํ•˜๋Š” ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. Laravel 13.x + Blade ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉฐ, ๊ณต์—ฐ๋ณ„๋กœ ๊ด€๊ฐ๋“ค์˜ ์ƒ์ƒํ•œ ๋ฐ˜์‘์„ ๋ชจ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐ŸŽฏ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

  • ๊ณต์—ฐ ์ •๋ณด ๋“ฑ๋ก (์ œ๋ชฉ, ๊ทน๋‹จ๋ช…, ๊ณต์—ฐ ๊ธฐ๊ฐ„, ์žฅ์†Œ, ํฌ์Šคํ„ฐ ์ด๋ฏธ์ง€)
  • ๊ณต์—ฐ๋ณ„ ํ›„๊ธฐ ์ž‘์„ฑ (๋ณ„์ , ๊ด€๋žŒ ๋‚ ์งœ, ๊ฐ์ƒํ‰, ์‚ฌ์ง„ ์—…๋กœ๋“œ)
  • ๊ณต์—ฐ ๋ชฉ๋ก ํŽ˜์ด์ง€ (์นด๋“œ ๋ ˆ์ด์•„์›ƒ with ํ‰๊ท  ๋ณ„์ )
  • ๊ณต์—ฐ ์ƒ์„ธ ํŽ˜์ด์ง€ (ํ›„๊ธฐ ๋ชฉ๋ก & ์‚ฌ์ง„ ๊ฐค๋Ÿฌ๋ฆฌ)
  • ํ›„๊ธฐ ์ข‹์•„์š” ๊ธฐ๋Šฅ (๊ณต๊ฐ ํ‘œ์‹œ)
  • ๋ณ„์  ํ•„ํ„ฐ๋ง (5์ ๋งŒ, 4์  ์ด์ƒ ๋“ฑ)
  • ๋ฐ˜์‘ํ˜• ๋””์ž์ธ (Tailwind CSS)

๐ŸŽ ๋ณด๋„ˆ์Šค ๊ธฐ๋Šฅ

  • ํ›„๊ธฐ ์ •๋ ฌ (์ตœ์‹ ์ˆœ, ์ข‹์•„์š”์ˆœ, ๋ณ„์ ์ˆœ)
  • ์‚ฌ์ง„ ํด๋ฆญ ์‹œ ๋ชจ๋‹ฌ๋กœ ํฌ๊ฒŒ ๋ณด๊ธฐ
  • ๊ณต์—ฐ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ (์ œ๋ชฉ, ๊ทน๋‹จ๋ช…)
  • ๋ฒ ์ŠคํŠธ ํ›„๊ธฐ ๋ฐฐ์ง€ (์ข‹์•„์š” 10๊ฐœ ์ด์ƒ)
  • ๊ด€๋žŒ ์ธ์ฆ ์Šคํ‹ฐ์ปค (๋‚ ์งœ ๋„์žฅ)

๐ŸŽจ ๋””์ž์ธ ํฌ์ธํŠธ

  • ๊ทน์žฅ ๋ถ„์œ„๊ธฐ์˜ ๋‹คํฌ ํ…Œ๋งˆ UI
  • ๋ณ„์  ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ
  • ์‚ฌ์ง„ ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ (Pinterest ์Šคํƒ€์ผ)
  • ํ˜ธ๋ฒ„ ์‹œ ์นด๋“œ ๋ฆฌํ”„ํŠธ ํšจ๊ณผ

์ œ์•ฝ ์กฐ๊ฑด

  • โ€ข Laravel 13.x ํ•„์ˆ˜ ์‚ฌ์šฉ
  • โ€ข Blade ํ…œํ”Œ๋ฆฟ ์—”์ง„ ์‚ฌ์šฉ (React/Vue ๊ธˆ์ง€)
  • โ€ข SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ
  • โ€ข Tailwind CSS๋กœ ์Šคํƒ€์ผ๋ง
  • โ€ข ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ๋Š” public/storage ์‚ฌ์šฉ
  • โ€ข ๋ผ์šฐํŠธ๋Š” web.php์— ์ •์˜
  • โ€ข ๋ชจ๋ธ๋ช…: Performance, Review
  • โ€ข ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์œผ๋กœ ํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ ๊ด€๋ฆฌ
  • โ€ข Blade ์ปดํฌ๋„ŒํŠธ ํ™œ์šฉ (๋ณ„์  ํ‘œ์‹œ, ์นด๋“œ ๋“ฑ)
  • โ€ข ํŒŒ์ผ ์—…๋กœ๋“œ validation (์ด๋ฏธ์ง€๋งŒ, ์ตœ๋Œ€ 2MB)

ํ”„๋กฌํ”„ํŠธ ๋ ˆ์‹œํ”ผ

์•„๋ž˜ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ AI์—๊ฒŒ ๋ณด๋‚ด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋ณต์‚ฌ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ฐ”๋กœ ์‚ฌ์šฉํ•˜์„ธ์š”.

1
Step 1
mkdir theater-audience-review-gallery && cd theater-audience-review-gallery

์ด ํด๋”์—์„œ Laravel 13.x ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ธฐ๋ณธ ์„ค์ •์„ ์™„๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

# ์š”๊ตฌ์‚ฌํ•ญ
1. Laravel 13.x ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
2. SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ • (.env ํŒŒ์ผ์—์„œ DB_CONNECTION=sqlite)
3. database/database.sqlite ํŒŒ์ผ ์ƒ์„ฑ
4. Tailwind CSS ์„ค์น˜ ๋ฐ ์„ค์ • (Laravel Breeze ์—†์ด ์ˆœ์ˆ˜ Tailwind)
5. public/storage ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์ƒ์„ฑ (php artisan storage:link)

# ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ƒ์„ฑ
- performances ํ…Œ์ด๋ธ”: id, title, company_name, poster_image, venue, start_date, end_date, description, created_at, updated_at
- reviews ํ…Œ์ด๋ธ”: id, performance_id, rating(1-5), review_date, content, photo_path(nullable), likes_count(default 0), created_at, updated_at

# ๋ชจ๋ธ ์ƒ์„ฑ
- Performance ๋ชจ๋ธ: hasMany reviews ๊ด€๊ณ„ ์ •์˜
- Review ๋ชจ๋ธ: belongsTo performance ๊ด€๊ณ„ ์ •์˜

# ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ์ƒ์„ฑ
- resources/views/layouts/app.blade.php ์ƒ์„ฑ
- ๋‹คํฌ ํ…Œ๋งˆ ๊ทน์žฅ ๋ถ„์œ„๊ธฐ (๋ฐฐ๊ฒฝ์ƒ‰ #1a1a2e, ์•ก์„ผํŠธ #e94560)
- ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ” ํฌํ•จ (๋กœ๊ณ , ๊ณต์—ฐ ๋ชฉ๋ก ๋งํฌ)

php artisan migrate ์‹คํ–‰๊นŒ์ง€ ์™„๋ฃŒํ•ด์ฃผ์„ธ์š”.

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: Laravel ํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๊ณ , SQLite ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— performances์™€ reviews ํ…Œ์ด๋ธ”์ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๋ฉ๋‹ˆ๋‹ค. Performance์™€ Review ๋ชจ๋ธ์ด ๊ด€๊ณ„ ์„ค์ •๊ณผ ํ•จ๊ป˜ ์ƒ์„ฑ๋˜๋ฉฐ, Tailwind CSS๊ฐ€ ์„ค์ •๋œ ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์ด ์ค€๋น„๋ฉ๋‹ˆ๋‹ค.

2
Step 2
๊ณต์—ฐ ๋ชฉ๋ก ํŽ˜์ด์ง€์™€ ๊ณต์—ฐ ๋“ฑ๋ก ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

# ๋ผ์šฐํŠธ (routes/web.php)
- GET / โ†’ ๊ณต์—ฐ ๋ชฉ๋ก ํŽ˜์ด์ง€
- GET /performances/create โ†’ ๊ณต์—ฐ ๋“ฑ๋ก ํผ
- POST /performances โ†’ ๊ณต์—ฐ ์ €์žฅ
- GET /performances/{id} โ†’ ๊ณต์—ฐ ์ƒ์„ธ ํŽ˜์ด์ง€

# ์ปจํŠธ๋กค๋Ÿฌ (PerformanceController)
- index(): ๋ชจ๋“  ๊ณต์—ฐ์„ ํ‰๊ท  ๋ณ„์ ๊ณผ ํ•จ๊ป˜ ์กฐํšŒ (์นด๋“œ ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ)
- create(): ๊ณต์—ฐ ๋“ฑ๋ก ํผ ํ‘œ์‹œ
- store(): ๊ณต์—ฐ ์ €์žฅ (ํฌ์Šคํ„ฐ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ํฌํ•จ, validation)
- show($id): ๊ณต์—ฐ ์ƒ์„ธ ์ •๋ณด + ํ›„๊ธฐ ๋ชฉ๋ก ํ‘œ์‹œ

# ๋ทฐ ํŒŒ์ผ
- resources/views/performances/index.blade.php: ๊ณต์—ฐ ์นด๋“œ ๊ทธ๋ฆฌ๋“œ (ํฌ์Šคํ„ฐ, ์ œ๋ชฉ, ๊ทน๋‹จ๋ช…, ํ‰๊ท  ๋ณ„์  ํ‘œ์‹œ)
- resources/views/performances/create.blade.php: ๊ณต์—ฐ ๋“ฑ๋ก ํผ (ํŒŒ์ผ ์—…๋กœ๋“œ ํฌํ•จ)
- Blade ์ปดํฌ๋„ŒํŠธ resources/views/components/star-rating.blade.php ์ƒ์„ฑ (๋ณ„์  ํ‘œ์‹œ์šฉ, 1-5์ )

# Tailwind CSS ์Šคํƒ€์ผ๋ง
- ์นด๋“œ ํ˜ธ๋ฒ„ ์‹œ transform scale-105 ํšจ๊ณผ
- ํฌ์Šคํ„ฐ ์ด๋ฏธ์ง€ aspect-ratio-3/4
- ๊ทธ๋ฆฌ๋“œ ๋ ˆ์ด์•„์›ƒ (lg:grid-cols-3 md:grid-cols-2)

# Validation
- title: required, max:255
- poster_image: required, image, max:2048
- start_date, end_date: required, date

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: ๊ณต์—ฐ ๋ชฉ๋ก ํŽ˜์ด์ง€์—์„œ ๋“ฑ๋ก๋œ ๊ณต์—ฐ๋“ค์ด ์นด๋“œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ, ๊ณต์—ฐ ๋“ฑ๋ก ํผ์„ ํ†ตํ•ด ์ƒˆ ๊ณต์—ฐ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํฌ์Šคํ„ฐ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ๊ฐ€ ์ •์ƒ ์ž‘๋™ํ•˜๊ณ , ํ‰๊ท  ๋ณ„์ ์ด ๊ณ„์‚ฐ๋˜์–ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

3
Step 3
๊ณต์—ฐ ์ƒ์„ธ ํŽ˜์ด์ง€์— ํ›„๊ธฐ ์ž‘์„ฑ ๊ธฐ๋Šฅ๊ณผ ํ›„๊ธฐ ๋ชฉ๋ก์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

# ๋ผ์šฐํŠธ ์ถ”๊ฐ€
- POST /performances/{id}/reviews โ†’ ํ›„๊ธฐ ์ €์žฅ
- POST /reviews/{id}/like โ†’ ํ›„๊ธฐ ์ข‹์•„์š”

# ์ปจํŠธ๋กค๋Ÿฌ (ReviewController)
- store($performanceId): ํ›„๊ธฐ ์ €์žฅ (๋ณ„์ , ๊ด€๋žŒ ๋‚ ์งœ, ๊ฐ์ƒํ‰, ์‚ฌ์ง„ ์—…๋กœ๋“œ)
- like($id): ํ›„๊ธฐ ์ข‹์•„์š” ์ฆ๊ฐ€ (likes_count++)

# ๋ทฐ ์ˆ˜์ • (performances/show.blade.php)
- ๊ณต์—ฐ ์ •๋ณด ์ƒ๋‹จ ํ‘œ์‹œ (ํฌ์Šคํ„ฐ, ์ œ๋ชฉ, ๊ทน๋‹จ๋ช…, ๊ณต์—ฐ ๊ธฐ๊ฐ„, ํ‰๊ท  ๋ณ„์ )
- ํ›„๊ธฐ ์ž‘์„ฑ ํผ (๋ณ„์  ์„ ํƒ ๋ผ๋””์˜ค ๋ฒ„ํŠผ with ๋ณ„ ์•„์ด์ฝ˜, ๊ด€๋žŒ ๋‚ ์งœ, ๊ฐ์ƒํ‰ textarea, ์‚ฌ์ง„ ์—…๋กœ๋“œ)
- ํ›„๊ธฐ ๋ชฉ๋ก ํ‘œ์‹œ (์นด๋“œ ํ˜•ํƒœ, ๋ณ„์ , ๊ด€๋žŒ ๋‚ ์งœ, ๊ฐ์ƒํ‰, ์‚ฌ์ง„, ์ข‹์•„์š” ์ˆ˜)
- ํ›„๊ธฐ ์‚ฌ์ง„ ํด๋ฆญ ์‹œ ์ƒˆ ํƒญ์—์„œ ํฌ๊ฒŒ ๋ณด๊ธฐ (target="_blank")

# Blade ์ปดํฌ๋„ŒํŠธ
- resources/views/components/review-card.blade.php ์ƒ์„ฑ (ํ›„๊ธฐ ์นด๋“œ UI)
- ์ข‹์•„์š” ๋ฒ„ํŠผ (ํ•˜ํŠธ ์•„์ด์ฝ˜, ํด๋ฆญ ์‹œ POST ์š”์ฒญ)

# Validation
- rating: required, integer, between:1,5
- review_date: required, date
- content: required, min:10
- photo: nullable, image, max:2048

# ์Šคํƒ€์ผ๋ง
- ํ›„๊ธฐ ์นด๋“œ border-l-4 border-pink-500 (์•ก์„ผํŠธ)
- ๋ณ„์  ์„ ํƒ ์‹œ ๋…ธ๋ž€์ƒ‰ ๋ณ„ ์ฑ„์šฐ๊ธฐ ํšจ๊ณผ
- ์‚ฌ์ง„ rounded-lg shadow-md

๊ธฐ๋Œ€ ๊ฒฐ๊ณผ: ๊ณต์—ฐ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ํ›„๊ธฐ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ž‘์„ฑ๋œ ํ›„๊ธฐ๋“ค์ด ๋ชฉ๋ก์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ณ„์ , ๊ด€๋žŒ ๋‚ ์งœ, ๊ฐ์ƒํ‰, ์‚ฌ์ง„์ด ๋ชจ๋‘ ์ €์žฅ๋˜๊ณ , ์ข‹์•„์š” ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์ง„์„ ํด๋ฆญํ•˜๋ฉด ํฌ๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ์ถœ๋œ ์ž‘ํ’ˆ (0)

๋กœ๊ทธ์ธ ํ›„ ์ œ์ถœ

์•„์ง ์ œ์ถœ๋œ ์ž‘ํ’ˆ์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋„์ „์ž๊ฐ€ ๋˜์–ด๋ณด์„ธ์š”!

๋Œ“๊ธ€ (0)

๋กœ๊ทธ์ธ ํ›„ ๋Œ“๊ธ€์„ ๋‚จ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ๋ณด์„ธ์š”!