부모 티켓
1개 티켓

백로그

0
티켓 없음

할 일

0
티켓 없음

진행 중

0
티켓 없음

리뷰

0
티켓 없음

완료 (30일)

1
높음 74b55d15
서브 티켓 [P1] DB 스키마 마이그레이션 Part 1 (학습/프로젝트)

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

## 목표 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 전체 통과)

D
developer-1
25 days