/** * 수집·분석·소개문 잡이 끝났을 때의 알림 문구. * * ★ "몇 건이 새로 들어왔는가"를 말해 주지 않으면 사장님은 버튼을 눌렀는데 아무 일도 * 일어나지 않은 것으로 읽는다. 숫자는 job.result 에만 있으므로 판독은 collectJobResult 가 * 맡고, 여기서는 문구만 만든다. */ import type {JobData} from '@/api'; import {notify} from '@/lib/notify'; import {readGroup, readNote, readNumber} from './collectJobResult'; /** * 재수집(정보) 결과 알림. * * ★ `facts.stored` 하나만 보여주면 "N건이 반영됐다"로 읽힌다 — 사실이 아니다. * stored 는 **후보로 새로 쌓인 것(candidate)** 과 **값이 같아 다시 확인만 된 것(refreshed)** 의 * 합이고, 노출 중인 값은 어느 쪽이든 그대로다(fact_service 의 업데이트 프로세스). * 그래서 둘을 갈라 보여주고, 승인이 남았다는 사실을 같이 적는다. */ export function notifyCollected(job: JobData) { const facts = readGroup(job, 'facts'); const media = readGroup(job, 'media'); const stored = readNumber(facts, 'stored'); const candidate = readNumber(facts, 'candidate'); const refreshed = readNumber(facts, 'refreshed'); const photos = readNumber(media, 'stored'); if (stored === 0 && photos === 0) { notify.warn( '새로 들어온 정보가 없습니다.', readNote(job) ?? '확정된 채널에서 달라진 값을 찾지 못했습니다.', ); return; } const parts = [`확인할 새 값 ${candidate}건`, `그대로인 값 ${refreshed}건`]; if (photos > 0) parts.push(`새 사진 ${photos}장`); notify.success( '다시 수집했습니다', `${parts.join(' · ')} — 새 값은 [맞아요]를 눌러야 사이트에 나갑니다.`, ); } /** 재분석(사진) 결과 알림. 신뢰도가 낮은 건은 자동 반영되지 않고 확인 큐에 남는다. */ export function notifyVision(job: JobData) { const analyzed = readNumber(job.result, 'analyzed'); if (analyzed === 0) { notify.warn('분석한 사진이 없습니다.', readNote(job) ?? '수집된 사진이 없습니다.'); return; } notify.success( '사진을 다시 분석했습니다', `${analyzed}장 · 자동 반영 ${readNumber(job.result, 'approved')}장 · ` + `확인 대기 ${readNumber(job.result, 'needs_review')}장`, ); } /** 재생성(소개문·FAQ) 결과 알림. 생성물도 미검증으로 들어가 사람이 승인해야 나간다. */ export function notifyCopy(job: JobData) { const faqCount = readNumber(job.result, 'faqs'); const hasIntro = (job.result as {intro?: unknown} | undefined)?.intro === true; if (!hasIntro && faqCount === 0) { notify.warn( '새로 만든 문장이 없습니다.', readNote(job) ?? '근거로 쓸 확인된 정보가 부족합니다. 정보를 먼저 확인해 주세요.', ); return; } notify.success( '소개문을 다시 만들었습니다', `소개문 ${hasIntro ? '1건' : '없음'} · FAQ ${faqCount}건 — 확인하신 뒤 사이트에 나갑니다.`, ); }