mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat(gateway/data): 新增 usage 关键词搜索、缓存命中摘要、结算成本摘要及 dashboard 聚合查询能力
- 新增 UsageAuditKeywordSearchQuery,支持多关键词、用户名、API Key 交叉过滤 - 新增 UsageCacheHitSummaryQuery/StoredUsageCacheHitSummary,统计请求缓存命中率 - 新增 UsageSettledCostSummaryQuery/StoredUsageSettledCostSummary,汇总结算成本 - 新增 UsageDashboardSummaryQuery、UsageBreakdownSummaryQuery 等 dashboard 聚合类型 - SQL 层实现对应查询方法,含 list_by_ids、list_usage_audits_by_keyword_search、count_usage_audits_by_keyword_search - 将上述能力通过 GatewayDataState / AdminAppState 暴露给 handler 层 - user_me_usage 及 dashboard_filters 切换为新查询接口,移除旧的内存过滤逻辑 - 同步更新 memory 层及测试
This commit is contained in:
@@ -36,6 +36,17 @@ impl AppState {
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_auth_api_key_export_records_by_name_search(
|
||||
&self,
|
||||
name_search: &str,
|
||||
) -> Result<Vec<aether_data::repository::auth::StoredAuthApiKeyExportRecord>, GatewayError>
|
||||
{
|
||||
self.data
|
||||
.list_auth_api_key_export_records_by_name_search(name_search)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_auth_api_key_export_standalone_records_page(
|
||||
&self,
|
||||
query: &aether_data::repository::auth::StandaloneApiKeyExportListQuery,
|
||||
|
||||
@@ -174,6 +174,15 @@ mod tests {
|
||||
self.lookup.list_export_api_keys_by_ids(api_key_ids).await
|
||||
}
|
||||
|
||||
async fn list_export_api_keys_by_name_search(
|
||||
&self,
|
||||
name_search: &str,
|
||||
) -> Result<Vec<StoredAuthApiKeyExportRecord>, aether_data::DataLayerError> {
|
||||
self.lookup
|
||||
.list_export_api_keys_by_name_search(name_search)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn list_export_standalone_api_keys_page(
|
||||
&self,
|
||||
query: &StandaloneApiKeyExportListQuery,
|
||||
|
||||
@@ -43,6 +43,47 @@ impl AppState {
|
||||
Ok(users)
|
||||
}
|
||||
|
||||
pub(crate) async fn search_auth_user_summaries_by_username(
|
||||
&self,
|
||||
username_search: &str,
|
||||
) -> Result<Vec<aether_data::repository::users::StoredUserSummary>, GatewayError> {
|
||||
let username_search = username_search.trim();
|
||||
if username_search.is_empty() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let mut users = BTreeMap::new();
|
||||
if self.has_user_data_reader() {
|
||||
for user in self
|
||||
.data
|
||||
.list_users_by_username_search(username_search)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))?
|
||||
{
|
||||
users.insert(user.id.clone(), user);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
if let Some(store) = self.auth_user_store.as_ref() {
|
||||
let username_search = username_search.to_ascii_lowercase();
|
||||
for user in store.lock().expect("auth user store should lock").values() {
|
||||
if user
|
||||
.username
|
||||
.to_ascii_lowercase()
|
||||
.contains(&username_search)
|
||||
{
|
||||
let summary = user
|
||||
.to_summary()
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))?;
|
||||
users.entry(summary.id.clone()).or_insert(summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(users.into_values().collect())
|
||||
}
|
||||
|
||||
pub(crate) async fn find_user_auth_by_id(
|
||||
&self,
|
||||
user_id: &str,
|
||||
|
||||
@@ -35,6 +35,26 @@ impl AppState {
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn find_request_usage_by_id(
|
||||
&self,
|
||||
usage_id: &str,
|
||||
) -> Result<Option<usage::StoredRequestUsageAudit>, GatewayError> {
|
||||
self.data
|
||||
.find_request_usage_by_id(usage_id)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_request_usage_by_ids(
|
||||
&self,
|
||||
usage_ids: &[String],
|
||||
) -> Result<Vec<usage::StoredRequestUsageAudit>, GatewayError> {
|
||||
self.data
|
||||
.list_request_usage_by_ids(usage_ids)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_usage_audits(
|
||||
&self,
|
||||
query: &usage::UsageAuditListQuery,
|
||||
@@ -55,6 +75,26 @@ impl AppState {
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_usage_audits_by_keyword_search(
|
||||
&self,
|
||||
query: &usage::UsageAuditKeywordSearchQuery,
|
||||
) -> Result<Vec<usage::StoredRequestUsageAudit>, GatewayError> {
|
||||
self.data
|
||||
.list_usage_audits_by_keyword_search(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn count_usage_audits_by_keyword_search(
|
||||
&self,
|
||||
query: &usage::UsageAuditKeywordSearchQuery,
|
||||
) -> Result<u64, GatewayError> {
|
||||
self.data
|
||||
.count_usage_audits_by_keyword_search(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn aggregate_usage_audits(
|
||||
&self,
|
||||
query: &usage::UsageAuditAggregationQuery,
|
||||
@@ -75,6 +115,136 @@ impl AppState {
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_cache_hit_summary(
|
||||
&self,
|
||||
query: &usage::UsageCacheHitSummaryQuery,
|
||||
) -> Result<usage::StoredUsageCacheHitSummary, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_cache_hit_summary(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_settled_cost(
|
||||
&self,
|
||||
query: &usage::UsageSettledCostSummaryQuery,
|
||||
) -> Result<usage::StoredUsageSettledCostSummary, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_settled_cost(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_cache_affinity_hit_summary(
|
||||
&self,
|
||||
query: &usage::UsageCacheAffinityHitSummaryQuery,
|
||||
) -> Result<usage::StoredUsageCacheAffinityHitSummary, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_cache_affinity_hit_summary(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_usage_cache_affinity_intervals(
|
||||
&self,
|
||||
query: &usage::UsageCacheAffinityIntervalQuery,
|
||||
) -> Result<Vec<usage::StoredUsageCacheAffinityIntervalRow>, GatewayError> {
|
||||
self.data
|
||||
.list_usage_cache_affinity_intervals(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_dashboard_usage(
|
||||
&self,
|
||||
query: &usage::UsageDashboardSummaryQuery,
|
||||
) -> Result<usage::StoredUsageDashboardSummary, GatewayError> {
|
||||
self.data
|
||||
.summarize_dashboard_usage(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_dashboard_daily_breakdown(
|
||||
&self,
|
||||
query: &usage::UsageDashboardDailyBreakdownQuery,
|
||||
) -> Result<Vec<usage::StoredUsageDashboardDailyBreakdownRow>, GatewayError> {
|
||||
self.data
|
||||
.list_dashboard_daily_breakdown(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_dashboard_provider_counts(
|
||||
&self,
|
||||
query: &usage::UsageDashboardProviderCountsQuery,
|
||||
) -> Result<Vec<usage::StoredUsageDashboardProviderCount>, GatewayError> {
|
||||
self.data
|
||||
.summarize_dashboard_provider_counts(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_breakdown(
|
||||
&self,
|
||||
query: &usage::UsageBreakdownSummaryQuery,
|
||||
) -> Result<Vec<usage::StoredUsageBreakdownSummaryRow>, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_breakdown(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn count_monitoring_usage_errors(
|
||||
&self,
|
||||
query: &usage::UsageMonitoringErrorCountQuery,
|
||||
) -> Result<u64, GatewayError> {
|
||||
self.data
|
||||
.count_monitoring_usage_errors(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn list_monitoring_usage_errors(
|
||||
&self,
|
||||
query: &usage::UsageMonitoringErrorListQuery,
|
||||
) -> Result<Vec<usage::StoredRequestUsageAudit>, GatewayError> {
|
||||
self.data
|
||||
.list_monitoring_usage_errors(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_error_distribution(
|
||||
&self,
|
||||
query: &usage::UsageErrorDistributionQuery,
|
||||
) -> Result<Vec<usage::StoredUsageErrorDistributionRow>, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_error_distribution(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_performance_percentiles(
|
||||
&self,
|
||||
query: &usage::UsagePerformancePercentilesQuery,
|
||||
) -> Result<Vec<usage::StoredUsagePerformancePercentilesRow>, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_performance_percentiles(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_cost_savings(
|
||||
&self,
|
||||
query: &usage::UsageCostSavingsSummaryQuery,
|
||||
) -> Result<usage::StoredUsageCostSavingsSummary, GatewayError> {
|
||||
self.data
|
||||
.summarize_usage_cost_savings(query)
|
||||
.await
|
||||
.map_err(|err| GatewayError::Internal(err.to_string()))
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_time_series(
|
||||
&self,
|
||||
query: &usage::UsageTimeSeriesQuery,
|
||||
|
||||
Reference in New Issue
Block a user