From 41e98ca5df27f8fd9aa214c7dd684b8908c406f6 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 Jul 2026 07:44:34 +0000 Subject: [PATCH] fix(procurement): exclude speed=0 signals + consistent speed formatting Reconciles Stock/Health working-tree WIP uncommitted since 2026-07-04: - supply-squeeze: exclude speed_gbps=0 / unclassified speed_tier=0 from price-momentum and AI-cluster-demand signals - dashboard: render transceiver speed via fmtSpd() (1600 -> 1.6T) in reorder-top, switch-compat, supply-squeeze, dead-stock-revival tables --- packages/api/src/routes/procurement.ts | 33 ++++++++++++++------------ packages/dashboard/index.html | 8 +++---- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/packages/api/src/routes/procurement.ts b/packages/api/src/routes/procurement.ts index 80f4dfe..12c250a 100644 --- a/packages/api/src/routes/procurement.ts +++ b/packages/api/src/routes/procurement.ts @@ -938,6 +938,7 @@ procurementRouter.get("/supply-squeeze", async (_req: Request, res: Response) => AND t.part_number NOT ILIKE '%AOC%' AND t.part_number NOT ILIKE '%-DAC-%' AND (t.standard_name IS NULL OR (t.standard_name NOT ILIKE '%Switch%' AND t.standard_name NOT ILIKE '%InfiniBand%')) + AND t.speed_gbps > 0 GROUP BY t.id, t.speed_gbps, t.form_factor ) SELECT @@ -955,21 +956,23 @@ procurementRouter.get("/supply-squeeze", async (_req: Request, res: Response) => GROUP BY speed_gbps, form_factor HAVING COUNT(*) >= 3 `), - // AI cluster demand by speed tier + // AI cluster demand by speed tier (speed_tier = 0 excluded — unclassified announcements) pool.query(` - SELECT - CASE - WHEN COALESCE(network_speed, title, summary, '') ILIKE '%800G%' THEN 800 - WHEN COALESCE(network_speed, title, summary, '') ILIKE '%400G%' THEN 400 - WHEN COALESCE(network_speed, title, summary, '') ILIKE '%100G%' THEN 100 - ELSE 0 - END AS speed_tier, - COALESCE(SUM(estimated_transceivers),0)::int AS total_tx, - COUNT(*)::int AS cluster_count - FROM ai_cluster_announcements - WHERE announced_date >= NOW() - INTERVAL '90 days' - GROUP BY 1 - HAVING COALESCE(SUM(estimated_transceivers),0) > 0 + SELECT speed_tier, total_tx, cluster_count FROM ( + SELECT + CASE + WHEN COALESCE(network_speed, title, summary, '') ILIKE '%800G%' THEN 800 + WHEN COALESCE(network_speed, title, summary, '') ILIKE '%400G%' THEN 400 + WHEN COALESCE(network_speed, title, summary, '') ILIKE '%100G%' THEN 100 + ELSE 0 + END AS speed_tier, + COALESCE(SUM(estimated_transceivers),0)::int AS total_tx, + COUNT(*)::int AS cluster_count + FROM ai_cluster_announcements + WHERE announced_date >= NOW() - INTERVAL '90 days' + GROUP BY 1 + HAVING COALESCE(SUM(estimated_transceivers),0) > 0 + ) t WHERE speed_tier > 0 `), // Hype phase per technology pool.query(` @@ -1047,7 +1050,7 @@ procurementRouter.get("/supply-squeeze", async (_req: Request, res: Response) => activeSignals, severity, reasons, }; }) - .filter((r) => r.activeSignals >= 1) + .filter((r) => r.activeSignals >= 1 && parseFloat(String(r.speed_gbps)) > 0) .sort((a, b) => b.activeSignals - a.activeSignals || b.price_momentum_pct - a.price_momentum_pct); res.json({ success: true, signals, criticalCount: signals.filter(s => s.severity === "critical").length }); diff --git a/packages/dashboard/index.html b/packages/dashboard/index.html index 8287f5c..22f5cc0 100644 --- a/packages/dashboard/index.html +++ b/packages/dashboard/index.html @@ -7990,7 +7990,7 @@ async function loadReorderTop() { + ''+esc(r.vendor_name||'')+'' + ''+esc(r.part_number||'')+'' + ''+esc(r.form_factor||'')+'' - + ''+esc(String(r.speed_gbps||''))+'G' + + ''+fmtSpd(r.speed_gbps)+'' + ''+str+'%' + ''+pt+' Preis · '+st+' Stock' + ''+esc(reasons.substring(0,80))+'' @@ -8106,7 +8106,7 @@ async function loadSwitchCompat() { + ''+esc(t.vendor_name)+'' + ''+esc(t.part_number||'')+'' + ''+esc(t.form_factor)+'' - + ''+esc(String(t.speed_gbps))+'G' + + ''+fmtSpd(t.speed_gbps)+'' + ''+esc(priceStr)+'' + ''+esc(t.verification_method||'')+'' + ''; @@ -8194,7 +8194,7 @@ async function loadSupplySqueeze() { var mom = s.price_momentum_pct !== 0 ? (s.price_momentum_pct > 0 ? '+' : '') + s.price_momentum_pct + '%' : '—'; var momColor = s.price_momentum_pct > 10 ? '#ef4444' : s.price_momentum_pct > 0 ? '#f59e0b' : '#22c55e'; return '' - + ''+icon+' '+esc(String(s.speed_gbps))+'G' + + ''+icon+' '+fmtSpd(s.speed_gbps)+'' + ''+esc(s.form_factor||'—')+'' + ''+esc(mom)+'' + ''+esc((s.hype_phase||'—').replace(/_/g,' '))+'' @@ -8246,7 +8246,7 @@ async function loadDeadStockRevival() { + ''+esc(r.vendor_name||'')+'' + ''+esc(r.part_number||'')+'' + ''+esc(r.form_factor)+'' - + ''+esc(String(r.speed_gbps))+'G' + + ''+fmtSpd(r.speed_gbps)+'' + ''+icon+' '+esc((r.hype_phase||'').replace(/_/g,' '))+'' + ''+Math.round(r.hype_score)+'' + ''+esc(trend)+''