Files
Genarrative/server-rs/crates/spacetime-module/src/big_fish/events.rs

60 lines
1.8 KiB
Rust

use crate::*;
/// Big Fish 创作事件类型。
///
/// 事件表只承接跨层订阅和审计所需的轻量事实,正式作品状态仍以
/// `big_fish_creation_session` 和 `big_fish_asset_slot` 为准。
#[derive(Clone, Copy, Debug, PartialEq, Eq, SpacetimeType)]
pub enum BigFishEventKind {
PublishReadinessEvaluated,
}
#[spacetimedb::table(
accessor = big_fish_event,
public,
event,
index(accessor = by_big_fish_event_session_id, btree(columns = [session_id])),
index(accessor = by_big_fish_event_owner_user_id, btree(columns = [owner_user_id]))
)]
pub struct BigFishEvent {
#[primary_key]
pub(crate) event_id: String,
pub(crate) session_id: String,
pub(crate) owner_user_id: String,
pub(crate) event_kind: BigFishEventKind,
pub(crate) publish_ready: bool,
pub(crate) blockers_json: String,
pub(crate) occurred_at: Timestamp,
}
pub(crate) fn emit_big_fish_publish_readiness_event(
ctx: &ReducerContext,
event: BigFishDomainEvent,
) -> Result<(), String> {
let BigFishDomainEvent::PublishReadinessEvaluated {
session_id,
owner_user_id,
publish_ready,
blockers,
occurred_at_micros,
} = event
else {
return Ok(());
};
let blockers_json = serde_json::to_string(&blockers)
.map_err(|error| format!("big_fish.publish_readiness.blockers 序列化失败: {error}"))?;
let state_slug = if publish_ready { "ready" } else { "blocked" };
ctx.db.big_fish_event().insert(BigFishEvent {
event_id: format!("bfevt_{session_id}_{occurred_at_micros}_{state_slug}"),
session_id,
owner_user_id,
event_kind: BigFishEventKind::PublishReadinessEvaluated,
publish_ready,
blockers_json,
occurred_at: Timestamp::from_micros_since_unix_epoch(occurred_at_micros),
});
Ok(())
}