feat(ui): 단계별 현황 재설계 — 완료 가시화 + 빈 단계 숨김 (사용자 피드백)

'대기만 보이고 성공은 안 보인다' 피드백 반영:
- overview 에 stages[] 노출 (stage 별 done_today + oldest_pending_age, SQL 1필드 추가)
- 게이지 의미 전환: 단계 간 대기량 비교(amber) → 단계 내 오늘 진척(완료=green 비율,
  가득 찬 초록 = 다 끝남) + 처리 중 pulse dot
- 움직임 없는 단계는 행 제거, 하단 '비어 있음: ...' 한 줄로
- 라벨 누수 fix: details 가 구 STAGE_LABEL 을 쓰던 것 → queueStageLabel 통일
  (deep_summary/markdown/summarize/chunk/fulltext 한글화)
- 헤더: 오늘 N 완료(성공 가시화) · 실패(error) · 대기. 데이터 소스 = overview 단일화

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
hyungi
2026-06-11 14:26:27 +09:00
parent 468804494d
commit 7031439364
5 changed files with 148 additions and 34 deletions
+26 -1
View File
@@ -329,7 +329,7 @@ def test_compose_overview_contract_shape():
deep_enabled=True,
now_kst=datetime(2026, 6, 11, 14, 30, tzinfo=KST),
)
assert set(out.keys()) == {"machines", "summarize_eta", "trend_24h", "totals"}
assert set(out.keys()) == {"machines", "stages", "summarize_eta", "trend_24h", "totals"}
assert [m["key"] for m in out["machines"]] == ["gpu", "macmini", "macbook"]
for m in out["machines"]:
assert set(m.keys()) == {
@@ -343,3 +343,28 @@ def test_compose_overview_contract_shape():
assert set(out["totals"].keys()) == {"pending", "processing", "failed"}
# 머신 label 고정 (raw 모델명 노출 금지 — label 만)
assert [m["label"] for m in out["machines"]] == ["GPU 서버", "맥미니", "맥북 M5 Max"]
# ─── build_stages (단계별 현황 — 2026-06-11 사용자 피드백: 완료 가시화) ──────
def test_build_stages_order_fields_and_age():
from datetime import timedelta, timezone
from services.queue_overview import build_stages
now = datetime(2026, 6, 11, 14, 0, tzinfo=timezone.utc)
stats = {
"summarize": {**_stage(pending=5, done_today=12),
"oldest_pending_at": now - timedelta(hours=4)},
"extract": _stage(failed=2),
}
rows = build_stages(stats, now=now)
by = {r["stage"]: r for r in rows}
# 파이프라인 순서: extract 가 summarize 보다 앞
assert rows[0]["stage"] == "extract"
assert by["summarize"]["pending"] == 5
assert by["summarize"]["done_today"] == 12
assert by["summarize"]["oldest_pending_age_sec"] == 4 * 3600
assert by["extract"]["failed"] == 2
assert by["extract"]["oldest_pending_age_sec"] is None
# 전 stage 행 존재 (빈 단계 숨김은 FE 몫)
assert {"stage", "pending", "processing", "failed", "done_today",
"oldest_pending_age_sec"} == set(rows[0].keys())