From b7e558545e3f140aa6f863618ca16e88dbbe2e9c Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 3 May 2026 07:03:27 +0000 Subject: [PATCH] fix(billing): stop double-counting realtime bandwidth into bandwidth MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backend already rolls realtimeBandwidth value + amount into the bandwidth resource, so the previous commit was summing them again (value + amount), inflating both the displayed total and the priced amount, and over-driving the progress bar. Use bandwidth?.value / bandwidth?.amount directly (already include realtime). For the multi-segment progress bar, carve the realtime slice out of the total instead of summing — regular = total - realtime, realtime = realtime — so the segments add to the actual bandwidth total. Same neutral colour family as before, no multi-colour added. Clamps realtime to [0, total] in case of dirty data. --- .../billing/planSummary.svelte | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte index 5f4e08b1d..11e25948f 100644 --- a/src/routes/(console)/organization-[organization]/billing/planSummary.svelte +++ b/src/routes/(console)/organization-[organization]/billing/planSummary.svelte @@ -149,17 +149,20 @@ } function createBandwidthProgressData( - regularBytes: number, + totalBytes: number, realtimeBytes: number, maxGB: number ): Array<{ size: number; color: string; tooltip?: { title: string; label: string } }> { if (maxGB <= 0) return []; const maxBytes = maxGB * 1000 * 1000 * 1000; - const total = regularBytes + realtimeBytes; - const percentage = Math.min((total / maxBytes) * 100, 100); - const regularSize = humanFileSize(regularBytes); - const realtimeSize = humanFileSize(realtimeBytes); + const percentage = Math.min((totalBytes / maxBytes) * 100, 100); + // Backend already rolls realtimeBytes into totalBytes; carve the realtime + // slice out of the total instead of summing them. Clamp in case of dirty data. + const realtimePortion = Math.max(0, Math.min(realtimeBytes, totalBytes)); + const regularPortion = Math.max(0, totalBytes - realtimePortion); + const regularSize = humanFileSize(regularPortion); + const realtimeSize = humanFileSize(realtimePortion); const segments: Array<{ size: number; @@ -167,9 +170,9 @@ tooltip?: { title: string; label: string }; }> = []; - if (regularBytes > 0) { + if (regularPortion > 0) { segments.push({ - size: regularBytes, + size: regularPortion, color: 'var(--bgcolor-neutral-invert)', tooltip: { title: `${percentage.toFixed(0)}% used`, @@ -178,9 +181,9 @@ }); } - if (realtimeBytes > 0) { + if (realtimePortion > 0) { segments.push({ - size: realtimeBytes, + size: realtimePortion, color: 'var(--bgcolor-neutral-invert-weak)', tooltip: { title: 'Realtime bandwidth', @@ -330,11 +333,11 @@ const storage = getResource(resources, 'storage'); const authPhone = getResource(resources, 'authPhone'); + // Backend already rolls realtimeBandwidth value + amount into bandwidth; + // use the bandwidth resource directly and pass realtime only as a slice + // for the progress segment, never as an additive total. const bandwidthValue = bandwidth?.value || 0; const realtimeBandwidthValue = realtimeBandwidth?.value || 0; - const combinedBandwidthValue = bandwidthValue + realtimeBandwidthValue; - const combinedBandwidthAmount = - (bandwidth?.amount || 0) + (realtimeBandwidth?.amount || 0); return { id: `project-${projectData.$id}`, @@ -353,16 +356,16 @@ label: 'Bandwidth', resource: bandwidth, planLimit: currentPlan?.bandwidth, - usageFormatter: ({ planLimit, hasLimit }) => + usageFormatter: ({ value, planLimit, hasLimit }) => formatBandwidthUsage( - combinedBandwidthValue, + value, hasLimit ? (planLimit ?? undefined) : undefined ), - priceFormatter: () => formatCurrency(combinedBandwidthAmount), - progressFactory: ({ planLimit, hasLimit }) => + priceFormatter: ({ amount }) => formatCurrency(amount), + progressFactory: ({ value, planLimit, hasLimit }) => hasLimit ? createBandwidthProgressData( - bandwidthValue, + value, realtimeBandwidthValue, planLimit || 0 )