AI QT 콘텐츠 자동 생성 - 서비스 + Job + Admin 컨트롤러/뷰 + 테스트
ID: 687b92f9-e1cd-4bf3-8705-7ac8329b34b4
## 목표
Admin에서 QT 테마를 선택하고 AI 생성 요청 시 Solid Queue Job으로 콘텐츠를 자동 생성하는 전체 플로우 구현
## 스키마 현황 (마이그레이션 불필요!)
- QtTheme: is_ai_generated, ai_prompt, bible_books, generation_status(enum: draft/generating/completed/published) 컬럼 이미 존재
- QtContent: day_number, bible_passage, reading_passage, theme_title, content, questions(json), difficulty 등 컬럼 존재
## 구현 항목
### 1. AiQtGenerator 서비스
- 파일: `app/services/ai_qt_generator.rb`
- 기존 서비스 패턴 (AiMeditationAnalyzer, AiSermonInterpreter)을 따를 것
- 핵심:
```ruby
class AiQtGenerator
def initialize(theme)
@theme = theme
end
def call
# 1. 테마 정보로 프롬프트 구성
# 2. OpenAI::Client로 API 호출
# 3. 응답 JSON 파싱 → QtContent 레코드 생성
# 4. 결과 반환
end
private
def build_prompt
# 한국어 QT 콘텐츠 생성 프롬프트
# 입력: theme.title, theme.description, theme.total_day, theme.bible_books
# 출력 형식: JSON 배열 [{day_number, bible_passage, reading_passage, theme_title, content, questions: [...5개], difficulty, estimated_minutes}]
end
def api_key
ENV["OPENAI_API_KEY"] || ENV["GEMINI_API_KEY"] || raise("AI API 키가 설정되지 않았습니다")
end
def ai_model
ENV["OPENAI_API_KEY"] ? "gpt-4o-mini" : "gemini-2.0-flash"
end
end
```
- **프롬프트 가이드**: 레거시에서 참고. 성경 통독 QT 콘텐츠 생성용:
- total_day 일분의 콘텐츠를 JSON 배열로 생성
- 각 콘텐츠: bible_passage(통독 범위), reading_passage(핵심 구절), theme_title, content(본문 해석), questions(5개 묵상 질문 배열)
- difficulty 1-5, estimated_minutes 기본 15
- 한국어로 생성
- 개역개정 성경 기준
### 2. GenerateQtContentsJob
- 파일: `app/jobs/generate_qt_contents_job.rb`
- Solid Queue 백그라운드 처리:
```ruby
class GenerateQtContentsJob < ApplicationJob
queue_as :default
def perform(theme_id)
theme = QtTheme.find(theme_id)
theme.generating! # 상태 변경
result = AiQtGenerator.new(theme).call
if result[:success]
theme.completed!
else
theme.draft! # 실패 시 롤백
Rails.logger.error("QT generation failed for theme #{theme_id}: #{result[:error]}")
end
rescue => e
theme&.draft!
Rails.logger.error("QT generation job error: #{e.message}")
raise # Solid Queue가 재시도하도록
end
end
```
### 3. Admin::QtThemesController
- 파일: `app/controllers/admin/qt_themes_controller.rb`
- Admin::BaseController 상속 (이미 authorize_admin! 포함)
- 액션: index, show, generate
```ruby
module Admin
class QtThemesController < BaseController
def index
@themes = QtTheme.order(created_at: :desc)
end
def show
@theme = QtTheme.find(params[:id])
@contents = @theme.qt_contents.order(:day_number)
end
def generate
@theme = QtTheme.find(params[:id])
if @theme.generating?
redirect_to admin_qt_theme_path(@theme), alert: "이미 생성 중입니다."
return
end
# 기존 콘텐츠 삭제 후 재생성
@theme.qt_contents.destroy_all if @theme.qt_contents.any?
GenerateQtContentsJob.perform_later(@theme.id)
redirect_to admin_qt_theme_path(@theme), notice: "AI 콘텐츠 생성이 시작되었습니다."
end
end
end
```
### 4. 라우트 수정
- 파일: `config/routes.rb`
- 기존 admin namespace에 추가:
```ruby
namespace :admin do
root "dashboard#index"
resources :qt_themes, only: [:index, :show] do
member do
post :generate
end
end
end
```
- **중요**: 기존 routes.rb를 먼저 읽고, admin namespace 안에 추가
### 5. Admin 뷰
- 파일: `app/views/admin/qt_themes/index.html.erb` (신규)
- 테마 목록 테이블 (제목, 일수, 상태 뱃지, AI 여부, 생성 버튼)
- shared/_table, _badge 파셜 활용
- admin layout 사용 확인
- 파일: `app/views/admin/qt_themes/show.html.erb` (신규)
- 테마 상세 정보
- 콘텐츠 목록 (day_number, bible_passage, theme_title)
- generation_status에 따른 UI 분기:
- draft: "AI 생성" 버튼 표시
- generating: "생성 중..." 로딩 표시
- completed: "생성 완료" 뱃지 + 콘텐츠 목록
- published: "발행됨" 뱃지
- "AI 생성" 버튼: `button_to generate_admin_qt_theme_path(@theme), method: :post`
### 6. 테스트
- 파일: `test/services/ai_qt_generator_test.rb` (신규)
- API 호출 stub
- 정상 생성 테스트
- 에러 처리 테스트
- 파일: `test/jobs/generate_qt_contents_job_test.rb` (신규)
- job enqueue 테스트
- 상태 전환 테스트
- 파일: `test/controllers/admin/qt_themes_controller_test.rb` (신규)
- admin 사용자 index 접근
- admin 사용자 show 접근
- admin 사용자 generate 요청
- 일반 사용자 접근 차단
- 비인증 사용자 접근 차단
## 기존 코드 참고 (반드시 먼저 읽을 것)
- `app/services/ai_meditation_analyzer.rb` - AI 서비스 패턴
- `app/services/ai_sermon_interpreter.rb` - AI 서비스 패턴
- `app/controllers/admin/base_controller.rb` - Admin 인증
- `app/controllers/admin/dashboard_controller.rb` - Admin 컨트롤러 예시
- `app/models/qt_theme.rb` - enum, 관계
- `app/models/qt_content.rb` - validates, 컬럼
- `app/views/admin/` - 기존 admin 레이아웃/뷰 구조
- `test/fixtures/qt_themes.yml` - fixture 구조
- `test/fixtures/qt_contents.yml` - fixture 구조
- `config/routes.rb` - 현재 라우트 구조
## 주의사항
- shared 파셜의 strict locals 준수 (반드시 파셜 파일을 읽어서 필요한 locals 확인)
- ERB 멀티라인 주석 안에 ERB 태그 금지 (SystemStackError)
- UUID PK 사용
- parallelize(workers: 1) 테스트 설정 확인
- 기존 테스트가 깨지지 않게 주의
- admin layout이 있는지 확인: `app/views/layouts/admin.html.erb`
- SQLite JSON 컬럼은 자동 파싱 안 됨 → JSON.parse() 사용 필요할 수 있음
- 전체 테스트 통과 확인: bin/rails test
첨부 이미지
이미지 추가 (Ctrl+V로 붙여넣기 또는 클릭)
JPEG, PNG, GIF, WebP / 최대 10MB
활동 로그
-
팀팀리드 상태 변경: 리뷰 → 완료
2026년 03월 02일 05:20:23
-
Aai-gen-dev AI QT 콘텐츠 자동 생성 구현 완료 - 리뷰 요청
2026년 03월 02일 05:18:34
상세 보기
## 변경 사항
### 신규 파일
- `app/services/ai_qt_generator.rb` - AI QT 콘텐츠 생성 서비스
- ruby-openai gem 사용 (기존 패턴 준수)
- 한국어 QT 콘텐츠 프롬프트 구성
- JSON 파싱 (markdown 코드블록 포함)
- QtContent 레코드 대량 생성
- 에러 처리 (API 키 미설정, API 오류, JSON 파싱 실패)- `app/jobs/generate_qt_contents_job.rb` - 비동기 콘텐츠 생성 Job
- theme.generating! → AI 호출 → theme.completed! (또는 실패 시 draft!)
- 예외 발생 시 상태 롤백 후 재발생- `test/services/ai_qt_generator_test.rb` - 서비스 테스트 (6개)
- `test/jobs/generate_qt_contents_job_test.rb` - Job 테스트 (4개)### 수정 파일
- `app/controllers/admin/qt_themes_controller.rb` - generate 액션 추가
- `config/routes.rb` - `post :generate` member 라우트 추가
- `app/views/admin/qt_themes/show.html.erb` - AI 생성 UI 섹션 추가
- draft: "AI 생성 시작" 버튼
- generating: 로딩 스피너
- completed/published: 생성 완료 뱃지 + 재생성 버튼
- `test/controllers/admin/qt_themes_controller_test.rb` - generate 테스트 4개 추가### 테스트 결과
- 새 테스트: 27 runs, 74 assertions, 0 failures, 0 errors
- 전체 테스트: 430 runs, 1002 assertions, 0 failures
(기존 3개 에러는 다른 팀원의 AI 서비스 테스트 stub 관련 문제로, 이 작업과 무관) -
Aai-gen-dev 상태 변경: 완료 → 리뷰
2026년 03월 02일 05:18:21
-
팀팀리드 상태 변경: 진행 중 → 완료
2026년 03월 02일 05:16:12
-
Aai-gen-dev AI QT 콘텐츠 자동 생성 구현 시작
2026년 03월 02일 05:12:53
상세 보기
## 작업 시작
- 기존 코드 읽기부터 시작
- TDD 방식으로 구현 예정
- 구현 항목: AiQtGenerator 서비스, GenerateQtContentsJob, Admin::QtThemesController, 뷰, 테스트 -
Aai-gen-dev 티켓 클레임 완료
2026년 03월 02일 05:12:45