h-lab/docs/superpowers/specs/2026-08-03-shortform-queue-design.md
hehihoho3@gmail.com 23fadea5e5 docs: 숏폼 큐(Opal 연동) 설계 스펙
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:39:29 +09:00

4.4 KiB

숏폼 큐 — Opal 연동 작업 큐/결과 저장 설계

2026-08-03. 유튜브 URL을 h-lab에 등록하면, 구글 Opal "숏폼 생성기" 앱(무료, Gemini Pro 영상분석)을 실행 엔진으로 삼아 결과를 DB에 구조화 저장하고 조회하는 기능.

배경·제약

  • Opal은 외부 API가 없다. 실행은 (A) 클로드가 브라우저 자동화로 대행하거나 (B) 사용자가 수동 실행 후 결과를 붙여넣는다. 두 경로 모두 동일한 저장 API로 수렴한다.
  • Gemini API 직접 호출은 Pro가 유료(2026-04부터 무료 티어 제외)라 배제. 단, 실행 엔진 교체가 쉽도록 h-lab은 "결과 텍스트를 받아 파싱·저장"만 담당한다.
  • Opal 출력 형식(프롬프트 v13.x): 구간(ID 1~5)별로 N===== 구분자 + ```json 블록(capcut2 붙여넣기용) + 📌 타이틀 후보 5선 + ⏱️ 컷 길이 검산표.

구성요소

1. 백엔드 — domain/shortform/ (DDD 컨벤션)

엔티티

  • ShortformJob (테이블 shortform_job): id, youtubeUrl, videoId(URL에서 추출), title(nullable, 결과 JSON의 title_main 첫 값 또는 null), status(PENDING/DONE/FAILED), rawOutput(TEXT, 파싱 실패 대비 원문 보존), createdAt, completedAt
  • ShortformClip (테이블 shortform_clip): id, job FK, clipNo(1~5), capcutJson(TEXT), titleCandidates(TEXT), durationTable(TEXT), titleTop/titleMain(파싱값, nullable)

API (ApiResponse<T> 래핑, /api/shortform/..., web/ 스타일 경로)

  • POST /api/shortform/jobs {youtubeUrl} → 큐 등록(PENDING). 중복 URL 등록 시 기존 작업 반환
  • GET /api/shortform/jobs → 목록(최신순)
  • GET /api/shortform/jobs/{id} → 상세(클립 포함)
  • POST /api/shortform/jobs/{id}/result {rawText} → 파싱·저장, status 갱신
  • POST /api/shortform/import {youtubeUrl, rawText} → 등록+결과 저장 한 번에 (수동 실행 후 붙여넣기용)
  • DELETE /api/shortform/jobs/{id}

파서 (ShortformOutputParser)

  • N===== 형태 구분자로 섹션 분리 → 섹션마다 ```json 코드블록, "타이틀 후보" 블록, "검산표" 블록 추출
  • JSON 파싱 성공 시 titleTop/titleMain 추출. 어떤 단계든 실패하면 해당 클립은 원문 조각만 저장하고 job은 DONE 유지(rawOutput이 항상 원본 보존) — 파싱 실패로 데이터를 잃지 않는다
  • 클립이 0개 추출되면 FAILED + rawOutput 보존

2. 프론트 — /shortform 페이지 (Thymeleaf, layout/base)

  • 사이드바에 "숏폼" 메뉴 추가 (currentPage=shortform)
  • 상단: URL 입력 폼(등록) + "결과 붙여넣기" 토글(URL+원문 textarea → import API)
  • 목록: 작업 카드(썸네일 img.youtube.com/vi/{videoId}/mqdefault.jpg, 상태 뱃지, 등록시각)
  • 상세(카드 펼침 또는 별도 영역): 클립 1~5 카드 — 타이틀(top/main), 타이틀 후보 5선, 검산표, capcut2 JSON 복사 버튼(클립보드 API)

3. 스킬 — .claude/skills/shortform-queue/SKILL.md

트리거: /shortform-queue, "숏폼 큐 돌려줘" 류 요청. 절차(오늘 세션에서 검증된 노하우를 명문화):

  1. GET /api/shortform/jobs에서 PENDING 목록 조회 (h-lab은 localhost:8088)
  2. 크롬 자동화로 opal.google → 숏폼 생성기 앱(edit URL 고정) 열기
  3. YouTube Video 노드 클릭 → URL 입력 → Apply → Preview의 Start
  4. 완료 폴링(전체 4~5분, Step 3 각 ~90초). 앱 UI는 접근성 트리에 안 잡히므로 스크린샷 + iframe#opal-app contentDocument에 JS 주입(shadow DOM 관통)으로 상태 확인
  5. Output 전문 추출(JS, "cuts" 포함 최대 텍스트) → POST /api/shortform/jobs/{id}/result
  6. 노드 에러 시 1회 재실행, 재실패면 FAILED 보고 후 다음 작업 진행. 큐 소진까지 반복, 요약 보고 주의사항: Opal 프롬프트 끝 중복 칩 이슈(2026-08-03 해결) 같은 앱 구조 변경 감지 시 사용자에게 보고.

순서·범위

  1. 백엔드(엔티티→파서→API) — 파서는 오늘 실행에서 얻은 실제 Output 샘플로 단위 테스트
  2. 프론트 페이지
  3. 스킬 파일 빌드·커밋은 변경 단위별. 실제 Opal 실행 검증은 스킬 완성 후 사용자 요청 시.

하지 않는 것 (YAGNI)

  • Gemini API 직접 호출(비용) — 파서/저장 구조만 호환되게 유지
  • n8n 연동, 스케줄 자동 실행(Opal이 로그인 세션 필요, 무인 실행 불가)
  • capcut2 앱으로의 직접 전송(현행 수동 붙여넣기 유지)