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(()) }