feat: add analytics date dimension bindings
Some checks failed
CI / verify (push) Has been cancelled

- lock profile task tracking scope to user

- add analytics date dimension module support and tests

- regenerate SpacetimeDB Rust bindings with private APIs
This commit is contained in:
2026-05-04 13:41:22 +08:00
committed by 历冰郁-hermes版
parent 9f3e34e81a
commit 5c7c039e52
253 changed files with 14783 additions and 1462 deletions

View File

@@ -0,0 +1,126 @@
use crate::*;
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct AnalyticsDateDimensionEnsureInput {
pub date_key: i64,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct AnalyticsDateDimensionSeedInput {
pub start_date: String,
pub end_date: String,
}
#[spacetimedb::table(
accessor = analytics_date_dimension,
index(accessor = by_analytics_date_dimension_iso_week, btree(columns = [iso_week_key])),
index(accessor = by_analytics_date_dimension_month, btree(columns = [month_key])),
index(accessor = by_analytics_date_dimension_quarter, btree(columns = [quarter_key])),
index(accessor = by_analytics_date_dimension_year, btree(columns = [year_key]))
)]
pub struct AnalyticsDateDimension {
#[primary_key]
pub(crate) date_key: i64,
// 中文注释:北京时间业务日对应的公历日期,格式 YYYY-MM-DD。
pub(crate) calendar_date: String,
// 中文注释ISO weekday周一=1周日=7方便统计层不重复计算。
pub(crate) weekday: u8,
// 中文注释ISO week 编码为 YYYYWW跨年周按 ISO 年归属。
pub(crate) iso_week_key: i32,
pub(crate) week_start_date_key: i64,
pub(crate) week_end_date_key: i64,
pub(crate) month_key: i32,
pub(crate) month_start_date_key: i64,
pub(crate) month_end_date_key: i64,
pub(crate) quarter_key: i32,
pub(crate) quarter_start_date_key: i64,
pub(crate) quarter_end_date_key: i64,
pub(crate) year_key: i32,
pub(crate) year_start_date_key: i64,
pub(crate) year_end_date_key: i64,
pub(crate) created_at: Timestamp,
pub(crate) updated_at: Timestamp,
}
#[spacetimedb::reducer]
pub fn ensure_analytics_date_dimension_for_date(
ctx: &ReducerContext,
input: AnalyticsDateDimensionEnsureInput,
) -> Result<(), String> {
ensure_analytics_date_dimension_row(ctx, input.date_key)?;
Ok(())
}
#[spacetimedb::reducer]
pub fn seed_analytics_date_dimensions(
ctx: &ReducerContext,
input: AnalyticsDateDimensionSeedInput,
) -> Result<(), String> {
let start_date_key = parse_analytics_calendar_date_key(&input.start_date)
.map_err(|error| format!("invalid start_date: {error}"))?;
let end_date_key = parse_analytics_calendar_date_key(&input.end_date)
.map_err(|error| format!("invalid end_date: {error}"))?;
if start_date_key > end_date_key {
return Err("start_date must be <= end_date".to_string());
}
let seed_days = end_date_key - start_date_key + 1;
if seed_days > ANALYTICS_DATE_DIMENSION_MAX_SEED_DAYS {
return Err(format!(
"date range too large: max {} days",
ANALYTICS_DATE_DIMENSION_MAX_SEED_DAYS
));
}
for date_key in start_date_key..=end_date_key {
ensure_analytics_date_dimension_row(ctx, date_key)?;
}
Ok(())
}
pub(crate) fn ensure_analytics_date_dimension_row(
ctx: &ReducerContext,
date_key: i64,
) -> Result<(), String> {
validate_analytics_date_dimension_date_key(date_key)
.map_err(|error| format!("invalid date_key: {error}"))?;
if ctx
.db
.analytics_date_dimension()
.date_key()
.find(&date_key)
.is_some()
{
return Ok(());
}
let snapshot = build_analytics_date_dimension_from_date_key(date_key);
ctx.db
.analytics_date_dimension()
.insert(build_analytics_date_dimension_row(snapshot, ctx.timestamp));
Ok(())
}
fn build_analytics_date_dimension_row(
snapshot: AnalyticsDateDimensionSnapshot,
now: Timestamp,
) -> AnalyticsDateDimension {
AnalyticsDateDimension {
date_key: snapshot.date_key,
calendar_date: snapshot.calendar_date,
weekday: snapshot.weekday,
iso_week_key: snapshot.iso_week_key,
week_start_date_key: snapshot.week_start_date_key,
week_end_date_key: snapshot.week_end_date_key,
month_key: snapshot.month_key,
month_start_date_key: snapshot.month_start_date_key,
month_end_date_key: snapshot.month_end_date_key,
quarter_key: snapshot.quarter_key,
quarter_start_date_key: snapshot.quarter_start_date_key,
quarter_end_date_key: snapshot.quarter_end_date_key,
year_key: snapshot.year_key,
year_start_date_key: snapshot.year_start_date_key,
year_end_date_key: snapshot.year_end_date_key,
created_at: now,
updated_at: now,
}
}