Commit Graph

4 Commits

Author SHA1 Message Date
e5205d9e9c feat: 내 채널 분석 페이지 분리 — OWN 역할 + 소재별 성과 랭킹
내 채널을 등록하면 그 영상이 수집함·칸반에 소재로 섞여 들어갔다. 이미 발행한
영상은 소재가 아니라 성과이므로 아예 분리한다.

- ChannelRole.OWN 추가. OWN 채널 영상은 source=OWN 으로 저장되고, 수집함·칸반·
  발굴 쿼리는 CHANNEL·SEARCH 화이트리스트라 자동으로 격리된다(쿼리 수정 불필요).
  /channels 목록에도 안 뜨고 피드에도 안 섞인다.
- /my-channel 신설: 성과 요약(구독·총조회·영상평균·최근30일), 성장 추이 차트,
  내 영상 목록.
- 핵심은 소재별 성과 랭킹(TopicPerformance). 해시태그별 평균 조회수를 채널 평균
  대비 배수로 보여준다. 실제 데이터로 유퀴즈 2.43x, 워크맨 0.30x 처럼 갈려서
  피드에서 무엇을 자를지 판단하는 근거가 된다. 1편짜리 우연은 2편 미만 컷으로 제외.
- 자동 수집·스냅샷 대상에 OWN 포함(findTrackedChannels). 해시태그 역분석의
  원천도 MY → OWN 으로 바꿨다.

테스트 8건 추가(TopicPerformance 6, ChannelRole 2) — 총 84건 통과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 18:28:31 +09:00
32540d1ceb fix: 내 채널이 없을 때 후보 자동 발굴이 조용히 0건으로 끝나던 문제
내 채널을 등록하면 그 영상이 수집함·칸반에 소재로 섞여 들어가서 등록을
취소했다. 그러면 해시태그 역분석의 원천이 사라지는데, 기존 코드는 키워드
0개로 검색 루프를 그냥 빠져나와 "발굴했지만 아무것도 못 찾음"처럼 보였다.

- 역분석할 해시태그가 없으면 이유를 명시한 오류를 던진다.
- 피드 화면의 '후보 자동 발굴'은 먼저 감지된 키워드를 보여주고 확인을 받는다.
  키워드가 없으면 프로그램 이름을 직접 입력받아 검색한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-02 09:41:59 +09:00
2574174d22 fix: 시드 자동 발굴이 엉뚱한 채널을 잡던 문제 — 채널검색→영상검색 집계, 이중 인코딩 제거
실제 내 채널(clipOut-log) 데이터로 돌려보니 구독자 1~2명짜리 채널만
잡혀서 원인을 둘 찾았다.

1) type=channel 검색은 채널 '이름'을 매칭한다. 프로그램 클립은 "유퀴즈"라는
   이름의 채널이 아니라 tvN D ENT·뜬뜬 같은 제작사 채널에 올라오므로
   이름으로는 절대 찾을 수 없다. type=video 로 25건을 뽑아 채널별로 집계하고
   3건 이상 등장한 채널만 채택하도록 바꿨다.

2) UriComponentsBuilder.encode().toUriString() 을 RestTemplate 에 String 으로
   넘기면 URI 템플릿으로 보고 한 번 더 인코딩한다. 한글 키워드가
   %25EC.. 로 깨져 검색어가 무의미해졌다. URI 오버로드로 교체.
   ChannelService.saveChannelFromUrl 도 한글 @핸들에서 같은 문제가 생기므로
   함께 고쳤다. (YoutubeSearchService 등 기존 코드는 이미 올바르게 쓰고 있었다)

수정 후 8개 키워드 전부 정확한 공식채널을 찾는다:
유퀴즈→tvN D ENT/디글 클래식, 워크맨→워크맨-Workman, 살롱드립→TEO 테오,
짠한형 신동엽·미미미누·핫이슈지·입만열면→각 공식채널.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 09:04:16 +09:00
592ed12c2b feat: 소재 발굴 피드 — 소스 롱폼/경쟁 쇼츠 최신순 2탭
쇼츠 클립 채널의 소재를 최신순으로 발굴하는 /feed 화면과 수집 파이프라인.

- 소재 원본 탭: 웹예능 공식채널의 신규 롱폼(durationSec > 65)만 수집.
  아직 아무도 안 자른 구간을 선점하는 용도라 공식계정 쇼츠는 제외한다.
- 경쟁 쇼츠 탭: 예능짤 채널의 신규 쇼츠. 제목·썸네일 벤치마킹용이라
  재가공 대신 원본 열기 액션을 준다.
- Channel.role(MY/SOURCE/RIVAL) 컬럼 하나로 역할을 구분하고, 기존
  uploads 플레이리스트 동기화를 그대로 재사용한다. 채널당 2 units라
  search.list(100 units) 대비 쿼터가 거의 들지 않는다.
- 3시간 주기 수집(FeedCollectionService). 소재 선점은 업로드 직후가
  승부라 기존 일 1회 채널 수집으로는 늦다.
- 수집함/발굴/떡상 후보 쿼리는 source 미지정 시 CHANNEL·SEARCH만 보도록
  좁혀, 피드 영상이 기존 화면을 덮지 않게 격리했다.
- 시드는 자동 후보 → 수동 승인. 내 채널 해시태그를 역분석해(HashtagExtractor)
  공식채널 후보를 추천 목록에 쌓고, 승인 시 SOURCE/RIVAL로 등록한다.
- 연속 3회 수집 실패한 시드는 자동 스킵해 쿼터 낭비를 막는다.
- role이 null인 기존 채널은 부팅 시 MY로 1회 백필(ddl-auto:update 특성).

UX: 기존 Editorial 디자인 시스템 유지. 골든타임(24h)·공식클립/풀에피·
떡상중·작업함 배지, 프로그램/길이/기간 필터, URL 상태 보존, 스켈레톤·
빈 상태·에러 복구 액션, 탭 키보드 이동, 이모지 대신 Lucide 아이콘.

테스트: HashtagExtractor·FeedBadges·ChannelRole 순수 로직 16건 추가(총 76건 통과).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:42:26 +09:00