Files
Genarrative/server-rs/crates/spacetime-module/src/runtime/analytics_date_dimension.rs
kdletters 5c7c039e52
Some checks failed
CI / verify (push) Has been cancelled
feat: add analytics date dimension bindings
- lock profile task tracking scope to user

- add analytics date dimension module support and tests

- regenerate SpacetimeDB Rust bindings with private APIs
2026-05-04 13:54:41 +08:00

127 lines
4.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
}
}