mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
refactor(workspace): enforce layered crate boundaries
This commit is contained in:
@@ -1818,24 +1818,11 @@ impl GatewayDataState {
|
||||
.effective_user_groups_for_user(&snapshot.user_id)
|
||||
.await?;
|
||||
|
||||
let allowed_providers =
|
||||
resolve_effective_list_policy(None, "unrestricted", &groups, |group| {
|
||||
(
|
||||
&group.allowed_providers_mode,
|
||||
group.allowed_providers.clone(),
|
||||
)
|
||||
});
|
||||
let allowed_api_formats =
|
||||
resolve_effective_api_format_policy(None, "unrestricted", &groups, |group| {
|
||||
(
|
||||
&group.allowed_api_formats_mode,
|
||||
group.allowed_api_formats.clone(),
|
||||
)
|
||||
});
|
||||
let allowed_models =
|
||||
resolve_effective_list_policy(None, "unrestricted", &groups, |group| {
|
||||
(&group.allowed_models_mode, group.allowed_models.clone())
|
||||
});
|
||||
let GatewayUserEffectiveListPolicies {
|
||||
allowed_providers,
|
||||
allowed_api_formats,
|
||||
allowed_models,
|
||||
} = resolve_group_effective_list_policies(&groups);
|
||||
let user_rate_limit = resolve_effective_rate_limit_policy(None, "system", &groups);
|
||||
snapshot.user_allowed_providers = allowed_providers;
|
||||
snapshot.user_allowed_api_formats = allowed_api_formats;
|
||||
@@ -1860,36 +1847,7 @@ impl GatewayDataState {
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
Ok(GatewayUserEffectiveListPolicies {
|
||||
allowed_providers: resolve_effective_list_policy(
|
||||
user.allowed_providers.clone(),
|
||||
&user.allowed_providers_mode,
|
||||
&groups,
|
||||
|group| {
|
||||
(
|
||||
&group.allowed_providers_mode,
|
||||
group.allowed_providers.clone(),
|
||||
)
|
||||
},
|
||||
),
|
||||
allowed_api_formats: resolve_effective_api_format_policy(
|
||||
user.allowed_api_formats.clone(),
|
||||
&user.allowed_api_formats_mode,
|
||||
&groups,
|
||||
|group| {
|
||||
(
|
||||
&group.allowed_api_formats_mode,
|
||||
group.allowed_api_formats.clone(),
|
||||
)
|
||||
},
|
||||
),
|
||||
allowed_models: resolve_effective_list_policy(
|
||||
user.allowed_models.clone(),
|
||||
&user.allowed_models_mode,
|
||||
&groups,
|
||||
|group| (&group.allowed_models_mode, group.allowed_models.clone()),
|
||||
),
|
||||
})
|
||||
Ok(resolve_group_effective_list_policies(&groups))
|
||||
}
|
||||
|
||||
async fn effective_user_groups_for_user(
|
||||
@@ -1979,6 +1937,35 @@ fn apply_admin_unrestricted_auth_snapshot(snapshot: &mut StoredAuthApiKeySnapsho
|
||||
snapshot.api_key_concurrent_limit = None;
|
||||
}
|
||||
|
||||
// Per-user list policy columns are retained only for legacy import/export compatibility.
|
||||
// Runtime authorization and user-facing catalogs must both treat group policies as authoritative.
|
||||
fn resolve_group_effective_list_policies(
|
||||
groups: &[aether_data::repository::users::StoredUserGroup],
|
||||
) -> GatewayUserEffectiveListPolicies {
|
||||
GatewayUserEffectiveListPolicies {
|
||||
allowed_providers: resolve_effective_list_policy(None, "unrestricted", groups, |group| {
|
||||
(
|
||||
&group.allowed_providers_mode,
|
||||
group.allowed_providers.clone(),
|
||||
)
|
||||
}),
|
||||
allowed_api_formats: resolve_effective_api_format_policy(
|
||||
None,
|
||||
"unrestricted",
|
||||
groups,
|
||||
|group| {
|
||||
(
|
||||
&group.allowed_api_formats_mode,
|
||||
group.allowed_api_formats.clone(),
|
||||
)
|
||||
},
|
||||
),
|
||||
allowed_models: resolve_effective_list_policy(None, "unrestricted", groups, |group| {
|
||||
(&group.allowed_models_mode, group.allowed_models.clone())
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_effective_list_policy(
|
||||
user_values: Option<Vec<String>>,
|
||||
user_mode: &str,
|
||||
@@ -2592,8 +2579,9 @@ mod tests {
|
||||
Some("hash-user".to_string()),
|
||||
snapshot,
|
||||
)]));
|
||||
let user = sample_auth_user("user-1", "user");
|
||||
let user_repository = Arc::new(InMemoryUserReadRepository::seed_auth_users(vec![
|
||||
sample_auth_user("user-1", "user"),
|
||||
user.clone()
|
||||
]));
|
||||
let group = user_repository
|
||||
.create_user_group(UpsertUserGroupRecord {
|
||||
@@ -2638,6 +2626,23 @@ mod tests {
|
||||
Some(&["claude-sonnet-4-5".to_string()][..])
|
||||
);
|
||||
assert_eq!(resolved.user_rate_limit, Some(30));
|
||||
|
||||
let catalog_policies = state
|
||||
.resolve_user_effective_list_policies(&user)
|
||||
.await
|
||||
.expect("catalog policies should resolve");
|
||||
assert_eq!(
|
||||
catalog_policies.allowed_providers.as_deref(),
|
||||
resolved.effective_allowed_providers()
|
||||
);
|
||||
assert_eq!(
|
||||
catalog_policies.allowed_api_formats.as_deref(),
|
||||
resolved.effective_allowed_api_formats()
|
||||
);
|
||||
assert_eq!(
|
||||
catalog_policies.allowed_models.as_deref(),
|
||||
resolved.effective_allowed_models()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,8 @@ use aether_data_contracts::repository::usage::{
|
||||
PendingUsageCleanupSummary, ProviderApiKeyWindowUsageRequest,
|
||||
StoredProviderApiKeyWindowUsageSummary, StoredUsageDailySummary, UsageAuditListQuery,
|
||||
UsageCleanupExecutionMode, UsageCleanupSummary, UsageCleanupTargets, UsageCleanupWindow,
|
||||
UsageCounterFlushSummary, UsageCounterHealthSnapshot, UsageDailyHeatmapQuery,
|
||||
UsageCounterFlushSummary, UsageCounterHealthSnapshot, UsageCounterPendingHealthSnapshot,
|
||||
UsageDailyHeatmapQuery,
|
||||
};
|
||||
use aether_runtime_state::RuntimeQueueStore;
|
||||
use aether_video_tasks_core::read_data_backed_video_task_response;
|
||||
@@ -152,6 +153,13 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn warm_database_pool(&self) -> Result<(), DataLayerError> {
|
||||
match &self.backends {
|
||||
Some(backends) => backends.warm_database_pool().await,
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn pending_database_backfills(
|
||||
&self,
|
||||
) -> Result<
|
||||
@@ -198,15 +206,22 @@ impl GatewayDataState {
|
||||
pub(crate) fn database_pool_summary_under_maintenance_pressure(
|
||||
summary: &aether_data::DatabasePoolSummary,
|
||||
) -> bool {
|
||||
summary.checked_out > 0 && summary.idle <= Self::maintenance_pool_idle_reserve(summary)
|
||||
summary.checked_out > 0
|
||||
&& Self::database_pool_available_capacity(summary)
|
||||
<= Self::maintenance_pool_idle_reserve(summary)
|
||||
}
|
||||
|
||||
pub(crate) fn database_pool_summary_under_usage_worker_pressure(
|
||||
summary: &aether_data::DatabasePoolSummary,
|
||||
) -> bool {
|
||||
summary.checked_out > 0
|
||||
&& (summary.checked_out >= summary.max_connections as usize
|
||||
|| summary.idle <= Self::usage_worker_pool_idle_reserve(summary))
|
||||
&& Self::database_pool_available_capacity(summary)
|
||||
<= Self::usage_worker_pool_idle_reserve(summary)
|
||||
}
|
||||
|
||||
fn database_pool_available_capacity(summary: &aether_data::DatabasePoolSummary) -> usize {
|
||||
let unopened = (summary.max_connections as usize).saturating_sub(summary.pool_size);
|
||||
summary.idle.saturating_add(unopened)
|
||||
}
|
||||
|
||||
pub(crate) fn maintenance_pool_idle_reserve(
|
||||
@@ -1353,6 +1368,15 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn read_usage_counter_pending_health(
|
||||
&self,
|
||||
) -> Result<UsageCounterPendingHealthSnapshot, DataLayerError> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.read_usage_counter_pending_health().await,
|
||||
None => Ok(UsageCounterPendingHealthSnapshot::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_usage_totals_by_user_ids(
|
||||
&self,
|
||||
user_ids: &[String],
|
||||
@@ -1439,6 +1463,22 @@ impl GatewayDataState {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn summarize_dashboard_stats(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageDashboardSummaryQuery,
|
||||
) -> Result<
|
||||
aether_data_contracts::repository::usage::StoredUsageDashboardStatsSummary,
|
||||
DataLayerError,
|
||||
> {
|
||||
match &self.usage_reader {
|
||||
Some(repository) => repository.summarize_dashboard_stats(query).await,
|
||||
None => Ok(
|
||||
aether_data_contracts::repository::usage::StoredUsageDashboardStatsSummary::default(
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn list_dashboard_daily_breakdown(
|
||||
&self,
|
||||
query: &aether_data_contracts::repository::usage::UsageDashboardDailyBreakdownQuery,
|
||||
|
||||
Reference in New Issue
Block a user