From 595f4b7d5ef7ec7eafb9f56b9cd24cd945156a6e Mon Sep 17 00:00:00 2001 From: hyungi Date: Sat, 13 Jun 2026 14:01:50 +0900 Subject: [PATCH] =?UTF-8?q?feat(board):=20=ED=86=B5=ED=95=A9=20=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20v3=20=E2=80=94=20=EB=A8=B8=EC=8B=A0=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B8=20+=20=EC=A0=95=EC=A7=81=20=EB=B2=88=EB=8B=A4?= =?UTF-8?q?=EC=9A=B4/ETA=20(B-1=C2=B72=C2=B73=C2=B75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ProcessingFlowBoard 를 통합안으로 재작성: - 머신 3레인(GPU/맥미니/맥북) = "누가 일하나" + 요약 오프로드 가시화 (요약 칩 분담 막대 맥미니 vs 맥북 + 맥북 레인 '요약 합류' 칩, summarize_by_machine 소비) - 지배 백로그 스트립 + 정직 ETA(summarize_eta, 유입 차감 / null=소진 불가) - 24h 번다운 SVG(유입 vs 소화) + 맥북 합류 변곡점 + 단계별 정직 ETA 미니리스트 - 신선도 '갱신 N초 전' + stale 경고(queueUpdatedAt, B-4) - 실패 드로어 + 노드 상세 패널은 v2 자산 그대로 재사용 - 레인 stack + 칩 wrap 으로 모바일 반응형 svelte-check: 변경 파일 에러 0. Co-Authored-By: Claude Fable 5 --- .../lib/components/ProcessingFlowBoard.svelte | 282 ++++++++++++------ 1 file changed, 195 insertions(+), 87 deletions(-) diff --git a/frontend/src/lib/components/ProcessingFlowBoard.svelte b/frontend/src/lib/components/ProcessingFlowBoard.svelte index f66bf77..16752dc 100644 --- a/frontend/src/lib/components/ProcessingFlowBoard.svelte +++ b/frontend/src/lib/components/ProcessingFlowBoard.svelte @@ -1,16 +1,18 @@
- +
처리 머신
@@ -219,80 +297,107 @@ onclick={openFailures} >실패 {totalFailed}건 처리 {/if} - {#if spark} -
- - - - - 요약 24h 유입/소화 -
- {/if} + + + {freshLabel}{#if stale} · 갱신 지연{/if} +
- -
- {#each machineStrip as m (m.key)} -
- - {m.meta?.label ?? m.label} - {m.meta?.model} - {formatRate(m.done_1h)}/h - {#if m.key === 'macbook' && m.deferred_pending > 0} - 보류 {m.deferred_pending} - {/if} + +
+ 지배 백로그 + 요약 + 대기 {eta.pending.toLocaleString()} · 순소화 {formatRate(eta.done_rate_1h)}/h · 유입 {formatRate(eta.inflow_rate_1h)}/h + + 정직 ETA + {honestEtaLabel} + +
+ + +
+ {#each lanes as lane (lane.key)} +
+
+ + {lane.meta.label} + {lane.meta.model} + {formatRate(lane.card?.done_1h ?? 0)}/h + {#if lane.key === 'macbook' && (lane.card?.deferred_pending ?? 0) > 0} + 보류 {lane.card?.deferred_pending} + {/if} + {#if lane.card?.state === 'deferred'} + 잠듦 — 요약은 맥미니로 복귀 + {/if} +
+
+ {#each lane.nodes as n (n.def.key)} + {@const idle = n.pending + n.processing + n.doneToday + n.failed === 0} + + {/each} + {#if lane.key === 'macbook' && offloadActive} + + {/if} +
{/each}
- -
- {#each mainNodes as n, i (n.def.key)} - {#if i > 0} - - {/if} -
toggleNode(n.def.key)} - onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleNode(n.def.key); } }} - title="{n.def.label} — 클릭하면 상세" - > - {#if n.failed > 0} - - {/if} - - {MACHINE_META[n.def.machine].label} · {n.def.engine} - -
- {n.def.label} - {#if n.processing > 0} - - {/if} - {#if n.inflowDominant} - 유입 우세 - {/if} -
-
- {n.pending.toLocaleString()} -
-
- {formatRate(n.done1h)}/h · 오늘 {n.doneToday.toLocaleString()} - {#if n.etaMinutes != null && !n.inflowDominant && n.pending > 0} - · {etaShort(n.etaMinutes)} - {/if} -
+ + {#if burn} +
+
+ 요약 백로그 24시간 + 유입(회색) vs 소화(녹색) + {#if offloadActive}맥북 합류 {burn.markHour} — 소화 급증{/if}
- {/each} -
+ + + + + {#if offloadActive} + + {/if} + +
+ {#each mainNodes.filter((n) => n.pending > 0 && n.def.key !== 'summarize') as n (n.def.key)} + {n.def.label} 대기 {n.pending.toLocaleString()}{#if netEtaLabel(n)} · {netEtaLabel(n)}{/if} + {/each} +
+
+ {/if}

@@ -413,6 +518,9 @@ .mtag-gpu { background: #e7eef6; color: #3b6ea5; } .mtag-macmini { background: #efe9f7; color: #8a5fbf; } .mtag-macbook { background: #f7eedd; color: #b07a10; } + /* 요약 오프로드 분담 막대 채움 (맥미니 보라 / 맥북 황) */ + .mtag-macmini-bar { background: #8a5fbf; } + .mtag-macbook-bar { background: #b07a10; } .node-sel { outline: 2px solid #3b6ea5; outline-offset: 1px; } .detail-frame { border-color: #3b6ea5; } .detail-head { background: #e7eef6; }