디글 클래식처럼 한 채널에 여러 프로그램이 섞인 경우 특정 프로그램만
피드에 수집하기 위한 설계. Channel에 feed_title_filter 컬럼을 추가하고
공백 무시 부분일치 OR 매칭으로 수집 단계에서 거른다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Opal이 title_top 같은 값에 따옴표를 이스케이프 없이 뱉으면 파서의
Jackson readTree가 던져서 status=FAILED, clips=0이 된다. 같은 JSON이
캡컷 구간 JSON 붙여넣기로도 들어가므로 저장과 영상 생성이 둘 다 막힌다.
저장 전에 파싱을 시도하고, 깨졌으면 fix-opal-json.ps1로 문자열 값
안쪽 따옴표만 이스케이프한 뒤 재검증한다. 그래도 안 되면 저장하지
않고 PENDING으로 남긴다. 정상 JSON에는 아무 변화가 없다.
캡컷 방식 선택도 모드별로 갈랐다 - 1단계는 구간 JSON(wpaste),
풀버전은 오팔 JSON(paste).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"숏폼 돌려줘"가 이제 1단계 앱으로 돌아간다. 풀버전은 "풀버전으로
돌려줘"로 명시할 때만 쓴다.
작업 저장이 DONE 되면 캡컷 에이전트(127.0.0.1:8001)의 자동 탭
구간 JSON 방식으로 유튜브 URL과 candidates JSON을 넣고 영상 생성을
시작만 시킨다. 완료를 기다리지 않고 바로 다음 작업의 Opal 실행으로
넘어간다. 서버가 analysis_id별로 독립 처리해 동시 실행이 가능하고,
작업마다 새 탭을 써서 앞 실행의 화면 상태가 덮이지 않게 한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
피드·인물 수집에서 새로 담긴 영상이 업로드 24시간(골든타임) 이내면
텔레그램으로 알림을 발송한다. 신규 insert만 대상이라 같은 영상이
두 번 울리지 않고, 경쟁(RIVAL) 채널 영상은 알림에서 제외한다.
기존 TelegramNotifier(hlab.notify.telegram) 재사용 — 미설정 시 no-op.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SKILL.md에 모드 선택 표(풀버전/1단계) 및 1단계 전용 절차 추가
("1단계만 돌려줘" → candidates JSON 앱으로 실행·저장)
- 오늘 실전에서 확인한 절차 개선 반영: application-local.yml 복사,
브라우저 fetch 차단(HTTPS→HTTP) 우회, PS 5.1 인코딩 주의
- docs/shortform-queue-skill-portable.md: 다른 PC에서 md 하나로
스킬 등록·전제조건 점검이 가능한 자기완결 가이드
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
피드 수집 필터를 쇼츠/롱폼 구분에서 최소 길이(초) 기준으로 교체.
기본 600초(10분) — FEED_MIN_DURATION_SEC 로 조정 가능.
화면 조회에도 같은 하한을 적용해 이미 담긴 10분 미만 영상도
소스·경쟁 탭에서 바로 사라진다. 길이 필터 라벨(공식클립 10~15분)도 정리.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
인물 추적은 65초 컷으로 쇼츠를 걸렀지만 유튜브 쇼츠가 최대 3분까지
허용되면서 1~3분짜리 쇼츠가 통과해 인물 탭에 들어왔다.
수집(PersonPicks)과 조회(feedByPerson) 모두 180초 컷으로 올려
이미 담긴 1~3분 영상도 탭에서 사라지게 했다.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
결과가 잘못 나왔을 때 지금은 작업을 통째로 삭제하고 URL을 다시 등록해야 했다.
등록 이력도 같이 날아간다.
큐 스킬이 status=PENDING 인 작업만 집어가므로, 결과만 비우고 PENDING 으로
되돌리면 그대로 재실행 대상이 된다.
- POST /api/shortform/jobs/{id}/reset — rawOutput·step1Output·clips·title·
completedAt 을 비우고 PENDING 으로. youtubeUrl·videoId·등록시각은 유지한다.
- 화면: PENDING 이 아닌 카드에만 되돌리기 버튼(확인창 포함). 결과가 삭제되므로
무엇이 지워지고 무엇이 남는지 문구에 명시했다.
- FAILED 재시도에 특히 필요했다 — 파싱 실패한 작업을 되살릴 방법이 아예 없었다.
fix: Mockito self-attach 실패로 목 기반 테스트 6건이 깨지던 문제
내 변경과 무관하게 환경에서 깨져 있었다(변경을 치운 깨끗한 트리에서도 동일 실패).
Mockito 가 JVM 에 self-attach 를 시도하다 실패하면 "Could not initialize plugin:
MockMaker" 로 DashboardServiceTest·YoutubeCommentServiceTest 가 전부 죽는다.
JDK 21+ 는 self-attach 를 경고하고 이후 버전에서 막으므로, 권장 방식대로
mockitoAgent 설정을 만들어 -javaagent 로 명시 지정했다. 116건 전부 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>