refactor: 大规模模块拆分与重组,新增 aether-admin crate

- 新建独立 aether-admin crate 承载 admin 相关共享契约与纯辅助函数
- 拆分 ai_pipeline 下 kiro/private_envelope/conversion/planner 等大文件为子模块目录
- 重组 admin handlers 各业务域(billing/oauth/provider/system/users 等)为目录结构,移除 shared.rs/builders.rs 等反模式
- 移除 ai_pipeline runtime adapters 旧实现(claude/openai/gemini/kiro/vertex/antigravity 等),改由 provider transport 统一承载
- 移除 control_facade/execution_facade/auth_snapshot_facade 等冗余 facade 层
- 拆分 query/billing 与 query/monitoring 模块、state/runtime/payments 与 security 模块
- 扩展架构测试覆盖 admin_billing/admin_model/admin_users 等新模块
- 删除 docs/architecture/refactor-execution-plan.md 已完成的执行计划文档
This commit is contained in:
fawney19
2026-04-09 00:10:38 +08:00
parent 4fb9882b54
commit 4fc95adfb9
663 changed files with 48471 additions and 40232 deletions

View File

@@ -0,0 +1,290 @@
use aether_data_contracts::repository::provider_catalog::{
StoredProviderCatalogEndpoint, StoredProviderCatalogKey,
};
use chrono::{TimeZone, Utc};
use serde_json::{json, Map, Value};
use std::collections::BTreeMap;
fn unix_secs_to_rfc3339(unix_secs: u64) -> Option<String> {
Utc.timestamp_opt(unix_secs as i64, 0)
.single()
.map(|value| value.to_rfc3339())
}
pub fn key_api_formats_without_entry(
key: &StoredProviderCatalogKey,
api_format: &str,
) -> Option<Vec<String>> {
let current_formats = key
.api_formats
.as_ref()
.and_then(serde_json::Value::as_array)
.map(|values| {
values
.iter()
.filter_map(serde_json::Value::as_str)
.map(ToOwned::to_owned)
.collect::<Vec<_>>()
})
.unwrap_or_default();
if !current_formats
.iter()
.any(|candidate| candidate == api_format)
{
return None;
}
Some(
current_formats
.into_iter()
.filter(|candidate| candidate != api_format)
.collect(),
)
}
pub fn endpoint_key_counts_by_format(
keys: &[StoredProviderCatalogKey],
) -> (BTreeMap<String, usize>, BTreeMap<String, usize>) {
let mut total = BTreeMap::new();
let mut active = BTreeMap::new();
for key in keys {
let Some(formats) = key
.api_formats
.as_ref()
.and_then(serde_json::Value::as_array)
else {
continue;
};
for api_format in formats.iter().filter_map(serde_json::Value::as_str) {
*total.entry(api_format.to_string()).or_insert(0) += 1;
if key.is_active {
*active.entry(api_format.to_string()).or_insert(0) += 1;
}
}
}
(total, active)
}
fn masked_proxy_value(proxy: Option<&serde_json::Value>) -> serde_json::Value {
let Some(proxy) = proxy.and_then(serde_json::Value::as_object) else {
return serde_json::Value::Null;
};
let mut masked = proxy.clone();
if masked
.get("password")
.and_then(serde_json::Value::as_str)
.is_some_and(|value| !value.trim().is_empty())
{
masked.insert("password".to_string(), json!("***"));
}
serde_json::Value::Object(masked)
}
fn endpoint_timestamp_or_now(value: Option<u64>, now_unix_secs: u64) -> serde_json::Value {
unix_secs_to_rfc3339(value.unwrap_or(now_unix_secs))
.map(serde_json::Value::String)
.unwrap_or(serde_json::Value::Null)
}
pub fn build_admin_provider_endpoint_response(
endpoint: &StoredProviderCatalogEndpoint,
provider_name: &str,
total_keys: usize,
active_keys: usize,
now_unix_secs: u64,
) -> serde_json::Value {
json!({
"id": endpoint.id,
"provider_id": endpoint.provider_id,
"provider_name": provider_name,
"api_format": endpoint.api_format,
"base_url": endpoint.base_url,
"custom_path": endpoint.custom_path,
"header_rules": endpoint.header_rules,
"body_rules": endpoint.body_rules,
"max_retries": endpoint.max_retries.unwrap_or(2),
"is_active": endpoint.is_active,
"config": endpoint.config,
"proxy": masked_proxy_value(endpoint.proxy.as_ref()),
"format_acceptance_config": endpoint.format_acceptance_config,
"total_keys": total_keys,
"active_keys": active_keys,
"created_at": endpoint_timestamp_or_now(endpoint.created_at_unix_secs, now_unix_secs),
"updated_at": endpoint_timestamp_or_now(endpoint.updated_at_unix_secs, now_unix_secs),
})
}
#[derive(Debug, Clone, Default)]
pub struct AdminProviderEndpointUpdateFields {
pub base_url: Option<String>,
pub custom_path: Option<String>,
pub header_rules: Option<Value>,
pub body_rules: Option<Value>,
pub max_retries: Option<i32>,
pub is_active: Option<bool>,
pub config: Option<Value>,
pub proxy: Option<Value>,
pub format_acceptance_config: Option<Value>,
}
fn trimmed_non_empty_string(value: Option<String>) -> Option<String> {
value.and_then(|value| {
let trimmed = value.trim().to_string();
(!trimmed.is_empty()).then_some(trimmed)
})
}
pub fn build_admin_provider_endpoint_record(
id: String,
provider_id: String,
normalized_api_format: String,
api_family: String,
endpoint_kind: String,
base_url: String,
custom_path: Option<String>,
header_rules: Option<Value>,
body_rules: Option<Value>,
max_retries: i32,
config: Option<Value>,
proxy: Option<Value>,
format_acceptance_config: Option<Value>,
now_unix_secs: u64,
) -> Result<StoredProviderCatalogEndpoint, String> {
StoredProviderCatalogEndpoint::new(
id,
provider_id,
normalized_api_format,
Some(api_family),
Some(endpoint_kind),
true,
)
.map_err(|err| err.to_string())?
.with_timestamps(Some(now_unix_secs), Some(now_unix_secs))
.with_transport_fields(
base_url,
header_rules,
body_rules,
Some(max_retries),
trimmed_non_empty_string(custom_path),
config,
format_acceptance_config,
proxy,
)
.map_err(|err| err.to_string())
}
pub fn apply_admin_provider_endpoint_update_fields(
existing_endpoint: &StoredProviderCatalogEndpoint,
raw_payload: &Map<String, Value>,
payload: &AdminProviderEndpointUpdateFields,
) -> Result<StoredProviderCatalogEndpoint, String> {
let mut updated = existing_endpoint.clone();
if let Some(value) = raw_payload.get("base_url") {
let Some(base_url) = payload.base_url.as_deref() else {
return Err(if value.is_null() {
"base_url 不能为空".to_string()
} else {
"base_url 必须是字符串".to_string()
});
};
updated.base_url = base_url.to_string();
}
if raw_payload.contains_key("custom_path") {
updated.custom_path = payload.custom_path.clone();
}
if let Some(value) = raw_payload.get("header_rules") {
if !value.is_null() && !value.is_array() {
return Err("header_rules 必须是数组或 null".to_string());
}
updated.header_rules = if value.is_null() {
None
} else {
payload.header_rules.clone()
};
}
if let Some(value) = raw_payload.get("body_rules") {
if !value.is_null() && !value.is_array() {
return Err("body_rules 必须是数组或 null".to_string());
}
updated.body_rules = if value.is_null() {
None
} else {
payload.body_rules.clone()
};
}
if let Some(value) = raw_payload.get("max_retries") {
let Some(max_retries) = payload.max_retries else {
return Err(if value.is_null() {
"max_retries 必须是 0 到 999 之间的整数".to_string()
} else {
"max_retries 必须是整数".to_string()
});
};
if !(0..=999).contains(&max_retries) {
return Err("max_retries 必须在 0 到 999 之间".to_string());
}
updated.max_retries = Some(max_retries);
}
if raw_payload.contains_key("is_active") {
let Some(is_active) = payload.is_active else {
return Err("is_active 必须是布尔值".to_string());
};
updated.is_active = is_active;
}
if let Some(value) = raw_payload.get("config") {
if !value.is_null() && !value.is_object() {
return Err("config 必须是对象或 null".to_string());
}
updated.config = if value.is_null() {
None
} else {
payload.config.clone()
};
}
if let Some(value) = raw_payload.get("proxy") {
if value.is_null() {
updated.proxy = None;
} else {
let Some(mut proxy) = payload
.proxy
.clone()
.and_then(|value| value.as_object().cloned())
else {
return Err("proxy 必须是对象或 null".to_string());
};
if !proxy.contains_key("password") {
if let Some(old_password) = existing_endpoint
.proxy
.as_ref()
.and_then(Value::as_object)
.and_then(|proxy| proxy.get("password"))
.and_then(Value::as_str)
.filter(|value| !value.is_empty())
{
proxy.insert("password".to_string(), json!(old_password));
}
}
updated.proxy = Some(Value::Object(proxy));
}
}
if let Some(value) = raw_payload.get("format_acceptance_config") {
if !value.is_null() && !value.is_object() {
return Err("format_acceptance_config 必须是对象或 null".to_string());
}
updated.format_acceptance_config = if value.is_null() {
None
} else {
payload.format_acceptance_config.clone()
};
}
Ok(updated)
}