- 빈 결과를 30분간 캐시하는 문제 수정 (성공 결과만 캐시)
- 건강 키워드가 없을 때 리프레이밍 폴백 추가 (트렌드를 건강 관점으로 재해석)
- 최종 폴백: 원본 인기 키워드 표시
- 프론트엔드 에러/안내 메시지 분리 (오류 vs 건강 키워드 없음)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Controller: analyzeScreenshots()를 try-catch로 감싸 JSON 에러 응답 보장
- Frontend: api() 함수에서 HTML 응답(504/502 등) 감지 → 친절한 한글 에러 메시지 표시
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- disabled 속성 제거 (브라우저 기본 스타일이 Tailwind을 덮어씌움)
- 클릭 가드로 중복 클릭 방지 대체
- !important로 배경/글자색 강제 적용 (indigo-900/white)
- is-loading 클래스로 진행 중 상태 명확히 구분
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- XHR upload.onprogress로 파일 업로드 실시간 진행률 표시 (0~50%)
- AI 분석 단계 진행률 시뮬레이션 표시 (50~100%)
- 버튼 내부에 반투명 progress fill 애니메이션
- 단계별 텍스트 변경: "업로드 중... 30%" → "AI 분석 중... 75%"
- 업로드+분석을 ScreenshotUpload 내부에서 일괄 처리
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- stale closure 버그 수정: useRef로 최신 files/previews 참조
- 이미지 추가 시 기존 preview URL 유지 (revoke 안 함) → 올바른 누적
- 드래그 앤 드롭 순서 변경 기능 추가
- + 버튼으로 추가 이미지 등록 UI 개선
- 파일 선택 후 input value 리셋 (같은 파일 재선택 가능)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ScreenAnalysisService: Gemini 프롬프트를 멀티스텝(3~5 steps) 출력으로 변경 + 하위 호환 fallback
- SlideAnnotationService: 스포트라이트 효과(annotateSlideWithSpotlight), 인트로/아웃트로 슬라이드 생성
- TutorialVideoJob: screen→steps 중첩 루프 + 인트로/아웃트로 씬 추가
- index.blade.php: 단계별 나레이션 편집 UI + 예상 시간 표시
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
preview에서 GCS redirect 대신 서명URL을 JSON 반환(?url=1)하여
video 태그에서 직접 사용. storage.googleapis.com→mng.sam.kr
favicon CORS 차단 문제 해결.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TutorialVideo 모델 (상태 관리, TenantScope)
- GeminiScriptService에 callGeminiWithParts() 멀티모달 지원 추가
- ScreenAnalysisService: Gemini Vision 스크린샷 AI 분석
- SlideAnnotationService: PHP GD 이미지 어노테이션 (마커, 캡션)
- TutorialAssemblyService: FFmpeg 이미지→영상 합성 (crossfade)
- TutorialVideoJob: 분석→슬라이드→TTS→BGM→합성 파이프라인
- TutorialVideoController: 업로드/분석/생성/상태/다운로드/이력 API
- React-in-Blade UI: 3단계 (업로드→분석확인→생성모니터링) + 이력
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Veo3Controller에 show 엔드포인트 추가 (시나리오/프롬프트 상세 데이터 반환)
- YouTube Shorts 제목/설명/해시태그 자동 생성 (완료된 영상)
- DetailModal 컴포넌트: 탭 UI (시나리오/프롬프트 | YouTube 텍스트)
- 이력 테이블 행 클릭 시 상세 모달 표시
- 복사 버튼으로 YouTube 텍스트 클립보드 복사
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
건강 채널 전용 트렌딩 시스템:
- Gemini로 실시간 트렌드에서 건강 관련 키워드만 필터링
- 간접적 키워드도 건강 앵글로 리프레이밍 (예: 김치 → 장건강)
- 필터 결과 30분 캐싱 (Gemini 호출 최소화)
- 필터 실패 시 원본 키워드 폴백
제목 생성 건강 앵글 반영:
- generateTrendingHookTitles 프롬프트에 건강 채널 명시
- trending_context에 health_angle, suggested_topic 추가
- 모든 제목이 건강/웰빙 관점으로 생성되도록 가이드
UI 건강 테마 적용:
- 버튼/칩 색상: orange/indigo → green 테마
- 칩에 건강 앵글 태그 배지 표시
- 칩 클릭 시 건강 주제(suggested_topic)가 인풋에 채워짐
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- KeywordInput 컴포넌트에 Google 실시간 급상승 키워드 가져오기 버튼 추가
- 키워드 칩(pill) 클릭 시 인풋 자동 채움 + trending_context 저장
- handleKeywordSubmit에서 trending_context를 POST body에 포함하여 전송
- 직접 입력 시 기존과 동일하게 동작 (하위 호환)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 날짜→생성일시: KST(Asia/Seoul) 기준 MM/DD HH:mm 형식
- 제작시간 열 추가: created_at~updated_at 차이 계산 (완료/실패 시)
- 진행 중인 항목은 "진행 중" 표시
- history API에 updated_at 추가 반환
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 이력 테이블 첫 열에 체크박스 추가 (전체 선택/해제)
- 선택 시 상단에 빨간색 삭제 버튼 표시
- DELETE /video/veo3/history API 엔드포인트 추가
- 삭제 후 이력 목록 자동 새로고침
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 경과 시간 실시간 표시 (초 단위 타이머)
- 단계별 타임라인 (Queue 대기 → TTS → 영상 → BGM → 합성)
- 프로그레스 바 shimmer 애니메이션 (작동 중 표시)
- 2분간 변화 없으면 경고 배너 표시
- 폴링 횟수 & 서버 마지막 업데이트 시간 표시
- status API에 updated_at/created_at 추가
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 기본 모델을 gemini-3.0-flash로 변경
- @apply를 순수 CSS로 전환 (Tailwind CDN 호환)
- 제목 카드에 라디오 도트, 체크 뱃지, hover/selected 효과 추가
- 선택 시 border glow + 체크마크 표시
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- GeminiScriptService: 트렌딩 제목/시나리오 생성
- VeoVideoService: Veo 3.1 영상 클립 생성
- TtsService: Google TTS 나레이션 생성
- BgmService: 분위기별 BGM 선택
- VideoAssemblyService: FFmpeg 영상 합성
- VideoGenerationJob: 백그라운드 처리
- Veo3Controller: API 엔드포인트
- React 프론트엔드 (5단계 위저드)
- GoogleCloudService.getAccessToken() public 변경
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>