온라인 클래스 수강평 플랫폼 - 별점 & 상세 리뷰 작성 - 바이브코딩 레시피
중급 PHP + JavaScript Laravel + React + Inertia.js AI: Claude

온라인 클래스 수강평 플랫폼 - 별점 & 상세 리뷰 작성

리포지토리명 online-course-review-platform
조회수 73 0건 제출

문제 설명

프로젝트 개요

온라인 강의 플랫폼에서 수강생들이 수강한 클래스에 대한 솔직한 리뷰를 남기고 다른 사람들의 후기를 확인할 수 있는 리뷰 플랫폼을 만듭니다. 실제 수강생들의 생생한 경험을 공유하여 예비 수강생들이 현명한 선택을 할 수 있도록 돕는 서비스입니다.

필수 기능

  • 클래스 목록 페이지: 카테고리별(프로그래밍, 디자인, 마케팅, 언어 등) 클래스 목록 표시
  • 클래스 상세 페이지: 클래스 정보, 평균 별점, 리뷰 목록 표시
  • 리뷰 작성 기능: 별점(1~5점), 제목, 상세 내용, 장단점 입력
  • 리뷰 정렬: 최신순, 별점 높은순, 별점 낮은순, 도움이 된 순
  • 리뷰 도움됨 기능: 다른 사용자가 리뷰에 '도움이 됐어요' 버튼 클릭
  • 필터링: 별점별 필터(5점만, 4점 이상 등), 카테고리 필터
  • 검색 기능: 클래스명, 강사명으로 검색
  • 반응형 디자인: 모바일/태블릿/데스크톱 대응

보너스 기능

  • 리뷰 수정/삭제 기능
  • 강사 프로필 페이지 (해당 강사의 모든 클래스 & 평균 평점)
  • 내가 작성한 리뷰 모아보기 (마이페이지)
  • 리뷰 신고 기능
  • 클래스 찜하기 기능
  • 최근 본 클래스 히스토리

기술 스택

  • 백엔드: Laravel 13.x (Eloquent ORM, Migration, Seeder)
  • 프론트엔드: React 19 + Inertia.js
  • 스타일링: Tailwind CSS
  • 데이터베이스: SQLite (개발용) 또는 MySQL
  • 인증: Laravel Breeze (선택사항)

이 프로젝트를 통해 Laravel의 관계형 데이터베이스 설계(클래스, 리뷰, 카테고리 관계), Inertia.js를 통한 SPA 경험, React의 상태 관리와 컴포넌트 분리, 그리고 실제 서비스 수준의 필터링/정렬/검색 기능 구현을 학습할 수 있습니다.

제약 조건

  • • Laravel 13.x + Inertia.js + React 19 모노리스 풀스택 구조 사용
  • • 별도 REST API 라우트 없이 Inertia::render()로 데이터 전달
  • • Laravel Breeze (React + Inertia) starter kit으로 프로젝트 초기화
  • • Tailwind CSS로 스타일링 (CDN 또는 npm 설치)
  • • 데이터베이스는 SQLite 또는 MySQL 사용
  • • 리뷰 작성 시 별점은 1~5점 범위로 제한
  • • 평균 별점은 소수점 첫째 자리까지 표시
  • • 페이지네이션은 Laravel의 paginate() 메서드 활용
  • • Inertia.js의 Link 컴포넌트로 페이지 이동 (새로고침 없이)
  • • 폼 검증은 Laravel의 FormRequest 또는 validate() 메서드 사용

프롬프트 레시피

아래 프롬프트를 순서대로 AI에게 보내면 됩니다. 복사 버튼을 눌러 바로 사용하세요.

1
Step 1
mkdir online-course-review-platform && cd online-course-review-platform

이 폴더에서 Laravel + Inertia.js + React 프로젝트를 시작합니다.

# Laravel Breeze (React + Inertia) 프로젝트 생성

다음 명령어로 Laravel 13 프로젝트를 생성하고 Breeze (React + Inertia) starter kit을 설치해주세요:

```bash
composer create-project laravel/laravel .
composer require laravel/breeze --dev
php artisan breeze:install react
npm install
npm run dev
```

설치 후 `.env` 파일을 열어 데이터베이스 설정을 SQLite로 변경해주세요:

```env
DB_CONNECTION=sqlite
# DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD 주석 처리
```

그리고 `database/database.sqlite` 파일을 생성해주세요:

```bash
touch database/database.sqlite
```

마이그레이션 실행:

```bash
php artisan migrate
```

서버 실행 확인:

```bash
php artisan serve
```

브라우저에서 http://localhost:8000 접속 시 Laravel 초기 화면이 보이면 성공입니다.

기대 결과: Laravel 13 + Breeze + React + Inertia.js 프로젝트가 생성되고, 기본 인증 화면(로그인/회원가입)이 동작하는 것을 확인할 수 있습니다. npm run dev로 Vite 개발 서버가 실행되고, Tailwind CSS가 적용된 UI를 볼 수 있습니다.

2
Step 2
# 데이터베이스 설계 및 마이그레이션 생성

온라인 클래스 리뷰 플랫폼에 필요한 테이블들을 설계하고 마이그레이션을 생성해주세요:

## 필요한 테이블:

1. **categories** (카테고리)
   - id (PK)
   - name (카테고리명, 예: 프로그래밍, 디자인, 마케팅)
   - slug (URL용)
   - timestamps

2. **courses** (클래스)
   - id (PK)
   - category_id (FK)
   - title (클래스명)
   - instructor (강사명)
   - description (클래스 설명)
   - thumbnail_url (썸네일 이미지 URL, nullable)
   - price (가격)
   - duration_hours (수강 시간, 예: 10시간)
   - timestamps

3. **reviews** (리뷰)
   - id (PK)
   - course_id (FK)
   - user_id (FK)
   - rating (별점, 1~5)
   - title (리뷰 제목)
   - content (상세 내용)
   - pros (장점, nullable)
   - cons (단점, nullable)
   - helpful_count (도움됨 수, default 0)
   - timestamps

4. **review_helpfuls** (리뷰 도움됨 기록)
   - id (PK)
   - review_id (FK)
   - user_id (FK)
   - timestamps
   - unique(review_id, user_id) - 한 사용자가 같은 리뷰에 중복 도움됨 방지

다음 명령어로 마이그레이션 파일을 생성하고 작성해주세요:

```bash
php artisan make:migration create_categories_table
php artisan make:migration create_courses_table
php artisan make:migration create_reviews_table
php artisan make:migration create_review_helpfuls_table
```

각 마이그레이션 파일에 위 스키마를 반영하여 작성해주세요. 외래 키 제약 조건과 인덱스도 추가해주세요.

마이그레이션 실행:

```bash
php artisan migrate
```

기대 결과: 4개의 마이그레이션 파일이 생성되고, 각 테이블의 컬럼과 관계가 정의됩니다. php artisan migrate 실행 시 데이터베이스에 테이블이 생성되며, 외래 키 제약 조건이 올바르게 설정됩니다.

3
Step 3
# Eloquent 모델 생성 및 관계 설정

각 테이블에 대응하는 Eloquent 모델을 생성하고 관계를 설정해주세요:

```bash
php artisan make:model Category
php artisan make:model Course
php artisan make:model Review
php artisan make:model ReviewHelpful
```

## 모델별 관계 설정:

### Category 모델:
- `courses()`: hasMany 관계 (한 카테고리는 여러 클래스를 가짐)

### Course 모델:
- `category()`: belongsTo 관계
- `reviews()`: hasMany 관계
- `averageRating()`: 평균 별점을 계산하는 accessor 또는 메서드 추가
- `reviewCount()`: 리뷰 개수를 반환하는 메서드

### Review 모델:
- `course()`: belongsTo 관계
- `user()`: belongsTo 관계
- `helpfuls()`: hasMany 관계 (ReviewHelpful)
- `isHelpfulBy($userId)`: 특정 사용자가 도움됨을 눌렀는지 확인하는 메서드

### ReviewHelpful 모델:
- `review()`: belongsTo 관계
- `user()`: belongsTo 관계

각 모델 파일에 관계 메서드를 정의하고, `$fillable` 속성도 설정해주세요.

Course 모델에 평균 별점을 계산하는 메서드 예시:

```php
public function averageRating()
{
    return $this->reviews()->avg('rating') ?? 0;
}
```

기대 결과: 4개의 Eloquent 모델이 생성되고, 각 모델 간의 관계(hasMany, belongsTo)가 올바르게 정의됩니다. Course 모델에서 평균 별점과 리뷰 개수를 조회할 수 있는 메서드가 추가됩니다.

4
Step 4
# 시더(Seeder) 생성 및 더미 데이터 삽입

개발 및 테스트를 위해 더미 데이터를 생성하는 시더를 작성해주세요:

```bash
php artisan make:seeder CategorySeeder
php artisan make:seeder CourseSeeder
php artisan make:seeder ReviewSeeder
```

## 시더 내용:

### CategorySeeder:
- 프로그래밍, 디자인, 마케팅, 비즈니스, 언어, 음악, 요리 등 7~10개 카테고리 생성

### CourseSeeder:
- 각 카테고리마다 3~5개씩 클래스 생성 (총 30~50개)
- 클래스명, 강사명, 설명, 가격, 수강 시간 등 현실적인 데이터로 작성
- 썸네일은 placeholder 이미지 URL 사용 (예: https://via.placeholder.com/400x300)

### ReviewSeeder:
- 각 클래스마다 3~10개의 리뷰 생성
- 별점은 1~5점 랜덤
- 리뷰 제목, 내용, 장점, 단점을 현실적으로 작성
- user_id는 1~10 범위로 랜덤 (실제 사용자는 없어도 됨, 테스트용)
- helpful_count는 0~20 랜덤

`DatabaseSeeder.php`에서 위 시더들을 호출하도록 설정해주세요:

```php
public function run()
{
    $this->call([
        CategorySeeder::class,
        CourseSeeder::class,
        ReviewSeeder::class,
    ]);
}
```

시더 실행:

```bash
php artisan db:seed
```

기대 결과: 데이터베이스에 카테고리, 클래스, 리뷰 더미 데이터가 삽입됩니다. 각 클래스는 카테고리에 속하고, 각 클래스는 여러 리뷰를 가지며, 리뷰는 별점과 상세 내용을 포함합니다.

5
Step 5
# 클래스 목록 페이지 구현 (컨트롤러 + React 컴포넌트)

## 1. CourseController 생성:

```bash
php artisan make:controller CourseController
```

`CourseController.php`에 `index` 메서드를 작성해주세요:

- 모든 클래스를 카테고리와 함께 조회 (eager loading)
- 각 클래스의 평균 별점과 리뷰 개수를 계산하여 전달
- 카테고리 필터, 검색어, 정렬 옵션을 쿼리 파라미터로 받아 처리
- 페이지네이션 적용 (한 페이지당 12개)
- Inertia::render('Courses/Index', [...])로 React 컴포넌트에 데이터 전달

## 2. 라우트 설정:

`routes/web.php`에 다음 라우트 추가:

```php
Route::get('/courses', [CourseController::class, 'index'])->name('courses.index');
```

## 3. React 컴포넌트 생성:

`resources/js/Pages/Courses/Index.jsx` 파일을 생성하고 다음 기능을 구현해주세요:

- props로 courses (페이지네이션 객체), categories, filters (현재 필터 상태) 받기
- 상단에 카테고리 필터 버튼 (전체, 프로그래밍, 디자인 등)
- 검색 입력창 (클래스명/강사명 검색)
- 정렬 드롭다운 (최신순, 평점 높은순, 리뷰 많은순)
- 클래스 카드 그리드 (썸네일, 제목, 강사명, 평균 별점, 리뷰 수, 가격 표시)
- 각 카드 클릭 시 클래스 상세 페이지로 이동 (Inertia Link 사용)
- 페이지네이션 컴포넌트

Tailwind CSS로 반응형 그리드 레이아웃 (모바일 1열, 태블릿 2열, 데스크톱 3~4열) 구성해주세요.

필터/검색/정렬 변경 시 Inertia.get()을 사용하여 쿼리 파라미터를 업데이트하고 페이지를 다시 로드해주세요.

기대 결과: 클래스 목록 페이지가 구현되어 http://localhost:8000/courses 접속 시 모든 클래스가 카드 형태로 표시됩니다. 카테고리 필터, 검색, 정렬 기능이 동작하며, 페이지네이션으로 다음 페이지를 볼 수 있습니다. 각 클래스 카드에는 평균 별점과 리뷰 수가 표시됩니다.

6
Step 6
# 클래스 상세 페이지 구현 (리뷰 목록 포함)

## 1. CourseController에 show 메서드 추가:

`CourseController.php`에 `show` 메서드를 작성해주세요:

- URL 파라미터로 클래스 ID를 받아 해당 클래스 조회
- 클래스 정보와 함께 카테고리, 평균 별점, 리뷰 개수 조회
- 해당 클래스의 리뷰 목록을 조회 (작성자 정보 포함, eager loading)
- 리뷰 정렬 옵션 (최신순, 별점 높은순, 별점 낮은순, 도움됨 많은순) 처리
- 별점 필터 (5점만, 4점 이상, 3점 이상 등) 처리
- 리뷰 페이지네이션 (한 페이지당 10개)
- Inertia::render('Courses/Show', [...])로 데이터 전달

## 2. 라우트 추가:

```php
Route::get('/courses/{course}', [CourseController::class, 'show'])->name('courses.show');
```

## 3. React 컴포넌트 생성:

`resources/js/Pages/Courses/Show.jsx` 파일을 생성하고 다음 기능을 구현해주세요:

- 상단에 클래스 정보 섹션 (썸네일, 제목, 강사명, 카테고리, 가격, 수강 시간, 설명)
- 평균 별점 및 리뷰 개수 표시 (별 아이콘으로 시각화)
- 별점 분포 그래프 (5점, 4점, 3점, 2점, 1점 각각 몇 개인지 막대 그래프)
- 리뷰 작성 버튼 (로그인 사용자만, 클릭 시 리뷰 작성 페이지로 이동)
- 리뷰 정렬 드롭다운 (최신순, 별점 높은순, 별점 낮은순, 도움됨 순)
- 별점 필터 버튼 (전체, 5점, 4점 이상, 3점 이상, 2점 이하)
- 리뷰 목록 (각 리뷰: 작성자명, 별점, 제목, 내용, 장점/단점, 작성일, 도움됨 수, 도움됨 버튼)
- 리뷰 페이지네이션

Tailwind CSS로 깔끔한 레이아웃 구성해주세요. 별점은 별 아이콘(★)으로 표시하고, 도움됨 버튼은 👍 아이콘 사용.

정렬/필터 변경 시 Inertia.get()으로 쿼리 파라미터 업데이트.

기대 결과: 클래스 상세 페이지가 구현되어 특정 클래스의 모든 정보와 리뷰 목록이 표시됩니다. 평균 별점과 별점 분포가 시각적으로 표시되고, 리뷰 정렬/필터 기능이 동작합니다. 리뷰 작성 버튼이 보입니다.

7
Step 7
# 리뷰 작성 기능 구현

## 1. ReviewController 생성:

```bash
php artisan make:controller ReviewController
```

`ReviewController.php`에 다음 메서드를 작성해주세요:

### create 메서드:
- URL 파라미터로 클래스 ID를 받아 해당 클래스 정보 조회
- Inertia::render('Reviews/Create', [...])로 리뷰 작성 폼 페이지 전달

### store 메서드:
- 폼 데이터 검증 (rating: 1~5 필수, title: 필수, content: 필수, pros/cons: 선택)
- 현재 로그인한 사용자의 user_id와 함께 리뷰 저장
- 저장 후 해당 클래스 상세 페이지로 리다이렉트
- 성공 메시지 플래시

## 2. 라우트 추가:

```php
Route::middleware('auth')->group(function () {
    Route::get('/courses/{course}/reviews/create', [ReviewController::class, 'create'])->name('reviews.create');
    Route::post('/courses/{course}/reviews', [ReviewController::class, 'store'])->name('reviews.store');
});
```

## 3. React 컴포넌트 생성:

`resources/js/Pages/Reviews/Create.jsx` 파일을 생성하고 다음 기능을 구현해주세요:

- 상단에 리뷰 작성 중인 클래스 정보 표시 (제목, 강사명)
- 별점 선택 UI (1~5점, 클릭 가능한 별 아이콘)
- 리뷰 제목 입력창 (텍스트 필드)
- 상세 내용 입력창 (textarea, 최소 50자)
- 장점 입력창 (textarea, 선택사항)
- 단점 입력창 (textarea, 선택사항)
- 제출 버튼
- 취소 버튼 (클래스 상세 페이지로 돌아가기)

React의 useState로 폼 상태 관리하고, Inertia의 useForm 훅 사용하여 폼 제출 처리.

별점 선택 UI는 interactive하게 구현 (마우스 오버 시 미리보기, 클릭 시 확정).

Tailwind CSS로 깔끔한 폼 레이아웃 구성.

기대 결과: 리뷰 작성 페이지가 구현되어 로그인한 사용자가 클래스에 대한 리뷰를 작성할 수 있습니다. 별점 선택 UI가 interactive하게 동작하고, 폼 검증이 올바르게 작동하며, 리뷰 저장 후 클래스 상세 페이지로 리다이렉트됩니다.

8
Step 8
# 리뷰 도움됨 기능 구현

## 1. ReviewController에 toggleHelpful 메서드 추가:

`ReviewController.php`에 `toggleHelpful` 메서드를 작성해주세요:

- URL 파라미터로 리뷰 ID를 받음
- 현재 로그인한 사용자가 해당 리뷰에 이미 도움됨을 눌렀는지 확인
- 눌렀다면 ReviewHelpful 레코드 삭제 & Review의 helpful_count 감소
- 누르지 않았다면 ReviewHelpful 레코드 생성 & Review의 helpful_count 증가
- JSON 응답으로 업데이트된 helpful_count와 현재 사용자의 도움됨 상태 반환

## 2. 라우트 추가:

```php
Route::middleware('auth')->group(function () {
    Route::post('/reviews/{review}/helpful', [ReviewController::class, 'toggleHelpful'])->name('reviews.helpful');
});
```

## 3. Courses/Show.jsx 컴포넌트 수정:

리뷰 목록의 각 리뷰에 도움됨 버튼 추가:

- 버튼 텍스트: "👍 도움이 됐어요 (숫자)"
- 현재 사용자가 이미 눌렀다면 버튼 스타일 변경 (활성화 상태)
- 버튼 클릭 시 Inertia.post()로 toggleHelpful 라우트 호출
- 응답 받아서 해당 리뷰의 helpful_count와 활성화 상태 업데이트
- 로그인하지 않은 사용자는 버튼 클릭 시 로그인 페이지로 리다이렉트

React의 useState로 각 리뷰의 도움됨 상태를 관리하고, 버튼 클릭 시 낙관적 업데이트(optimistic update) 적용.

Tailwind CSS로 버튼 스타일링 (기본 상태와 활성화 상태 구분).

기대 결과: 클래스 상세 페이지의 각 리뷰에 도움됨 버튼이 추가되고, 버튼 클릭 시 도움됨 수가 증가/감소합니다. 현재 사용자가 이미 눌렀는지 여부가 시각적으로 표시되며, 로그인하지 않은 사용자는 버튼 클릭 시 로그인 페이지로 이동합니다.

9
Step 9
# 메인 페이지 및 네비게이션 개선

## 1. HomeController 생성 및 메인 페이지 구현:

```bash
php artisan make:controller HomeController
```

`HomeController.php`에 `index` 메서드 작성:

- 평균 별점이 높은 인기 클래스 6개 조회
- 최근 등록된 신규 클래스 6개 조회
- 리뷰가 많은 클래스 6개 조회
- Inertia::render('Home', [...])로 데이터 전달

라우트 설정:

```php
Route::get('/', [HomeController::class, 'index'])->name('home');
```

## 2. React 컴포넌트 생성:

`resources/js/Pages/Home.jsx` 파일을 생성하고 다음 기능을 구현해주세요:

- 히어로 섹션 (큰 제목, 설명, "클래스 둘러보기" CTA 버튼)
- "인기 클래스" 섹션 (6개 카드 그리드)
- "신규 클래스" 섹션 (6개 카드 그리드)
- "리뷰가 많은 클래스" 섹션 (6개 카드 그리드)
- 각 섹션마다 "더보기" 버튼 (클래스 목록 페이지로 이동)

Tailwind CSS로 매력적인 랜딩 페이지 디자인 구성.

## 3. 공통 레이아웃 네비게이션 개선:

`resources/js/Layouts/AuthenticatedLayout.jsx` (또는 GuestLayout.jsx)를 수정하여 네비게이션 바 추가:

- 로고 (홈으로 링크)
- "클래스 둘러보기" 메뉴 (courses.index로 링크)
- 검색창 (클래스명 검색, 엔터 시 courses.index로 이동)
- 로그인/회원가입 버튼 (로그인 전) 또는 프로필 드롭다운 (로그인 후)

Inertia의 Link 컴포넌트로 페이지 전환.

Tailwind CSS로 반응형 네비게이션 바 구성 (모바일에서는 햄버거 메뉴).

기대 결과: 메인 페이지가 구현되어 인기 클래스, 신규 클래스, 리뷰 많은 클래스가 섹션별로 표시됩니다. 네비게이션 바가 모든 페이지에 공통으로 표시되며, 로고 클릭 시 홈으로, 클래스 둘러보기 클릭 시 목록 페이지로 이동합니다. 검색 기능이 네비게이션에 통합됩니다.

10
Step 10
# 최종 마무리 및 UX 개선

## 1. 로딩 상태 및 에러 처리:

- Inertia의 progress bar 활성화 (nprogress 라이브러리 설치 및 설정)
- 각 페이지에서 데이터 로딩 중일 때 스켈레톤 UI 표시
- 폼 제출 중일 때 버튼 비활성화 및 로딩 스피너 표시
- 에러 메시지 표시 (폼 검증 실패 시 각 필드 아래에 에러 메시지)

## 2. 반응형 디자인 최종 점검:

- 모든 페이지가 모바일, 태블릿, 데스크톱에서 올바르게 표시되는지 확인
- 네비게이션 바 모바일 햔버거 메뉴 동작 확인
- 클래스 카드 그리드 반응형 레이아웃 확인
- 리뷰 작성 폼 모바일에서 사용성 확인

## 3. 접근성 개선:

- 별점 아이콘에 aria-label 추가
- 버튼에 명확한 텍스트 또는 aria-label 추가
- 폼 필드에 label 연결
- 키보드 내비게이션 지원 확인

## 4. 성능 최적화:

- Eloquent 쿼리에서 N+1 문제 해결 (eager loading 확인)
- 불필요한 리렌더링 방지 (React.memo, useMemo 활용)
- 이미지 lazy loading 적용

## 5. README.md 작성:

프로젝트 루트에 `README.md` 파일을 작성하여 다음 내용 포함:

- 프로젝트 소개
- 주요 기능 목록
- 기술 스택
- 설치 및 실행 방법
- 스크린샷 (선택사항)
- 라이선스

## 6. 최종 테스트:

- 회원가입 → 로그인 → 클래스 둘러보기 → 클래스 상세 → 리뷰 작성 → 도움됨 버튼 클릭 전체 플로우 테스트
- 필터/정렬/검색 기능 동작 확인
- 페이지네이션 동작 확인
- 로그아웃 후 비로그인 상태에서의 동작 확인 (리뷰 작성 버튼 클릭 시 로그인 페이지로 이동)

모든 기능이 정상 동작하면 프로젝트 완성입니다! 🎉

기대 결과: 모든 페이지가 반응형으로 동작하고, 로딩 상태와 에러 처리가 올바르게 구현되어 사용자 경험이 개선됩니다. 접근성과 성능이 최적화되고, README.md가 작성되어 프로젝트를 다른 사람에게 공유할 수 있습니다. 전체 플로우가 원활하게 동작하여 실제 서비스 수준의 온라인 클래스 리뷰 플랫폼이 완성됩니다.

제출된 작품 (0)

로그인 후 제출

아직 제출된 작품이 없습니다. 첫 번째 도전자가 되어보세요!

댓글 (0)

로그인 후 댓글을 남길 수 있습니다.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!