๐ฎ ๊ฒ์ ์์ดํ ๊ฑฐ๋ ์ฅํฐ - ์ค๊ณ ๊ฒ์ ์์ดํ ์ฌ๊ณ ํ๊ธฐ
game-item-marketplace-laravel
๋ฌธ์ ์ค๋ช
๐ฏ ํ๋ก์ ํธ ๊ฐ์
๊ฒ์ ์์ดํ ์ ์ฌ๊ณ ํ๋ ์ค๊ณ ๊ฑฐ๋ ํ๋ซํผ์ ๋ง๋ค์ด๋ด ๋๋ค. ์ฌ์ฉ์๋ค์ด ๊ฒ์ ์์ดํ ์ ๋ฑ๋กํ๊ณ , ๋ค๋ฅธ ์ฌ์ฉ์๋ค์ด ๊ด์ฌ ์๋ ์์ดํ ์ ์ฐพ์๋ณผ ์ ์๋ ๊ฐ๋จํ ๋ง์ผํ๋ ์ด์ค์ ๋๋ค. Laravel 13.x + Blade + Tailwind CSS๋ก ๊ตฌํํ๋ฉฐ, ํ๋ก๊ทธ๋๋ฐ ์ ๋ฌธ์๋ AI ๋๊ตฌ์ ํจ๊ป๋ผ๋ฉด ์ถฉ๋ถํ ์์ฑํ ์ ์๋ ์์ค์ ๋๋ค.
โจ ํ์ ๊ธฐ๋ฅ
- ์์ดํ ๋ฑ๋ก: ์์ดํ ๋ช , ๊ฒ์ ์ด๋ฆ, ๊ฐ๊ฒฉ, ์ค๋ช , ์ํ(์๊ฒ/์ค๊ณ ) ์ ๋ ฅ
- ์์ดํ ๋ชฉ๋ก: ๋ฑ๋ก๋ ๋ชจ๋ ์์ดํ ์ ์นด๋ ํ์์ผ๋ก ๋ณด๊ธฐ
- ์์ดํ ์์ธ: ํด๋ฆญํ๋ฉด ์์ธ ์ ๋ณด ํ์ธ ๊ฐ๋ฅ
- ํํฐ๋ง: ๊ฒ์๋ณ, ๊ฐ๊ฒฉ๋๋ณ ํํฐ ๊ธฐ๋ฅ
- ๊ฒ์: ์์ดํ ๋ช ์ผ๋ก ๊ฒ์
- ํ๋งค ์ํ ํ์: ํ๋งค์ค/ํ๋งค์๋ฃ ๋ฑ์ง
- ๋ฐ์ํ ๋์์ธ: ๋ชจ๋ฐ์ผ/๋ฐ์คํฌํฑ ๋ชจ๋ ์ง์
๐ ๋ณด๋์ค ๊ธฐ๋ฅ (์ ํ)
- ์์ดํ ์ด๋ฏธ์ง ์ ๋ก๋ ๊ธฐ๋ฅ
- ์ฐํ๊ธฐ(์์๋ฆฌ์คํธ) ๊ธฐ๋ฅ
- ์ต๊ทผ ๋ฑ๋ก์/๊ฐ๊ฒฉ์ ์ ๋ ฌ
- ํ์ด์ง๋ค์ด์ (ํ ํ์ด์ง์ 12๊ฐ์ฉ)
- ํ๋งค์ ์ฐ๋ฝ์ฒ ์จ๊น ์ฒ๋ฆฌ (์์ธ ํ์ด์ง์์๋ง ๊ณต๊ฐ)
๐ ๊ธฐ์ ์คํ
- ๋ฐฑ์๋: Laravel 13.x
- ํ๋ก ํธ์๋: Blade ํ ํ๋ฆฟ + Tailwind CSS
- ๋ฐ์ดํฐ๋ฒ ์ด์ค: SQLite (๊ฐ๋จํ ์ค์ )
- ์์ด์ฝ: Heroicons (Tailwind์ ์ ์ด์ธ๋ฆผ)
๐ ํ์ต ๋ชฉํ
- Laravel ๊ธฐ๋ณธ ๊ตฌ์กฐ ์ดํด (๋ผ์ฐํ , ์ปจํธ๋กค๋ฌ, ๋ชจ๋ธ)
- Blade ํ ํ๋ฆฟ ๋ฌธ๋ฒ ์ตํ๊ธฐ
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ง์ด๊ทธ๋ ์ด์ & Eloquent ORM ์ฌ์ฉ
- CRUD ๊ธฐ๋ณธ ๊ฐ๋ ์ค์ต
- Tailwind CSS๋ก ๋น ๋ฅธ UI ๊ตฌ์ฑ
- ํผ ์ ํจ์ฑ ๊ฒ์ฌ (Validation)
์ด ํ๋ก์ ํธ๋ ์ค์ ์ค๊ณ ๊ฑฐ๋ ํ๋ซํผ์ ํต์ฌ ๊ธฐ๋ฅ์ ๋ด๊ณ ์์ด ์ค์ฉ์ ์ด๋ฉฐ, ์์ฑ ํ์๋ ํฌํธํด๋ฆฌ์ค๋ก๋ ํ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
์ ์ฝ ์กฐ๊ฑด
- โข Laravel 13.x ์ต์ ๋ฒ์ ์ฌ์ฉ ํ์
- โข Blade ํ ํ๋ฆฟ ์์ง ์ฌ์ฉ (React/Vue ๋ฑ SPA ํ๋ ์์ํฌ ์ฌ์ฉ ๊ธ์ง)
- โข Tailwind CSS๋ก ์คํ์ผ๋ง (CDN ๋๋ npm ์ค์น)
- โข SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ (์ค์ ๊ฐํธ)
- โข ์ฝ๋๋ ํ๊ธ ์ฃผ์ ํฌํจํ์ฌ ์ด๋ณด์๋ ์ดํดํ๊ธฐ ์ฝ๊ฒ
- โข ๋ฐ์ํ ๋์์ธ ํ์ (๋ชจ๋ฐ์ผ ์ฐ์ )
- โข Laravel์ ๊ธฐ๋ณธ ํด๋ ๊ตฌ์กฐ ์ค์
- โข ์ธ๋ถ ํจํค์ง ์ต์ํ (Laravel ๊ธฐ๋ณธ ๊ธฐ๋ฅ ํ์ฉ)
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir game-item-marketplace-laravel && cd game-item-marketplace-laravel
์ด ํด๋์์ ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค.
Laravel 13.x ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ๊ธฐ๋ณธ ์ค์ ์ ํด์ฃผ์ธ์.
์๊ตฌ์ฌํญ:
1. Laravel 13.x ์ต์ ๋ฒ์ ์ผ๋ก ํ๋ก์ ํธ ์์ฑ
2. .env ํ์ผ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ SQLite๋ก ์ค์
- DB_CONNECTION=sqlite
- DB_DATABASE ๊ฒฝ๋ก๋ฅผ database/database.sqlite๋ก ์ค์
3. database/database.sqlite ํ์ผ ์์ฑ
4. Tailwind CSS ์ค์น ๋ฐ ์ค์ (npm ๋๋ CDN)
5. ๊ธฐ๋ณธ ๋ ์ด์์ ํ์ผ ์์ฑ (resources/views/layouts/app.blade.php)
- Tailwind CSS ํฌํจ
- ๋ค๋น๊ฒ์ด์
๋ฐ (๋ก๊ณ , ํ, ์์ดํ
๋ฑ๋ก ๋งํฌ)
- ํธํฐ
- @yield('content') ์น์
6. ์ฐ์ปด ํ์ด์ง๋ฅผ ๊ฐ๋จํ ๋๋ฉ ํ์ด์ง๋ก ์์
- "๊ฒ์ ์์ดํ
๊ฑฐ๋ ์ฅํฐ" ํ์ดํ
- "์ค๊ณ ๊ฒ์ ์์ดํ
์ ์ฌ๊ณ ํ์๋ณด์ธ์" ์๋ธํ์ดํ
- "์์ดํ
๋๋ฌ๋ณด๊ธฐ" ๋ฒํผ
๋ชจ๋ ์ค์ ์ด ์๋ฃ๋๋ฉด php artisan serve๋ก ์๋ฒ๋ฅผ ์คํํ๊ณ http://localhost:8000์์ ํ์ธํ ์ ์์ด์ผ ํฉ๋๋ค.
๊ธฐ๋ ๊ฒฐ๊ณผ: Laravel ํ๋ก์ ํธ๊ฐ ์์ฑ๋๊ณ , SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์ค์ ๋๋ฉฐ, Tailwind CSS๊ฐ ์ ์ฉ๋ ๊ธฐ๋ณธ ๋ ์ด์์๊ณผ ๋๋ฉ ํ์ด์ง๊ฐ ์์ฑ๋ฉ๋๋ค. ๋ธ๋ผ์ฐ์ ์์ ๊น๋ํ ๋ค๋น๊ฒ์ด์ ๋ฐ์ ๋ฉ์ธ ํ์ดํ์ด ๋ณด์ ๋๋ค.
๊ฒ์ ์์ดํ ์ ์ ์ฅํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ ๋ชจ๋ธ์ ์์ฑํด์ฃผ์ธ์. ์๊ตฌ์ฌํญ: 1. Item ๋ชจ๋ธ ์์ฑ (php artisan make:model Item -m) 2. ๋ง์ด๊ทธ๋ ์ด์ ํ์ผ์ ๋ค์ ์ปฌ๋ผ ์ถ๊ฐ: - name (string, ์์ดํ ๋ช ) - game_title (string, ๊ฒ์ ์ด๋ฆ) - price (integer, ๊ฐ๊ฒฉ) - description (text, ์ค๋ช ) - condition (enum: 'new', 'used', ๊ธฐ๋ณธ๊ฐ 'used', ์ํ) - status (enum: 'available', 'sold', ๊ธฐ๋ณธ๊ฐ 'available', ํ๋งค ์ํ) - seller_contact (string, nullable, ํ๋งค์ ์ฐ๋ฝ์ฒ) - timestamps (created_at, updated_at) 3. ๋ง์ด๊ทธ๋ ์ด์ ์คํ (php artisan migrate) 4. Item ๋ชจ๋ธ์ $fillable ์์ฑ ์ค์ (๋๋ ํ ๋น ๊ฐ๋ฅํ ํ๋) 5. ๋๋ฏธ ๋ฐ์ดํฐ 5๊ฐ ์ ๋ ์์ฑํ๋ ์๋ ๋ง๋ค๊ธฐ (ItemSeeder) - ๋ค์ํ ๊ฒ์ ์์ดํ ์์ (์: "๋ฆฌ๊ทธ ์ค๋ธ ๋ ์ ๋ ์คํจ", "ํผํ ์ฝ์ธ", "๋ก๋ธ๋ก์ค ์์ดํ " ๋ฑ) - php artisan db:seed --class=ItemSeeder๋ก ์คํ ์๋ฃ ํ php artisan tinker๋ก Item::all()์ ์คํํด์ ๋ฐ์ดํฐ๊ฐ ์ ๋ค์ด๊ฐ๋์ง ํ์ธํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: items ํ ์ด๋ธ์ด ์์ฑ๋๊ณ , Item ๋ชจ๋ธ์ด ์ค๋น๋๋ฉฐ, ๋๋ฏธ ๋ฐ์ดํฐ 5๊ฐ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฝ์ ๋ฉ๋๋ค. Tinker์์ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
์์ดํ
๋ชฉ๋ก ํ์ด์ง์ ์์ธ ํ์ด์ง๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์.
์๊ตฌ์ฌํญ:
1. ItemController ์์ฑ (php artisan make:controller ItemController)
2. ๋ผ์ฐํธ ์ค์ (web.php):
- GET /items -> index (๋ชฉ๋ก)
- GET /items/{id} -> show (์์ธ)
3. ItemController์ index ๋ฉ์๋:
- ๋ชจ๋ ์์ดํ
์ ๊ฐ์ ธ์์ resources/views/items/index.blade.php๋ก ์ ๋ฌ
4. index.blade.php ์์ฑ:
- ๋ ์ด์์ ์์ (@extends('layouts.app'))
- ๊ทธ๋ฆฌ๋ ๋ ์ด์์์ผ๋ก ์์ดํ
์นด๋ ํ์ (3์ด, ๋ฐ์ํ)
- ๊ฐ ์นด๋์ ์์ดํ
๋ช
, ๊ฒ์ ์ด๋ฆ, ๊ฐ๊ฒฉ, ์ํ ๋ฑ์ง ํ์
- ํ๋งค์ค/ํ๋งค์๋ฃ ๋ฑ์ง ์์ ๊ตฌ๋ถ (์ด๋ก/ํ์)
- ์นด๋ ํด๋ฆญ ์ ์์ธ ํ์ด์ง๋ก ์ด๋
5. ItemController์ show ๋ฉ์๋:
- ํน์ ์์ดํ
์ ๋ณด๋ฅผ ๊ฐ์ ธ์์ resources/views/items/show.blade.php๋ก ์ ๋ฌ
6. show.blade.php ์์ฑ:
- ์์ดํ
์ ๋ชจ๋ ์ ๋ณด ํ์ (์ด๋ฆ, ๊ฒ์, ๊ฐ๊ฒฉ, ์ค๋ช
, ์ํ, ํ๋งค์ ์ฐ๋ฝ์ฒ)
- ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ
- ํ๋งค ์ํ์ ๋ฐ๋ผ "๊ตฌ๋งค ๋ฌธ์ํ๊ธฐ" ๋๋ "ํ๋งค ์๋ฃ" ๋ฒํผ ํ์
Tailwind CSS๋ก ๊น๋ํ๊ฒ ์คํ์ผ๋งํ๊ณ , ์นด๋์ ํธ๋ฒ ํจ๊ณผ๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: /items ๊ฒฝ๋ก์์ ์์ดํ ๋ชฉ๋ก์ด ๊ทธ๋ฆฌ๋ ํํ๋ก ๋ณด์ด๊ณ , ๊ฐ ์นด๋๋ฅผ ํด๋ฆญํ๋ฉด ์์ธ ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค. ์์ธ ํ์ด์ง์์๋ ์์ดํ ์ ๋ชจ๋ ์ ๋ณด๊ฐ ๋ณด๊ธฐ ์ข๊ฒ ํ์๋ฉ๋๋ค.
์์ดํ
๋ฑ๋ก ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ฃผ์ธ์.
์๊ตฌ์ฌํญ:
1. ๋ผ์ฐํธ ์ถ๊ฐ (web.php):
- GET /items/create -> create (๋ฑ๋ก ํผ)
- POST /items -> store (๋ฑ๋ก ์ฒ๋ฆฌ)
2. ItemController์ create ๋ฉ์๋:
- resources/views/items/create.blade.php๋ก ์ด๋
3. create.blade.php ์์ฑ:
- ๋ ์ด์์ ์์
- ์์ดํ
๋ฑ๋ก ํผ (name, game_title, price, description, condition, seller_contact)
- ๊ฐ ํ๋์ ์ ์ ํ input ํ์
์ฌ์ฉ (text, number, textarea, select)
- condition์ ๋๋กญ๋ค์ด (์๊ฒ/์ค๊ณ )
- ํ์ ์
๋ ฅ ํ๋ ํ์ (*)
- "๋ฑ๋กํ๊ธฐ" ๋ฒํผ
4. ItemController์ store ๋ฉ์๋:
- ํผ ๋ฐ์ดํฐ ์ ํจ์ฑ ๊ฒ์ฌ (Validation)
- name: required, max:100
- game_title: required, max:100
- price: required, integer, min:0
- description: required
- condition: required, in:new,used
- seller_contact: nullable, max:50
- ์ ํจ์ฑ ๊ฒ์ฌ ํต๊ณผ ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ
- ๋ฑ๋ก ํ ์์ดํ
๋ชฉ๋ก ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ + ์ฑ๊ณต ๋ฉ์์ง
5. ๋ ์ด์์์ ์ฑ๊ณต ๋ฉ์์ง ํ์ ์์ญ ์ถ๊ฐ (session ํ๋์ ๋ฉ์์ง)
ํผ์ Tailwind CSS๋ก ๊น๋ํ๊ฒ ๋์์ธํ๊ณ , ์ ํจ์ฑ ๊ฒ์ฌ ์๋ฌ ๋ฉ์์ง๋ ๋นจ๊ฐ์์ผ๋ก ํ์ํด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: /items/create ๊ฒฝ๋ก์์ ์์ดํ ๋ฑ๋ก ํผ์ด ๋ณด์ด๊ณ , ํผ์ ์์ฑํ์ฌ ์ ์ถํ๋ฉด ์ ์์ดํ ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ๋ฉ๋๋ค. ๋ชฉ๋ก ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ๋๋ฉฐ "์์ดํ ์ด ๋ฑ๋ก๋์์ต๋๋ค!" ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค. ์ ํจ์ฑ ๊ฒ์ฌ ์คํจ ์ ์๋ฌ ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
๊ฒ์ ๋ฐ ํํฐ ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ฃผ์ธ์.
์๊ตฌ์ฌํญ:
1. index.blade.php ์๋จ์ ๊ฒ์ ๋ฐ ํํฐ UI ์ถ๊ฐ:
- ๊ฒ์์ฐฝ (์์ดํ
๋ช
์ผ๋ก ๊ฒ์)
- ๊ฒ์ ์ ํ ๋๋กญ๋ค์ด (์ ์ฒด/๋ฑ๋ก๋ ๊ฒ์ ๋ชฉ๋ก)
- ๊ฐ๊ฒฉ๋ ์ ํ ๋๋กญ๋ค์ด (์ ์ฒด/0-10,000์/10,000-50,000์/50,000์ ์ด์)
- "๊ฒ์" ๋ฒํผ
2. ItemController์ index ๋ฉ์๋ ์์ :
- GET ํ๋ผ๋ฏธํฐ๋ก search, game, price_range ๋ฐ๊ธฐ
- ๊ฒ์์ด๊ฐ ์์ผ๋ฉด ์์ดํ
๋ช
์ ํด๋น ๋จ์ด๊ฐ ํฌํจ๋ ์์ดํ
๋ง ํํฐ๋ง
- ๊ฒ์์ด ์ ํ๋๋ฉด ํด๋น ๊ฒ์ ์์ดํ
๋ง ํํฐ๋ง
- ๊ฐ๊ฒฉ๋๊ฐ ์ ํ๋๋ฉด ํด๋น ๋ฒ์์ ์์ดํ
๋ง ํํฐ๋ง
- ํํฐ๋ง๋ ๊ฒฐ๊ณผ๋ฅผ ๋ทฐ๋ก ์ ๋ฌ
3. ๊ฒ์ ๋ชฉ๋ก ๋์ ์์ฑ:
- Item::distinct()->pluck('game_title')๋ก ๋ฑ๋ก๋ ๊ฒ์ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
- ๋๋กญ๋ค์ด์ ๋์ ์ผ๋ก ํ์
4. ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ ๋ "๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ต๋๋ค" ๋ฉ์์ง ํ์
5. ํ์ฌ ์ ์ฉ๋ ํํฐ ํ์ (์: "๋ฆฌ๊ทธ ์ค๋ธ ๋ ์ ๋ ์์ดํ
3๊ฐ")
๊ฒ์/ํํฐ UI๋ ์๋จ์ ๊ณ ์ ๋๋๋ก ํ๊ณ , ๋ชจ๋ฐ์ผ์์๋ ์ฌ์ฉํ๊ธฐ ํธํ๊ฒ ๋ฐ์ํ์ผ๋ก ๋ง๋ค์ด์ฃผ์ธ์.
๊ธฐ๋ ๊ฒฐ๊ณผ: ์์ดํ ๋ชฉ๋ก ํ์ด์ง ์๋จ์ ๊ฒ์์ฐฝ๊ณผ ํํฐ๊ฐ ํ์๋๊ณ , ๊ฒ์์ด๋ ํํฐ๋ฅผ ์ ์ฉํ๋ฉด ํด๋น ์กฐ๊ฑด์ ๋ง๋ ์์ดํ ๋ง ํ์๋ฉ๋๋ค. ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ์๋ด ๋ฉ์์ง๊ฐ ๋ํ๋ฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!