Skip to content

Comments

Claude Enterprise web usage: support org/member overage limits and hide empty session metrics#405

Open
mkkim417 wants to merge 3 commits intosteipete:mainfrom
mkkim417:fix/claude-enterprise-web-usage
Open

Claude Enterprise web usage: support org/member overage limits and hide empty session metrics#405
mkkim417 wants to merge 3 commits intosteipete:mainfrom
mkkim417:fix/claude-enterprise-web-usage

Conversation

@mkkim417
Copy link

@mkkim417 mkkim417 commented Feb 20, 2026

Summary

This PR improves Claude Enterprise behavior in the web data source path.

What was happening

For some Enterprise accounts, CodexBar showed:

  • Invalid response from Claude API, or
  • misleading usage bars when Claude returned 200 but all usage windows were null.

Root cause

  • GET /api/organizations/{orgId}/usage can return all usage windows as null for Enterprise contexts.
  • GET /api/organizations/{orgId}/overage_spend_limit without account_uuid can return organization-level values (limit_type=organization) instead of member-specific values.

What changed

  1. Enterprise-safe usage parsing
  • Accept usage responses where session/weekly windows are null without failing the fetch.
  1. Member-aware overage lookup
  • Parse account UUID from GET /api/account.
  • Call:
    • GET /api/organizations/{orgId}/overage_spend_limit?account_uuid={accountUUID}
    • fallback to endpoint without query if needed.
  1. UI behavior for empty usage windows
  • If Claude web usage windows are effectively empty (all missing) for Enterprise, hide session/weekly/opus usage metrics.
  • Keep account/plan and Extra Usage cost visible.
  1. Tests
  • Added/updated tests for:
    • all-null usage window handling
    • enterprise overage payload parsing
    • account UUID extraction
    • hiding usage metrics only for the all-null enterprise web case

Before / After

Before

  • Invalid response from Claude API in Enterprise cases, or usage bars shown with no real usage window data.
  • Overage could show organization-level totals.

After

  • No parse failure on all-null usage windows.
  • Usage bars are hidden when window data is unavailable.
  • Extra Usage uses member-aware overage lookup when account_uuid is available.

Screenshots

  • Before:
image
  • After:
스크린샷 2026-02-20 오전 11 09 01

Validation

  • swift test --filter ClaudeUsageTests
  • ./Scripts/compile_and_run.sh (run locally)

Notes

  • Scope is limited to Claude web path (Enterprise edge cases).
  • No provider behavior changes outside this path.

Copy link

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

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.

Reviewed commit: 08ba0ad64a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines 461 to 466
var sessionPercent: Double = 0
var sessionResets: Date?
if let fiveHour = json["five_hour"] as? [String: Any] {
if let utilization = fiveHour["utilization"] as? Int {
sessionPercent = Double(utilization)
if let utilization = fiveHour["utilization"] as? NSNumber {
sessionPercent = utilization.doubleValue
}

Choose a reason for hiding this comment

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

P1 Badge Validate session window before accepting web usage payload

In ClaudeWebAPIFetcher.parseUsageResponse, sessionPercent now defaults to 0 and the function no longer rejects responses missing five_hour.utilization, so any HTTP 200 JSON body without usage windows is treated as successful usage data. In auto mode this suppresses the intended fallback path and can surface fabricated 0% used metrics instead of an error/fallback result, which is a regression from the previous invalidResponse behavior for malformed payloads.

Useful? React with 👍 / 👎.

guard usage.primary.usedPercent == 0 else { return false }
guard usage.primary.resetsAt == nil, usage.primary.resetDescription == nil else { return false }
// Web path provides account identity; OAuth generally does not.
guard usage.accountEmail != nil else { return false }

Choose a reason for hiding this comment

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

P2 Badge Do not gate null-window hiding on account email availability

shouldHideUsageMetrics requires accountEmail != nil, but account info is fetched best-effort and can independently fail even when /usage succeeds with all-null enterprise windows. In that case the new parser still maps usage to 0 while this guard prevents suppression, so users continue to see the misleading session metric this change is trying to eliminate; the condition should be based on the usage-window shape/source, not whether /account happened to return email.

Useful? React with 👍 / 👎.

@mkkim417
Copy link
Author

@codex review

Copy link

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

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.

Reviewed commit: e9932f67a5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

@Test
func parsesClaudeWebAPIUsageResponseWhenAllUsageWindowsAreNull() throws {

Choose a reason for hiding this comment

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

P2 Badge Preserve @test annotation for overage spend limit case

This insertion reuses the existing @Test attribute for the new parsesClaudeWebAPIUsageResponseWhenAllUsageWindowsAreNull method, which leaves the following parsesClaudeWebAPIOverageSpendLimit function unannotated and therefore undiscovered by Swift Testing. In practice, that baseline overage parsing check silently stops running in CI, so regressions in _parseOverageSpendLimitForTesting can slip through without signal.

Useful? React with 👍 / 👎.

@mkkim417
Copy link
Author

@codex review

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Nice work!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

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