h-lab/docs/superpowers/specs/2026-05-30-dashboard-fullset-design.md

4.7 KiB

대시보드 풀세트 강화 — 설계

작성일: 2026-05-30 상태: 승인됨 (구현 대기)

목적

홈 대시보드에서 파이프라인 전체(수집→큐레이션→재가공→발행)를 한눈에 본다. 현재 빠진 완료(DONE)·발행(publish) 현황·카테고리 분포를 채우고 단계별 흐름을 시각화한다.

제약 / 비범위

  • 시계열 추이 없음: ChannelVideo에 수집 시각 필드가 없어(있는 건 영상 업로드일 publishedAt) "날짜별 수집량" 차트는 만들지 않는다. "현재 스냅샷" 중심.
  • AI/외부 호출 없음.
  • 차트 라이브러리 추가 없음 — 막대는 CSS(div 너비 %)로 그린다. (채널 성장 차트가 쓰는 Chart.js는 CDN으로 이미 있으나 대시보드엔 도입 안 함, YAGNI.)

현재 상태

  • dashboard.html: KPI 카드 3개(수집 총계/TARGET/NEW) + 떡상 후보 TOP5 + 수집 출처. /api/v1/channel-videos/stats·/outperformers 를 각각 fetch.
  • pipelineStats()(curation): total, byStatus(NEW/REVIEWING/TARGET/DONE/EXCLUDED), bySource(CHANNEL/SEARCH) 반환.
  • 발행/카테고리 집계는 대시보드에 없음.

화면 구성 (dashboard.html 재작성)

  1. KPI 카드 5개: 수집 총계 · 미검토(NEW) · 작업대상(TARGET) · 완료(DONE) · 발행완료(PUBLISHED). (뒤 2개 신규)
  2. 파이프라인 깔때기: 수집 → 검토중 → 작업대상 → 완료 → 발행완료 가로 막대(각 단계 너비 = 총계 대비 %). 제외(EXCLUDED)는 깔때기 밖 작은 뱃지로 별도 표기.
  3. 2단: 떡상 후보 TOP5(기존 유지) | 발행 현황(DRAFT/READY/PUBLISHED 카운트 막대 + 최근 5건 목록).
  4. 2단: 카테고리 분포(카테고리 색상 막대 + 건수 + 총계 대비 %, 미분류 포함) | 수집 출처 & 포맷(채널/검색 + Shorts/롱폼 비율).

전체는 단일 호출 GET /api/dashboard/summary 로 받아 렌더(현재의 다중 fetch 제거).

백엔드

단위와 책임

  1. ChannelVideoRepository (수정) — 카운트 2개 추가:
    • long countByIsShortsTrue();
    • long countByCategoryIdIsNull();
  2. PublishPackageRepository (수정) — long countByStatus(String status);
  3. ChannelVideoCurationService.pipelineStats() (수정) — 기존 반환에 shorts(Shorts 수), longForm(total - shorts) 키 추가. (기존 키 유지 → 보드 등 하위호환)
  4. CategoryService.distribution() (신규) — Map: categories=[{id,name,color,count}], uncategorized=미분류 수. (이미 categoryRepository + channelVideoRepository 보유)
  5. PublishService.dashboardSummary() (신규) — Map: byStatus={DRAFT,READY,PUBLISHED}, recent=최신 5건(list(null) 앞 5개).
  6. DashboardService.summary() (신규, service 패키지) — 위 서비스들을 조합해 하나의 Map 반환:
    { pipeline: pipelineStats(),            // total, byStatus, bySource, shorts, longForm
      categories: categoryService.distribution(),
      publish: publishService.dashboardSummary(),
      outperformers: curationService.findOutperformers(5, BigDecimal.ONE) }
    
    의존: ChannelVideoCurationService, CategoryService, PublishService (서비스만 조합, 리포지토리 직접 접근 없음).
  7. DashboardApiController (신규, web 패키지) — GET /api/dashboard/summaryApiResponse<Map<String,Object>>.

데이터 흐름

dashboard.html (진입)
  → GET /api/dashboard/summary
    → DashboardService.summary()
       ├ curationService.pipelineStats()      (+shorts/longForm)
       ├ categoryService.distribution()
       ├ publishService.dashboardSummary()
       └ curationService.findOutperformers(5, 1)
  → KPI/깔때기/떡상/발행/카테고리/출처 렌더

에러 / 빈 상태

  • summary 호출 실패: 각 섹션에 "불러오기 실패" 표시(현재 dashboard.html 의 try/catch 패턴 유지, 단 단일 호출).
  • 데이터 0: 깔때기·분포는 0% 막대 + "아직 데이터가 없습니다" 류 안내. 떡상 0건은 기존 문구 유지.
  • 백필 안 된 옛 영상으로 shorts/비율이 0이어도 화면은 정상(0 표기).

검증 방법

테스트 인프라가 없으므로(기존 관행) compileJava + bootRun 기동(빈/쿼리 에러 0건) + (UI 수동 확인은 사용자가 나중에 일괄).

영향 / 변경 파일 요약

신규: DashboardService, DashboardApiController, 스펙 문서. 수정: ChannelVideoRepository(count 2), PublishPackageRepository(count 1), ChannelVideoCurationService(pipelineStats 확장), CategoryService(distribution 추가), PublishService(dashboardSummary 추가), dashboard.html(재작성). 기존 페이지/엔드포인트(보드·수집함·발굴 등)는 영향 없음.