mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-09 10:57:03 +08:00
feat(usage): enrich audit metadata and detail views
This commit is contained in:
@@ -135,22 +135,22 @@ INSERT INTO `usage` (
|
||||
ON DUPLICATE KEY UPDATE
|
||||
user_id = VALUES(user_id),
|
||||
api_key_id = VALUES(api_key_id),
|
||||
provider_name = VALUES(provider_name),
|
||||
model = VALUES(model),
|
||||
target_model = VALUES(target_model),
|
||||
provider_id = VALUES(provider_id),
|
||||
provider_endpoint_id = VALUES(provider_endpoint_id),
|
||||
provider_api_key_id = VALUES(provider_api_key_id),
|
||||
request_type = VALUES(request_type),
|
||||
api_format = VALUES(api_format),
|
||||
api_family = VALUES(api_family),
|
||||
endpoint_kind = VALUES(endpoint_kind),
|
||||
endpoint_api_format = VALUES(endpoint_api_format),
|
||||
provider_api_family = VALUES(provider_api_family),
|
||||
provider_endpoint_kind = VALUES(provider_endpoint_kind),
|
||||
has_format_conversion = VALUES(has_format_conversion),
|
||||
is_stream = VALUES(is_stream),
|
||||
upstream_is_stream = VALUES(upstream_is_stream),
|
||||
provider_name = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN provider_name ELSE VALUES(provider_name) END,
|
||||
model = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN model ELSE VALUES(model) END,
|
||||
target_model = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN target_model ELSE VALUES(target_model) END,
|
||||
provider_id = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN provider_id ELSE VALUES(provider_id) END,
|
||||
provider_endpoint_id = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN provider_endpoint_id ELSE VALUES(provider_endpoint_id) END,
|
||||
provider_api_key_id = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN provider_api_key_id ELSE VALUES(provider_api_key_id) END,
|
||||
request_type = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN request_type ELSE VALUES(request_type) END,
|
||||
api_format = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN api_format ELSE VALUES(api_format) END,
|
||||
api_family = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN api_family ELSE VALUES(api_family) END,
|
||||
endpoint_kind = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN endpoint_kind ELSE VALUES(endpoint_kind) END,
|
||||
endpoint_api_format = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN endpoint_api_format ELSE VALUES(endpoint_api_format) END,
|
||||
provider_api_family = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN provider_api_family ELSE VALUES(provider_api_family) END,
|
||||
provider_endpoint_kind = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN provider_endpoint_kind ELSE VALUES(provider_endpoint_kind) END,
|
||||
has_format_conversion = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN has_format_conversion ELSE VALUES(has_format_conversion) END,
|
||||
is_stream = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN is_stream ELSE VALUES(is_stream) END,
|
||||
upstream_is_stream = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN upstream_is_stream ELSE VALUES(upstream_is_stream) END,
|
||||
input_tokens = CASE
|
||||
WHEN status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming') THEN input_tokens
|
||||
ELSE VALUES(input_tokens)
|
||||
@@ -231,15 +231,15 @@ ON DUPLICATE KEY UPDATE
|
||||
WHEN status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming') THEN billing_status
|
||||
ELSE VALUES(billing_status)
|
||||
END,
|
||||
request_metadata = VALUES(request_metadata),
|
||||
candidate_id = VALUES(candidate_id),
|
||||
candidate_index = VALUES(candidate_index),
|
||||
key_name = VALUES(key_name),
|
||||
planner_kind = VALUES(planner_kind),
|
||||
route_family = VALUES(route_family),
|
||||
route_kind = VALUES(route_kind),
|
||||
execution_path = VALUES(execution_path),
|
||||
local_execution_runtime_miss_reason = VALUES(local_execution_runtime_miss_reason),
|
||||
request_metadata = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN request_metadata ELSE VALUES(request_metadata) END,
|
||||
candidate_id = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN candidate_id ELSE VALUES(candidate_id) END,
|
||||
candidate_index = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN candidate_index ELSE VALUES(candidate_index) END,
|
||||
key_name = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN key_name ELSE VALUES(key_name) END,
|
||||
planner_kind = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN planner_kind ELSE VALUES(planner_kind) END,
|
||||
route_family = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN route_family ELSE VALUES(route_family) END,
|
||||
route_kind = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN route_kind ELSE VALUES(route_kind) END,
|
||||
execution_path = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN execution_path ELSE VALUES(execution_path) END,
|
||||
local_execution_runtime_miss_reason = CASE WHEN (status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming')) OR (status = 'streaming' AND VALUES(status) = 'pending') THEN local_execution_runtime_miss_reason ELSE VALUES(local_execution_runtime_miss_reason) END,
|
||||
finalized_at = CASE
|
||||
WHEN status IN ('completed', 'failed', 'cancelled') AND VALUES(status) IN ('pending', 'streaming') THEN finalized_at
|
||||
ELSE VALUES(finalized_at)
|
||||
|
||||
@@ -65,6 +65,50 @@ fn mysql_usage_upsert_keeps_terminal_state_when_streaming_arrives_late() {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_usage_upsert_guards_candidate_identity_metadata_and_routing_from_late_lifecycle() {
|
||||
for field in [
|
||||
"provider_name",
|
||||
"model",
|
||||
"target_model",
|
||||
"provider_id",
|
||||
"provider_endpoint_id",
|
||||
"provider_api_key_id",
|
||||
"request_type",
|
||||
"api_format",
|
||||
"api_family",
|
||||
"endpoint_kind",
|
||||
"endpoint_api_format",
|
||||
"provider_api_family",
|
||||
"provider_endpoint_kind",
|
||||
"has_format_conversion",
|
||||
"is_stream",
|
||||
"upstream_is_stream",
|
||||
"request_metadata",
|
||||
"candidate_id",
|
||||
"candidate_index",
|
||||
"key_name",
|
||||
"planner_kind",
|
||||
"route_family",
|
||||
"route_kind",
|
||||
"execution_path",
|
||||
"local_execution_runtime_miss_reason",
|
||||
] {
|
||||
let assignment = format!("{field} = CASE WHEN (");
|
||||
assert!(
|
||||
super::UPSERT_USAGE_SQL.contains(&assignment),
|
||||
"missing lifecycle guard for {field}"
|
||||
);
|
||||
let preserve = format!("THEN {field} ELSE VALUES({field}) END");
|
||||
assert!(
|
||||
super::UPSERT_USAGE_SQL.contains(&preserve),
|
||||
"late lifecycle must preserve {field}"
|
||||
);
|
||||
}
|
||||
assert!(super::UPSERT_USAGE_SQL
|
||||
.contains("OR (status = 'streaming' AND VALUES(status) = 'pending')"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn mysql_usage_write_repository_upserts_when_url_is_set() {
|
||||
let Some(database_url) = std::env::var("AETHER_TEST_MYSQL_URL")
|
||||
|
||||
Reference in New Issue
Block a user