백로그
0할 일
0진행 중
0리뷰
1학습자 레슨 뷰 — Learn 네임스페이스 컨트롤러 + 뷰 + 진행 추적 + 완료 버튼 + 테스트
## 목표 Learn 네임스페이스에서 학습자용 커리큘럼/레슨 뷰 구현. UserLessonProgress 생성. 완료 버튼. ## 현재 상태 - Learn::CurriculaController 스텁 (index, show) - Learn::LessonsController 스텁 (show, complete) - Learn::HomeController 스텁 (index) - 라우트: `namespace :learn { get "/", to: "home#index"; resources :curricula, only: [:index, :show] do resources :lessons, only: [:show] do post :complete, on: :member end end }` - Curriculum 모델: has_many :lessons, scope :published - Lesson 모델: belongs_to :curriculum, has_many :user_lesson_progresses, scope :published - UserLessonProgress 모델: belongs_to :user, belongs_to :lesson, completed(boolean), completed_at, started_at, time_spent_seconds - User: has_many :user_lesson_progresses, has_many :lessons(through) ## 구현 사항 ### 1. Learn::HomeController ```ruby def index @curricula = Curriculum.published.order(:position).includes(:lessons) end ``` ### 2. Learn::CurriculaController ```ruby def index @curricula = Curriculum.published.order(:position).includes(:lessons) end def show @curriculum = Curriculum.published.find(params[:id]) @lessons = @curriculum.lessons.published.order(:position) # 현재 유저의 진행 상태 로드 @progresses = Current.user.user_lesson_progresses .where(lesson_id: @lessons.pluck(:id)) .index_by(&:lesson_id) end ``` ### 3. Learn::LessonsController ```ruby def show @curriculum = Curriculum.published.find(params[:curriculum_id]) @lesson = @curriculum.lessons.published.find(params[:id]) @progress = Current.user.user_lesson_progresses.find_or_initialize_by(lesson: @lesson) # started_at 기록 @progress.update(started_at: Time.current) if @progress.started_at.nil? end def complete @curriculum = Curriculum.published.find(params[:curriculum_id]) @lesson = @curriculum.lessons.published.find(params[:id]) progress = Current.user.user_lesson_progresses.find_or_initialize_by(lesson: @lesson) progress.update!(completed: true, completed_at: Time.current) redirect_to learn_curriculum_lesson_path(@curriculum, @lesson), notice: "레슨을 완료했습니다!" end ``` ### 4. 뷰 - **다크 테마** (bg-bg, bg-surface, text-text-primary, bg-accent) - 기존 Partial 활용 (_button, _card) **learn/home/index.html.erb**: 커리큘럼 카드 목록 + 각 커리큘럼의 진행률 **learn/curricula/index.html.erb**: 커리큘럼 목록 (published만), week 범위 표시 **learn/curricula/show.html.erb**: 커리큘럼 상세 + 레슨 목록 - 각 레슨에 완료 체크 표시 (UserLessonProgress 기반) - content_type 아이콘 (article/video/guide) - read_time_minutes 표시 **learn/lessons/show.html.erb**: 레슨 상세 - content_type별 렌더링 (article→simple_format, video→iframe, guide→simple_format) - "완료" 버튼 (POST complete) - 이미 완료된 경우 "완료됨" 표시 - 이전/다음 레슨 네비게이션 ### 5. role 기반 접근 제어 (선택사항) - Lesson의 required_role 확인: 0=free(모두 접근), 1=cohort(cohort/admin만), 2=admin - 접근 불가 시 Flash + 리다이렉트 ### ⚠️ 주의 - learn/ 범위만 수정 (developer-2는 build/ 작업 중) - 모델 수정 불필요 - N+1 방지: includes, index_by 활용 - 한국어 Flash 메시지 ### 테스트 (TDD) - Learn::CurriculaController: index(published만), show - Learn::LessonsController: show, complete(progress 생성), 이미 완료 시 - Learn::HomeController: index - 인증 필요 확인 - fixture 활용 ### 완료 기준 - 커리큘럼/레슨 목록 페이지 - 레슨 상세 컨텐츠 표시 - "완료" 버튼 → progress 레코드 생성 - 완료 레슨 체크 표시 - bin/rails test 전체 통과