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:
fawney19
2026-04-17 01:00:38 +08:00
parent 6e5af5ef70
commit 1e0bc61526
48 changed files with 5241 additions and 1162 deletions
@@ -47,6 +47,29 @@ impl<'a> AdminAppState<'a> {
self.app.count_usage_audits(query).await
}
pub(crate) async fn list_usage_audits_by_keyword_search(
&self,
query: &aether_data_contracts::repository::usage::UsageAuditKeywordSearchQuery,
) -> Result<Vec<aether_data_contracts::repository::usage::StoredRequestUsageAudit>, GatewayError>
{
self.app.list_usage_audits_by_keyword_search(query).await
}
pub(crate) async fn count_usage_audits_by_keyword_search(
&self,
query: &aether_data_contracts::repository::usage::UsageAuditKeywordSearchQuery,
) -> Result<u64, GatewayError> {
self.app.count_usage_audits_by_keyword_search(query).await
}
pub(crate) async fn list_monitoring_usage_errors(
&self,
query: &aether_data_contracts::repository::usage::UsageMonitoringErrorListQuery,
) -> Result<Vec<aether_data_contracts::repository::usage::StoredRequestUsageAudit>, GatewayError>
{
self.app.list_monitoring_usage_errors(query).await
}
pub(crate) async fn aggregate_usage_audits(
&self,
query: &aether_data_contracts::repository::usage::UsageAuditAggregationQuery,
@@ -65,6 +88,44 @@ impl<'a> AdminAppState<'a> {
self.app.summarize_usage_audits(query).await
}
pub(crate) async fn summarize_usage_cache_hit_summary(
&self,
query: &aether_data_contracts::repository::usage::UsageCacheHitSummaryQuery,
) -> Result<aether_data_contracts::repository::usage::StoredUsageCacheHitSummary, GatewayError>
{
self.app.summarize_usage_cache_hit_summary(query).await
}
pub(crate) async fn summarize_usage_settled_cost(
&self,
query: &aether_data_contracts::repository::usage::UsageSettledCostSummaryQuery,
) -> Result<aether_data_contracts::repository::usage::StoredUsageSettledCostSummary, GatewayError>
{
self.app.summarize_usage_settled_cost(query).await
}
pub(crate) async fn summarize_usage_cache_affinity_hit_summary(
&self,
query: &aether_data_contracts::repository::usage::UsageCacheAffinityHitSummaryQuery,
) -> Result<
aether_data_contracts::repository::usage::StoredUsageCacheAffinityHitSummary,
GatewayError,
> {
self.app
.summarize_usage_cache_affinity_hit_summary(query)
.await
}
pub(crate) async fn list_usage_cache_affinity_intervals(
&self,
query: &aether_data_contracts::repository::usage::UsageCacheAffinityIntervalQuery,
) -> Result<
Vec<aether_data_contracts::repository::usage::StoredUsageCacheAffinityIntervalRow>,
GatewayError,
> {
self.app.list_usage_cache_affinity_intervals(query).await
}
pub(crate) async fn summarize_usage_time_series(
&self,
query: &aether_data_contracts::repository::usage::UsageTimeSeriesQuery,
@@ -85,6 +146,36 @@ impl<'a> AdminAppState<'a> {
self.app.summarize_usage_leaderboard(query).await
}
pub(crate) async fn summarize_usage_error_distribution(
&self,
query: &aether_data_contracts::repository::usage::UsageErrorDistributionQuery,
) -> Result<
Vec<aether_data_contracts::repository::usage::StoredUsageErrorDistributionRow>,
GatewayError,
> {
self.app.summarize_usage_error_distribution(query).await
}
pub(crate) async fn summarize_usage_performance_percentiles(
&self,
query: &aether_data_contracts::repository::usage::UsagePerformancePercentilesQuery,
) -> Result<
Vec<aether_data_contracts::repository::usage::StoredUsagePerformancePercentilesRow>,
GatewayError,
> {
self.app
.summarize_usage_performance_percentiles(query)
.await
}
pub(crate) async fn summarize_usage_cost_savings(
&self,
query: &aether_data_contracts::repository::usage::UsageCostSavingsSummaryQuery,
) -> Result<aether_data_contracts::repository::usage::StoredUsageCostSavingsSummary, GatewayError>
{
self.app.summarize_usage_cost_savings(query).await
}
pub(crate) async fn summarize_usage_daily_heatmap(
&self,
query: &aether_data_contracts::repository::usage::UsageDailyHeatmapQuery,
@@ -107,6 +198,14 @@ impl<'a> AdminAppState<'a> {
.map_err(|err| GatewayError::Internal(err.to_string()))
}
pub(crate) async fn list_request_usage_by_ids(
&self,
usage_ids: &[String],
) -> Result<Vec<aether_data_contracts::repository::usage::StoredRequestUsageAudit>, GatewayError>
{
self.app.list_request_usage_by_ids(usage_ids).await
}
pub(crate) async fn resolve_request_usage_body_ref(
&self,
body_ref: &str,
@@ -118,27 +217,6 @@ impl<'a> AdminAppState<'a> {
.map_err(|err| GatewayError::Internal(err.to_string()))
}
pub(crate) async fn list_admin_usage_for_range(
&self,
time_range: &crate::handlers::admin::observability::AdminStatsTimeRange,
filters: &crate::handlers::admin::observability::AdminStatsUsageFilter,
) -> Result<Vec<aether_data_contracts::repository::usage::StoredRequestUsageAudit>, GatewayError>
{
crate::handlers::admin::observability::list_usage_for_range(self, time_range, filters).await
}
pub(crate) async fn list_admin_usage_for_optional_range(
&self,
time_range: Option<&crate::handlers::admin::observability::AdminStatsTimeRange>,
filters: &crate::handlers::admin::observability::AdminStatsUsageFilter,
) -> Result<Vec<aether_data_contracts::repository::usage::StoredRequestUsageAudit>, GatewayError>
{
crate::handlers::admin::observability::list_usage_for_optional_range(
self, time_range, filters,
)
.await
}
pub(crate) async fn build_api_format_health_monitor_payload(
&self,
lookback_hours: u64,
@@ -26,6 +26,15 @@ impl<'a> AdminAppState<'a> {
self.app.resolve_auth_user_summaries_by_ids(user_ids).await
}
pub(crate) async fn search_auth_user_summaries_by_username(
&self,
username_search: &str,
) -> Result<Vec<aether_data::repository::users::StoredUserSummary>, GatewayError> {
self.app
.search_auth_user_summaries_by_username(username_search)
.await
}
pub(crate) async fn list_export_users_page(
&self,
query: &aether_data::repository::users::UserExportListQuery,
@@ -383,6 +392,16 @@ impl<'a> AdminAppState<'a> {
.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.app
.list_auth_api_key_export_records_by_name_search(name_search)
.await
}
pub(crate) async fn list_auth_api_key_export_standalone_records_page(
&self,
query: &aether_data::repository::auth::StandaloneApiKeyExportListQuery,