mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat: 引入 status_snapshot 统一 provider key 状态管理
- 新增 StatusSnapshot 模型,聚合 OAuth / 账号 / 配额三维状态 - 新增 StatusSnapshotStore 负责快照的持久化与查询 - 重构 response_builder / endpoint_models,基于 snapshot 输出状态字段 - 前端抽取 providerKeyStatus / oauthRefreshFeedback 工具函数, 统一 PoolManagement、ProviderDetailDrawer、BatchDialog 的状态展示 - errorParser 增加已知 OAuth 错误的友好提示 - refresher 适配 snapshot 写入,account_state 扩展状态分类 - 新增 alembic 迁移及存量数据回填脚本 - 补充前后端单元测试
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.services.provider.pool.account_state import (
|
||||
build_provider_key_status_snapshot,
|
||||
resolve_pool_account_state,
|
||||
should_auto_remove_account_state,
|
||||
)
|
||||
@@ -192,3 +193,68 @@ def test_auto_remove_state_excludes_token_expired_and_verification() -> None:
|
||||
assert should_auto_remove_account_state(expired) is False
|
||||
assert should_auto_remove_account_state(verification) is False
|
||||
assert should_auto_remove_account_state(disabled) is True
|
||||
|
||||
|
||||
def test_build_provider_key_status_snapshot_separates_account_block_from_oauth_state() -> None:
|
||||
snapshot = build_provider_key_status_snapshot(
|
||||
auth_type="oauth",
|
||||
oauth_expires_at=2_000_000_000,
|
||||
oauth_invalid_at=1_900_000_000,
|
||||
oauth_invalid_reason="[ACCOUNT_BLOCK] 工作区已停用 (deactivated_workspace)",
|
||||
provider_type="codex",
|
||||
upstream_metadata=None,
|
||||
now_ts=1_800_000_000,
|
||||
)
|
||||
|
||||
assert snapshot.account.blocked is True
|
||||
assert snapshot.account.code == "workspace_deactivated"
|
||||
assert snapshot.account.label == "工作区停用"
|
||||
assert snapshot.oauth.code == "valid"
|
||||
assert snapshot.oauth.requires_reauth is False
|
||||
|
||||
|
||||
def test_build_provider_key_status_snapshot_keeps_refresh_failure_visible_beside_account_block() -> (
|
||||
None
|
||||
):
|
||||
snapshot = build_provider_key_status_snapshot(
|
||||
auth_type="oauth",
|
||||
oauth_expires_at=2_000_000_000,
|
||||
oauth_invalid_at=1_900_000_000,
|
||||
oauth_invalid_reason=(
|
||||
"[ACCOUNT_BLOCK] 工作区已停用 (deactivated_workspace)\n"
|
||||
"[REFRESH_FAILED] Token 续期失败 (400): refresh_token_reused"
|
||||
),
|
||||
provider_type="codex",
|
||||
upstream_metadata=None,
|
||||
now_ts=1_800_000_000,
|
||||
)
|
||||
|
||||
assert snapshot.account.blocked is True
|
||||
assert snapshot.account.code == "workspace_deactivated"
|
||||
assert snapshot.oauth.code == "invalid"
|
||||
assert snapshot.oauth.label == "已失效"
|
||||
assert snapshot.oauth.reason == "Token 续期失败 (400): refresh_token_reused"
|
||||
assert snapshot.oauth.requires_reauth is True
|
||||
|
||||
|
||||
def test_build_provider_key_status_snapshot_marks_quota_exhausted() -> None:
|
||||
snapshot = build_provider_key_status_snapshot(
|
||||
auth_type="oauth",
|
||||
oauth_expires_at=2_000_000_000,
|
||||
oauth_invalid_at=None,
|
||||
oauth_invalid_reason=None,
|
||||
provider_type="codex",
|
||||
upstream_metadata={
|
||||
"codex": {
|
||||
"primary_used_percent": 100.0,
|
||||
"secondary_used_percent": 20.0,
|
||||
"updated_at": 1_800_000_000,
|
||||
"plan_type": "team",
|
||||
}
|
||||
},
|
||||
now_ts=1_800_000_000,
|
||||
)
|
||||
|
||||
assert snapshot.quota.code == "exhausted"
|
||||
assert snapshot.quota.exhausted is True
|
||||
assert snapshot.quota.reason == "Codex 周限额剩余 0%"
|
||||
|
||||
Reference in New Issue
Block a user