DB 마이그레이션 Part 1 — projects, build_steps, curricula, lessons, user_lesson_progresses

ID: 74b55d15-9994-4d98-a0bc-3c21293c285f

높음 완료

## 목표
PRD Section 8.3~8.4, 8.7~8.9 기반 5개 테이블 생성 + 모델 + 연관관계 + 테스트.

## 생성할 테이블 (PRD 그대로)

### 1. projects (Section 8.3)
```ruby
create_table :projects do |t|
t.references :user, null: false, foreign_key: true
t.string :title, null: false
t.text :description
t.integer :status, default: 0, null: false
t.text :raw_idea
t.string :one_line_definition
t.jsonb :core_features, default: []
t.string :target_customer
t.string :revenue_model
t.jsonb :competitor_analysis, default: {}
t.string :tech_stack
t.string :tech_stack_reason
t.jsonb :db_schema_draft, default: {}
t.jsonb :pages_list, default: []
t.jsonb :dev_priority, default: []
t.text :claude_md_content
t.datetime :claude_md_generated_at
t.string :service_url
t.datetime :launched_at
t.integer :user_count, default: 0
t.string :landing_headline
t.string :landing_subcopy
t.string :landing_cta
t.string :category
t.timestamps
end
add_index :projects, :user_id # references가 자동 생성하지만 확인
add_index :projects, :status
```

### 2. build_steps (Section 8.4)
```ruby
create_table :build_steps do |t|
t.references :project, null: false, foreign_key: true
t.integer :step_number, null: false
t.string :title, null: false
t.text :description
t.text :prompt_template
t.boolean :completed, default: false
t.datetime :completed_at
t.timestamps
end
add_index :build_steps, [:project_id, :step_number], unique: true
```

### 3. curricula (Section 8.7)
```ruby
create_table :curricula do |t|
t.string :title, null: false
t.text :description
t.integer :week_start, null: false
t.integer :week_end, null: false
t.integer :position, null: false
t.boolean :published, default: false
t.timestamps
end
```

### 4. lessons (Section 8.8)
```ruby
create_table :lessons do |t|
t.references :curriculum, null: false, foreign_key: true
t.string :title, null: false
t.text :content
t.string :content_type, default: "article"
t.string :video_url
t.integer :read_time_minutes
t.integer :position
t.boolean :published, default: false
t.integer :required_role, default: 0
t.timestamps
end
```

### 5. user_lesson_progresses (Section 8.9)
```ruby
create_table :user_lesson_progresses do |t|
t.references :user, null: false, foreign_key: true
t.references :lesson, null: false, foreign_key: true
t.boolean :completed, default: false
t.datetime :completed_at
t.datetime :started_at
t.integer :time_spent_seconds, default: 0
t.timestamps
end
add_index :user_lesson_progresses, [:user_id, :lesson_id], unique: true
```

## 모델 (PRD Section 9 참조)

### Project
```ruby
belongs_to :user
has_many :build_steps, -> { order(:step_number) }, dependent: :destroy
has_many :ai_conversations, dependent: :destroy # 아직 테이블 없음 — 선언만
has_one :showcase_service, dependent: :destroy # 아직 테이블 없음 — 선언만
enum :status, { ideating: 0, building: 1, launched: 2, abandoned: 3 }
validates :title, presence: true
def completion_percentage
total = build_steps.count
return 0 if total.zero?
(build_steps.where(completed: true).count.to_f / total * 100).round
end
```

### BuildStep
```ruby
belongs_to :project
validates :step_number, presence: true, uniqueness: { scope: :project_id }
validates :title, presence: true
```

### Curriculum
```ruby
has_many :lessons, -> { order(:position) }, dependent: :destroy
validates :title, presence: true
scope :published, -> { where(published: true) }
```

### Lesson
```ruby
belongs_to :curriculum
has_many :user_lesson_progresses, dependent: :destroy
validates :title, presence: true
scope :published, -> { where(published: true) }
```

### UserLessonProgress
```ruby
belongs_to :user
belongs_to :lesson
validates :lesson_id, uniqueness: { scope: :user_id }
```

### User 모델 업데이트 (추가 연관관계)
```ruby
has_many :projects, dependent: :destroy
has_many :user_lesson_progresses, dependent: :destroy
has_many :lessons, through: :user_lesson_progresses
```

## ⚠️ 주의
- ai_conversations, showcase_services 테이블은 아직 없음 → has_many 선언은 하되, 없는 테이블 참조 시 에러나지 않도록 주의
- `dev_level` enum은 `no_experience: 0`으로 변경됨 (이전 세션에서 수정)
- 기존 User 모델의 normalizes, validates 유지

## 테스트 (TDD)
- 각 모델 테스트: validates, enum, 연관관계
- Project#completion_percentage 테스트
- fixture 파일 생성 (각 모델 최소 2개)
- User has_many :projects 테스트

## 완료 기준
- bin/rails db:migrate 성공
- 모든 인덱스 생성 확인
- 모델 테스트 전체 통과
- 기존 테스트 깨지지 않음 (bin/rails test 전체 통과)

첨부 이미지

이미지 추가 (Ctrl+V로 붙여넣기 또는 클릭)

JPEG, PNG, GIF, WebP / 최대 10MB

담당자: developer-1
생성일: 2026년 03월 26일 03:36

활동 로그

  • 팀리드 상태 변경: 리뷰 → 완료

    2026년 03월 26일 08:05:46

  • D
    developer-1 상태 변경: 할 일 → 리뷰

    2026년 03월 26일 07:48:19