feat: add analytics metric granularity query
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-04 16:29:11 +08:00
parent 44d9bd55de
commit 1d9d8c2e41
19 changed files with 787 additions and 7 deletions

View File

@@ -471,6 +471,27 @@ pub fn list_profile_wallet_ledger(
}
}
// analytics metric 查询直接聚合 tracking_daily_stat避免 API 层订阅全量表后自行汇总。
#[spacetimedb::procedure]
pub fn query_analytics_metric(
ctx: &mut ProcedureContext,
input: AnalyticsMetricQueryInput,
) -> AnalyticsMetricQueryProcedureResult {
match ctx.try_with_tx(|tx| query_analytics_metric_buckets(tx, input.clone())) {
Ok(buckets) => AnalyticsMetricQueryProcedureResult {
ok: true,
buckets,
error_message: None,
},
Err(message) => AnalyticsMetricQueryProcedureResult {
ok: false,
buckets: Vec::new(),
error_message: Some(message),
},
}
}
// 任务中心读取会顺手记录当日登录埋点,确保“每日登录”只依赖后端事实。
#[spacetimedb::procedure]
pub fn get_profile_task_center(
@@ -2726,6 +2747,45 @@ fn build_profile_task_center_snapshot(
})
}
fn query_analytics_metric_buckets(
ctx: &ReducerContext,
input: AnalyticsMetricQueryInput,
) -> Result<Vec<AnalyticsBucketMetric>, String> {
let validated_input = build_analytics_metric_query_input(
input.event_key,
input.scope_kind,
input.scope_id,
input.granularity,
)
.map_err(|error| error.to_string())?;
let stats = ctx
.db
.tracking_daily_stat()
.iter()
.filter(|row| {
row.event_key.trim() == validated_input.event_key
&& row.scope_kind == validated_input.scope_kind
&& row.scope_id.trim() == validated_input.scope_id
})
.map(|row| RuntimeAnalyticsDailyStatSnapshot {
event_key: row.event_key,
scope_kind: row.scope_kind,
scope_id: row.scope_id,
day_key: row.day_key,
count: row.count,
})
.collect::<Vec<_>>();
Ok(aggregate_runtime_tracking_daily_stats(
stats,
&validated_input.event_key,
validated_input.scope_kind,
&validated_input.scope_id,
validated_input.granularity,
))
}
fn refresh_profile_task_progress(
ctx: &ReducerContext,
user_id: &str,