스튜디오 타임슬롯 예약 시스템 - 음악/사진 스튜디오 시간 예약 - 바이브코딩 레시피
중급 PHP + JavaScript Laravel + React + Inertia.js AI: Claude

스튜디오 타임슬롯 예약 시스템 - 음악/사진 스튜디오 시간 예약

리포지토리명 studio-timeslot-booking-inertia
조회수 77 0건 제출

문제 설명

🎵 스튜디오 타임슬롯 예약 시스템

음악 스튜디오나 사진 촬영 스튜디오를 시간 단위로 예약할 수 있는 풀스택 예약 플랫폼입니다. Laravel 13.x + Inertia.js + React 19 모노리스 아키텍처로 구현하며, 실시간 예약 현황을 캘린더 뷰로 확인하고 타임슬롯별 예약 가능 여부를 시각적으로 표시합니다.

필수 기능

  • 스튜디오 관리: 여러 스튜디오룸(A룸, B룸 등) 등록 및 관리
  • 타임슬롯 시스템: 30분 또는 1시간 단위로 예약 가능한 시간대 설정
  • 캘린더 뷰: 주간 또는 일간 캘린더로 예약 현황 한눈에 보기
  • 예약 생성: 사용자가 원하는 스튜디오와 시간대 선택하여 예약
  • 예약 상태 관리: 예약 대기/확정/취소 상태 관리
  • 충돌 방지: 동일 시간대 중복 예약 불가 로직
  • 내 예약 목록: 사용자별 예약 내역 조회 및 취소 기능
  • 실시간 가용성 표시: 예약된 슬롯은 회색, 가능한 슬롯은 초록색으로 표시

보너스 기능

  • 예약 시 자동 이메일 알림 (Laravel Mail)
  • 예약 전날 리마인더 알림
  • 스튜디오별 가격 차등 및 결제 금액 계산
  • 관리자 대시보드로 전체 예약 통계 확인
  • 반복 예약 기능 (매주 같은 시간 자동 예약)
  • 예약 취소 정책 설정 (24시간 전까지만 취소 가능 등)

제약 조건

  • • Laravel 13.x + Inertia.js + React 19 모노리스 풀스택 구조 (별도 API 라우트 없이 Inertia::render() 사용)
  • • Laravel Breeze (React + Inertia) starter kit으로 프로젝트 초기화
  • • SQLite 데이터베이스 사용 (개발 환경 간소화)
  • • Tailwind CSS로 UI 스타일링
  • • 타임슬롯은 30분 또는 1시간 단위로 설정 (설정 가능하게)
  • • 동일 시간대 중복 예약 불가 검증 로직 필수
  • • React 컴포넌트는 Pages 폴더에 배치 (Inertia 컨벤션)
  • • Laravel의 Eloquent 관계(hasMany, belongsTo)를 활용한 DB 설계
  • • 예약 상태는 Enum 또는 상수로 관리 (pending, confirmed, cancelled)
  • • 캘린더 UI는 react-big-calendar 또는 직접 구현
  • • 날짜/시간 처리는 Carbon (Laravel) 및 date-fns (React) 활용

프롬프트 레시피

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

1
Step 1
mkdir studio-timeslot-booking-inertia && cd studio-timeslot-booking-inertia

이 폴더에서 스튜디오 타임슬롯 예약 시스템 프로젝트를 시작합니다.

Laravel 13.x + Inertia.js + React 19 기반 모노리스 풀스택 프로젝트를 생성해주세요.

1. `npx create laravel` 명령으로 Laravel 13.x 프로젝트 생성 (현재 폴더에)
2. Laravel Breeze (React + Inertia) starter kit 설치:
   - `php artisan breeze:install react`
   - `npm install && npm run dev`
3. SQLite 데이터베이스 설정:
   - `.env` 파일에서 `DB_CONNECTION=sqlite`
   - `touch database/database.sqlite`
4. 프로젝트 구조 확인:
   - `resources/js/Pages/` (React 페이지 컴포넌트)
   - `app/Http/Controllers/` (Laravel 컨트롤러)
   - `routes/web.php` (Inertia 라우트)
5. Tailwind CSS가 이미 설정되어 있는지 확인
6. 기본 인증 시스템(로그인/회원가입) 동작 확인

프로젝트가 정상적으로 생성되고 `npm run dev` 및 `php artisan serve`로 실행되면 브라우저에서 기본 화면을 확인해주세요.

기대 결과: Laravel 13.x + Breeze (React + Inertia) 프로젝트가 생성되고, 기본 인증 페이지(로그인/회원가입)가 정상 작동합니다. SQLite 데이터베이스 파일이 생성되고, Vite 개발 서버가 실행됩니다.

2
Step 2
데이터베이스 스키마를 설계하고 마이그레이션을 생성해주세요.

필요한 테이블:

1. **studios 테이블** (스튜디오룸 정보)
   - id (primary key)
   - name (스튜디오명, 예: 'A룸', 'B룸')
   - description (설명, nullable)
   - capacity (수용 인원, integer)
   - hourly_rate (시간당 가격, decimal, nullable)
   - is_active (활성화 여부, boolean, default true)
   - timestamps

2. **bookings 테이블** (예약 정보)
   - id (primary key)
   - user_id (foreign key to users)
   - studio_id (foreign key to studios)
   - booking_date (예약 날짜, date)
   - start_time (시작 시간, time)
   - end_time (종료 시간, time)
   - status (예약 상태: 'pending', 'confirmed', 'cancelled', default 'pending')
   - purpose (예약 목적, text, nullable)
   - total_price (총 가격, decimal, nullable)
   - cancelled_at (취소 시간, timestamp, nullable)
   - timestamps
   - unique index on (studio_id, booking_date, start_time) - 중복 예약 방지

마이그레이션 파일을 생성하고 `php artisan migrate` 실행까지 해주세요.

추가로 Studio와 Booking 모델도 생성하고 Eloquent 관계를 설정해주세요:
- Studio hasMany Bookings
- Booking belongsTo Studio
- Booking belongsTo User

기대 결과: studios, bookings 테이블이 생성되고, Studio 및 Booking 모델이 Eloquent 관계와 함께 생성됩니다. 데이터베이스 마이그레이션이 성공적으로 실행됩니다.

3
Step 3
시더(Seeder)를 생성하여 테스트 데이터를 추가해주세요.

1. **StudioSeeder** 생성:
   - 3개의 스튜디오룸 생성 (예: 'A룸 - 녹음실', 'B룸 - 연습실', 'C룸 - 촬영 스튜디오')
   - 각 스튜디오에 설명, 수용 인원(2~10명), 시간당 가격(20,000~50,000원) 설정

2. **BookingSeeder** 생성 (선택사항):
   - 더미 예약 데이터 5~10개 생성 (다양한 날짜와 시간대)
   - 일부는 confirmed, 일부는 pending 상태로

`DatabaseSeeder`에서 StudioSeeder를 호출하도록 설정하고 `php artisan db:seed` 실행해주세요.

추가로 `php artisan tinker`에서 Studio::all()을 실행하여 데이터가 잘 들어갔는지 확인해주세요.

기대 결과: 3개의 스튜디오룸 데이터가 데이터베이스에 삽입되고, tinker에서 조회 가능합니다. 선택적으로 더미 예약 데이터도 생성됩니다.

4
Step 4
스튜디오 목록 및 상세 페이지를 구현해주세요.

1. **StudioController 생성**:
   - `index()` 메서드: 모든 활성화된 스튜디오 목록 조회
   - `show($id)` 메서드: 특정 스튜디오 상세 정보 및 해당 스튜디오의 금주 예약 현황 조회
   - Inertia::render()로 React 컴포넌트에 데이터 전달

2. **라우트 설정** (routes/web.php):
   - `GET /studios` → StudioController@index
   - `GET /studios/{id}` → StudioController@show
   - 인증된 사용자만 접근 가능하도록 auth 미들웨어 적용

3. **React 컴포넌트 생성**:
   - `resources/js/Pages/Studios/Index.jsx`: 스튜디오 목록 페이지
     * 스튜디오 카드 형태로 표시 (이름, 설명, 수용 인원, 시간당 가격)
     * 각 카드 클릭 시 상세 페이지로 이동 (Link 컴포넌트 사용)
   - `resources/js/Pages/Studios/Show.jsx`: 스튜디오 상세 페이지
     * 스튜디오 정보 표시
     * 금주 예약 현황을 간단한 테이블 또는 리스트로 표시
     * "예약하기" 버튼 (다음 단계에서 구현)

4. Tailwind CSS로 깔끔하게 스타일링해주세요.

네비게이션 바에 "스튜디오 목록" 링크를 추가하여 접근 가능하게 해주세요.

기대 결과: 스튜디오 목록 페이지에서 모든 스튜디오를 카드 형태로 볼 수 있고, 클릭 시 상세 페이지로 이동합니다. 상세 페이지에서는 스튜디오 정보와 금주 예약 현황을 확인할 수 있습니다.

5
Step 5
예약 생성 페이지 및 로직을 구현해주세요.

1. **BookingController 생성**:
   - `create($studioId)` 메서드: 예약 폼 페이지 렌더링 (선택한 스튜디오 정보 전달)
   - `store(Request $request)` 메서드: 예약 생성 로직
     * 유효성 검증: booking_date, start_time, end_time, studio_id 필수
     * 중복 예약 체크: 동일 스튜디오, 동일 날짜, 겹치는 시간대가 있는지 확인
     * 예약 생성 시 user_id는 auth()->id()로 자동 설정
     * 총 가격 계산 (스튜디오 시간당 가격 * 예약 시간)
     * 성공 시 "예약이 완료되었습니다" 메시지와 함께 내 예약 목록 페이지로 리다이렉트
     * 실패 시 에러 메시지 반환

2. **라우트 설정**:
   - `GET /studios/{id}/book` → BookingController@create
   - `POST /bookings` → BookingController@store

3. **React 컴포넌트 생성**:
   - `resources/js/Pages/Bookings/Create.jsx`: 예약 폼
     * 스튜디오 정보 표시 (읽기 전용)
     * 날짜 선택 (input type="date", 오늘 이후 날짜만 선택 가능)
     * 시작 시간 선택 (select 또는 input type="time", 30분 단위 옵션)
     * 종료 시간 선택 (시작 시간 이후만 선택 가능)
     * 예약 목적 입력 (textarea, 선택사항)
     * 예상 총 가격 표시 (시작/종료 시간 선택 시 자동 계산)
     * "예약하기" 버튼 (Inertia form submit)

4. 중복 예약 방지 로직을 명확히 구현해주세요:
   - 기존 예약 중 status가 'cancelled'가 아닌 것만 체크
   - 새 예약의 (start_time, end_time)이 기존 예약 시간대와 겹치는지 확인

5. 스튜디오 상세 페이지의 "예약하기" 버튼을 `/studios/{id}/book` 링크로 연결해주세요.

기대 결과: 스튜디오 상세 페이지에서 "예약하기" 버튼을 클릭하면 예약 폼 페이지로 이동합니다. 날짜와 시간을 선택하면 예상 가격이 자동 계산되고, 예약 제출 시 중복 체크 후 성공적으로 예약이 생성됩니다.

6
Step 6
내 예약 목록 페이지 및 예약 취소 기능을 구현해주세요.

1. **BookingController에 메서드 추가**:
   - `index()` 메서드: 현재 로그인한 사용자의 모든 예약 조회 (스튜디오 정보 포함, with('studio'))
     * 최신 예약순으로 정렬
     * status별로 필터링 가능하도록 (선택사항)
   - `cancel($id)` 메서드: 예약 취소 로직
     * 해당 예약이 현재 사용자의 것인지 확인
     * status를 'cancelled'로 변경, cancelled_at에 현재 시간 저장
     * 성공 메시지와 함께 내 예약 목록으로 리다이렉트

2. **라우트 설정**:
   - `GET /my-bookings` → BookingController@index
   - `DELETE /bookings/{id}` → BookingController@cancel

3. **React 컴포넌트 생성**:
   - `resources/js/Pages/Bookings/Index.jsx`: 내 예약 목록
     * 예약 목록을 테이블 또는 카드 형태로 표시
     * 각 예약: 스튜디오명, 예약 날짜, 시작/종료 시간, 상태, 총 가격
     * 상태별 색상 구분 (pending: 노란색, confirmed: 초록색, cancelled: 회색)
     * confirmed 또는 pending 상태인 예약에만 "취소하기" 버튼 표시
     * 취소 버튼 클릭 시 확인 메시지 후 DELETE 요청
     * 예약이 없을 경우 "예약 내역이 없습니다" 메시지 표시

4. 네비게이션 바에 "내 예약" 링크를 추가해주세요.

5. 취소 버튼은 Inertia의 router.delete() 또는 Link method="delete"를 사용하여 구현해주세요.

기대 결과: "내 예약" 페이지에서 사용자의 모든 예약을 확인할 수 있고, 상태별로 색상이 구분됩니다. "취소하기" 버튼을 클릭하면 확인 후 예약이 취소되고, 상태가 'cancelled'로 변경됩니다.

7
Step 7
스튜디오 상세 페이지에 주간 캘린더 뷰를 추가하여 예약 가능 시간대를 시각적으로 표시해주세요.

1. **StudioController의 show() 메서드 수정**:
   - 선택한 주(week)의 예약 현황을 조회 (기본값: 이번 주)
   - 해당 스튜디오의 모든 예약 중 status가 'cancelled'가 아닌 것만 필터링
   - 날짜별, 시간대별로 그룹화하여 React 컴포넌트에 전달
   - 추가로 스튜디오의 운영 시간 정보 전달 (예: 09:00 ~ 22:00, 30분 단위)

2. **React 컴포넌트 수정** (Studios/Show.jsx):
   - 주간 캘린더 UI 구현:
     * 월요일부터 일요일까지 7일 표시
     * 각 날짜별로 시간대(09:00, 09:30, 10:00, ... 22:00) 세로 나열
     * 예약된 시간대는 회색 배경 + "예약됨" 표시
     * 예약 가능한 시간대는 초록색 배경 + 클릭 시 예약 폼으로 이동 (날짜/시간 자동 입력)
     * 과거 시간대는 비활성화 (회색 + 클릭 불가)
   - 이전 주/다음 주 버튼 추가 (주 단위 네비게이션)
   - 반응형 디자인: 모바일에서는 하루씩 스와이프 가능하게 (선택사항)

3. 예약 가능한 슬롯 클릭 시:
   - 예약 폼 페이지로 이동하면서 날짜와 시작 시간을 쿼리 파라미터로 전달
   - 예약 폼에서 이 값들을 자동으로 채워주기

4. Tailwind CSS로 캘린더 그리드 레이아웃을 깔끔하게 구현해주세요.

캘린더 라이브러리를 사용하지 않고 직접 구현하거나, react-big-calendar 등을 사용해도 좋습니다.

기대 결과: 스튜디오 상세 페이지에 주간 캘린더가 표시되고, 예약된 시간대는 회색, 예약 가능한 시간대는 초록색으로 구분됩니다. 예약 가능한 슬롯을 클릭하면 해당 날짜/시간이 자동 입력된 예약 폼으로 이동합니다.

제출된 작품 (0)

로그인 후 제출

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

댓글 (0)

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