fix: 내 채널이 없을 때 후보 자동 발굴이 조용히 0건으로 끝나던 문제

내 채널을 등록하면 그 영상이 수집함·칸반에 소재로 섞여 들어가서 등록을
취소했다. 그러면 해시태그 역분석의 원천이 사라지는데, 기존 코드는 키워드
0개로 검색 루프를 그냥 빠져나와 "발굴했지만 아무것도 못 찾음"처럼 보였다.

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

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
hehihoho3@gmail.com 2026-08-02 09:41:59 +09:00
parent 2574174d22
commit 32540d1ceb
2 changed files with 26 additions and 2 deletions

View File

@ -97,6 +97,13 @@ public class SeedSuggestService {
if (targets.size() >= maxKeywords) break; if (targets.size() >= maxKeywords) break;
targets.add(k); targets.add(k);
} }
// 채널이 등록돼 있지 않으면 역분석할 해시태그가 없다. 조용히 0건으로 끝내면
// 사용자는 "발굴했는데 아무것도 못 찾았다" 오해하므로 이유를 분명히 말한다.
if (targets.isEmpty()) {
throw new IllegalArgumentException(
"역분석할 해시태그가 없습니다. 내 채널이 등록돼 있지 않거나 수집된 영상에 해시태그가 없습니다. "
+ "키워드를 직접 입력해 발굴하세요.");
}
} }
int searched = 0, found = 0, saved = 0, skippedByQuota = 0; int searched = 0, found = 0, saved = 0, skippedByQuota = 0;

View File

@ -648,10 +648,27 @@
} }
async function suggestSeeds(){ async function suggestSeeds(){
if(!confirm('내 채널 해시태그를 역분석해 소재 원본 후보를 찾습니다.\n키워드 1개당 YouTube 쿼터 100 units 를 씁니다. 진행할까요?')) return; // 내 채널이 등록돼 있으면 해시태그를 역분석하고, 없으면 키워드를 직접 받는다.
let detected = {};
try { detected = await api(API + '/seeds/keywords') || {}; } catch(e){ detected = {}; }
const tags = Object.keys(detected);
let keywords = null;
if(tags.length > 0){
const preview = tags.slice(0, 8).map(t => `#${t}(${detected[t]})`).join(' ');
if(!confirm(`내 채널에서 찾은 키워드로 소재 원본 채널을 검색합니다.\n\n${preview}\n\n키워드 1개당 쿼터 100 units. 진행할까요?`)) return;
} else {
const input = prompt('내 채널이 등록돼 있지 않아 자동 역분석을 못 합니다.\n프로그램 이름을 쉼표로 구분해 입력하세요. (키워드당 쿼터 100 units)',
'유퀴즈, 핑계고, 살롱드립');
if(input == null) return;
keywords = input.split(',').map(s => s.trim()).filter(Boolean);
if(keywords.length === 0) return;
}
try { try {
const r = await api(API + '/seeds/suggest', { const r = await api(API + '/seeds/suggest', {
method:'POST', headers:{'Content-Type':'application/json'}, body:'{}' method:'POST', headers:{'Content-Type':'application/json'},
body: JSON.stringify(keywords ? { keywords } : {})
}); });
toast(`후보 ${r.saved}개를 추천 채널에 담았습니다 — 추천 채널 화면에서 승인하세요`); toast(`후보 ${r.saved}개를 추천 채널에 담았습니다 — 추천 채널 화면에서 승인하세요`);
} catch(e){ toast('발굴 실패: ' + e.message, true); } } catch(e){ toast('발굴 실패: ' + e.message, true); }