예능 전환 2단계 — 소재 발굴을 예능 쪽으로 강화하고, 매일 아침 추천을 자동으로 받는다.
발굴 예능 특화
- ChannelDiscoveryService: 지역 인기 Shorts 발굴에 더해, 설정된 예능 키워드
(hlab.discovery.keywords, 기본 "예능,방송,하이라이트")로 지역×키워드 Shorts를
조회수순 검색해 예능 클립 소재 채널을 우선 발굴.
- 매 검색마다 쿼터 가드, 소진 시 전체 발굴 중단(라벨 break). 키워드 비면 기존 동작 유지.
텔레그램 아침 추천
- TelegramNotifier 신규(global/notify): bot-token/chat-id 미설정 시 no-op,
발송 예외는 삼켜 호출측을 깨지 않음. @Qualifier("restTemplate") 주입.
- 매일 04:30 발굴 직후 NEW 추천채널 상위 N개를 한국어 HTML 다이제스트로 발송.
- 활성화: env TELEGRAM_BOT_TOKEN / TELEGRAM_CHAT_ID 설정.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
느려짐의 유력 원인 두 가지를 정리한다.
1) p6spy가 모든 SQL을 파라미터값 포함해 매번 로깅하던 것을 기본 OFF로.
디버깅 시 P6SPY_LOGGING=true 로 켠다.
2) channel_videos에 인덱스가 하나도 없어 데이터가 늘면 풀스캔이었다.
리포지토리의 실제 필터/정렬 컬럼에 인덱스 추가(ddl-auto가 자동 생성):
video_id, channel_id, interest_status, source, category_id,
published_at, views_per_sub_ratio
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
유통(내가 올려서 발행)에서 예능 소재 파이프라인으로 방향을 틀면서
발행 큐 기능을 제거한다. domain/publish 전체와 발행 준비 UI(재가공 화면),
사이드바 발행 큐 링크, 대시보드 발행 현황 위젯을 걷어냈다.
- domain/publish/* (Controller/Service/Repository/Entity) 삭제
- publish.html · PublishServiceTest 삭제
- rework.html 발행 준비 섹션·JS 제거
- dashboard.html · DashboardService 발행 집계 제거
- WebController /publish 라우트, sidebar 링크 제거
- ChannelVideo.publishedAt(원본 게시일)은 발행 기능과 무관하여 그대로 유지
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
카드 레이아웃은 유지한 채 댓글 내용 텍스트만 확대/축소하는 A−/A+ 스테퍼와,
배경을 기본→흰색→검정 순환하는 토글 추가. 검정 배경일 때 글자는 흰색으로 대비 확보.
배율은 카드 인라인 변수(--cc-text-scale)로 지정해 재렌더·PNG 캡처에도 그대로 반영됨.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- surface-2는 다크에서 배경과 거의 같아 color-mix로 텍스트색을 섞어 확실한 회색으로
- 왼쪽 accent 바 + 흐림(opacity)로 저장 여부를 한눈에 구분
- 렌더 루프에서 카드마다 lucide.createIcons()를 호출하던 것 제거(전체 스캔 반복 방지)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 저장 완료 카드에 회색 톤(.saved)과 '저장됨 ✓' 버튼 상태 부여
- 저장 표시는 화면 전용: 캡처 직전 .saved를 벗겨 PNG엔 남지 않음
- 댓글에 고유 id를 붙여 필터·정렬 재렌더 후에도 저장 표시 유지
- '저장 폴더' 버튼 재클릭 시 지정 해제 → 브라우저 다운로드 폴더로 저장
(해제 이후 '전체 저장'은 폴더를 다시 묻지 않음)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- '저장 폴더' 버튼(File System Access API)으로 폴더를 한 번 고르면
⬇ 저장·전체 저장이 그 폴더로 바로 저장(이 사이트 세션에만 적용)
- '전체 저장' 버튼: 현재 표시된 카드를 순서대로 일괄 저장(진행 표시)
- 미지원 브라우저(파이어폭스/사파리)는 폴더 버튼 숨김·기존 다운로드 폴백
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 토글(모자이크/모서리/단어가리기) ON 상태 accent로 시각화 + aria-pressed
- 검색·좋아요 필터 200ms 디바운스(대량 카드 렉 완화), 아바타 loading=lazy
- 수집 중 스피너, prefers-reduced-motion 대응
- 작은 회색 글자 대비 상향(text-3→text-2), 숫자 tabular-nums
- 아이콘 버튼/셀렉트 터치 타깃 확대, 입력 16px(iOS 확대 방지)
- 월별 댓글량 값 상시 노출(hover 의존 제거)
- 카드 키보드 접근(role/tabindex/Enter·Space 복사), focus-visible 링
- 섹션 아이콘 이모지→Lucide 통일(카드 내 👍💬는 export용 유지)
- 입력 aria-label, 결과 URL ?v= 딥링크(공유·새로고침 유지)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
기본은 댓글 단어 클릭 시 해당 단어만 블러(다시 클릭 해제).
'🖍 단어 가리기' 토글을 끄면 카드 클릭=이미지 복사로 전환.
블러는 캡처 PNG에도 그대로 반영됨.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 수집 상한 1,000→20,000개(안전 상한)로 상향해 전체 댓글 기준 분석
- 분석 패널: 많이 언급된 타임라인(클릭 시 해당 시점 유튜브 이동), 자주 나온 단어(조사 제거+불용어, 좋아요 가중 토글), 요약 통계(총/평균 좋아요·참여자·최다 좋아요 댓글·월별 댓글량)
- 모자이크 기본 ON, '모서리 둥글게' 토글 추가(기본 각진 모서리)
- 카드 렌더는 상위 2,000개로 제한(브라우저 보호), 분석은 전체 기준
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
필터바에 검색 입력창 추가 → 입력 즉시 댓글 내용에 그 단어가 포함된 카드만 노출
(작성자 제외, 내용만 매칭). 클라이언트 필터라 추가 API 호출 없음. JS 캐시버스터 갱신.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
캡컷은 클립보드 이미지 붙여넣기를 못 받아 파일 불러오기가 필요 → 카드별 '⬇ 저장' 버튼으로
PNG 다운로드 제공. 저장 버튼은 cc-noexport+modern-screenshot filter로 캡처 이미지에서 제외.
카드 클릭=클립보드 복사는 유지.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
복사 버튼이 캡처 이미지에 함께 찍히던 문제 해결. 버튼을 없애고 카드 자체 클릭으로
복사하도록 변경, 완료 피드백은 카드 밖 토스트로 표시(캡처에 미포함). JS 캐시버스터 갱신.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
grid가 행 단위로 최대 높이에 맞춰 늘어나던 것을 CSS 다단(column)으로 변경.
각 카드가 내용 높이에 맞고 빈틈없이 쌓이도록 break-inside:avoid + margin-bottom 적용.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
commentThreads가 order=relevance에서 간헐적으로 403 forbidden을 반환하는 문제 대응.
generic 403/rateLimit/5xx는 백오프 후 최대 2회 재시도, commentsDisabled/quotaExceeded는
재시도 없이 즉시 안내. 재시도 성공/비재시도 단위 테스트 추가.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
403을 무조건 '댓글 비활성화'로 표시하던 문제 수정. error.errors[0].reason을 파싱해
commentsDisabled/quotaExceeded/기타(keyInvalid 등)를 각각 안내하고, 비-403 오류가
opaque 500으로 새던 것도 의미있는 메시지로 노출. 단위 테스트 추가.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
HTML5 드래그가 터치에서 동작 안 하는 문제 — 카드마다 상태 드롭다운을 두어
터치로도 컬럼 이동 가능. 데스크톱은 드래그 유지(드롭다운은 모바일/터치에서만 노출).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Channel 에 country 추가(YouTube snippet.country 저장), 추천 채널 region 으로 기존 채널
백필(POST /api/channels/backfill-country), /channels 에 국가 탭+카운트 필터.
선택 영상 보기 버튼 한글화.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
querySelector('i')가 lucide 치환 후 null→TypeError로 시각 토글이 첫 카드에서 멈춰
전체 선택이 안 되는 것처럼 보였음. querySelector('svg, i') + null 가드로 수정.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 목록 API status 파라미터(NEW|EXCLUDED|REGISTERED), POST /{id}/restore(→NEW)
- recommend.html: 헤더 '제외 목록' 토글로 EXCLUDED 채널 보기, 카드에 '복원' 버튼
(제외 보기에선 등록/제외 대신 복원+채널이동만), 지역 탭은 그대로 적용
검증: 제외→EXCLUDED 목록 노출→복원→NEW 복귀 end-to-end 확인.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- region 을 채널 국가가 아닌 '검색 발견 지역(regionCode)'으로 태깅(UNKNOWN 해소)
- upsert: 같은 배율이면 갱신(지역 등 메타 최신화)
- recommend.html: 전체/KR/JP/US 탭으로 필터, 등록/제외 시 목록 갱신
검증: 재발굴 후 KR14·JP7·US1 로 분포, 탭 필터 동작.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
지역(KR,JP,US) 인기 Shorts 주기 검색 → 작은구독자·고배율 떡상 채널 발굴 →
RecommendedChannel 저장 → /recommend 페이지에서 등록/제외. 쿼터 가드·기존 검색 재사용.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
URL자막 버튼 제거에 따라 안내문/placeholder의 'URL자막' 언급 삭제,
미사용 함수 extractScript/translateToEditor 제거(copyToEditor는 유지).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>