mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-11 03:58:28 +08:00
refactor: 清理数据库字段命名歧义
- users 表:重命名 allowed_endpoints 为 allowed_api_formats(修正历史命名错误) - api_keys 表:删除 allowed_endpoints 字段(未使用的功能) - providers 表:删除 rate_limit 字段(与 rpm_limit 重复) - usage 表:重命名 provider 为 provider_name(避免与 provider_id 外键混淆) 同步更新前后端所有相关代码
This commit is contained in:
@@ -73,7 +73,6 @@ async def create_provider(request: Request, db: Session = Depends(get_db)):
|
||||
- `rpm_limit`: 每分钟请求数限制(可选)
|
||||
- `provider_priority`: 提供商优先级(数字越小优先级越高,默认 100)
|
||||
- `is_active`: 是否启用(默认 true)
|
||||
- `rate_limit`: 速率限制配置(可选)
|
||||
- `concurrent_limit`: 并发限制(可选)
|
||||
- `config`: 额外配置信息(JSON,可选)
|
||||
|
||||
@@ -110,7 +109,6 @@ async def update_provider(provider_id: str, request: Request, db: Session = Depe
|
||||
- `rpm_limit`: 每分钟请求数限制
|
||||
- `provider_priority`: 提供商优先级
|
||||
- `is_active`: 是否启用
|
||||
- `rate_limit`: 速率限制配置
|
||||
- `concurrent_limit`: 并发限制
|
||||
- `config`: 额外配置信息(JSON)
|
||||
|
||||
@@ -228,7 +226,6 @@ class AdminCreateProviderAdapter(AdminApiAdapter):
|
||||
rpm_limit=validated_data.rpm_limit,
|
||||
provider_priority=validated_data.provider_priority,
|
||||
is_active=validated_data.is_active,
|
||||
rate_limit=validated_data.rate_limit,
|
||||
concurrent_limit=validated_data.concurrent_limit,
|
||||
config=validated_data.config,
|
||||
)
|
||||
|
||||
@@ -684,7 +684,6 @@ class AdminExportConfigAdapter(AdminApiAdapter):
|
||||
"rpm_limit": provider.rpm_limit,
|
||||
"provider_priority": provider.provider_priority,
|
||||
"is_active": provider.is_active,
|
||||
"rate_limit": provider.rate_limit,
|
||||
"concurrent_limit": provider.concurrent_limit,
|
||||
"config": provider.config,
|
||||
"endpoints": endpoints_data,
|
||||
@@ -831,7 +830,6 @@ class AdminImportConfigAdapter(AdminApiAdapter):
|
||||
"provider_priority", 100
|
||||
)
|
||||
existing_provider.is_active = prov_data.get("is_active", True)
|
||||
existing_provider.rate_limit = prov_data.get("rate_limit")
|
||||
existing_provider.concurrent_limit = prov_data.get(
|
||||
"concurrent_limit"
|
||||
)
|
||||
@@ -856,7 +854,6 @@ class AdminImportConfigAdapter(AdminApiAdapter):
|
||||
rpm_limit=prov_data.get("rpm_limit"),
|
||||
provider_priority=prov_data.get("provider_priority", 100),
|
||||
is_active=prov_data.get("is_active", True),
|
||||
rate_limit=prov_data.get("rate_limit"),
|
||||
concurrent_limit=prov_data.get("concurrent_limit"),
|
||||
config=prov_data.get("config"),
|
||||
)
|
||||
@@ -1109,7 +1106,6 @@ class AdminExportUsersAdapter(AdminApiAdapter):
|
||||
"balance_used_usd": key.balance_used_usd,
|
||||
"current_balance_usd": key.current_balance_usd,
|
||||
"allowed_providers": key.allowed_providers,
|
||||
"allowed_endpoints": key.allowed_endpoints,
|
||||
"allowed_api_formats": key.allowed_api_formats,
|
||||
"allowed_models": key.allowed_models,
|
||||
"rate_limit": key.rate_limit,
|
||||
@@ -1146,7 +1142,7 @@ class AdminExportUsersAdapter(AdminApiAdapter):
|
||||
"password_hash": user.password_hash,
|
||||
"role": user.role.value if user.role else "user",
|
||||
"allowed_providers": user.allowed_providers,
|
||||
"allowed_endpoints": user.allowed_endpoints,
|
||||
"allowed_api_formats": user.allowed_api_formats,
|
||||
"allowed_models": user.allowed_models,
|
||||
"model_capability_settings": user.model_capability_settings,
|
||||
"quota_usd": user.quota_usd,
|
||||
@@ -1238,7 +1234,6 @@ class AdminImportUsersAdapter(AdminApiAdapter):
|
||||
balance_used_usd=key_data.get("balance_used_usd", 0.0),
|
||||
current_balance_usd=key_data.get("current_balance_usd"),
|
||||
allowed_providers=key_data.get("allowed_providers"),
|
||||
allowed_endpoints=key_data.get("allowed_endpoints"),
|
||||
allowed_api_formats=key_data.get("allowed_api_formats"),
|
||||
allowed_models=key_data.get("allowed_models"),
|
||||
rate_limit=key_data.get("rate_limit"),
|
||||
@@ -1282,7 +1277,7 @@ class AdminImportUsersAdapter(AdminApiAdapter):
|
||||
if user_data.get("role"):
|
||||
existing_user.role = UserRole(user_data["role"])
|
||||
existing_user.allowed_providers = user_data.get("allowed_providers")
|
||||
existing_user.allowed_endpoints = user_data.get("allowed_endpoints")
|
||||
existing_user.allowed_api_formats = user_data.get("allowed_api_formats")
|
||||
existing_user.allowed_models = user_data.get("allowed_models")
|
||||
existing_user.model_capability_settings = user_data.get(
|
||||
"model_capability_settings"
|
||||
@@ -1306,7 +1301,7 @@ class AdminImportUsersAdapter(AdminApiAdapter):
|
||||
password_hash=user_data.get("password_hash", ""),
|
||||
role=role,
|
||||
allowed_providers=user_data.get("allowed_providers"),
|
||||
allowed_endpoints=user_data.get("allowed_endpoints"),
|
||||
allowed_api_formats=user_data.get("allowed_api_formats"),
|
||||
allowed_models=user_data.get("allowed_models"),
|
||||
model_capability_settings=user_data.get("model_capability_settings"),
|
||||
quota_usd=user_data.get("quota_usd"),
|
||||
|
||||
@@ -353,8 +353,8 @@ class AdminUsageByModelAdapter(AdminApiAdapter):
|
||||
)
|
||||
# 过滤掉 pending/streaming 状态的请求(尚未完成的请求不应计入统计)
|
||||
query = query.filter(Usage.status.notin_(["pending", "streaming"]))
|
||||
# 过滤掉 unknown/pending provider(请求未到达任何提供商)
|
||||
query = query.filter(Usage.provider.notin_(["unknown", "pending"]))
|
||||
# 过滤掉 unknown/pending provider_name(请求未到达任何提供商)
|
||||
query = query.filter(Usage.provider_name.notin_(["unknown", "pending"]))
|
||||
|
||||
if self.start_date:
|
||||
query = query.filter(Usage.created_at >= self.start_date)
|
||||
@@ -565,8 +565,8 @@ class AdminUsageByApiFormatAdapter(AdminApiAdapter):
|
||||
)
|
||||
# 过滤掉 pending/streaming 状态的请求
|
||||
query = query.filter(Usage.status.notin_(["pending", "streaming"]))
|
||||
# 过滤掉 unknown/pending provider
|
||||
query = query.filter(Usage.provider.notin_(["unknown", "pending"]))
|
||||
# 过滤掉 unknown/pending provider_name
|
||||
query = query.filter(Usage.provider_name.notin_(["unknown", "pending"]))
|
||||
# 只统计有 api_format 的记录
|
||||
query = query.filter(Usage.api_format.isnot(None))
|
||||
|
||||
@@ -765,8 +765,8 @@ class AdminUsageRecordsAdapter(AdminApiAdapter):
|
||||
float(usage.rate_multiplier) if usage.rate_multiplier is not None else 1.0
|
||||
)
|
||||
|
||||
# 提供商名称优先级:关联的 Provider 表 > usage.provider 字段
|
||||
provider_name = usage.provider
|
||||
# 提供商名称优先级:关联的 Provider 表 > usage.provider_name 字段
|
||||
provider_name = usage.provider_name
|
||||
if usage.provider_id and str(usage.provider_id) in provider_map:
|
||||
provider_name = provider_map[str(usage.provider_id)]
|
||||
|
||||
@@ -881,7 +881,7 @@ class AdminUsageDetailAdapter(AdminApiAdapter):
|
||||
"name": api_key.name if api_key else None,
|
||||
"display": api_key.get_display_key() if api_key else None,
|
||||
},
|
||||
"provider": usage_record.provider,
|
||||
"provider": usage_record.provider_name,
|
||||
"api_format": usage_record.api_format,
|
||||
"model": usage_record.model,
|
||||
"target_model": usage_record.target_model,
|
||||
@@ -934,7 +934,7 @@ class AdminUsageDetailAdapter(AdminApiAdapter):
|
||||
# 尝试获取模型的阶梯配置(带来源信息)
|
||||
cost_service = ModelCostService(db)
|
||||
pricing_result = await cost_service.get_tiered_pricing_with_source_async(
|
||||
usage_record.provider, usage_record.model
|
||||
usage_record.provider_name, usage_record.model
|
||||
)
|
||||
|
||||
if not pricing_result:
|
||||
|
||||
@@ -246,7 +246,7 @@ class AdminCreateUserAdapter(AdminApiAdapter):
|
||||
"username": user.username,
|
||||
"role": user.role.value,
|
||||
"allowed_providers": user.allowed_providers,
|
||||
"allowed_endpoints": user.allowed_endpoints,
|
||||
"allowed_api_formats": user.allowed_api_formats,
|
||||
"allowed_models": user.allowed_models,
|
||||
"quota_usd": user.quota_usd,
|
||||
"used_usd": user.used_usd,
|
||||
@@ -274,7 +274,7 @@ class AdminListUsersAdapter(AdminApiAdapter):
|
||||
"username": u.username,
|
||||
"role": u.role.value,
|
||||
"allowed_providers": u.allowed_providers,
|
||||
"allowed_endpoints": u.allowed_endpoints,
|
||||
"allowed_api_formats": u.allowed_api_formats,
|
||||
"allowed_models": u.allowed_models,
|
||||
"quota_usd": u.quota_usd,
|
||||
"used_usd": u.used_usd,
|
||||
@@ -309,7 +309,7 @@ class AdminGetUserAdapter(AdminApiAdapter):
|
||||
"username": user.username,
|
||||
"role": user.role.value,
|
||||
"allowed_providers": user.allowed_providers,
|
||||
"allowed_endpoints": user.allowed_endpoints,
|
||||
"allowed_api_formats": user.allowed_api_formats,
|
||||
"allowed_models": user.allowed_models,
|
||||
"quota_usd": user.quota_usd,
|
||||
"used_usd": user.used_usd,
|
||||
@@ -375,7 +375,7 @@ class AdminUpdateUserAdapter(AdminApiAdapter):
|
||||
"username": user.username,
|
||||
"role": user.role.value,
|
||||
"allowed_providers": user.allowed_providers,
|
||||
"allowed_endpoints": user.allowed_endpoints,
|
||||
"allowed_api_formats": user.allowed_api_formats,
|
||||
"allowed_models": user.allowed_models,
|
||||
"quota_usd": user.quota_usd,
|
||||
"used_usd": user.used_usd,
|
||||
|
||||
@@ -528,7 +528,7 @@ class AuthCurrentUserAdapter(AuthenticatedApiAdapter):
|
||||
"used_usd": user.used_usd,
|
||||
"total_usd": user.total_usd,
|
||||
"allowed_providers": user.allowed_providers,
|
||||
"allowed_endpoints": user.allowed_endpoints,
|
||||
"allowed_api_formats": user.allowed_api_formats,
|
||||
"allowed_models": user.allowed_models,
|
||||
"created_at": user.created_at.isoformat(),
|
||||
"last_login_at": user.last_login_at.isoformat() if user.last_login_at else None,
|
||||
|
||||
@@ -143,12 +143,13 @@ class AccessRestrictions:
|
||||
allowed_api_formats = api_key.allowed_api_formats
|
||||
|
||||
# 如果 API Key 没有限制,检查 User 的限制
|
||||
# 注意: User 没有 allowed_api_formats 字段
|
||||
if user:
|
||||
if allowed_providers is None and user.allowed_providers is not None:
|
||||
allowed_providers = user.allowed_providers
|
||||
if allowed_models is None and user.allowed_models is not None:
|
||||
allowed_models = user.allowed_models
|
||||
if allowed_api_formats is None and user.allowed_api_formats is not None:
|
||||
allowed_api_formats = user.allowed_api_formats
|
||||
|
||||
return cls(
|
||||
allowed_providers=allowed_providers,
|
||||
|
||||
@@ -766,7 +766,7 @@ class DashboardProviderStatusAdapter(DashboardAdapter):
|
||||
for provider in providers:
|
||||
count = (
|
||||
db.query(func.count(Usage.id))
|
||||
.filter(and_(Usage.provider == provider.name, Usage.created_at >= since))
|
||||
.filter(and_(Usage.provider_name == provider.name, Usage.created_at >= since))
|
||||
.scalar()
|
||||
)
|
||||
entries.append(
|
||||
@@ -854,7 +854,7 @@ class DashboardDailyStatsAdapter(DashboardAdapter):
|
||||
.scalar() or 0
|
||||
)
|
||||
today_unique_providers = (
|
||||
db.query(func.count(func.distinct(Usage.provider)))
|
||||
db.query(func.count(func.distinct(Usage.provider_name)))
|
||||
.filter(Usage.created_at >= today)
|
||||
.scalar() or 0
|
||||
)
|
||||
|
||||
@@ -126,7 +126,9 @@ def _filter_formats_by_restrictions(
|
||||
"""
|
||||
if restrictions.allowed_api_formats is None:
|
||||
return formats, None
|
||||
filtered = [f for f in formats if f in restrictions.allowed_api_formats]
|
||||
# 统一转为大写比较,兼容数据库中存储的大小写
|
||||
allowed_upper = {f.upper() for f in restrictions.allowed_api_formats}
|
||||
filtered = [f for f in formats if f.upper() in allowed_upper]
|
||||
if not filtered:
|
||||
logger.info(f"[Models] API Key 不允许访问格式 {api_format}")
|
||||
return [], _build_empty_list_response(api_format)
|
||||
|
||||
@@ -847,7 +847,7 @@ class GetUsageAdapter(AuthenticatedApiAdapter):
|
||||
"records": [
|
||||
{
|
||||
"id": r.id,
|
||||
"provider": r.provider,
|
||||
"provider": r.provider_name,
|
||||
"model": r.model,
|
||||
"target_model": r.target_model, # 映射后的目标模型名
|
||||
"api_format": r.api_format,
|
||||
|
||||
Reference in New Issue
Block a user