Skip to content

Commit 447c404

Browse files
committed
fix(billing): deterministic apportionment order, block audit export during stale data
Cursor Bugbot caught two more real issues on the latest push: 1. Same stale-export bug as the earlier Credit usage fix, this time in Audit Logs: Export stayed enabled while useAuditLogs held prior rows via keepPreviousData, so it could export against a just-changed filter while the table still showed the old one. Now also disabled while isPlaceholderData is true. 2. getUsageCreditsByLogId had no ORDER BY before apportionCredits's largest-remainder tie-break, so which row absorbed a tied remainder credit depended on undefined Postgres row order — the same event's displayed credit could flip between calls (list vs. export, or even two successive requests). Added the same `orderBy(desc(createdAt), desc(id))` the main list query already uses, making the tie-break reproducible. Verified live: 3 identically-costed rows produced the same tie-break winner across 3 repeated requests (previously order-dependent).
1 parent bd67ebd commit 447c404

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

apps/sim/ee/audit-logs/components/audit-logs.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,15 @@ export function AuditLogs() {
297297
}
298298
}, [debouncedSearch, selectedTypes, timeRange, customStartDate, customEndDate])
299299

300-
const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage, refetch } =
301-
useAuditLogs(filters)
300+
const {
301+
data,
302+
isLoading,
303+
isPlaceholderData,
304+
isFetchingNextPage,
305+
hasNextPage,
306+
fetchNextPage,
307+
refetch,
308+
} = useAuditLogs(filters)
302309

303310
const allEntries = useMemo(() => {
304311
if (!data?.pages) return []
@@ -403,7 +410,7 @@ export function AuditLogs() {
403410
text: 'Export',
404411
icon: Download,
405412
onSelect: () => void handleExportCsv(),
406-
disabled: allEntries.length === 0 || isExporting,
413+
disabled: allEntries.length === 0 || isExporting || isPlaceholderData,
407414
},
408415
]}
409416
>

apps/sim/lib/billing/core/usage-log.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ export async function getUsageCreditsByLogId(
550550
.select({ id: usageLog.id, cost: usageLog.cost })
551551
.from(usageLog)
552552
.where(and(...buildUsageLogConditions(userId, filter)))
553+
.orderBy(desc(usageLog.createdAt), desc(usageLog.id))
553554

554555
return apportionCredits(
555556
rows.map((row) => ({ key: row.id, dollars: Number.parseFloat(row.cost) }))

0 commit comments

Comments
 (0)