Commit Graph

191 Commits

Author SHA1 Message Date
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
e9d3f9a9f4 feat: 소재 피드에서 숏폼 큐로 바로 보내기
발굴한 롱폼을 숏폼 큐로 넘기는 동선이 없어 URL을 손으로 옮겨야 했다.
채널 등록·롱폼 수집·정보 표시는 이미 소재 피드에 있으므로 페이지를 새로
만들지 않고 카드에 버튼만 붙였다.

- 소재 원본/인물 탭 카드의 주 버튼을 '숏폼 큐로'로 바꿨다. 경쟁 쇼츠는 이미
  잘린 결과물이라 큐 대상이 아니라 원본 보기만 남긴다.
- 피드를 열 때 큐 목록을 함께 받아 이미 담긴 영상은 '큐에 있음'으로 표시하고
  숏폼 큐로 링크한다. 등록 API가 videoId 기준 멱등이라 중복 클릭도 안전하다.
- 기존 재가공 스튜디오 진입은 아이콘 버튼으로 남겼다.
- 큐 목록 조회가 실패해도 피드 자체는 정상 동작한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 09:13:51 +09:00
9a960be663 feat: 숏폼 큐에 전체 Output 복사 버튼 — capcut2 오팔 JSON 탭 통짜 붙여넣기용
JobDetail에 rawOutput 노출, 카드 펼침 상단에 전체 복사·영상 URL 복사 툴바 추가.
capcut2가 구분선·타이틀 후보 섞인 통짜 텍스트에서 JSON 5개를 알아서 뽑고
타이틀은 자체 선택 화면에서 고르므로 원문 그대로 복사한다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:48:47 +09:00
de30174cd1 feat: shortform-queue 스킬 — Opal 브라우저 대행 절차 명문화
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:39:30 +09:00
be96f68f6f feat: 숏폼 큐 페이지 — URL 등록·결과 붙여넣기·클립 카드·JSON 복사
사이드바 소재 섹션에 '숏폼 큐' 메뉴 추가.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:39:30 +09:00
db6a9831b6 feat: 숏폼 큐 서비스·REST API — 등록/조회/결과저장/import/삭제
status=PENDING 필터는 shortform-queue 스킬의 큐 조회용.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:39:29 +09:00
005df3225b feat: 숏폼 큐 엔티티(ShortformJob/Clip)와 리포지토리
rawOutput은 파싱 성공 여부와 무관하게 원문 보존. videoId 유니크로 중복 등록 방지.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:39:29 +09:00
3fda9077a6 feat: 유튜브 URL videoId 추출 유틸
watch/shorts/embed/live/youtu.be 지원, 11자 ID 검증.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:39:29 +09:00