Skip to content

fix(token): 状态筛选按正交维度派生过期/耗尽,修复「已过期」筛不全 - #6670

Open
uthanw wants to merge 1 commit into
QuantumNous:mainfrom
uthanw:fix/token-expired-filter
Open

fix(token): 状态筛选按正交维度派生过期/耗尽,修复「已过期」筛不全#6670
uthanw wants to merge 1 commit into
QuantumNous:mainfrom
uthanw:fix/token-expired-filter

Conversation

@uthanw

@uthanw uthanw commented Aug 5, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

令牌的「启用/禁用」与「过期/耗尽」是两个正交维度,原实现把派生维度 3/4 当作与 1/2 互斥的枚举存进同一 status 字段,叠加 Redis 开关导致行为不一致。

本 PR 采用 issue #6661 的「方式二」:保留enable/disable 是用户意图的互斥维度,expired/exhaustedexpired_time/remain_quota 读时派生,可叠加到任意意图上。数据层本就正交,过期是时间派生属性,同仓库 redemption-codes 已是此模式,且无需后台同步基础设施——读时算一次永远正确,status 只保留启停意图,3/4 成为历史遗留值。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

  1. 创建带时效的令牌使之过期。
  2. 打开 API Key 页面,筛选「已过期」→ 能看到该令牌,Status 列显示 Expired 徽章(非绿色 Enabled)。
  3. 筛选「Enabled」→ 不包含该过期令牌。
  4. 翻页确认所有过期令牌都能被筛出(后端过滤,非仅当前页)。
Before After
image image

Summary by CodeRabbit

  • New Features
    • Added API key filtering for enabled, disabled, expired, and exhausted keys.
    • Added clear status badges for expired and quota-exhausted keys on desktop and mobile.
    • API key validation now reflects current expiration and quota availability.
  • Bug Fixes
    • Improved consistency between API key status filters, search results, and status updates.
    • Prevented outdated stored statuses from affecting key validation.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3eab0869-a564-4101-a901-6a5502e73532

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab0202 and d914abe.

📒 Files selected for processing (8)
  • controller/token.go
  • model/token.go
  • web/src/features/keys/api.ts
  • web/src/features/keys/components/api-keys-columns.tsx
  • web/src/features/keys/components/api-keys-table.tsx
  • web/src/features/keys/lib/index.ts
  • web/src/features/keys/lib/utils.ts
  • web/src/features/keys/types.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • web/src/features/keys/lib/index.ts
  • controller/token.go
  • web/src/features/keys/components/api-keys-columns.tsx
  • web/src/features/keys/api.ts
  • web/src/features/keys/types.ts
  • model/token.go
  • web/src/features/keys/components/api-keys-table.tsx

Walkthrough

The change adds API key status filtering across the backend and frontend. Expired and exhausted states are derived from expiration and quota data. Token validation uses these values directly, and table filtering sends status criteria to the server.

Changes

API key status semantics

Layer / File(s) Summary
Backend status search and validation
controller/token.go, model/token.go
Token searches accept status filters for enabled, disabled, expired, and exhausted keys. Validation checks enabled state, expiration, and quota directly. The SelectUpdate method is removed.
Derived API key state handling
web/src/features/keys/lib/*, web/src/features/keys/types.ts, web/src/features/keys/components/api-keys-columns.tsx, web/src/features/keys/components/api-keys-table.tsx
The frontend derives expired and exhausted states, displays corresponding badges, includes them in status filtering, and treats them as disabled rows where applicable.
Server-side status filtering
web/src/features/keys/api.ts, web/src/features/keys/components/api-keys-table.tsx
Status filters are added to API requests and query keys. The table enables manual filtering. Status updates skip business-error handling.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ApiKeysTable
  participant searchApiKeys
  participant SearchTokens
  participant SearchUserTokens
  User->>ApiKeysTable: Select status filter
  ApiKeysTable->>searchApiKeys: Send status query and cache key
  searchApiKeys->>SearchTokens: Request filtered tokens
  SearchTokens->>SearchUserTokens: Pass status filter
  SearchUserTokens-->>ApiKeysTable: Return matching API keys
  ApiKeysTable-->>User: Render derived status badges
Loading

Possibly related PRs

Poem

A rabbit checks each key with care,
Expired and exhausted states are there.
The server filters every page,
Badges show each status stage.
Hop, hop—the states align.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了按正交维度派生过期和耗尽状态,并修复过期筛选不完整的问题。
Linked Issues check ✅ Passed 变更实现了后端状态维度筛选、前端服务端过滤,并支持启用与过期状态重叠,满足问题 #6661 的目标。
Out of Scope Changes check ✅ Passed 所有变更均围绕令牌状态派生、筛选和验证逻辑,未发现与问题目标无关的代码修改。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/features/keys/components/api-keys-table.tsx`:
- Around line 70-101: Update the local helpers isDisabledApiKeyRow and
renderApiKeyStatusBadge with explicit return annotations: boolean for
isDisabledApiKeyRow and a nullable React node type for renderApiKeyStatusBadge,
preserving their existing return behavior.

In `@web/src/features/keys/lib/utils.ts`:
- Around line 28-30: Update isApiKeyExpired so only expired_time === -1 is
treated as non-expiring, and compare the expiry value against the current Unix
timestamp in seconds rather than milliseconds. Preserve the boolean return
contract while matching the backend predicate exactly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b9e4a0f1-1f46-4ee6-b5b9-5c00dc19f840

📥 Commits

Reviewing files that changed from the base of the PR and between 0ab0202 and a01fa93.

📒 Files selected for processing (8)
  • controller/token.go
  • model/token.go
  • web/src/features/keys/api.ts
  • web/src/features/keys/components/api-keys-columns.tsx
  • web/src/features/keys/components/api-keys-table.tsx
  • web/src/features/keys/lib/index.ts
  • web/src/features/keys/lib/utils.ts
  • web/src/features/keys/types.ts

Comment thread web/src/features/keys/components/api-keys-table.tsx Outdated
Comment thread web/src/features/keys/lib/utils.ts Outdated
令牌的启用/禁用与过期/耗尽是两个正交维度,原实现把 3/4 当作与 1/2
互斥的枚举存进同一字段,叠加 Redis 开关导致行为不一致:

- ValidateUserToken 仅在 !RedisEnabled 时把 status 覆写为 3/4,Redis
  启用时过期令牌 DB 永远 status=1;且只有被调用过的令牌才触发判断,
  从未被调用的过期令牌永远保持 status=1。按 status=3 筛选几乎查不到。
- 前端 status 筛选不传后端、未设 manualFiltering,退化为对当前页的
  客户端过滤,跨页过期令牌必然漏掉。
- Status 列徽章直接用 status,启用但过期的令牌显示绿色 Enabled。

对齐 redemption-codes 的实现,按正交维度拆分:

后端:
- SearchUserTokens 增加 status 参数,expired=expired_time<now(任意
  status)、exhausted=!unlimited && remain_quota<=0(任意 status)、
  enabled/disabled 按 status 精确匹配(含对应派生态)。
- ValidateUserToken 不再把 status 覆写为 3/4,过期/耗尽态从
  expired_time/remain_quota 派生判断,消除 Redis 开关不一致。
- UpdateToken 启用校验从 expired_time/remain_quota 派生,不依赖
  cleanToken.Status==3/4。
- 删除无调用者的 SelectUpdate(原仅 ValidateUserToken 调用,仍
  Select status 有误用风险)。

前端:
- 新增 isApiKeyExpired/isApiKeyExhausted(参考 isRedemptionExpired),
  Status 列 cell 与 filterFn 用派生态判断,过期/耗尽优先于用户意图展示。
- api-keys-table 提取 statusFilterValue 纳入 shouldSearch/queryKey,
  searchApiKeys 传 status,useDataTable 加 manualFiltering。
- isDisabledApiKeyRow 与移动端徽章纳入过期/耗尽派生态。

Closes QuantumNous#6661
@uthanw
uthanw force-pushed the fix/token-expired-filter branch from a01fa93 to d914abe Compare August 5, 2026 14:49
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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] API 密钥状态筛选把启用/过期当作互斥状态,导致「已过期」筛不全

1 participant