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

@@ -136,6 +136,7 @@ use module_puzzle::{
use module_runtime::{
RuntimeBrowseHistoryRecord, RuntimePlatformTheme as DomainRuntimePlatformTheme,
RuntimeProfileDashboardRecord, RuntimeProfileInviteCodeRecord, RuntimeProfilePlayStatsRecord,
AnalyticsMetricQueryResponse as DomainAnalyticsMetricQueryResponse,
RuntimeProfileRechargeCenterRecord, RuntimeProfileRechargeOrderRecord,
RuntimeProfileRedeemCodeMode as DomainRuntimeProfileRedeemCodeMode,
RuntimeProfileRedeemCodeRecord, RuntimeProfileRewardCodeRedeemRecord,
@@ -167,6 +168,7 @@ use module_runtime::{
build_runtime_profile_wallet_adjustment_input,
build_runtime_profile_wallet_ledger_entry_record,
build_runtime_profile_wallet_ledger_list_input, build_runtime_referral_invite_center_get_input,
build_analytics_metric_query_input,
build_runtime_referral_invite_center_record, build_runtime_referral_redeem_input,
build_runtime_referral_redeem_record, build_runtime_setting_get_input,
build_runtime_setting_record, build_runtime_setting_upsert_input,

View File

@@ -181,6 +181,17 @@ impl From<module_runtime::RuntimeProfileTaskCenterGetInput> for RuntimeProfileTa
}
}
impl From<module_runtime::AnalyticsMetricQueryInput> for AnalyticsMetricQueryInput {
fn from(input: module_runtime::AnalyticsMetricQueryInput) -> Self {
Self {
event_key: input.event_key,
scope_kind: map_runtime_tracking_scope_kind(input.scope_kind),
scope_id: input.scope_id,
granularity: map_analytics_granularity(input.granularity),
}
}
}
impl From<module_runtime::RuntimeProfileTaskClaimInput> for RuntimeProfileTaskClaimInput {
fn from(input: module_runtime::RuntimeProfileTaskClaimInput) -> Self {
Self {
@@ -899,6 +910,22 @@ pub(crate) fn map_runtime_profile_task_center_procedure_result(
))
}
pub(crate) fn map_analytics_metric_query_procedure_result(
result: AnalyticsMetricQueryProcedureResult,
) -> Result<DomainAnalyticsMetricQueryResponse, SpacetimeClientError> {
if !result.ok {
return Err(SpacetimeClientError::procedure_failed(result.error_message));
}
Ok(DomainAnalyticsMetricQueryResponse {
buckets: result
.buckets
.into_iter()
.map(map_analytics_bucket_metric)
.collect(),
})
}
pub(crate) fn map_runtime_profile_task_claim_procedure_result(
result: RuntimeProfileTaskClaimProcedureResult,
) -> Result<RuntimeProfileTaskClaimRecord, SpacetimeClientError> {
@@ -1751,6 +1778,17 @@ pub(crate) fn map_runtime_profile_dashboard_snapshot(
}
}
pub(crate) fn map_analytics_bucket_metric(
bucket: AnalyticsBucketMetric,
) -> module_runtime::AnalyticsBucketMetric {
module_runtime::AnalyticsBucketMetric {
bucket_key: bucket.bucket_key,
bucket_start_date_key: bucket.bucket_start_date_key,
bucket_end_date_key: bucket.bucket_end_date_key,
value: bucket.value,
}
}
pub(crate) fn map_runtime_profile_wallet_ledger_entry_snapshot(
snapshot: RuntimeProfileWalletLedgerEntrySnapshot,
) -> module_runtime::RuntimeProfileWalletLedgerEntrySnapshot {
@@ -4012,6 +4050,18 @@ pub(crate) fn map_runtime_profile_wallet_ledger_source_type_back(
}
}
pub(crate) fn map_analytics_granularity(
granularity: module_runtime::AnalyticsGranularity,
) -> AnalyticsGranularity {
match granularity {
module_runtime::AnalyticsGranularity::Day => AnalyticsGranularity::Day,
module_runtime::AnalyticsGranularity::Week => AnalyticsGranularity::Week,
module_runtime::AnalyticsGranularity::Month => AnalyticsGranularity::Month,
module_runtime::AnalyticsGranularity::Quarter => AnalyticsGranularity::Quarter,
module_runtime::AnalyticsGranularity::Year => AnalyticsGranularity::Year,
}
}
pub(crate) fn map_runtime_tracking_scope_kind(
value: DomainRuntimeTrackingScopeKind,
) -> crate::module_bindings::RuntimeTrackingScopeKind {

View File

@@ -0,0 +1,18 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct AnalyticsBucketMetric {
pub bucket_key: String,
pub bucket_start_date_key: i64,
pub bucket_end_date_key: i64,
pub value: u64,
}
impl __sdk::InModule for AnalyticsBucketMetric {
type Module = super::RemoteModule;
}

View File

@@ -0,0 +1,24 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
#[derive(Copy, Eq, Hash)]
pub enum AnalyticsGranularity {
Day,
Week,
Month,
Quarter,
Year,
}
impl __sdk::InModule for AnalyticsGranularity {
type Module = super::RemoteModule;
}

View File

@@ -0,0 +1,21 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::analytics_granularity_type::AnalyticsGranularity;
use super::runtime_tracking_scope_kind_type::RuntimeTrackingScopeKind;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct AnalyticsMetricQueryInput {
pub event_key: String,
pub scope_kind: RuntimeTrackingScopeKind,
pub scope_id: String,
pub granularity: AnalyticsGranularity,
}
impl __sdk::InModule for AnalyticsMetricQueryInput {
type Module = super::RemoteModule;
}

View File

@@ -0,0 +1,19 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::analytics_bucket_metric_type::AnalyticsBucketMetric;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct AnalyticsMetricQueryProcedureResult {
pub ok: bool,
pub buckets: Vec<AnalyticsBucketMetric>,
pub error_message: Option<String>,
}
impl __sdk::InModule for AnalyticsMetricQueryProcedureResult {
type Module = super::RemoteModule;
}

View File

@@ -690,6 +690,12 @@ pub mod user_account_type;
pub mod user_browse_history_table;
pub mod user_browse_history_type;
pub mod analytics_bucket_metric_type;
pub mod analytics_granularity_type;
pub mod analytics_metric_query_input_type;
pub mod analytics_metric_query_procedure_result_type;
pub mod query_analytics_metric_procedure;
pub use accept_quest_reducer::accept_quest;
pub use acknowledge_quest_completion_reducer::acknowledge_quest_completion;
pub use admin_disable_profile_redeem_code_procedure::admin_disable_profile_redeem_code;
@@ -736,6 +742,10 @@ pub use analytics_date_dimension_ensure_input_type::AnalyticsDateDimensionEnsure
pub use analytics_date_dimension_seed_input_type::AnalyticsDateDimensionSeedInput;
pub use analytics_date_dimension_table::*;
pub use analytics_date_dimension_type::AnalyticsDateDimension;
pub use analytics_bucket_metric_type::AnalyticsBucketMetric;
pub use analytics_granularity_type::AnalyticsGranularity;
pub use analytics_metric_query_input_type::AnalyticsMetricQueryInput;
pub use analytics_metric_query_procedure_result_type::AnalyticsMetricQueryProcedureResult;
pub use append_ai_text_chunk_and_return_procedure::append_ai_text_chunk_and_return;
pub use apply_chapter_progression_ledger_entry_and_return_procedure::apply_chapter_progression_ledger_entry_and_return;
pub use apply_chapter_progression_ledger_entry_reducer::apply_chapter_progression_ledger_entry;
@@ -978,6 +988,7 @@ pub use get_profile_play_stats_procedure::get_profile_play_stats;
pub use get_profile_recharge_center_procedure::get_profile_recharge_center;
pub use get_profile_referral_invite_center_procedure::get_profile_referral_invite_center;
pub use get_profile_task_center_procedure::get_profile_task_center;
pub use query_analytics_metric_procedure::query_analytics_metric;
pub use get_puzzle_agent_session_procedure::get_puzzle_agent_session;
pub use get_puzzle_gallery_detail_procedure::get_puzzle_gallery_detail;
pub use get_puzzle_run_procedure::get_puzzle_run;

View File

@@ -0,0 +1,59 @@
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)]
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
use super::analytics_metric_query_input_type::AnalyticsMetricQueryInput;
use super::analytics_metric_query_procedure_result_type::AnalyticsMetricQueryProcedureResult;
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
struct QueryAnalyticsMetricArgs {
pub input: AnalyticsMetricQueryInput,
}
impl __sdk::InModule for QueryAnalyticsMetricArgs {
type Module = super::RemoteModule;
}
#[allow(non_camel_case_types)]
/// Extension trait for access to the procedure `query_analytics_metric`.
///
/// Implemented for [`super::RemoteProcedures`].
pub trait query_analytics_metric {
fn query_analytics_metric(&self, input: AnalyticsMetricQueryInput) {
self.query_analytics_metric_then(input, |_, _| {});
}
fn query_analytics_metric_then(
&self,
input: AnalyticsMetricQueryInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<AnalyticsMetricQueryProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
);
}
impl query_analytics_metric for super::RemoteProcedures {
fn query_analytics_metric_then(
&self,
input: AnalyticsMetricQueryInput,
__callback: impl FnOnce(
&super::ProcedureEventContext,
Result<AnalyticsMetricQueryProcedureResult, __sdk::InternalError>,
) + Send
+ 'static,
) {
self.imp
.invoke_procedure_with_callback::<_, AnalyticsMetricQueryProcedureResult>(
"query_analytics_metric",
QueryAnalyticsMetricArgs { input },
__callback,
);
}
}

View File

@@ -348,6 +348,31 @@ impl SpacetimeClient {
.await
}
pub async fn query_analytics_metric(
&self,
event_key: String,
scope_kind: DomainRuntimeTrackingScopeKind,
scope_id: String,
granularity: module_runtime::AnalyticsGranularity,
) -> Result<DomainAnalyticsMetricQueryResponse, SpacetimeClientError> {
let procedure_input =
build_analytics_metric_query_input(event_key, scope_kind, scope_id, granularity)
.map_err(SpacetimeClientError::validation_failed)?
.into();
self.call_after_connect(move |connection, sender| {
connection
.procedures()
.query_analytics_metric_then(procedure_input, move |_, result| {
let mapped = result
.map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_analytics_metric_query_procedure_result);
send_once(&sender, mapped);
});
})
.await
}
pub async fn admin_list_profile_task_configs(
&self,
admin_user_id: String,