Skip to content

fix(quota): rebuild Codex quota history tracking - #446

Open
Willxup wants to merge 2 commits into
mainfrom
worktree/quota-history-rebuild
Open

fix(quota): rebuild Codex quota history tracking#446
Willxup wants to merge 2 commits into
mainfrom
worktree/quota-history-rebuild

Conversation

@Willxup

@Willxup Willxup commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • rebuild Codex quota observations on generic quota cycle and percentage segment tables, clearing invalid legacy history through migration
  • process manual, scheduled, and inspection observations immediately while buffering Header samples and stabilizing reset boundaries
  • query history by upstream window role, include the current cycle in records, and label real 5h, Weekly, and Monthly windows without exposing role names

Validation

  • full local baseline: backend tests; 1129 frontend tests; lint; typecheck; production build
  • targeted repository, quota, and API tests under TZ=UTC and TZ=Asia/Shanghai
  • git diff --check

Closes #445

Willxup and others added 2 commits August 23, 2026 04:01
Replace the invalid Codex-only history schema with generic quota cycle and percentage segment tables.

Separate trusted refresh writes from buffered Header samples, stabilize reset boundaries, and query current plus completed cycles by upstream window role.

Refs: #445
Co-authored-by: YouShouldBetOnMe <153986019+YouShouldBetOnMe@users.noreply.github.com>
Select history by upstream window role while labeling only the real 5h, Weekly, Monthly, or fallback duration.

Include the current cycle in the records list and render effective boundaries, percentage baselines, and observation counts.

Refs: #445
Co-authored-by: YouShouldBetOnMe <153986019+YouShouldBetOnMe@users.noreply.github.com>

@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.

Reviewed commit: 1e887517d8

ℹ️ 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 187 to +190
if !found {
cycle = newCodexQuotaCycle(observation)
cycle = newQuotaCycle(observation, quotaKey)
if err := tx.Create(&cycle).Error; err != nil {
return fmt.Errorf("create codex quota cycle: %w", err)
return fmt.Errorf("create quota cycle: %w", err)

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 Reuse a prior cycle when a window role switches back

When a role changes from Weekly to 5h and then returns to the still-existing Weekly cycle, this path only compares against the latest 5h row and unconditionally creates a new Weekly row. The earlier Weekly row already has the same (provider, auth_index, quota_key, window_seconds, reset_at) identity, so the unique index rejects the insert; subsequent observations keep retrying the same failing insert until the reset changes, and the surrounding batch transaction can also roll back unrelated observations. Look up and reuse the exact prior cycle before creating a row.

Useful? React with 👍 / 👎.

Comment on lines +321 to +326
func quotaResetTimesMatch(left time.Time, right time.Time) bool {
distance := left.Sub(right)
if distance < 0 {
distance = -distance
}
return time.Duration(toleranceSeconds) * time.Second
return distance <= codexQuotaResetTolerance

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Bound reset tolerance by the quota window length

History now accepts arbitrary positive header windows, including 1- or 2-minute windows, but this fixed two-minute tolerance treats consecutive cycles for those windows as the same cycle because their reset times differ by at most 120 seconds. A reset can therefore be rejected as a percentage increase or overwrite/delete the prior cycle's tail instead of creating a new cycle. The tolerance needs to remain strictly smaller than the observed window, such as the previous window-relative bound.

Useful? React with 👍 / 👎.

Comment on lines +182 to +185
// 被丢弃 Header 只损失本轮不足十秒的样本;清空引用让完整快照可尽快回收。
for index := range inputs {
inputs[index].Snapshot = nil
inputs[index].Observations = nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve header samples for unrelated accounts

When any manual, scheduled, or inspection observation reaches the trusted queue during a header aggregation window, this loop clears every queued header input, regardless of its auth index or window role. For example, a manual refresh of account A can permanently discard account B's only usage-header observation; if B has no subsequent traffic, its baseline or percentage transition is never recorded. Only header observations superseded by a trusted fact for the same account and role should be dropped.

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.

[Bug] Codex Primary 和 Secondary 配额效率历史不显示

1 participant