Skip to content

Release: Critical Billing Fix - 2025.10.24 - #641

Merged
maxtechera merged 1 commit into
productionfrom
staging
Oct 24, 2025
Merged

Release: Critical Billing Fix - 2025.10.24#641
maxtechera merged 1 commit into
productionfrom
staging

Conversation

@maxtechera

Copy link
Copy Markdown
Collaborator

Summary

  • CRITICAL FIX: Corrected Langfuse billing trace discovery to find oldest unprocessed traces instead of newest
  • This ensures complete historical billing data processing instead of only processing recent traces

Changes

Critical Bug Fix

Fixed billing trace discovery query ordering (packages/server/src/aai-utils/billing/langfuse/LangfuseProvider.ts)

  • Added missing orderBy: 'timestamp' parameter to findOldestUnprocessedTrace()
  • Without explicit ordering, API returned newest traces first, causing system to miss historical unprocessed traces
  • Now correctly discovers oldest trace first, enabling proper time window creation for complete historical processing

Impact

Before this fix:

  • ❌ Discovery query found NEWEST unprocessed trace
  • ❌ Created single time window for current day only
  • ❌ Missed ALL historical unprocessed traces
  • ❌ Incomplete billing data

After this fix:

  • ✅ Discovery query finds OLDEST unprocessed trace
  • ✅ Creates proper time windows from oldest trace forward
  • ✅ Processes complete historical billing data
  • ✅ Accurate billing records

Technical Details

The findOldestUnprocessedTrace() method lacked the orderBy parameter, causing Langfuse API to return traces in default order (newest first). This resulted in discovering only recent traces and missing years of historical data.

Fix: Added explicit orderBy: 'timestamp' to ensure ascending chronological order, plus enhanced logging to track discovered trace timestamps.

Test Plan

  • Code review - ordering logic verified
  • Enhanced logging added for monitoring
  • Fallback safety maintained (falls back to 2020-01-01 on error)
  • Production deployment monitoring for trace processing coverage

🤖 Generated with Claude Code

…d trace

## Problem
The findOldestUnprocessedTrace() discovery query was missing the orderBy parameter.
Without explicit ordering, Langfuse API returned traces in default order (likely newest first).

Result:
- Discovery found NEWEST unprocessed trace instead of OLDEST
- Only created 1 time window (today → today)
- Missed ALL historical unprocessed traces
- User reported: "only found a single trace and did not go back in time"

## Root Cause
```typescript
// WRONG - no orderBy, gets newest trace
const response = await this.fetchTraces({
    limit: 1,
    filter: UNPROCESSED_FILTER
    // Missing: orderBy parameter!
})
```

## Fix
Added orderBy: 'timestamp' to get oldest trace first:

```typescript
// CORRECT - explicitly order by timestamp ascending
const response = await this.fetchTraces({
    limit: 1,
    filter: UNPROCESSED_FILTER,
    orderBy: 'timestamp'  // ✅ Gets OLDEST trace
})
```

Also added:
- orderBy parameter to fetchTraces() signature
- Enhanced logging to show discovered trace timestamp
- Comment explaining fallback behavior

## Impact

Before:
- ❌ Found newest trace (e.g., 2025-10-24)
- ❌ Created window: [2025-10-24 → 2025-10-24]
- ❌ Missed years of historical traces

After:
- ✅ Finds oldest trace (e.g., 2024-01-01)
- ✅ Creates windows: [2024-01-01 → 2024-01-31], [2024-02-01 → 2024-02-29], ...
- ✅ Processes complete historical data

## Fallback Safety
If orderBy doesn't work or returns wrong order:
- Still falls back to 2020-01-01 on error
- Ensures complete coverage regardless

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 24, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
answerai-docs Ready Ready Preview Oct 24, 2025 7:29pm
the-answerai Ready Ready Preview Oct 24, 2025 7:29pm

@maxtechera
maxtechera merged commit 7ca8879 into production Oct 24, 2025
11 of 12 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 152 to +158
limit: 1,
page: 1,
filter: LangfuseProvider.UNPROCESSED_FILTER,
fields: 'core' // Minimal fields for discovery
fields: 'core', // Minimal fields for discovery
orderBy: 'timestamp' // CRITICAL: Order by timestamp ascending (default) to get OLDEST first
// Note: Langfuse API defaults to ascending order, so just 'timestamp' should work
// If this returns newest instead of oldest, we fall back to 2020-01-01 anyway

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Oldest-trace lookup still sorts newest first

The fix adds orderBy: 'timestamp' to findOldestUnprocessedTrace() but does not change the sort direction that the Langfuse API applies. The API returns traces ordered by timestamp descending unless an ascending direction is sent (e.g., an order parameter or orderBy=timestamp,asc). Passing only the field name leaves the default direction intact, so the limit: 1 call still returns the newest unprocessed trace and the subsequent window loop begins near “now”, skipping historical traces exactly as before. To actually fetch the oldest trace, the request must explicitly specify ascending order.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant