Commit Graph

198 Commits

Author SHA1 Message Date
d70bb142c0 feat: 유통 피드 미리보기와 영상 길이 표시 2026-09-04 22:41:03 +09:00
55f56fb390 fix: 외부 수집 요청 헤더 중복 제거 2026-09-04 18:11:35 +09:00
dcc3eba2e0 fix: 페이스북 릴 수집 경로 보강 2026-09-04 18:08:35 +09:00
b01039c223 fix: 페이스북 공개 피드 대체 수집 경로 추가 2026-09-04 17:57:46 +09:00
b7836cdee9 fix: 유통 피드 표시와 페이스북 수집 재시도 2026-09-04 17:52:02 +09:00
d25093dd44 feat: 유통 소셜 피드와 텔레그램 알림 추가 2026-09-04 16:12:01 +09:00
ea08b6d6b7 feat: 숏폼 복사 시 작업 완료 처리 2026-09-03 09:27:09 +09:00
80e462acbf feat: 페이스북 영상 다운로드 게시판 추가 2026-09-02 09:28:54 +09:00
b4a72115b5 feat: 숏폼 큐 복사 완료 흐름 간소화 2026-09-02 09:15:35 +09:00
6151228248 feat: 업로드 성과 일별 조회수 분석 추가 2026-08-31 16:33:36 +09:00
17b8a0c74d feat: 유튜브 실제 업로드와 예약 공개 구현 2026-08-31 15:55:43 +09:00
536d87aba2 fix: 유튜브 최근 업로드 실제 동기화 2026-08-31 14:15:27 +09:00
6e4b23e849 fix: 연결 전 OAuth 설정 수정 허용 2026-08-31 12:50:50 +09:00
eef46aec9b fix: 유튜브 OAuth 최초 설정 흐름 단순화 2026-08-31 12:42:08 +09:00
a6c87ffbcb feat: 원격 서버 OAuth 키 설정 지원 2026-08-31 12:25:24 +09:00
d74bbaf657 feat: 화면에서 유튜브 OAuth 연결 지원 2026-08-31 11:52:43 +09:00
bc416ab7bb feat: 유튜브 업로드 스튜디오 화면 추가 2026-08-31 11:25:55 +09:00
0e155c852c feat: 숏폼 큐 원본 영상 제목 표시 2026-08-25 15:15:18 +09:00
51fcfffffa feat: 소재 중심 대시보드와 조회수 현행화 2026-08-16 07:11:07 +09:00
381ec71291 docs: 예능 쇼츠 후보 수와 길이 유연화 2026-08-13 15:28:37 +09:00
f0ef7c32ff fix: Whisper 전사 제한 시간 확대 2026-08-13 15:23:43 +09:00
f51cab471e feat: 숏폼 자막 완료 텔레그램 알림 추가 2026-08-13 15:05:45 +09:00
504d0f09d5 fix: 자막 상태 갱신과 재시작 복구 개선 2026-08-13 15:02:26 +09:00
9d27ad3d79 fix: 숏폼 자막 갱신 중 카드 펼침 유지 2026-08-13 14:58:05 +09:00
4ce5017ab5 docs: 예능 쇼츠 VTT 분석 지침 추가 2026-08-13 14:49:37 +09:00
9a3047142d feat: 숏폼 자막 Whisper 폴백 추가 2026-08-13 14:32:29 +09:00
f284a5b1e5 feat: 숏폼 큐 자막 자동 수집 확대 2026-08-13 14:27:14 +09:00
5da8121daf docs: 정치 쇼츠 VTT 시간 기준 강제 2026-08-12 16:30:19 +09:00
d21fd4a919 feat: 정치 큐 등록 시 유튜브 자막 수집 2026-08-12 16:24:03 +09:00
17194d66cc docs: 정치 구간 JSON 출력 필드 축소 2026-08-12 15:59:44 +09:00
22da1fe725 docs: 정치 쇼츠 타임스탬프 우선 검증 적용 2026-08-12 15:55:08 +09:00
b13c5f68d2 docs: 정치 쇼츠 자막 증거 검증 추가 2026-08-12 12:18:52 +09:00
6b5f936a1c docs: 정치 쇼츠 구간 검증 지침 강화 2026-08-12 12:06:12 +09:00
74350afc38 feat: 정치 피드 URL 복사 버튼 추가 2026-08-12 11:39:15 +09:00
f47e07a9e8 docs: 정치 쇼츠 Opal 지침 추가 2026-08-12 11:35:11 +09:00
d75885a42b feat: 정치 피드와 숏폼 큐 분류 추가 2026-08-12 11:09:03 +09:00
b8b119a94a docs: 시드 채널 제목 키워드 필터 설계
디글 클래식처럼 한 채널에 여러 프로그램이 섞인 경우 특정 프로그램만
피드에 수집하기 위한 설계. Channel에 feed_title_filter 컬럼을 추가하고
공백 무시 부분일치 OR 매칭으로 수집 단계에서 거른다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 12:38:18 +09:00
7d8c6bc49b feat: 숏폼 큐 스킬 - 저장 전 JSON 검증·따옴표 보정 단계 추가
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>
2026-08-10 17:12:49 +09:00
be56ff39df feat: 숏폼 큐 스킬 - 기본 모드 1단계로 전환 + 캡컷 에이전트 연동
"숏폼 돌려줘"가 이제 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>
2026-08-10 17:00:25 +09:00
9c9bc9afdb feat: 피드 자동 수집 주기 3시간 -> 1시간
골든타임 선점이 목적이라 주기를 줄임. 채널당 2 units라
시드 20개 기준 하루 960 units - 일일 쿼터(10,000)에 부담 없음.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-10 01:04:44 +09:00
7866217ca0 feat: 텔레그램 알림 토큰·챗ID 기본값 설정 — 골든타임 알림 활성화
서버 컨테이너에 환경변수 없이도 골든타임 소재 알림과 아침
다이제스트가 발송되도록 기존 시크릿 fallback 패턴을 따라 설정.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 08:52:30 +09:00
4cc5e6548d feat: 골든타임 소재 텔레그램 알림
피드·인물 수집에서 새로 담긴 영상이 업로드 24시간(골든타임) 이내면
텔레그램으로 알림을 발송한다. 신규 insert만 대상이라 같은 영상이
두 번 울리지 않고, 경쟁(RIVAL) 채널 영상은 알림에서 제외한다.
기존 TelegramNotifier(hlab.notify.telegram) 재사용 — 미설정 시 no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-08 07:10:08 +09:00
52108847f5 feat: shortform-queue 스킬 1단계 모드 추가 + 타PC 이식 가이드
- 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>
2026-08-07 17:20:17 +09:00
88179bb620 feat: 숏폼 큐 파서 - 1단계 candidates JSON도 클립으로 인식
- Opal "숏폼 생성기 1단계" 출력(candidates JSON)을 N===== 구분자
  매칭 실패 시 폴백으로 파싱해 DONE 처리
- 후보 원본 JSON은 capcutJson 자리에 보존, 시간·경계·선정이유는
  durationTable 요약으로 표시
- 실전 픽스처 opal-step1-candidates-sample.txt 추가
- 낡은 테스트 정리: ChannelRole.acceptsShorts 제거 반영,
  PersonPicks 쇼츠 컷 180초 반영

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 17:04:06 +09:00
d4547056e3 feat: 소재 피드 10분 이상만 수집·표시 (min-duration-sec)
피드 수집 필터를 쇼츠/롱폼 구분에서 최소 길이(초) 기준으로 교체.
기본 600초(10분) — FEED_MIN_DURATION_SEC 로 조정 가능.
화면 조회에도 같은 하한을 적용해 이미 담긴 10분 미만 영상도
소스·경쟁 탭에서 바로 사라진다. 길이 필터 라벨(공식클립 10~15분)도 정리.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 12:42:02 +09:00
e964cecceb feat: 인물 추적 쇼츠 컷 180초로 — 3분짜리 쇼츠 차단
인물 추적은 65초 컷으로 쇼츠를 걸렀지만 유튜브 쇼츠가 최대 3분까지
허용되면서 1~3분짜리 쇼츠가 통과해 인물 탭에 들어왔다.
수집(PersonPicks)과 조회(feedByPerson) 모두 180초 컷으로 올려
이미 담긴 1~3분 영상도 탭에서 사라지게 했다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 12:07:02 +09:00
f96e4c583d feat: 소재 피드 롱폼만 수집 — 경쟁 채널 쇼츠 수집 제거
피드 수집이 역할(SOURCE/RIVAL)과 무관하게 롱폼만 저장하도록 변경.
쇼츠는 이미 잘린 결과물이라 자를 원본(소재)이 아니므로 수집 대상에서 제외.
UI 문구(경쟁 쇼츠 → 경쟁 채널)와 길이 필터도 함께 정리.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 11:50:47 +09:00
aba3c5badc feat: 숏폼 큐 작업 되돌리기 — 결과를 지우고 다시 대기로
결과가 잘못 나왔을 때 지금은 작업을 통째로 삭제하고 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>
2026-08-07 10:52:33 +09:00
b48ab6494c feat: 숏폼 큐에 Step 1 후보구간 원문 저장·복사 추가
ShortformJob.step1Output(TEXT) + result/import API에 step1Text 옵션 필드.
카드 펼침에 'Step 1 후보구간 복사' 버튼과 접이식 원문 표시.
shortform-queue 스킬에 콘솔 Step 1 추출 절차(d-2) 추가.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 10:31:25 +09:00
13dd61d80c feat: 소재 피드에서 영상을 사이트 안에서 재생
썸네일·제목을 누르면 YouTube 새 탭으로 나가던 걸 레이어 팝업 재생으로 바꿨다.
쇼츠는 세로(9:16), 롱폼은 가로(16:9)로 비율을 맞추고, 팝업 안에 숏폼 큐 등록과
YouTube 열기를 함께 뒀다. Escape·배경 클릭으로 닫히고 닫을 때 재생이 멈춘다.

임베드를 막아둔 채널이 많다는 걸 실측했다 — 소재 원본 9건 중 4건이 차단이고
채널 단위로 갈린다(짠한형 전부 차단, 뜬뜬·스프 전부 가능). 그대로 두면 절반이
"동영상을 재생할 수 없음" 화면을 보게 되므로:

- 수집할 때 videos.list 에 status 파트를 붙여 embeddable 을 저장한다(쿼터 동일).
- 차단된 영상은 팝업 대신 바로 YouTube 새 탭으로 연다.
- 차단 영상 썸네일에 외부링크 아이콘을 띄워 눌렀을 때 나가는 걸 예고한다.
- embeddable 이 null(미수집)이면 일단 재생을 시도한다 — 팝업 안에 YouTube 링크가
  있어 막혀도 빠져나갈 수 있다.

브라우저에서 확인: 재생 가능 영상은 팝업에서 실제 재생됐고(썸네일·제목 클릭 모두),
차단 채널 카드에만 외부링크 아이콘이 붙었다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 10:16:52 +09:00