diff --git a/package.json b/package.json index 6ddc5166..720c0aff 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "admin-web:preview": "npm --prefix apps/admin-web run preview --", "spacetime:generate": "node scripts/generate-spacetime-bindings.mjs", "check:api-server-env": "node scripts/check-api-server-env.mjs", + "check:spacetime-runtime-access": "node scripts/check-spacetime-runtime-access.mjs", "deploy:rust:remote": "node scripts/run-bash-script.mjs scripts/deploy-rust-remote.sh", "build:production-release": "node scripts/run-bash-script.mjs scripts/build-production-release.sh", "build:rust:ubuntu": "node scripts/run-bash-script.mjs scripts/deploy-rust-remote.sh", @@ -31,7 +32,7 @@ "check:visual-novel-vn11": "node scripts/check-visual-novel-vn11-negative-scan.mjs", "check:visual-novel-vn12": "node scripts/check-visual-novel-vn12-acceptance.mjs", "check:wechat-miniprogram-auth": "node scripts/check-wechat-miniprogram-auth-smoke.mjs", - "check:server-rs-ddd": "npm run check:spacetime-schema && node scripts/check-server-rs-ddd-boundaries.mjs", + "check:server-rs-ddd": "npm run check:spacetime-schema && npm run check:spacetime-runtime-access && node scripts/check-server-rs-ddd-boundaries.mjs", "lint:eslint": "eslint . --ext .ts,.tsx,.js,.mjs,.cjs --max-warnings 0", "lint:guardrails": "npm run lint:eslint", "typecheck": "tsc -p tsconfig.typecheck-guardrails.json --noEmit", diff --git a/scripts/check-spacetime-runtime-access.mjs b/scripts/check-spacetime-runtime-access.mjs new file mode 100644 index 00000000..7ca05f89 --- /dev/null +++ b/scripts/check-spacetime-runtime-access.mjs @@ -0,0 +1,221 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +const repoRoot = process.cwd(); + +function readUtf8(relativePath) { + const absolute = path.join(repoRoot, relativePath); + if (!fs.existsSync(absolute)) { + failures.push(`${relativePath}: 文件不存在,无法执行 SpacetimeDB runtime access 检查`); + return null; + } + return fs.readFileSync(absolute, 'utf8'); +} + +const forbiddenSnippets = [ + { + file: 'server-rs/crates/spacetime-module/src/puzzle.rs', + snippet: '.puzzle_work_profile()\n .iter()\n .filter(|row| row.owner_user_id == input.owner_user_id)', + reason: 'puzzle_work_profile 已有 by_puzzle_work_owner_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/puzzle.rs', + snippet: '.puzzle_work_profile()\n .iter()\n .filter(|row| row.publication_status == PuzzlePublicationStatus::Published)', + reason: 'puzzle_work_profile 已有 by_puzzle_work_publication_status 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/puzzle.rs', + snippet: '.puzzle_leaderboard_entry()\n .iter()\n .filter(|row| row.profile_id == profile_id && row.grid_size == grid_size)', + reason: 'puzzle_leaderboard_entry 已有 by_puzzle_leaderboard_profile_grid 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/match3d/mod.rs', + snippet: '.match3d_work_profile()\n .iter()\n .filter(|row| {', + reason: 'match3d_work_profile 已有 owner/status 索引,列表不应整表过滤', + }, + { + file: 'server-rs/crates/spacetime-module/src/visual_novel.rs', + snippet: '.visual_novel_work_profile()\n .iter()\n .filter(|row| {', + reason: 'visual_novel_work_profile 已有 owner/status 索引,列表不应整表过滤', + }, + { + file: 'server-rs/crates/spacetime-module/src/asset_metadata/objects.rs', + snippet: '.asset_object()\n .iter()\n .find(|row| row.bucket == input.bucket && row.object_key == input.object_key)', + reason: 'asset_object 已有 by_bucket_object_key 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/asset_metadata/objects.rs', + snippet: '.asset_object()\n .iter()\n .filter(|row| row.asset_kind == asset_kind)', + reason: 'asset_object 已有 asset_kind 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/ai/stages.rs', + snippet: '.ai_task_stage()\n .iter()\n .filter(|row| row.task_id == task_id)', + reason: 'ai_task_stage 已有 by_ai_task_stage_task_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/ai/stages.rs', + snippet: '.ai_text_chunk()\n .iter()\n .filter(|row| row.task_id == task_id && row.stage_kind == stage_kind)', + reason: 'ai_text_chunk 已有 by_ai_text_chunk_task_id / by_ai_text_chunk_task_stage_sequence 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/ai/snapshots.rs', + snippet: '.ai_task_stage()\n .iter()\n .filter(|stage| stage.task_id == row.task_id)', + reason: 'ai_task_stage 快照组装应使用 by_ai_task_stage_task_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/ai/snapshots.rs', + snippet: '.ai_result_reference()\n .iter()\n .filter(|reference| reference.task_id == row.task_id)', + reason: 'ai_result_reference 快照组装应使用 by_ai_result_reference_task_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/runtime/profile.rs', + snippet: '.profile_save_archive()\n .iter()\n .filter(|row| row.user_id == validated_input.user_id)', + reason: 'profile_save_archive 已有 by_profile_save_archive_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/runtime/profile.rs', + snippet: '.profile_played_world()\n .iter()\n .filter(|row| row.user_id == validated_input.user_id)', + reason: 'profile_played_world 已有 by_profile_played_world_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/runtime/profile.rs', + snippet: '.profile_wallet_ledger()\n .iter()\n .filter(|row| row.user_id == validated_input.user_id)', + reason: 'profile_wallet_ledger 已有 by_profile_wallet_ledger_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/runtime/profile.rs', + snippet: '.profile_referral_relation()\n .iter()\n .filter(|row| row.inviter_user_id == user_id)', + reason: 'profile_referral_relation 已有 by_profile_referral_inviter_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/runtime/profile.rs', + snippet: '.profile_recharge_order()\n .iter()\n .filter(|row| row.user_id == user_id)', + reason: 'profile_recharge_order 已有 by_profile_recharge_order_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/runtime/profile.rs', + snippet: '.tracking_daily_stat()\n .iter()\n .filter(|row| {', + reason: 'tracking_daily_stat 已有 by_tracking_daily_stat_scope_day / event_day 索引,analytics 查询不应整表过滤', + }, + { + file: 'server-rs/crates/spacetime-module/src/custom_world/mod.rs', + snippet: '.custom_world_profile()\n .iter()\n .find(|row| {', + reason: 'custom_world_profile owner 维度已有 by_custom_world_profile_owner_user_id 索引', + }, + { + file: 'server-rs/crates/spacetime-module/src/custom_world/mod.rs', + snippet: '.custom_world_profile()\n .iter()\n .filter(|profile| {', + reason: 'custom_world_profile Published 同步已有 by_custom_world_profile_publication_status 索引', + }, +]; + +const procedureResultFiles = [ + 'server-rs/crates/module-puzzle/src/application.rs', + 'server-rs/crates/module-big-fish/src/domain.rs', + 'server-rs/crates/spacetime-module/src/match3d/types.rs', + 'server-rs/crates/spacetime-module/src/square_hole/types.rs', + 'server-rs/crates/spacetime-module/src/visual_novel.rs', + 'server-rs/crates/spacetime-module/src/bark_battle/types.rs', +]; + +const mapperCompatibilityFiles = [ + 'server-rs/crates/spacetime-client/src/mapper.rs', + 'server-rs/crates/spacetime-client/src/lib.rs', +]; + +const bigFishRuntimeFiles = [ + 'server-rs/crates/module-big-fish/src/commands.rs', + 'server-rs/crates/spacetime-module/src/big_fish/runtime.rs', + 'server-rs/crates/spacetime-module/src/big_fish/session.rs', +]; + +const legacyMapperPatterns = [ + { + pattern: /\b[A-Za-z0-9_]*JsonRecord\b/u, + reason: 'spacetime-client mapper 不应保留旧 ProcedureResult JSON 兼容 Record', + }, + { + pattern: /\bCompatibleBigFish[A-Za-z0-9_]*\b/u, + reason: 'spacetime-client mapper 不应保留 BigFish 旧 JSON 兼容结构', + }, + { + pattern: /\bmap_[A-Za-z0-9_]*_json\b/u, + reason: 'spacetime-client mapper 不应再通过 map_*_json 反序列化 procedure payload', + }, + { + pattern: /serde_json::from_str::<[A-Za-z0-9_:]*JsonRecord/u, + reason: 'spacetime-client mapper 不应把 procedure result 再反序列化为 JsonRecord', + }, + { + pattern: /\b(?:items|run|work|session|event|feedback)_json:\s*Some\(/u, + reason: 'mapper 测试与兼容路径不应再构造旧 procedure JSON 字符串字段', + }, +]; + +const typedProcedurePayloadFieldPattern = + /\b(?:row|session|work|item|items|run|event|feedback)_json:\s*Option/gu; + +const failures = []; + +for (const rule of forbiddenSnippets) { + const content = readUtf8(rule.file); + if (content === null) { + continue; + } + if (content.includes(rule.snippet)) { + failures.push(`${rule.file}: ${rule.reason}`); + } +} + +for (const file of procedureResultFiles) { + const content = readUtf8(file); + if (content === null) { + continue; + } + const resultBlocks = content.match(/pub struct [A-Za-z0-9_]*ProcedureResult\s*\{[\s\S]*?\n\}/g) ?? []; + for (const block of resultBlocks) { + const jsonFields = block.match(typedProcedurePayloadFieldPattern); + if (jsonFields?.length) { + const name = block.match(/pub struct ([A-Za-z0-9_]+)/)?.[1] ?? 'ProcedureResult'; + failures.push(`${file}: ${name} 仍通过 ${jsonFields.join(', ')} 跨层返回 JSON 字符串`); + } + } +} + +for (const file of mapperCompatibilityFiles) { + const content = readUtf8(file); + if (content === null) { + continue; + } + for (const rule of legacyMapperPatterns) { + if (rule.pattern.test(content)) { + failures.push(`${file}: ${rule.reason}`); + } + } +} + +for (const file of bigFishRuntimeFiles) { + const content = readUtf8(file); + if (content === null) { + continue; + } + const resultBlocks = content.match(/pub struct [A-Za-z0-9_]*ProcedureResult\s*\{[\s\S]*?\n\}/g) ?? []; + for (const block of resultBlocks) { + const jsonFields = block.match(typedProcedurePayloadFieldPattern); + if (jsonFields?.length) { + const name = block.match(/pub struct ([A-Za-z0-9_]+)/)?.[1] ?? 'ProcedureResult'; + failures.push(`${file}: ${name} 仍通过 ${jsonFields.join(', ')} 跨层返回 JSON 字符串`); + } + } +} + +if (failures.length > 0) { + console.error('SpacetimeDB runtime access 检查失败:'); + for (const failure of failures) { + console.error(`- ${failure}`); + } + process.exit(1); +} + +console.log('SpacetimeDB runtime access 检查通过。'); diff --git a/server-rs/crates/module-bark-battle/src/application.rs b/server-rs/crates/module-bark-battle/src/application.rs new file mode 100644 index 00000000..840d5977 --- /dev/null +++ b/server-rs/crates/module-bark-battle/src/application.rs @@ -0,0 +1 @@ +//! 中文注释:汪汪声浪领域应用服务预留落位,当前规则仍集中在 domain/scoring。 diff --git a/server-rs/crates/module-bark-battle/src/commands.rs b/server-rs/crates/module-bark-battle/src/commands.rs new file mode 100644 index 00000000..c6be3434 --- /dev/null +++ b/server-rs/crates/module-bark-battle/src/commands.rs @@ -0,0 +1 @@ +//! 中文注释:汪汪声浪命令归一化预留落位,当前无独立命令构造。 diff --git a/server-rs/crates/module-bark-battle/src/errors.rs b/server-rs/crates/module-bark-battle/src/errors.rs new file mode 100644 index 00000000..06ea419b --- /dev/null +++ b/server-rs/crates/module-bark-battle/src/errors.rs @@ -0,0 +1 @@ +//! 中文注释:汪汪声浪领域错误预留落位,当前复用调用方错误文本。 diff --git a/server-rs/crates/module-bark-battle/src/events.rs b/server-rs/crates/module-bark-battle/src/events.rs new file mode 100644 index 00000000..fc838aae --- /dev/null +++ b/server-rs/crates/module-bark-battle/src/events.rs @@ -0,0 +1 @@ +//! 中文注释:汪汪声浪领域事件预留落位,当前不导出独立事件类型。 diff --git a/server-rs/crates/module-bark-battle/src/lib.rs b/server-rs/crates/module-bark-battle/src/lib.rs index b587645a..64a3b54d 100644 --- a/server-rs/crates/module-bark-battle/src/lib.rs +++ b/server-rs/crates/module-bark-battle/src/lib.rs @@ -1,4 +1,8 @@ +mod application; +mod commands; pub mod domain; +mod errors; +mod events; pub mod scoring; pub use domain::*; diff --git a/server-rs/crates/module-big-fish/src/commands.rs b/server-rs/crates/module-big-fish/src/commands.rs index 72d67bdd..0b186ac7 100644 --- a/server-rs/crates/module-big-fish/src/commands.rs +++ b/server-rs/crates/module-big-fish/src/commands.rs @@ -68,7 +68,7 @@ pub struct BigFishWorkRemixInput { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct BigFishWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } @@ -188,9 +188,9 @@ pub struct BigFishInputSubmitInput { } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct BigFishRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/module-creative-agent/src/events.rs b/server-rs/crates/module-creative-agent/src/events.rs new file mode 100644 index 00000000..669dec26 --- /dev/null +++ b/server-rs/crates/module-creative-agent/src/events.rs @@ -0,0 +1 @@ +//! 中文注释:创意 Agent 领域事件预留落位,当前流程不导出独立事件类型。 diff --git a/server-rs/crates/module-creative-agent/src/lib.rs b/server-rs/crates/module-creative-agent/src/lib.rs index b68fa524..b700e48b 100644 --- a/server-rs/crates/module-creative-agent/src/lib.rs +++ b/server-rs/crates/module-creative-agent/src/lib.rs @@ -2,6 +2,7 @@ mod application; mod commands; mod domain; mod errors; +mod events; pub use application::*; pub use commands::*; diff --git a/server-rs/crates/module-puzzle/src/application.rs b/server-rs/crates/module-puzzle/src/application.rs index dfa24169..eed25933 100644 --- a/server-rs/crates/module-puzzle/src/application.rs +++ b/server-rs/crates/module-puzzle/src/application.rs @@ -16,7 +16,7 @@ use crate::{domain::*, errors::PuzzleFieldError}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PuzzleAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } @@ -24,7 +24,7 @@ pub struct PuzzleAgentSessionProcedureResult { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PuzzleWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } @@ -32,15 +32,15 @@ pub struct PuzzleWorksProcedureResult { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct PuzzleWorkProcedureResult { pub ok: bool, - pub item_json: Option, + pub item: Option, pub error_message: Option, } #[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct PuzzleRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/module-visual-novel/src/commands.rs b/server-rs/crates/module-visual-novel/src/commands.rs new file mode 100644 index 00000000..975799fa --- /dev/null +++ b/server-rs/crates/module-visual-novel/src/commands.rs @@ -0,0 +1 @@ +//! 中文注释:视觉小说命令归一化预留落位,当前命令校验仍由 application 承接。 diff --git a/server-rs/crates/module-visual-novel/src/events.rs b/server-rs/crates/module-visual-novel/src/events.rs new file mode 100644 index 00000000..9f691de8 --- /dev/null +++ b/server-rs/crates/module-visual-novel/src/events.rs @@ -0,0 +1 @@ +//! 中文注释:视觉小说领域事件预留落位,当前不导出独立事件类型。 diff --git a/server-rs/crates/module-visual-novel/src/lib.rs b/server-rs/crates/module-visual-novel/src/lib.rs index 290d744e..0b5c82a5 100644 --- a/server-rs/crates/module-visual-novel/src/lib.rs +++ b/server-rs/crates/module-visual-novel/src/lib.rs @@ -1,6 +1,8 @@ mod application; +mod commands; mod domain; mod errors; +mod events; pub use application::*; pub use domain::*; diff --git a/server-rs/crates/spacetime-client/src/mapper.rs b/server-rs/crates/spacetime-client/src/mapper.rs index 38551408..8ee6a7c5 100644 --- a/server-rs/crates/spacetime-client/src/mapper.rs +++ b/server-rs/crates/spacetime-client/src/mapper.rs @@ -782,33 +782,94 @@ pub type BarkBattleRunRecord = serde_json::Value; pub(crate) fn map_bark_battle_draft_config_procedure_result( result: BarkBattleProcedureResult, ) -> Result { - parse_bark_battle_row_json(result, "Bark Battle draft config") + if !result.ok { + return Err(SpacetimeClientError::procedure_failed(result.error_message)); + } + result + .draft_config + .ok_or_else(|| SpacetimeClientError::missing_snapshot("Bark Battle draft config")) + .map(bark_battle_draft_config_to_value) } pub(crate) fn map_bark_battle_runtime_config_procedure_result( result: BarkBattleProcedureResult, ) -> Result { - parse_bark_battle_row_json(result, "Bark Battle runtime config") + if !result.ok { + return Err(SpacetimeClientError::procedure_failed(result.error_message)); + } + result + .runtime_config + .ok_or_else(|| SpacetimeClientError::missing_snapshot("Bark Battle runtime config")) + .map(bark_battle_runtime_config_to_value) } pub(crate) fn map_bark_battle_run_procedure_result( result: BarkBattleProcedureResult, ) -> Result { - parse_bark_battle_row_json(result, "Bark Battle run") -} - -fn parse_bark_battle_row_json( - result: BarkBattleProcedureResult, - label: &'static str, -) -> Result { if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let row_json = result - .row_json - .ok_or_else(|| SpacetimeClientError::missing_snapshot(label))?; - serde_json::from_str(&row_json) - .map_err(|error| SpacetimeClientError::Runtime(format!("{label} JSON 解析失败: {error}"))) + result + .run + .ok_or_else(|| SpacetimeClientError::missing_snapshot("Bark Battle run")) + .map(bark_battle_run_to_value) +} + +fn bark_battle_draft_config_to_value(snapshot: BarkBattleDraftConfigSnapshot) -> serde_json::Value { + serde_json::json!({ + "draftId": snapshot.draft_id, + "ownerUserId": snapshot.owner_user_id, + "workId": snapshot.work_id, + "configVersion": snapshot.config_version, + "rulesetVersion": snapshot.ruleset_version, + "difficultyPreset": snapshot.difficulty_preset, + "leaderboardEnabled": snapshot.leaderboard_enabled, + "configJson": snapshot.config_json, + "editorStateJson": snapshot.editor_state_json, + "createdAtMicros": snapshot.created_at_micros, + "updatedAtMicros": snapshot.updated_at_micros, + }) +} + +fn bark_battle_runtime_config_to_value( + snapshot: BarkBattleRuntimeConfigSnapshot, +) -> serde_json::Value { + serde_json::json!({ + "workId": snapshot.work_id, + "ownerUserId": snapshot.owner_user_id, + "sourceDraftId": snapshot.source_draft_id, + "configVersion": snapshot.config_version, + "rulesetVersion": snapshot.ruleset_version, + "difficultyPreset": snapshot.difficulty_preset, + "leaderboardEnabled": snapshot.leaderboard_enabled, + "configJson": snapshot.config_json, + "publishedSnapshotJson": snapshot.published_snapshot_json, + "publishedAtMicros": snapshot.published_at_micros, + "updatedAtMicros": snapshot.updated_at_micros, + }) +} + +fn bark_battle_run_to_value(snapshot: BarkBattleRunSnapshot) -> serde_json::Value { + serde_json::json!({ + "runId": snapshot.run_id, + "ownerUserId": snapshot.owner_user_id, + "workId": snapshot.work_id, + "configVersion": snapshot.config_version, + "rulesetVersion": snapshot.ruleset_version, + "difficultyPreset": snapshot.difficulty_preset, + "leaderboardEnabled": snapshot.leaderboard_enabled, + "status": snapshot.status, + "clientStartedAtMicros": snapshot.client_started_at_micros, + "serverStartedAtMicros": snapshot.server_started_at_micros, + "clientFinishedAtMicros": snapshot.client_finished_at_micros, + "serverFinishedAtMicros": snapshot.server_finished_at_micros, + "metricsJson": snapshot.metrics_json, + "serverResult": snapshot.server_result, + "validationStatus": snapshot.validation_status, + "antiCheatFlagsJson": snapshot.anti_cheat_flags_json, + "leaderboardScore": snapshot.leaderboard_score, + "scoreId": snapshot.score_id, + }) } pub type CreationEntryConfigRecord = @@ -1479,6 +1540,20 @@ pub(crate) fn map_custom_world_library_detail_result( }) } +pub(crate) fn map_custom_world_gallery_list_result( + result: CustomWorldGalleryListResult, +) -> Result, SpacetimeClientError> { + if !result.ok { + return Err(SpacetimeClientError::procedure_failed(result.error_message)); + } + + Ok(result + .entries + .into_iter() + .map(map_custom_world_gallery_entry_snapshot) + .collect::, _>>()?) +} + pub(crate) fn map_custom_world_library_mutation_result( result: CustomWorldLibraryMutationResult, ) -> Result { @@ -1612,13 +1687,9 @@ pub(crate) fn map_puzzle_agent_session_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let session_json = result - .session_json + let session = result + .session .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle agent session 快照"))?; - let session: DomainPuzzleAgentSessionSnapshot = - serde_json::from_str(&session_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("puzzle agent session_json 非法: {error}")) - })?; Ok(map_puzzle_agent_session_snapshot(session)) } @@ -1629,12 +1700,9 @@ pub(crate) fn map_puzzle_work_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let item_json = result - .item_json + let item = result + .item .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle work 快照"))?; - let item: DomainPuzzleWorkProfile = serde_json::from_str(&item_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("puzzle work item_json 非法: {error}")) - })?; Ok(map_puzzle_work_profile(item)) } @@ -1645,14 +1713,11 @@ pub(crate) fn map_puzzle_works_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let items_json = result - .items_json - .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle works 快照"))?; - let items: Vec = - serde_json::from_str(&items_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("puzzle works items_json 非法: {error}")) - })?; - Ok(items.into_iter().map(map_puzzle_work_profile).collect()) + Ok(result + .items + .into_iter() + .map(map_puzzle_work_profile) + .collect()) } pub(crate) fn map_puzzle_run_procedure_result( @@ -1662,12 +1727,9 @@ pub(crate) fn map_puzzle_run_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let run_json = result - .run_json + let run = result + .run .ok_or_else(|| SpacetimeClientError::missing_snapshot("puzzle run 快照"))?; - let run: DomainPuzzleRunSnapshot = serde_json::from_str(&run_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("puzzle run run_json 非法: {error}")) - })?; Ok(map_puzzle_run_snapshot(run)) } @@ -1687,52 +1749,17 @@ pub(crate) fn map_big_fish_session_procedure_result( pub(crate) fn map_big_fish_works_procedure_result( result: BigFishWorksProcedureResult, - fallback_owner_user_id: Option<&str>, + _fallback_owner_user_id: Option<&str>, ) -> Result, SpacetimeClientError> { if !result.ok { return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let items_json = result - .items_json - .ok_or_else(|| SpacetimeClientError::missing_snapshot("big fish works 快照"))?; - serde_json::from_str::>(&items_json) - .map(|items| { - items - .into_iter() - .map(|item| item.into_record(fallback_owner_user_id)) - .collect() - }) - .map_err(|error| { - SpacetimeClientError::Runtime(format!("big fish works items_json 非法: {error}")) - }) -} - -pub(crate) fn map_big_fish_gallery_view_row( - row: BigFishWorkSummarySnapshot, - recent_play_count_7d: u32, -) -> BigFishWorkSummaryRecord { - BigFishWorkSummaryRecord { - work_id: row.work_id, - source_session_id: row.source_session_id, - owner_user_id: row.owner_user_id, - title: row.title, - subtitle: row.subtitle, - summary: row.summary, - cover_image_src: row.cover_image_src, - status: row.status, - updated_at_micros: row.updated_at_micros, - published_at_micros: row.published_at_micros, - publish_ready: row.publish_ready, - level_count: row.level_count, - level_main_image_ready_count: row.level_main_image_ready_count, - level_motion_ready_count: row.level_motion_ready_count, - background_ready: row.background_ready, - play_count: row.play_count, - remix_count: row.remix_count, - like_count: row.like_count, - recent_play_count_7d, - } + Ok(result + .items + .into_iter() + .map(map_big_fish_work_summary_snapshot) + .collect()) } pub(crate) fn map_big_fish_run_procedure_result( @@ -1742,13 +1769,9 @@ pub(crate) fn map_big_fish_run_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let run_json = result - .run_json + let run = result + .run .ok_or_else(|| SpacetimeClientError::missing_snapshot("big fish run 快照"))?; - let run: module_big_fish::BigFishRuntimeSnapshot = - serde_json::from_str(&run_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("big fish run run_json 非法: {error}")) - })?; Ok(map_big_fish_runtime_snapshot(run)) } @@ -1763,15 +1786,11 @@ pub(crate) fn map_match3d_agent_session_procedure_result( )); } - let session_json = result.session_json.ok_or_else(|| { + let session = result.session.ok_or_else(|| { SpacetimeClientError::Procedure( "SpacetimeDB procedure 未返回 match3d agent session 快照".to_string(), ) })?; - let session = - serde_json::from_str::(&session_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("match3d session_json 非法: {error}")) - })?; Ok(map_match3d_agent_session_snapshot(session)) } @@ -1787,14 +1806,11 @@ pub(crate) fn map_match3d_work_procedure_result( )); } - let work_json = result.work_json.ok_or_else(|| { + let work = result.work.ok_or_else(|| { SpacetimeClientError::Procedure( "SpacetimeDB procedure 未返回 match3d work 快照".to_string(), ) })?; - let work = serde_json::from_str::(&work_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("match3d work_json 非法: {error}")) - })?; Ok(map_match3d_work_snapshot(work)) } @@ -1810,17 +1826,11 @@ pub(crate) fn map_match3d_works_procedure_result( )); } - let items_json = result.items_json.ok_or_else(|| { - SpacetimeClientError::Procedure( - "SpacetimeDB procedure 未返回 match3d works 快照".to_string(), - ) - })?; - let items = - serde_json::from_str::>(&items_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("match3d works items_json 非法: {error}")) - })?; - - Ok(items.into_iter().map(map_match3d_work_snapshot).collect()) + Ok(result + .items + .into_iter() + .map(map_match3d_work_snapshot) + .collect()) } pub(crate) fn map_match3d_run_procedure_result( @@ -1834,10 +1844,10 @@ pub(crate) fn map_match3d_run_procedure_result( )); } - let run_json = result.run_json.ok_or_else(|| { + let run = result.run.ok_or_else(|| { SpacetimeClientError::Procedure("SpacetimeDB procedure 未返回 match3d run 快照".to_string()) })?; - map_match3d_run_json(run_json) + Ok(map_match3d_run_snapshot(run)) } pub(crate) fn map_match3d_click_item_procedure_result( @@ -1851,12 +1861,12 @@ pub(crate) fn map_match3d_click_item_procedure_result( )); } - let run_json = result.run_json.ok_or_else(|| { + let run = result.run.ok_or_else(|| { SpacetimeClientError::Procedure( "SpacetimeDB procedure 未返回 match3d click run 快照".to_string(), ) })?; - let run = map_match3d_run_json(run_json)?; + let run = map_match3d_run_snapshot(run); let accepted = result.status == "Accepted"; let accepted_item_instance_id = result.accepted_item_instance_id.clone(); let entered_slot_index = accepted_item_instance_id.as_deref().and_then(|item_id| { @@ -1885,12 +1895,9 @@ pub(crate) fn map_square_hole_agent_session_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let session_json = result - .session_json + let session = result + .session .ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole agent session 快照"))?; - let session = serde_json::from_str::(&session_json).map_err( - |error| SpacetimeClientError::Runtime(format!("square hole session_json 非法: {error}")), - )?; Ok(map_square_hole_agent_session_snapshot(session)) } @@ -1902,12 +1909,9 @@ pub(crate) fn map_square_hole_work_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let work_json = result - .work_json + let work = result + .work .ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole work 快照"))?; - let work = serde_json::from_str::(&work_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("square hole work_json 非法: {error}")) - })?; Ok(map_square_hole_work_snapshot(work)) } @@ -1919,15 +1923,8 @@ pub(crate) fn map_square_hole_works_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let items_json = result - .items_json - .ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole works 快照"))?; - let items = - serde_json::from_str::>(&items_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("square hole works items_json 非法: {error}")) - })?; - - Ok(items + Ok(result + .items .into_iter() .map(map_square_hole_work_snapshot) .collect()) @@ -1940,10 +1937,10 @@ pub(crate) fn map_square_hole_run_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let run_json = result - .run_json + let run = result + .run .ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole run 快照"))?; - map_square_hole_run_json(run_json) + Ok(map_square_hole_run_snapshot(run)) } pub(crate) fn map_square_hole_drop_shape_procedure_result( @@ -1953,17 +1950,13 @@ pub(crate) fn map_square_hole_drop_shape_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let run_json = result - .run_json + let run = result + .run .ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole drop run 快照"))?; - let feedback_json = result - .feedback_json + let feedback = result + .feedback .ok_or_else(|| SpacetimeClientError::missing_snapshot("square hole drop feedback 快照"))?; - let run = map_square_hole_run_json(run_json)?; - let feedback = serde_json::from_str::(&feedback_json) - .map_err(|error| { - SpacetimeClientError::Runtime(format!("square hole feedback_json 非法: {error}")) - })?; + let run = map_square_hole_run_snapshot(run); Ok(SquareHoleDropConfirmationRecord { status: result.status, @@ -1982,13 +1975,9 @@ pub(crate) fn map_visual_novel_agent_session_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let session_json = result - .session_json + let session = result + .session .ok_or_else(|| SpacetimeClientError::missing_snapshot("visual novel agent session 快照"))?; - let session = serde_json::from_str::(&session_json) - .map_err(|error| { - SpacetimeClientError::Runtime(format!("visual novel session_json 非法: {error}")) - })?; Ok(map_visual_novel_agent_session_snapshot(session)) } @@ -2000,12 +1989,9 @@ pub(crate) fn map_visual_novel_work_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let work_json = result - .work_json + let work = result + .work .ok_or_else(|| SpacetimeClientError::missing_snapshot("visual novel work 快照"))?; - let work = serde_json::from_str::(&work_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("visual novel work_json 非法: {error}")) - })?; Ok(map_visual_novel_work_snapshot(work)) } @@ -2017,15 +2003,8 @@ pub(crate) fn map_visual_novel_works_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let items_json = result - .items_json - .ok_or_else(|| SpacetimeClientError::missing_snapshot("visual novel works 快照"))?; - let items = - serde_json::from_str::>(&items_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("visual novel works items_json 非法: {error}")) - })?; - - Ok(items + Ok(result + .items .into_iter() .map(map_visual_novel_work_snapshot) .collect()) @@ -2038,12 +2017,9 @@ pub(crate) fn map_visual_novel_run_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let run_json = result - .run_json + let run = result + .run .ok_or_else(|| SpacetimeClientError::missing_snapshot("visual novel run 快照"))?; - let run = serde_json::from_str::(&run_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("visual novel run_json 非法: {error}")) - })?; Ok(map_visual_novel_run_snapshot(run)) } @@ -2055,15 +2031,8 @@ pub(crate) fn map_visual_novel_history_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let items_json = result - .items_json - .ok_or_else(|| SpacetimeClientError::missing_snapshot("visual novel history 快照"))?; - let items = serde_json::from_str::>(&items_json) - .map_err(|error| { - SpacetimeClientError::Runtime(format!("visual novel history items_json 非法: {error}")) - })?; - - Ok(items + Ok(result + .items .into_iter() .map(map_visual_novel_history_entry) .collect()) @@ -2076,12 +2045,9 @@ pub(crate) fn map_visual_novel_runtime_event_procedure_result( return Err(SpacetimeClientError::procedure_failed(result.error_message)); } - let event_json = result - .event_json + let event = result + .event .ok_or_else(|| SpacetimeClientError::missing_snapshot("visual novel runtime event 快照"))?; - let event = serde_json::from_str::(&event_json).map_err( - |error| SpacetimeClientError::Runtime(format!("visual novel event_json 非法: {error}")), - )?; Ok(map_visual_novel_runtime_event(event)) } @@ -3061,14 +3027,14 @@ pub(crate) fn map_big_fish_session_snapshot( } pub(crate) fn map_puzzle_agent_session_snapshot( - snapshot: DomainPuzzleAgentSessionSnapshot, + snapshot: PuzzleAgentSessionSnapshot, ) -> PuzzleAgentSessionRecord { PuzzleAgentSessionRecord { session_id: snapshot.session_id, seed_text: snapshot.seed_text, current_turn: snapshot.current_turn, progress_percent: snapshot.progress_percent, - stage: snapshot.stage.as_str().to_string(), + stage: format_puzzle_agent_stage(snapshot.stage).to_string(), anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack), draft: snapshot.draft.map(map_puzzle_result_draft), messages: snapshot @@ -3088,7 +3054,7 @@ pub(crate) fn map_puzzle_agent_session_snapshot( } } -pub(crate) fn map_puzzle_anchor_pack(snapshot: DomainPuzzleAnchorPack) -> PuzzleAnchorPackRecord { +pub(crate) fn map_puzzle_anchor_pack(snapshot: PuzzleAnchorPack) -> PuzzleAnchorPackRecord { PuzzleAnchorPackRecord { theme_promise: map_puzzle_anchor_item(snapshot.theme_promise), visual_subject: map_puzzle_anchor_item(snapshot.visual_subject), @@ -3098,26 +3064,7 @@ pub(crate) fn map_puzzle_anchor_pack(snapshot: DomainPuzzleAnchorPack) -> Puzzle } } -fn map_puzzle_anchor_pack_row(snapshot: PuzzleAnchorPack) -> PuzzleAnchorPackRecord { - PuzzleAnchorPackRecord { - theme_promise: map_puzzle_anchor_item_row(snapshot.theme_promise), - visual_subject: map_puzzle_anchor_item_row(snapshot.visual_subject), - visual_mood: map_puzzle_anchor_item_row(snapshot.visual_mood), - composition_hooks: map_puzzle_anchor_item_row(snapshot.composition_hooks), - tags_and_forbidden: map_puzzle_anchor_item_row(snapshot.tags_and_forbidden), - } -} - -pub(crate) fn map_puzzle_anchor_item(snapshot: DomainPuzzleAnchorItem) -> PuzzleAnchorItemRecord { - PuzzleAnchorItemRecord { - key: snapshot.key, - label: snapshot.label, - value: snapshot.value, - status: snapshot.status.as_str().to_string(), - } -} - -fn map_puzzle_anchor_item_row(snapshot: PuzzleAnchorItem) -> PuzzleAnchorItemRecord { +pub(crate) fn map_puzzle_anchor_item(snapshot: PuzzleAnchorItem) -> PuzzleAnchorItemRecord { PuzzleAnchorItemRecord { key: snapshot.key, label: snapshot.label, @@ -3126,9 +3073,7 @@ fn map_puzzle_anchor_item_row(snapshot: PuzzleAnchorItem) -> PuzzleAnchorItemRec } } -pub(crate) fn map_puzzle_result_draft( - snapshot: DomainPuzzleResultDraft, -) -> PuzzleResultDraftRecord { +pub(crate) fn map_puzzle_result_draft(snapshot: PuzzleResultDraft) -> PuzzleResultDraftRecord { PuzzleResultDraftRecord { work_title: snapshot.work_title, work_description: snapshot.work_description, @@ -3156,9 +3101,7 @@ pub(crate) fn map_puzzle_result_draft( } } -pub(crate) fn map_puzzle_form_draft( - snapshot: module_puzzle::PuzzleFormDraft, -) -> PuzzleFormDraftRecord { +pub(crate) fn map_puzzle_form_draft(snapshot: PuzzleFormDraft) -> PuzzleFormDraftRecord { PuzzleFormDraftRecord { work_title: snapshot.work_title, work_description: snapshot.work_description, @@ -3166,7 +3109,7 @@ pub(crate) fn map_puzzle_form_draft( } } -pub(crate) fn map_puzzle_draft_level(snapshot: DomainPuzzleDraftLevel) -> PuzzleDraftLevelRecord { +pub(crate) fn map_puzzle_draft_level(snapshot: PuzzleDraftLevel) -> PuzzleDraftLevelRecord { PuzzleDraftLevelRecord { level_id: snapshot.level_id, level_name: snapshot.level_name, @@ -3188,44 +3131,7 @@ pub(crate) fn map_puzzle_draft_level(snapshot: DomainPuzzleDraftLevel) -> Puzzle } } -fn map_puzzle_draft_level_row(snapshot: PuzzleDraftLevel) -> PuzzleDraftLevelRecord { - PuzzleDraftLevelRecord { - level_id: snapshot.level_id, - level_name: snapshot.level_name, - picture_description: snapshot.picture_description, - picture_reference: snapshot.picture_reference, - ui_background_prompt: snapshot.ui_background_prompt, - ui_background_image_src: snapshot.ui_background_image_src, - ui_background_image_object_key: snapshot.ui_background_image_object_key, - background_music: snapshot.background_music.map(map_puzzle_audio_asset_row), - candidates: snapshot - .candidates - .into_iter() - .map(map_puzzle_generated_image_candidate_row) - .collect(), - selected_candidate_id: snapshot.selected_candidate_id, - cover_image_src: snapshot.cover_image_src, - cover_asset_id: snapshot.cover_asset_id, - generation_status: snapshot.generation_status, - } -} - -pub(crate) fn map_puzzle_audio_asset( - asset: module_puzzle::PuzzleAudioAsset, -) -> PuzzleAudioAssetRecord { - PuzzleAudioAssetRecord { - task_id: asset.task_id, - provider: asset.provider, - asset_object_id: asset.asset_object_id, - asset_kind: asset.asset_kind, - audio_src: asset.audio_src, - prompt: asset.prompt, - title: asset.title, - updated_at: asset.updated_at, - } -} - -fn map_puzzle_audio_asset_row(asset: PuzzleAudioAsset) -> PuzzleAudioAssetRecord { +pub(crate) fn map_puzzle_audio_asset(asset: PuzzleAudioAsset) -> PuzzleAudioAssetRecord { PuzzleAudioAssetRecord { task_id: asset.task_id, provider: asset.provider, @@ -3239,7 +3145,7 @@ fn map_puzzle_audio_asset_row(asset: PuzzleAudioAsset) -> PuzzleAudioAssetRecord } pub(crate) fn map_puzzle_creator_intent( - snapshot: DomainPuzzleCreatorIntent, + snapshot: PuzzleCreatorIntent, ) -> PuzzleCreatorIntentRecord { PuzzleCreatorIntentRecord { source_mode: snapshot.source_mode, @@ -3254,20 +3160,6 @@ pub(crate) fn map_puzzle_creator_intent( } pub(crate) fn map_puzzle_generated_image_candidate( - snapshot: DomainPuzzleGeneratedImageCandidate, -) -> PuzzleGeneratedImageCandidateRecord { - PuzzleGeneratedImageCandidateRecord { - candidate_id: snapshot.candidate_id, - image_src: snapshot.image_src, - asset_id: snapshot.asset_id, - prompt: snapshot.prompt, - actual_prompt: snapshot.actual_prompt, - source_type: snapshot.source_type, - selected: snapshot.selected, - } -} - -fn map_puzzle_generated_image_candidate_row( snapshot: PuzzleGeneratedImageCandidate, ) -> PuzzleGeneratedImageCandidateRecord { PuzzleGeneratedImageCandidateRecord { @@ -3282,19 +3174,19 @@ fn map_puzzle_generated_image_candidate_row( } pub(crate) fn map_puzzle_agent_message_snapshot( - snapshot: DomainPuzzleAgentMessageSnapshot, + snapshot: PuzzleAgentMessageSnapshot, ) -> PuzzleAgentMessageRecord { PuzzleAgentMessageRecord { message_id: snapshot.message_id, - role: snapshot.role.as_str().to_string(), - kind: snapshot.kind.as_str().to_string(), + role: format_puzzle_agent_message_role(snapshot.role).to_string(), + kind: format_puzzle_agent_message_kind(snapshot.kind).to_string(), text: snapshot.text, created_at: format_timestamp_micros(snapshot.created_at_micros), } } fn map_match3d_agent_session_snapshot( - snapshot: Match3DAgentSessionJsonRecord, + snapshot: Match3DAgentSessionSnapshot, ) -> Match3DAgentSessionRecord { let config = map_match3d_creator_config(snapshot.config); Match3DAgentSessionRecord { @@ -3319,7 +3211,7 @@ fn map_match3d_agent_session_snapshot( } fn map_match3d_creator_config( - snapshot: Match3DCreatorConfigJsonRecord, + snapshot: Match3DCreatorConfigSnapshot, ) -> Match3DCreatorConfigRecord { Match3DCreatorConfigRecord { theme_text: snapshot.theme_text, @@ -3334,7 +3226,7 @@ fn map_match3d_creator_config( } fn map_match3d_result_draft( - snapshot: Match3DDraftJsonRecord, + snapshot: Match3DDraftSnapshot, reference_image_src: Option, ) -> Match3DResultDraftRecord { Match3DResultDraftRecord { @@ -3347,15 +3239,15 @@ fn map_match3d_result_draft( reference_image_src, clear_count: snapshot.clear_count, difficulty: snapshot.difficulty, + generated_item_assets_json: snapshot.generated_item_assets_json, total_item_count: snapshot.clear_count.saturating_mul(3), publish_ready: false, blockers: Vec::new(), - generated_item_assets_json: snapshot.generated_item_assets_json, } } fn map_match3d_agent_message_snapshot( - snapshot: Match3DAgentMessageJsonRecord, + snapshot: Match3DAgentMessageSnapshot, ) -> Match3DAgentMessageRecord { Match3DAgentMessageRecord { message_id: snapshot.message_id, @@ -3366,7 +3258,7 @@ fn map_match3d_agent_message_snapshot( } } -fn map_match3d_work_snapshot(snapshot: Match3DWorkJsonRecord) -> Match3DWorkProfileRecord { +fn map_match3d_work_snapshot(snapshot: Match3DWorkSnapshot) -> Match3DWorkProfileRecord { let config = map_match3d_creator_config(snapshot.config); Match3DWorkProfileRecord { work_id: snapshot.profile_id.clone(), @@ -3419,14 +3311,7 @@ pub(crate) fn map_match3d_gallery_view_row(row: Match3DGalleryViewRow) -> Match3 } } -fn map_match3d_run_json(run_json: String) -> Result { - let run = serde_json::from_str::(&run_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("match3d run_json 非法: {error}")) - })?; - Ok(map_match3d_run_snapshot(run)) -} - -fn map_match3d_run_snapshot(snapshot: Match3DRunJsonRecord) -> Match3DRunRecord { +fn map_match3d_run_snapshot(snapshot: Match3DRunSnapshot) -> Match3DRunRecord { let tray_slots = snapshot .tray_slots .into_iter() @@ -3467,7 +3352,7 @@ fn map_match3d_run_snapshot(snapshot: Match3DRunJsonRecord) -> Match3DRunRecord } fn map_match3d_item_snapshot( - snapshot: Match3DItemJsonRecord, + snapshot: Match3DItemSnapshot, tray_slot_index: Option, ) -> Match3DItemSnapshotRecord { Match3DItemSnapshotRecord { @@ -3484,7 +3369,7 @@ fn map_match3d_item_snapshot( } } -fn map_match3d_tray_slot_snapshot(snapshot: Match3DTraySlotJsonRecord) -> Match3DTraySlotRecord { +fn map_match3d_tray_slot_snapshot(snapshot: Match3DTraySlotSnapshot) -> Match3DTraySlotRecord { Match3DTraySlotRecord { slot_index: snapshot.slot_index, item_instance_id: snapshot.item_instance_id, @@ -3518,7 +3403,7 @@ fn build_match3d_anchor_item(key: &str, label: &str, value: &str) -> Match3DAnch } fn map_square_hole_agent_session_snapshot( - snapshot: SquareHoleAgentSessionJsonRecord, + snapshot: SquareHoleAgentSessionSnapshot, ) -> SquareHoleAgentSessionRecord { let config = map_square_hole_creator_config(snapshot.config); SquareHoleAgentSessionRecord { @@ -3541,7 +3426,7 @@ fn map_square_hole_agent_session_snapshot( } fn map_square_hole_creator_config( - snapshot: SquareHoleCreatorConfigJsonRecord, + snapshot: SquareHoleCreatorConfigSnapshot, ) -> SquareHoleCreatorConfigRecord { SquareHoleCreatorConfigRecord { theme_text: snapshot.theme_text, @@ -3564,9 +3449,7 @@ fn map_square_hole_creator_config( } } -fn map_square_hole_result_draft( - snapshot: SquareHoleDraftJsonRecord, -) -> SquareHoleResultDraftRecord { +fn map_square_hole_result_draft(snapshot: SquareHoleDraftSnapshot) -> SquareHoleResultDraftRecord { SquareHoleResultDraftRecord { profile_id: snapshot.profile_id, game_name: snapshot.game_name, @@ -3595,7 +3478,7 @@ fn map_square_hole_result_draft( } fn map_square_hole_agent_message_snapshot( - snapshot: SquareHoleAgentMessageJsonRecord, + snapshot: SquareHoleAgentMessageSnapshot, ) -> SquareHoleAgentMessageRecord { SquareHoleAgentMessageRecord { id: snapshot.message_id, @@ -3606,9 +3489,7 @@ fn map_square_hole_agent_message_snapshot( } } -fn map_square_hole_work_snapshot( - snapshot: SquareHoleWorkJsonRecord, -) -> SquareHoleWorkProfileRecord { +fn map_square_hole_work_snapshot(snapshot: SquareHoleWorkSnapshot) -> SquareHoleWorkProfileRecord { SquareHoleWorkProfileRecord { work_id: snapshot.work_id, profile_id: snapshot.profile_id, @@ -3664,12 +3545,12 @@ pub(crate) fn map_square_hole_gallery_view_row( shape_options: row .shape_options .into_iter() - .map(map_square_hole_shape_option_snapshot) + .map(map_square_hole_shape_option) .collect(), hole_options: row .hole_options .into_iter() - .map(map_square_hole_hole_option_snapshot) + .map(map_square_hole_hole_option) .collect(), shape_count: row.shape_count, difficulty: row.difficulty, @@ -3682,14 +3563,7 @@ pub(crate) fn map_square_hole_gallery_view_row( } } -fn map_square_hole_run_json(run_json: String) -> Result { - let run = serde_json::from_str::(&run_json).map_err(|error| { - SpacetimeClientError::Runtime(format!("square hole run_json 非法: {error}")) - })?; - Ok(map_square_hole_run_snapshot(run)) -} - -fn map_square_hole_run_snapshot(snapshot: SquareHoleRunJsonRecord) -> SquareHoleRunRecord { +fn map_square_hole_run_snapshot(snapshot: SquareHoleRunSnapshot) -> SquareHoleRunRecord { SquareHoleRunRecord { run_id: snapshot.run_id, profile_id: snapshot.profile_id, @@ -3721,7 +3595,7 @@ fn map_square_hole_run_snapshot(snapshot: SquareHoleRunJsonRecord) -> SquareHole } fn map_square_hole_shape_snapshot( - snapshot: SquareHoleShapeJsonRecord, + snapshot: SquareHoleShapeSnapshot, ) -> SquareHoleShapeSnapshotRecord { SquareHoleShapeSnapshotRecord { shape_id: snapshot.shape_id, @@ -3733,9 +3607,7 @@ fn map_square_hole_shape_snapshot( } } -fn map_square_hole_hole_snapshot( - snapshot: SquareHoleHoleJsonRecord, -) -> SquareHoleHoleSnapshotRecord { +fn map_square_hole_hole_snapshot(snapshot: SquareHoleHoleSnapshot) -> SquareHoleHoleSnapshotRecord { SquareHoleHoleSnapshotRecord { hole_id: snapshot.hole_id, hole_kind: snapshot.hole_kind, @@ -3747,31 +3619,6 @@ fn map_square_hole_hole_snapshot( } fn map_square_hole_shape_option( - snapshot: SquareHoleShapeOptionJsonRecord, -) -> SquareHoleShapeOptionRecord { - SquareHoleShapeOptionRecord { - option_id: snapshot.option_id, - shape_kind: snapshot.shape_kind, - label: snapshot.label, - target_hole_id: snapshot.target_hole_id, - image_prompt: snapshot.image_prompt, - image_src: empty_string_to_none(snapshot.image_src), - } -} - -fn map_square_hole_hole_option( - snapshot: SquareHoleHoleOptionJsonRecord, -) -> SquareHoleHoleOptionRecord { - SquareHoleHoleOptionRecord { - hole_id: snapshot.hole_id, - hole_kind: snapshot.hole_kind, - label: snapshot.label, - image_prompt: snapshot.image_prompt, - image_src: empty_string_to_none(snapshot.image_src), - } -} - -fn map_square_hole_shape_option_snapshot( snapshot: SquareHoleShapeOptionSnapshot, ) -> SquareHoleShapeOptionRecord { SquareHoleShapeOptionRecord { @@ -3784,7 +3631,7 @@ fn map_square_hole_shape_option_snapshot( } } -fn map_square_hole_hole_option_snapshot( +fn map_square_hole_hole_option( snapshot: SquareHoleHoleOptionSnapshot, ) -> SquareHoleHoleOptionRecord { SquareHoleHoleOptionRecord { @@ -3797,7 +3644,7 @@ fn map_square_hole_hole_option_snapshot( } fn map_square_hole_feedback_snapshot( - snapshot: SquareHoleDropFeedbackJsonRecord, + snapshot: SquareHoleDropFeedbackSnapshot, ) -> SquareHoleDropFeedbackRecord { SquareHoleDropFeedbackRecord { accepted: snapshot.accepted, @@ -3844,7 +3691,7 @@ fn build_square_hole_anchor_item( } fn map_visual_novel_agent_session_snapshot( - snapshot: VisualNovelAgentSessionJsonRecord, + snapshot: VisualNovelAgentSessionSnapshot, ) -> VisualNovelAgentSessionRecord { VisualNovelAgentSessionRecord { session_id: snapshot.session_id, @@ -3860,8 +3707,8 @@ fn map_visual_novel_agent_session_snapshot( .into_iter() .map(map_visual_novel_agent_message) .collect(), - draft: snapshot.draft, - pending_action: snapshot.pending_action, + draft: snapshot.draft.map(visual_novel_json_to_value), + pending_action: snapshot.pending_action.map(visual_novel_json_to_value), last_assistant_reply: snapshot.last_assistant_reply, published_profile_id: snapshot.published_profile_id, created_at: format_timestamp_micros(snapshot.created_at_micros), @@ -3870,7 +3717,7 @@ fn map_visual_novel_agent_session_snapshot( } fn map_visual_novel_agent_message( - snapshot: VisualNovelAgentMessageJsonRecord, + snapshot: VisualNovelAgentMessageSnapshot, ) -> VisualNovelAgentMessageRecord { VisualNovelAgentMessageRecord { message_id: snapshot.message_id, @@ -3883,7 +3730,7 @@ fn map_visual_novel_agent_message( } fn map_visual_novel_work_snapshot( - snapshot: VisualNovelWorkJsonRecord, + snapshot: VisualNovelWorkSnapshot, ) -> VisualNovelWorkProfileRecord { VisualNovelWorkProfileRecord { work_id: snapshot.work_id, @@ -3896,7 +3743,7 @@ fn map_visual_novel_work_snapshot( tags: snapshot.tags, cover_image_src: snapshot.cover_image_src, source_asset_ids: snapshot.source_asset_ids, - draft: snapshot.draft, + draft: visual_novel_json_to_value(snapshot.draft), publication_status: snapshot.publication_status, publish_ready: snapshot.publish_ready, play_count: snapshot.play_count, @@ -3931,7 +3778,7 @@ pub(crate) fn map_visual_novel_gallery_view_row( } } -fn map_visual_novel_run_snapshot(snapshot: VisualNovelRunJsonRecord) -> VisualNovelRunRecord { +fn map_visual_novel_run_snapshot(snapshot: VisualNovelRunSnapshot) -> VisualNovelRunRecord { VisualNovelRunRecord { run_id: snapshot.run_id, owner_user_id: snapshot.owner_user_id, @@ -3941,14 +3788,14 @@ fn map_visual_novel_run_snapshot(snapshot: VisualNovelRunJsonRecord) -> VisualNo current_scene_id: snapshot.current_scene_id, current_phase_id: snapshot.current_phase_id, visible_character_ids: snapshot.visible_character_ids, - flags: snapshot.flags, - metrics: snapshot.metrics, + flags: visual_novel_json_to_value(snapshot.flags), + metrics: visual_novel_json_to_value(snapshot.metrics), history: snapshot .history .into_iter() .map(map_visual_novel_history_entry) .collect(), - available_choices: snapshot.available_choices, + available_choices: visual_novel_json_to_value(snapshot.available_choices), text_mode_enabled: snapshot.text_mode_enabled, created_at: format_timestamp_micros(snapshot.created_at_micros), updated_at: format_timestamp_micros(snapshot.updated_at_micros), @@ -3956,7 +3803,7 @@ fn map_visual_novel_run_snapshot(snapshot: VisualNovelRunJsonRecord) -> VisualNo } fn map_visual_novel_history_entry( - snapshot: VisualNovelHistoryEntryJsonRecord, + snapshot: VisualNovelRuntimeHistoryEntrySnapshot, ) -> VisualNovelHistoryEntryRecord { VisualNovelHistoryEntryRecord { entry_id: snapshot.entry_id, @@ -3966,7 +3813,7 @@ fn map_visual_novel_history_entry( turn_index: snapshot.turn_index, source: snapshot.source, action_text: snapshot.action_text, - steps: snapshot.steps, + steps: visual_novel_json_to_value(snapshot.steps), snapshot_before_hash: snapshot.snapshot_before_hash, snapshot_after_hash: snapshot.snapshot_after_hash, created_at: format_timestamp_micros(snapshot.created_at_micros), @@ -3974,7 +3821,7 @@ fn map_visual_novel_history_entry( } fn map_visual_novel_runtime_event( - snapshot: VisualNovelRuntimeEventJsonRecord, + snapshot: VisualNovelRuntimeEventSnapshot, ) -> VisualNovelRuntimeEventRecord { VisualNovelRuntimeEventRecord { event_id: snapshot.event_id, @@ -3984,11 +3831,32 @@ fn map_visual_novel_runtime_event( event_kind: snapshot.event_kind, client_event_id: snapshot.client_event_id, history_entry_id: snapshot.history_entry_id, - payload: snapshot.payload, + payload: visual_novel_json_to_value(snapshot.payload), occurred_at: format_timestamp_micros(snapshot.occurred_at_micros), } } +fn visual_novel_json_to_value(value: VisualNovelJsonValue) -> serde_json::Value { + match value { + VisualNovelJsonValue::Null => serde_json::Value::Null, + VisualNovelJsonValue::Bool(value) => serde_json::Value::Bool(value), + VisualNovelJsonValue::Number(value) => serde_json::Number::from_f64(value) + .map(serde_json::Value::Number) + .unwrap_or(serde_json::Value::Null), + VisualNovelJsonValue::String(value) => serde_json::Value::String(value), + VisualNovelJsonValue::Array(items) => { + serde_json::Value::Array(items.into_iter().map(visual_novel_json_to_value).collect()) + } + VisualNovelJsonValue::Object(fields) => { + let object = fields + .into_iter() + .map(|field| (field.key, visual_novel_json_to_value(field.value))) + .collect(); + serde_json::Value::Object(object) + } + } +} + fn normalize_match3d_stage(value: &str) -> &str { match value { "Collecting" | "collecting" | "collecting_config" => "collecting_config", @@ -3999,22 +3867,6 @@ fn normalize_match3d_stage(value: &str) -> &str { } } -fn format_puzzle_publication_status(value: PuzzlePublicationStatus) -> &'static str { - match value { - PuzzlePublicationStatus::Draft => "draft", - PuzzlePublicationStatus::Published => "published", - } -} - -fn format_puzzle_anchor_status(value: PuzzleAnchorStatus) -> &'static str { - match value { - PuzzleAnchorStatus::Missing => "missing", - PuzzleAnchorStatus::Inferred => "inferred", - PuzzleAnchorStatus::Confirmed => "confirmed", - PuzzleAnchorStatus::Locked => "locked", - } -} - fn normalize_match3d_publication_status(value: &str) -> &str { match value { "Draft" | "draft" => "draft", @@ -4092,7 +3944,7 @@ fn i64_to_u64_ms(value: i64) -> u64 { } pub(crate) fn map_puzzle_suggested_action( - snapshot: DomainPuzzleAgentSuggestedAction, + snapshot: PuzzleAgentSuggestedAction, ) -> PuzzleAgentSuggestedActionRecord { PuzzleAgentSuggestedActionRecord { action_id: snapshot.id, @@ -4102,7 +3954,7 @@ pub(crate) fn map_puzzle_suggested_action( } pub(crate) fn map_puzzle_result_preview( - snapshot: DomainPuzzleResultPreviewEnvelope, + snapshot: PuzzleResultPreviewEnvelope, ) -> PuzzleResultPreviewRecord { PuzzleResultPreviewRecord { draft: map_puzzle_result_draft(snapshot.draft), @@ -4121,7 +3973,7 @@ pub(crate) fn map_puzzle_result_preview( } pub(crate) fn map_puzzle_result_preview_blocker( - snapshot: DomainPuzzleResultPreviewBlocker, + snapshot: PuzzleResultPreviewBlocker, ) -> PuzzleResultPreviewBlockerRecord { PuzzleResultPreviewBlockerRecord { blocker_id: snapshot.id, @@ -4131,7 +3983,7 @@ pub(crate) fn map_puzzle_result_preview_blocker( } pub(crate) fn map_puzzle_result_preview_finding( - snapshot: DomainPuzzleResultPreviewFinding, + snapshot: PuzzleResultPreviewFinding, ) -> PuzzleResultPreviewFindingRecord { PuzzleResultPreviewFindingRecord { finding_id: snapshot.id, @@ -4141,42 +3993,7 @@ pub(crate) fn map_puzzle_result_preview_finding( } } -pub(crate) fn map_puzzle_work_profile( - snapshot: DomainPuzzleWorkProfile, -) -> PuzzleWorkProfileRecord { - PuzzleWorkProfileRecord { - work_id: snapshot.work_id, - profile_id: snapshot.profile_id, - owner_user_id: snapshot.owner_user_id, - source_session_id: snapshot.source_session_id, - author_display_name: snapshot.author_display_name, - work_title: snapshot.work_title, - work_description: snapshot.work_description, - level_name: snapshot.level_name, - summary: snapshot.summary, - theme_tags: snapshot.theme_tags, - cover_image_src: snapshot.cover_image_src, - cover_asset_id: snapshot.cover_asset_id, - publication_status: snapshot.publication_status.as_str().to_string(), - updated_at: format_timestamp_micros(snapshot.updated_at_micros), - published_at: snapshot.published_at_micros.map(format_timestamp_micros), - play_count: snapshot.play_count, - remix_count: snapshot.remix_count, - like_count: snapshot.like_count, - recent_play_count_7d: snapshot.recent_play_count_7d, - point_incentive_total_half_points: snapshot.point_incentive_total_half_points, - point_incentive_claimed_points: snapshot.point_incentive_claimed_points, - publish_ready: snapshot.publish_ready, - anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack), - levels: snapshot - .levels - .into_iter() - .map(map_puzzle_draft_level) - .collect(), - } -} - -pub(crate) fn map_puzzle_work_profile_row(snapshot: PuzzleWorkProfile) -> PuzzleWorkProfileRecord { +pub(crate) fn map_puzzle_work_profile(snapshot: PuzzleWorkProfile) -> PuzzleWorkProfileRecord { PuzzleWorkProfileRecord { work_id: snapshot.work_id, profile_id: snapshot.profile_id, @@ -4201,16 +4018,20 @@ pub(crate) fn map_puzzle_work_profile_row(snapshot: PuzzleWorkProfile) -> Puzzle point_incentive_total_half_points: snapshot.point_incentive_total_half_points, point_incentive_claimed_points: snapshot.point_incentive_claimed_points, publish_ready: snapshot.publish_ready, - anchor_pack: map_puzzle_anchor_pack_row(snapshot.anchor_pack), + anchor_pack: map_puzzle_anchor_pack(snapshot.anchor_pack), levels: snapshot .levels .into_iter() - .map(map_puzzle_draft_level_row) + .map(map_puzzle_draft_level) .collect(), } } -pub(crate) fn map_puzzle_run_snapshot(snapshot: DomainPuzzleRunSnapshot) -> PuzzleRunRecord { +pub(crate) fn map_puzzle_work_profile_row(snapshot: PuzzleWorkProfile) -> PuzzleWorkProfileRecord { + map_puzzle_work_profile(snapshot) +} + +pub(crate) fn map_puzzle_run_snapshot(snapshot: PuzzleRunSnapshot) -> PuzzleRunRecord { PuzzleRunRecord { run_id: snapshot.run_id, entry_profile_id: snapshot.entry_profile_id, @@ -4240,7 +4061,7 @@ pub(crate) fn map_puzzle_run_snapshot(snapshot: DomainPuzzleRunSnapshot) -> Puzz } fn map_puzzle_recommended_next_work( - snapshot: module_puzzle::PuzzleRecommendedNextWork, + snapshot: PuzzleRecommendedNextWork, ) -> PuzzleRecommendedNextWorkRecord { PuzzleRecommendedNextWorkRecord { profile_id: snapshot.profile_id, @@ -4253,10 +4074,10 @@ fn map_puzzle_recommended_next_work( } pub(crate) fn map_puzzle_runtime_level_snapshot( - snapshot: DomainPuzzleRuntimeLevelSnapshot, + snapshot: PuzzleRuntimeLevelSnapshot, ) -> PuzzleRuntimeLevelRecord { let started_at_ms = if snapshot.started_at_ms == 0 { - // 中文注释:旧 run_json 没有计时字段时只补一个可用开始时间,其余限时字段保持旧默认值。 + // 中文注释:运行态快照缺少可用开始时间时只补一个可用值,其余限时字段保持快照原值。 current_unix_millis_for_legacy_puzzle_snapshot() } else { snapshot.started_at_ms @@ -4276,7 +4097,7 @@ pub(crate) fn map_puzzle_runtime_level_snapshot( ui_background_image_object_key: snapshot.ui_background_image_object_key, background_music: snapshot.background_music.map(map_puzzle_audio_asset), board: map_puzzle_board_snapshot(snapshot.board), - status: snapshot.status.as_str().to_string(), + status: format_puzzle_runtime_level_status(snapshot.status).to_string(), started_at_ms, cleared_at_ms: snapshot.cleared_at_ms, elapsed_ms: snapshot.elapsed_ms, @@ -4303,7 +4124,7 @@ fn current_unix_millis_for_legacy_puzzle_snapshot() -> u64 { } pub(crate) fn map_puzzle_leaderboard_entry( - snapshot: module_puzzle::PuzzleLeaderboardEntry, + snapshot: PuzzleLeaderboardEntry, ) -> PuzzleLeaderboardEntryRecord { PuzzleLeaderboardEntryRecord { rank: snapshot.rank, @@ -4314,7 +4135,7 @@ pub(crate) fn map_puzzle_leaderboard_entry( } } -pub(crate) fn map_puzzle_board_snapshot(snapshot: DomainPuzzleBoardSnapshot) -> PuzzleBoardRecord { +pub(crate) fn map_puzzle_board_snapshot(snapshot: PuzzleBoardSnapshot) -> PuzzleBoardRecord { PuzzleBoardRecord { rows: snapshot.rows, cols: snapshot.cols, @@ -4333,7 +4154,7 @@ pub(crate) fn map_puzzle_board_snapshot(snapshot: DomainPuzzleBoardSnapshot) -> } } -pub(crate) fn map_puzzle_piece_state(snapshot: DomainPuzzlePieceState) -> PuzzlePieceStateRecord { +pub(crate) fn map_puzzle_piece_state(snapshot: PuzzlePieceState) -> PuzzlePieceStateRecord { PuzzlePieceStateRecord { piece_id: snapshot.piece_id, correct_row: snapshot.correct_row, @@ -4345,7 +4166,7 @@ pub(crate) fn map_puzzle_piece_state(snapshot: DomainPuzzlePieceState) -> Puzzle } pub(crate) fn map_puzzle_merged_group_state( - snapshot: DomainPuzzleMergedGroupState, + snapshot: PuzzleMergedGroupState, ) -> PuzzleMergedGroupRecord { PuzzleMergedGroupRecord { group_id: snapshot.group_id, @@ -4358,9 +4179,7 @@ pub(crate) fn map_puzzle_merged_group_state( } } -pub(crate) fn map_puzzle_cell_position( - snapshot: DomainPuzzleCellPosition, -) -> PuzzleCellPositionRecord { +pub(crate) fn map_puzzle_cell_position(snapshot: PuzzleCellPosition) -> PuzzleCellPositionRecord { PuzzleCellPositionRecord { row: snapshot.row, col: snapshot.col, @@ -4494,13 +4313,48 @@ pub(crate) fn map_big_fish_agent_message_snapshot( } } +pub(crate) fn map_big_fish_work_summary_snapshot( + snapshot: BigFishWorkSummarySnapshot, +) -> BigFishWorkSummaryRecord { + BigFishWorkSummaryRecord { + work_id: snapshot.work_id, + source_session_id: snapshot.source_session_id, + owner_user_id: snapshot.owner_user_id, + title: snapshot.title, + subtitle: snapshot.subtitle, + summary: snapshot.summary, + cover_image_src: snapshot.cover_image_src, + status: snapshot.status, + updated_at_micros: snapshot.updated_at_micros, + published_at_micros: snapshot.published_at_micros, + publish_ready: snapshot.publish_ready, + level_count: snapshot.level_count, + level_main_image_ready_count: snapshot.level_main_image_ready_count, + level_motion_ready_count: snapshot.level_motion_ready_count, + background_ready: snapshot.background_ready, + play_count: snapshot.play_count, + remix_count: snapshot.remix_count, + like_count: snapshot.like_count, + recent_play_count_7d: snapshot.recent_play_count_7_d, + } +} + +pub(crate) fn map_big_fish_gallery_view_row( + row: BigFishWorkSummarySnapshot, + recent_play_count_7d: u32, +) -> BigFishWorkSummaryRecord { + let mut record = map_big_fish_work_summary_snapshot(row); + record.recent_play_count_7d = recent_play_count_7d; + record +} + pub(crate) fn map_big_fish_runtime_snapshot( - snapshot: module_big_fish::BigFishRuntimeSnapshot, + snapshot: BigFishRuntimeSnapshot, ) -> BigFishRuntimeRunRecord { BigFishRuntimeRunRecord { run_id: snapshot.run_id, session_id: snapshot.session_id, - status: snapshot.status.as_str().to_string(), + status: format_big_fish_run_status(snapshot.status).to_string(), tick: snapshot.tick, player_level: snapshot.player_level, win_level: snapshot.win_level, @@ -4523,7 +4377,7 @@ pub(crate) fn map_big_fish_runtime_snapshot( } fn map_big_fish_runtime_entity_snapshot( - snapshot: module_big_fish::BigFishRuntimeEntitySnapshot, + snapshot: BigFishRuntimeEntitySnapshot, ) -> BigFishRuntimeEntityRecord { BigFishRuntimeEntityRecord { entity_id: snapshot.entity_id, @@ -4534,7 +4388,7 @@ fn map_big_fish_runtime_entity_snapshot( } } -fn map_big_fish_vector2(snapshot: module_big_fish::BigFishVector2) -> BigFishVector2Record { +fn map_big_fish_vector2(snapshot: BigFishVector2) -> BigFishVector2Record { BigFishVector2Record { x: snapshot.x, y: snapshot.y, @@ -4999,6 +4853,57 @@ pub(crate) fn parse_puzzle_agent_stage_record( } } +pub(crate) fn format_puzzle_agent_stage(value: PuzzleAgentStage) -> &'static str { + match value { + PuzzleAgentStage::CollectingAnchors => "collecting_anchors", + PuzzleAgentStage::DraftReady => "draft_ready", + PuzzleAgentStage::ImageRefining => "image_refining", + PuzzleAgentStage::ReadyToPublish => "ready_to_publish", + PuzzleAgentStage::Published => "published", + } +} + +pub(crate) fn format_puzzle_anchor_status(value: PuzzleAnchorStatus) -> &'static str { + match value { + PuzzleAnchorStatus::Missing => "missing", + PuzzleAnchorStatus::Inferred => "inferred", + PuzzleAnchorStatus::Confirmed => "confirmed", + PuzzleAnchorStatus::Locked => "locked", + } +} + +pub(crate) fn format_puzzle_agent_message_role(value: PuzzleAgentMessageRole) -> &'static str { + match value { + PuzzleAgentMessageRole::User => "user", + PuzzleAgentMessageRole::Assistant => "assistant", + PuzzleAgentMessageRole::System => "system", + } +} + +pub(crate) fn format_puzzle_agent_message_kind(value: PuzzleAgentMessageKind) -> &'static str { + match value { + PuzzleAgentMessageKind::Chat => "chat", + PuzzleAgentMessageKind::Summary => "summary", + PuzzleAgentMessageKind::ActionResult => "action_result", + PuzzleAgentMessageKind::Warning => "warning", + } +} + +pub(crate) fn format_puzzle_publication_status(value: PuzzlePublicationStatus) -> &'static str { + match value { + PuzzlePublicationStatus::Draft => "draft", + PuzzlePublicationStatus::Published => "published", + } +} + +pub(crate) fn format_puzzle_runtime_level_status(value: PuzzleRuntimeLevelStatus) -> &'static str { + match value { + PuzzleRuntimeLevelStatus::Playing => "playing", + PuzzleRuntimeLevelStatus::Cleared => "cleared", + PuzzleRuntimeLevelStatus::Failed => "failed", + } +} + pub(crate) fn parse_rpg_agent_stage_record( value: &str, ) -> Result { @@ -5246,6 +5151,14 @@ pub(crate) fn format_big_fish_asset_status(value: BigFishAssetStatus) -> &'stati } } +pub(crate) fn format_big_fish_run_status(value: BigFishRunStatus) -> &'static str { + match value { + BigFishRunStatus::Running => "running", + BigFishRunStatus::Won => "won", + BigFishRunStatus::Failed => "failed", + } +} + pub(crate) fn format_custom_world_theme_mode(value: DomainCustomWorldThemeMode) -> &'static str { match value { DomainCustomWorldThemeMode::Martial => "martial", @@ -6715,10 +6628,10 @@ pub struct Match3DResultDraftRecord { pub reference_image_src: Option, pub clear_count: u32, pub difficulty: u32, + pub generated_item_assets_json: Option, pub total_item_count: u32, pub publish_ready: bool, pub blockers: Vec, - pub generated_item_assets_json: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -6823,137 +6736,6 @@ pub struct Match3DClickConfirmationRecord { pub run: Match3DRunRecord, } -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DCreatorConfigJsonRecord { - theme_text: String, - reference_image_src: Option, - clear_count: u32, - difficulty: u32, - #[serde(default)] - asset_style_id: Option, - #[serde(default)] - asset_style_label: Option, - #[serde(default)] - asset_style_prompt: Option, - #[serde(default)] - generate_click_sound: bool, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DAgentMessageJsonRecord { - message_id: String, - #[allow(dead_code)] - session_id: String, - role: String, - kind: String, - text: String, - created_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DDraftJsonRecord { - profile_id: String, - game_name: String, - theme_text: String, - summary_text: String, - tags: Vec, - clear_count: u32, - difficulty: u32, - #[serde(default)] - generated_item_assets_json: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DAgentSessionJsonRecord { - session_id: String, - #[allow(dead_code)] - owner_user_id: String, - #[allow(dead_code)] - seed_text: String, - current_turn: u32, - progress_percent: u32, - stage: String, - config: Match3DCreatorConfigJsonRecord, - draft: Option, - messages: Vec, - last_assistant_reply: String, - published_profile_id: Option, - #[allow(dead_code)] - created_at_micros: i64, - updated_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DWorkJsonRecord { - profile_id: String, - owner_user_id: String, - source_session_id: String, - author_display_name: String, - game_name: String, - theme_text: String, - summary_text: String, - tags: Vec, - cover_image_src: String, - cover_asset_id: String, - clear_count: u32, - difficulty: u32, - config: Match3DCreatorConfigJsonRecord, - publication_status: String, - publish_ready: bool, - play_count: u32, - updated_at_micros: i64, - published_at_micros: Option, - #[serde(default)] - generated_item_assets_json: Option, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DItemJsonRecord { - item_instance_id: String, - item_type_id: String, - visual_key: String, - x: f32, - y: f32, - radius: f32, - layer: u32, - state: String, - clickable: bool, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DTraySlotJsonRecord { - slot_index: u32, - item_instance_id: Option, - item_type_id: Option, - visual_key: Option, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct Match3DRunJsonRecord { - run_id: String, - profile_id: String, - status: String, - snapshot_version: u32, - started_at_ms: i64, - duration_limit_ms: i64, - server_now_ms: i64, - remaining_ms: i64, - clear_count: u32, - total_item_count: u32, - cleared_item_count: u32, - tray_slots: Vec, - items: Vec, - failure_reason: Option, -} - #[derive(Clone, Debug, PartialEq, Eq)] pub struct SquareHoleAgentSessionCreateRecordInput { pub session_id: String, @@ -7273,109 +7055,6 @@ pub struct VisualNovelRuntimeEventRecord { pub occurred_at: String, } -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct VisualNovelAgentMessageJsonRecord { - message_id: String, - session_id: String, - role: String, - kind: String, - text: String, - created_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct VisualNovelAgentSessionJsonRecord { - session_id: String, - owner_user_id: String, - source_mode: String, - status: String, - seed_text: String, - source_asset_ids: Vec, - current_turn: u32, - progress_percent: u32, - messages: Vec, - draft: Option, - pending_action: Option, - last_assistant_reply: Option, - published_profile_id: Option, - created_at_micros: i64, - updated_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct VisualNovelWorkJsonRecord { - work_id: String, - profile_id: String, - owner_user_id: String, - source_session_id: Option, - author_display_name: String, - work_title: String, - work_description: String, - tags: Vec, - cover_image_src: Option, - source_asset_ids: Vec, - draft: serde_json::Value, - publication_status: String, - publish_ready: bool, - play_count: u32, - created_at_micros: i64, - updated_at_micros: i64, - published_at_micros: Option, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct VisualNovelHistoryEntryJsonRecord { - entry_id: String, - run_id: String, - owner_user_id: String, - profile_id: String, - turn_index: u32, - source: String, - action_text: Option, - steps: serde_json::Value, - snapshot_before_hash: Option, - snapshot_after_hash: Option, - created_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct VisualNovelRunJsonRecord { - run_id: String, - owner_user_id: String, - profile_id: String, - mode: String, - status: String, - current_scene_id: Option, - current_phase_id: Option, - visible_character_ids: Vec, - flags: serde_json::Value, - metrics: serde_json::Value, - history: Vec, - available_choices: serde_json::Value, - text_mode_enabled: bool, - created_at_micros: i64, - updated_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct VisualNovelRuntimeEventJsonRecord { - event_id: String, - run_id: Option, - owner_user_id: String, - profile_id: Option, - event_kind: String, - client_event_id: Option, - history_entry_id: Option, - payload: serde_json::Value, - occurred_at_micros: i64, -} - #[derive(Clone, Debug, PartialEq, Eq)] pub struct SquareHoleAnchorItemRecord { pub key: String, @@ -7554,204 +7233,6 @@ pub struct SquareHoleDropConfirmationRecord { pub run: SquareHoleRunRecord, } -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleCreatorConfigJsonRecord { - theme_text: String, - twist_rule: String, - shape_count: u32, - difficulty: u32, - #[serde(default)] - shape_options: Vec, - #[serde(default)] - hole_options: Vec, - #[serde(default)] - background_prompt: String, - #[serde(default)] - cover_image_src: String, - #[serde(default)] - background_image_src: String, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleShapeOptionJsonRecord { - option_id: String, - shape_kind: String, - label: String, - #[serde(default)] - target_hole_id: String, - image_prompt: String, - #[serde(default)] - image_src: String, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleHoleOptionJsonRecord { - hole_id: String, - hole_kind: String, - label: String, - #[serde(default)] - image_prompt: String, - #[serde(default)] - image_src: String, - #[serde(default)] - bonus: bool, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleAgentMessageJsonRecord { - message_id: String, - #[allow(dead_code)] - session_id: String, - role: String, - kind: String, - text: String, - created_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleDraftJsonRecord { - profile_id: String, - game_name: String, - theme_text: String, - twist_rule: String, - summary_text: String, - tags: Vec, - #[serde(default)] - cover_image_src: String, - #[serde(default)] - background_prompt: String, - #[serde(default)] - background_image_src: String, - #[serde(default)] - shape_options: Vec, - #[serde(default)] - hole_options: Vec, - shape_count: u32, - difficulty: u32, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleAgentSessionJsonRecord { - session_id: String, - #[allow(dead_code)] - owner_user_id: String, - #[allow(dead_code)] - seed_text: String, - current_turn: u32, - progress_percent: u32, - stage: String, - config: SquareHoleCreatorConfigJsonRecord, - draft: Option, - messages: Vec, - last_assistant_reply: String, - published_profile_id: Option, - #[allow(dead_code)] - created_at_micros: i64, - updated_at_micros: i64, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleWorkJsonRecord { - work_id: String, - profile_id: String, - owner_user_id: String, - source_session_id: String, - author_display_name: String, - game_name: String, - theme_text: String, - twist_rule: String, - summary_text: String, - tags: Vec, - cover_image_src: String, - #[serde(default)] - background_prompt: String, - #[serde(default)] - background_image_src: String, - #[serde(default)] - shape_options: Vec, - #[serde(default)] - hole_options: Vec, - shape_count: u32, - difficulty: u32, - #[allow(dead_code)] - config: SquareHoleCreatorConfigJsonRecord, - publication_status: String, - publish_ready: bool, - play_count: u32, - updated_at_micros: i64, - published_at_micros: Option, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleShapeJsonRecord { - shape_id: String, - shape_kind: String, - label: String, - #[serde(default)] - target_hole_id: String, - color: String, - #[serde(default)] - image_src: String, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleHoleJsonRecord { - hole_id: String, - hole_kind: String, - label: String, - x: f32, - y: f32, - #[serde(default)] - image_src: String, - #[serde(default)] - bonus: bool, -} - -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleDropFeedbackJsonRecord { - accepted: bool, - reject_reason: Option, - message: String, -} - -#[derive(Clone, Debug, PartialEq, serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct SquareHoleRunJsonRecord { - run_id: String, - profile_id: String, - owner_user_id: String, - status: String, - snapshot_version: u64, - started_at_ms: i64, - duration_limit_ms: i64, - server_now_ms: i64, - remaining_ms: i64, - total_shape_count: u32, - completed_shape_count: u32, - combo: u32, - best_combo: u32, - score: u32, - rule_label: String, - #[serde(default)] - background_image_src: String, - #[serde(default)] - #[allow(dead_code)] - shape_options: Vec, - current_shape: Option, - holes: Vec, - last_feedback: Option, -} - #[derive(Clone, Debug, PartialEq, Eq)] pub struct PuzzleAnchorItemRecord { pub key: String, @@ -8273,184 +7754,122 @@ pub struct BigFishWorkSummaryRecord { pub recent_play_count_7d: u32, } -#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)] -struct CompatibleBigFishWorkSummaryRecord { - work_id: String, - source_session_id: String, - #[serde(default)] - owner_user_id: Option, - title: String, - subtitle: String, - summary: String, - cover_image_src: Option, - status: String, - updated_at_micros: i64, - #[serde(default)] - published_at_micros: Option, - publish_ready: bool, - level_count: u32, - level_main_image_ready_count: u32, - level_motion_ready_count: u32, - background_ready: bool, - #[serde(default)] - play_count: u32, - #[serde(default)] - remix_count: u32, - #[serde(default)] - like_count: u32, - #[serde(default)] - recent_play_count_7d: u32, -} - -impl CompatibleBigFishWorkSummaryRecord { - fn into_record(self, fallback_owner_user_id: Option<&str>) -> BigFishWorkSummaryRecord { - BigFishWorkSummaryRecord { - work_id: self.work_id, - source_session_id: self.source_session_id, - // 中文注释:兼容旧 works JSON 没有 owner_user_id 的历史数据,避免一次字段升级把整个作品列表打崩。 - owner_user_id: self.owner_user_id.unwrap_or_else(|| { - fallback_owner_user_id - .map(str::to_string) - .unwrap_or_default() - }), - title: self.title, - subtitle: self.subtitle, - summary: self.summary, - cover_image_src: self.cover_image_src, - status: self.status, - updated_at_micros: self.updated_at_micros, - published_at_micros: self.published_at_micros, - publish_ready: self.publish_ready, - level_count: self.level_count, - level_main_image_ready_count: self.level_main_image_ready_count, - level_motion_ready_count: self.level_motion_ready_count, - background_ready: self.background_ready, - play_count: self.play_count, - remix_count: self.remix_count, - like_count: self.like_count, - recent_play_count_7d: self.recent_play_count_7d, - } - } -} - #[cfg(test)] mod tests { use super::*; #[test] - fn puzzle_works_mapper_backfills_missing_public_stat_fields() { + fn puzzle_works_mapper_keeps_typed_public_stat_fields() { let result = PuzzleWorksProcedureResult { ok: true, - items_json: Some( - r#"[{ - "work_id":"puzzle-work-1", - "profile_id":"puzzle-profile-1", - "owner_user_id":"user-1", - "source_session_id":null, - "author_display_name":"测试作者", - "level_name":"雨夜拼图", - "summary":"旧公开作品摘要", - "theme_tags":["雨夜","猫咪","神庙"], - "cover_image_src":null, - "cover_asset_id":null, - "publication_status":"Published", - "updated_at_micros":123000000, - "published_at_micros":123000000, - "publish_ready":true, - "anchor_pack":{ - "theme_promise":{ - "key":"themePromise", - "label":"题材承诺", - "value":"雨夜冒险", - "status":"Inferred" - }, - "visual_subject":{ - "key":"visualSubject", - "label":"画面主体", - "value":"猫咪神庙", - "status":"Inferred" - }, - "visual_mood":{ - "key":"visualMood", - "label":"视觉气质", - "value":"温暖", - "status":"Inferred" - }, - "composition_hooks":{ - "key":"compositionHooks", - "label":"拼图记忆点", - "value":"灯光", - "status":"Inferred" - }, - "tags_and_forbidden":{ - "key":"tagsAndForbidden", - "label":"标签与禁忌", - "value":"雨夜, 猫咪, 神庙", - "status":"Inferred" - } - } - }]"# - .to_string(), - ), + items: vec![PuzzleWorkProfile { + work_id: "puzzle-work-1".to_string(), + profile_id: "puzzle-profile-1".to_string(), + owner_user_id: "user-1".to_string(), + source_session_id: None, + author_display_name: "测试作者".to_string(), + work_title: "雨夜拼图作品".to_string(), + work_description: "拼图作品说明".to_string(), + level_name: "雨夜拼图".to_string(), + summary: "公开作品摘要".to_string(), + theme_tags: vec!["雨夜".to_string(), "猫咪".to_string(), "神庙".to_string()], + cover_image_src: None, + cover_asset_id: None, + levels: Vec::new(), + publication_status: PuzzlePublicationStatus::Published, + updated_at_micros: 123000000, + published_at_micros: Some(123000000), + play_count: 11, + remix_count: 7, + like_count: 5, + recent_play_count_7_d: 3, + point_incentive_total_half_points: 4, + point_incentive_claimed_points: 2, + publish_ready: true, + anchor_pack: test_puzzle_anchor_pack(), + }], error_message: None, }; let items = map_puzzle_works_procedure_result(result) - .expect("旧 puzzle works JSON 缺统计字段时应按 0 兼容"); + .expect("typed puzzle works result 应能映射统计字段"); assert_eq!(items.len(), 1); - assert_eq!(items[0].play_count, 0); - assert_eq!(items[0].remix_count, 0); - assert_eq!(items[0].like_count, 0); + assert_eq!(items[0].play_count, 11); + assert_eq!(items[0].remix_count, 7); + assert_eq!(items[0].like_count, 5); + assert_eq!(items[0].recent_play_count_7d, 3); } #[test] - fn puzzle_run_mapper_backfills_missing_timer_fields() { + fn puzzle_run_mapper_maps_typed_timer_fields() { let result = PuzzleRunProcedureResult { ok: true, - run_json: Some( - r#"{ - "run_id":"puzzle-run-1", - "entry_profile_id":"puzzle-profile-1", - "cleared_level_count":0, - "current_level_index":1, - "current_grid_size":3, - "played_profile_ids":["puzzle-profile-1"], - "previous_level_tags":["雨夜","猫咪","神庙"], - "current_level":{ - "run_id":"puzzle-run-1", - "level_index":1, - "grid_size":3, - "profile_id":"puzzle-profile-1", - "level_name":"雨夜拼图", - "author_display_name":"测试作者", - "theme_tags":["雨夜","猫咪","神庙"], - "cover_image_src":null, - "board":{ - "rows":3, - "cols":3, - "pieces":[{ - "piece_id":"piece-1", - "correct_row":0, - "correct_col":0, - "current_row":0, - "current_col":0, - "merged_group_id":null - }], - "merged_groups":[], - "selected_piece_id":null - }, - "status":"Playing" + run: Some(PuzzleRunSnapshot { + run_id: "puzzle-run-1".to_string(), + entry_profile_id: "puzzle-profile-1".to_string(), + cleared_level_count: 0, + current_level_index: 1, + current_grid_size: 3, + played_profile_ids: vec!["puzzle-profile-1".to_string()], + previous_level_tags: vec![ + "雨夜".to_string(), + "猫咪".to_string(), + "神庙".to_string(), + ], + current_level: Some(PuzzleRuntimeLevelSnapshot { + run_id: "puzzle-run-1".to_string(), + level_index: 1, + level_id: None, + grid_size: 3, + profile_id: "puzzle-profile-1".to_string(), + level_name: "雨夜拼图".to_string(), + author_display_name: "测试作者".to_string(), + theme_tags: vec!["雨夜".to_string(), "猫咪".to_string(), "神庙".to_string()], + cover_image_src: None, + ui_background_image_src: None, + ui_background_image_object_key: None, + background_music: None, + board: PuzzleBoardSnapshot { + rows: 3, + cols: 3, + pieces: vec![PuzzlePieceState { + piece_id: "piece-1".to_string(), + correct_row: 0, + correct_col: 0, + current_row: 0, + current_col: 0, + merged_group_id: None, + }], + merged_groups: Vec::new(), + selected_piece_id: None, + all_tiles_resolved: false, }, - "recommended_next_profile_id":null - }"# - .to_string(), - ), + status: PuzzleRuntimeLevelStatus::Playing, + started_at_ms: 0, + cleared_at_ms: None, + elapsed_ms: None, + time_limit_ms: 0, + remaining_ms: 0, + paused_accumulated_ms: 0, + pause_started_at_ms: None, + freeze_accumulated_ms: 0, + freeze_started_at_ms: None, + freeze_until_ms: None, + leaderboard_entries: Vec::new(), + }), + recommended_next_profile_id: None, + next_level_mode: "none".to_string(), + next_level_profile_id: None, + next_level_id: None, + recommended_next_works: Vec::new(), + leaderboard_entries: Vec::new(), + }), error_message: None, }; let run = map_puzzle_run_procedure_result(result) - .expect("旧 puzzle run JSON 缺计时字段时应按默认值兼容"); + .expect("typed puzzle run result 应能映射计时字段"); let level = run.current_level.expect("兼容后仍应保留当前关卡"); assert_eq!(run.run_id, "puzzle-run-1"); @@ -8461,115 +7880,87 @@ mod tests { } #[test] - fn big_fish_works_mapper_backfills_missing_owner_user_id_for_private_lists() { + fn big_fish_works_mapper_uses_typed_owner_and_public_stats() { let result = BigFishWorksProcedureResult { ok: true, - items_json: Some( - r#"[{ - "work_id":"big-fish-work-session-1", - "source_session_id":"session-1", - "title":"深海草稿", - "subtitle":"副标题", - "summary":"摘要", - "cover_image_src":null, - "status":"draft", - "updated_at_micros":123, - "publish_ready":false, - "level_count":8, - "level_main_image_ready_count":0, - "level_motion_ready_count":0, - "background_ready":false - }]"# - .to_string(), - ), + items: vec![BigFishWorkSummarySnapshot { + work_id: "big-fish-work-session-1".to_string(), + source_session_id: "session-1".to_string(), + owner_user_id: "user-1".to_string(), + title: "深海草稿".to_string(), + subtitle: "副标题".to_string(), + summary: "摘要".to_string(), + cover_image_src: None, + status: "draft".to_string(), + updated_at_micros: 123, + publish_ready: false, + level_count: 8, + level_main_image_ready_count: 0, + level_motion_ready_count: 0, + background_ready: false, + play_count: 9, + remix_count: 4, + like_count: 2, + recent_play_count_7_d: 6, + published_at_micros: None, + }], error_message: None, }; let items = map_big_fish_works_procedure_result(result, Some("user-1")) - .expect("旧 works JSON 应能被兼容解析"); + .expect("typed big fish works result 应能映射 owner 和统计字段"); assert_eq!(items.len(), 1); assert_eq!(items[0].owner_user_id, "user-1"); assert_eq!(items[0].published_at_micros, None); - assert_eq!(items[0].play_count, 0); - assert_eq!(items[0].remix_count, 0); - assert_eq!(items[0].like_count, 0); - } - - #[test] - fn big_fish_works_mapper_keeps_empty_owner_when_gallery_legacy_json_lacks_field() { - let result = BigFishWorksProcedureResult { - ok: true, - items_json: Some( - r#"[{ - "work_id":"big-fish-work-session-2", - "source_session_id":"session-2", - "title":"公开作品", - "subtitle":"副标题", - "summary":"摘要", - "cover_image_src":null, - "status":"published", - "updated_at_micros":456, - "publish_ready":true, - "level_count":8, - "level_main_image_ready_count":8, - "level_motion_ready_count":16, - "background_ready":true - }]"# - .to_string(), - ), - error_message: None, - }; - - let items = map_big_fish_works_procedure_result(result, None) - .expect("公开 works 旧 JSON 也不应因缺字段报错"); - - assert_eq!(items.len(), 1); - assert!(items[0].owner_user_id.is_empty()); - assert_eq!(items[0].published_at_micros, None); - assert_eq!(items[0].play_count, 0); - assert_eq!(items[0].remix_count, 0); - assert_eq!(items[0].like_count, 0); + assert_eq!(items[0].play_count, 9); + assert_eq!(items[0].remix_count, 4); + assert_eq!(items[0].like_count, 2); + assert_eq!(items[0].recent_play_count_7d, 6); } #[test] fn match3d_work_mapper_keeps_generated_item_assets_json() { let result = Match3DWorkProcedureResult { ok: true, - work_json: Some( - r#"{ - "profileId":"match3d-profile-1", - "ownerUserId":"user-1", - "sourceSessionId":"match3d-session-1", - "authorDisplayName":"测试作者", - "gameName":"水果抓大鹅", - "themeText":"水果", - "summaryText":"水果主题", - "tags":["水果"], - "coverImageSrc":"", - "coverAssetId":"", - "clearCount":3, - "difficulty":3, - "config":{ - "themeText":"水果", - "referenceImageSrc":null, - "clearCount":3, - "difficulty":3 - }, - "publicationStatus":"Draft", - "publishReady":false, - "playCount":0, - "updatedAtMicros":123000000, - "publishedAtMicros":null, - "generatedItemAssetsJson":"[{\"itemId\":\"match3d-item-1\",\"itemName\":\"草莓\",\"imageSrc\":\"/generated-match3d-assets/session/profile/items/item/image.png\",\"status\":\"image_ready\"}]" - }"# - .to_string(), - ), + work: Some(Match3DWorkSnapshot { + profile_id: "match3d-profile-1".to_string(), + owner_user_id: "user-1".to_string(), + source_session_id: "match3d-session-1".to_string(), + author_display_name: "测试作者".to_string(), + game_name: "水果抓大鹅".to_string(), + theme_text: "水果".to_string(), + summary_text: "水果主题".to_string(), + tags: vec!["水果".to_string()], + cover_image_src: String::new(), + cover_asset_id: String::new(), + clear_count: 3, + difficulty: 3, + config: Match3DCreatorConfigSnapshot { + theme_text: "水果".to_string(), + reference_image_src: None, + clear_count: 3, + difficulty: 3, + asset_style_id: None, + asset_style_label: None, + asset_style_prompt: None, + generate_click_sound: false, + }, + publication_status: "Draft".to_string(), + publish_ready: false, + play_count: 0, + updated_at_micros: 123000000, + published_at_micros: None, + generated_item_assets_json: Some( + r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"}]"# + .to_string(), + ), + }), error_message: None, }; let item = map_match3d_work_procedure_result(result) - .expect("match3d work JSON 应保留生成素材 JSON"); + .expect("typed match3d work result 应保留生成素材 JSON"); assert_eq!( item.generated_item_assets_json.as_deref(), @@ -8578,6 +7969,29 @@ mod tests { ) ); } + + fn test_puzzle_anchor_pack() -> PuzzleAnchorPack { + PuzzleAnchorPack { + theme_promise: test_puzzle_anchor_item("themePromise", "题材承诺", "雨夜冒险"), + visual_subject: test_puzzle_anchor_item("visualSubject", "画面主体", "猫咪神庙"), + visual_mood: test_puzzle_anchor_item("visualMood", "视觉气质", "温暖"), + composition_hooks: test_puzzle_anchor_item("compositionHooks", "拼图记忆点", "灯光"), + tags_and_forbidden: test_puzzle_anchor_item( + "tagsAndForbidden", + "标签与禁忌", + "雨夜, 猫咪, 神庙", + ), + } + } + + fn test_puzzle_anchor_item(key: &str, label: &str, value: &str) -> PuzzleAnchorItem { + PuzzleAnchorItem { + key: key.to_string(), + label: label.to_string(), + value: value.to_string(), + status: PuzzleAnchorStatus::Inferred, + } + } } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_draft_config_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_draft_config_snapshot_type.rs new file mode 100644 index 00000000..1271082f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_draft_config_snapshot_type.rs @@ -0,0 +1,25 @@ +// 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 BarkBattleDraftConfigSnapshot { + pub draft_id: String, + pub owner_user_id: String, + pub work_id: String, + pub config_version: u64, + pub ruleset_version: String, + pub difficulty_preset: String, + pub leaderboard_enabled: bool, + pub config_json: String, + pub editor_state_json: String, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for BarkBattleDraftConfigSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_procedure_result_type.rs index 6fe7a3ee..03e6fe2c 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_procedure_result_type.rs @@ -4,11 +4,17 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::bark_battle_draft_config_snapshot_type::BarkBattleDraftConfigSnapshot; +use super::bark_battle_run_snapshot_type::BarkBattleRunSnapshot; +use super::bark_battle_runtime_config_snapshot_type::BarkBattleRuntimeConfigSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct BarkBattleProcedureResult { pub ok: bool, - pub row_json: Option, + pub draft_config: Option, + pub runtime_config: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_run_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_run_snapshot_type.rs new file mode 100644 index 00000000..474af775 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_run_snapshot_type.rs @@ -0,0 +1,32 @@ +// 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 BarkBattleRunSnapshot { + pub run_id: String, + pub owner_user_id: String, + pub work_id: String, + pub config_version: u64, + pub ruleset_version: String, + pub difficulty_preset: String, + pub leaderboard_enabled: bool, + pub status: String, + pub client_started_at_micros: i64, + pub server_started_at_micros: i64, + pub client_finished_at_micros: Option, + pub server_finished_at_micros: Option, + pub metrics_json: String, + pub server_result: Option, + pub validation_status: String, + pub anti_cheat_flags_json: String, + pub leaderboard_score: Option, + pub score_id: Option, +} + +impl __sdk::InModule for BarkBattleRunSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_runtime_config_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_runtime_config_snapshot_type.rs new file mode 100644 index 00000000..e176ca63 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/bark_battle_runtime_config_snapshot_type.rs @@ -0,0 +1,25 @@ +// 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 BarkBattleRuntimeConfigSnapshot { + pub work_id: String, + pub owner_user_id: String, + pub source_draft_id: Option, + pub config_version: u64, + pub ruleset_version: String, + pub difficulty_preset: String, + pub leaderboard_enabled: bool, + pub config_json: String, + pub published_snapshot_json: String, + pub published_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for BarkBattleRuntimeConfigSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_run_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_run_procedure_result_type.rs index 2dc3db1d..86d73fc2 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_run_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_run_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::big_fish_runtime_snapshot_type::BigFishRuntimeSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct BigFishRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_runtime_entity_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_runtime_entity_snapshot_type.rs new file mode 100644 index 00000000..ce829b70 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_runtime_entity_snapshot_type.rs @@ -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::big_fish_vector_2_type::BigFishVector2; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct BigFishRuntimeEntitySnapshot { + pub entity_id: String, + pub level: u32, + pub position: BigFishVector2, + pub radius: f32, + pub offscreen_seconds: f32, +} + +impl __sdk::InModule for BigFishRuntimeEntitySnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_runtime_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_runtime_snapshot_type.rs new file mode 100644 index 00000000..48f71186 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_runtime_snapshot_type.rs @@ -0,0 +1,31 @@ +// 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::big_fish_run_status_type::BigFishRunStatus; +use super::big_fish_runtime_entity_snapshot_type::BigFishRuntimeEntitySnapshot; +use super::big_fish_vector_2_type::BigFishVector2; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct BigFishRuntimeSnapshot { + pub run_id: String, + pub session_id: String, + pub status: BigFishRunStatus, + pub tick: u64, + pub player_level: u32, + pub win_level: u32, + pub leader_entity_id: Option, + pub owned_entities: Vec, + pub wild_entities: Vec, + pub camera_center: BigFishVector2, + pub last_input: BigFishVector2, + pub event_log: Vec, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for BigFishRuntimeSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_vector_2_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_vector_2_type.rs new file mode 100644 index 00000000..745063ad --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_vector_2_type.rs @@ -0,0 +1,16 @@ +// 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 BigFishVector2 { + pub x: f32, + pub y: f32, +} + +impl __sdk::InModule for BigFishVector2 { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_works_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_works_procedure_result_type.rs index 37d7c7b6..ea3cac68 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/big_fish_works_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/big_fish_works_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::big_fish_work_summary_snapshot_type::BigFishWorkSummarySnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct BigFishWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_message_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_message_snapshot_type.rs new file mode 100644 index 00000000..b157584f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_message_snapshot_type.rs @@ -0,0 +1,20 @@ +// 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 Match3DAgentMessageSnapshot { + pub message_id: String, + pub session_id: String, + pub role: String, + pub kind: String, + pub text: String, + pub created_at_micros: i64, +} + +impl __sdk::InModule for Match3DAgentMessageSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_procedure_result_type.rs index 45f54f93..ca860890 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::match_3_d_agent_session_snapshot_type::Match3DAgentSessionSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Match3DAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_snapshot_type.rs new file mode 100644 index 00000000..f0ea685a --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_agent_session_snapshot_type.rs @@ -0,0 +1,31 @@ +// 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::match_3_d_agent_message_snapshot_type::Match3DAgentMessageSnapshot; +use super::match_3_d_creator_config_snapshot_type::Match3DCreatorConfigSnapshot; +use super::match_3_d_draft_snapshot_type::Match3DDraftSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Match3DAgentSessionSnapshot { + pub session_id: String, + pub owner_user_id: String, + pub seed_text: String, + pub current_turn: u32, + pub progress_percent: u32, + pub stage: String, + pub config: Match3DCreatorConfigSnapshot, + pub draft: Option, + pub messages: Vec, + pub last_assistant_reply: String, + pub published_profile_id: Option, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for Match3DAgentSessionSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_click_item_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_click_item_procedure_result_type.rs index 80f32a59..c8a58510 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_click_item_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_click_item_procedure_result_type.rs @@ -4,12 +4,14 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::match_3_d_run_snapshot_type::Match3DRunSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Match3DClickItemProcedureResult { pub ok: bool, pub status: String, - pub run_json: Option, + pub run: Option, pub accepted_item_instance_id: Option, pub cleared_item_instance_ids: Vec, pub failure_reason: Option, diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_creator_config_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_creator_config_snapshot_type.rs new file mode 100644 index 00000000..a0fd2d61 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_creator_config_snapshot_type.rs @@ -0,0 +1,22 @@ +// 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 Match3DCreatorConfigSnapshot { + pub theme_text: String, + pub reference_image_src: Option, + pub clear_count: u32, + pub difficulty: u32, + pub asset_style_id: Option, + pub asset_style_label: Option, + pub asset_style_prompt: Option, + pub generate_click_sound: bool, +} + +impl __sdk::InModule for Match3DCreatorConfigSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_draft_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_draft_snapshot_type.rs new file mode 100644 index 00000000..32a67c83 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_draft_snapshot_type.rs @@ -0,0 +1,22 @@ +// 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 Match3DDraftSnapshot { + pub profile_id: String, + pub game_name: String, + pub theme_text: String, + pub summary_text: String, + pub tags: Vec, + pub clear_count: u32, + pub difficulty: u32, + pub generated_item_assets_json: Option, +} + +impl __sdk::InModule for Match3DDraftSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_item_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_item_snapshot_type.rs new file mode 100644 index 00000000..fefdd184 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_item_snapshot_type.rs @@ -0,0 +1,23 @@ +// 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 Match3DItemSnapshot { + pub item_instance_id: String, + pub item_type_id: String, + pub visual_key: String, + pub x: f32, + pub y: f32, + pub radius: f32, + pub layer: u32, + pub state: String, + pub clickable: bool, +} + +impl __sdk::InModule for Match3DItemSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_procedure_result_type.rs index f3c4ceec..56da83e6 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::match_3_d_run_snapshot_type::Match3DRunSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Match3DRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_snapshot_type.rs new file mode 100644 index 00000000..3165a471 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_run_snapshot_type.rs @@ -0,0 +1,31 @@ +// 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::match_3_d_item_snapshot_type::Match3DItemSnapshot; +use super::match_3_d_tray_slot_snapshot_type::Match3DTraySlotSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Match3DRunSnapshot { + pub run_id: String, + pub profile_id: String, + pub status: String, + pub snapshot_version: u32, + pub started_at_ms: i64, + pub duration_limit_ms: i64, + pub server_now_ms: i64, + pub remaining_ms: i64, + pub clear_count: u32, + pub total_item_count: u32, + pub cleared_item_count: u32, + pub tray_slots: Vec, + pub items: Vec, + pub failure_reason: Option, +} + +impl __sdk::InModule for Match3DRunSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_tray_slot_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_tray_slot_snapshot_type.rs new file mode 100644 index 00000000..823cff0c --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_tray_slot_snapshot_type.rs @@ -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 Match3DTraySlotSnapshot { + pub slot_index: u32, + pub item_instance_id: Option, + pub item_type_id: Option, + pub visual_key: Option, +} + +impl __sdk::InModule for Match3DTraySlotSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_procedure_result_type.rs index 9cb5d518..d4d589f1 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::match_3_d_work_snapshot_type::Match3DWorkSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Match3DWorkProcedureResult { pub ok: bool, - pub work_json: Option, + pub work: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_snapshot_type.rs new file mode 100644 index 00000000..fc1a862f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_work_snapshot_type.rs @@ -0,0 +1,35 @@ +// 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::match_3_d_creator_config_snapshot_type::Match3DCreatorConfigSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct Match3DWorkSnapshot { + pub profile_id: String, + pub owner_user_id: String, + pub source_session_id: String, + pub author_display_name: String, + pub game_name: String, + pub theme_text: String, + pub summary_text: String, + pub tags: Vec, + pub cover_image_src: String, + pub cover_asset_id: String, + pub clear_count: u32, + pub difficulty: u32, + pub config: Match3DCreatorConfigSnapshot, + pub publication_status: String, + pub publish_ready: bool, + pub play_count: u32, + pub updated_at_micros: i64, + pub published_at_micros: Option, + pub generated_item_assets_json: Option, +} + +impl __sdk::InModule for Match3DWorkSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_works_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_works_procedure_result_type.rs index f1cfd0be..0bc07ad4 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_works_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/match_3_d_works_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::match_3_d_work_snapshot_type::Match3DWorkSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct Match3DWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/mod.rs b/server-rs/crates/spacetime-client/src/module_bindings/mod.rs index 383ffd25..b828cfa5 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/mod.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/mod.rs @@ -95,6 +95,7 @@ pub mod auth_store_snapshot_type; pub mod auth_store_snapshot_upsert_input_type; pub mod authorize_database_migration_operator_procedure; pub mod bark_battle_draft_config_row_type; +pub mod bark_battle_draft_config_snapshot_type; pub mod bark_battle_draft_config_table; pub mod bark_battle_draft_config_upsert_input_type; pub mod bark_battle_draft_create_input_type; @@ -107,8 +108,10 @@ pub mod bark_battle_published_config_row_type; pub mod bark_battle_published_config_table; pub mod bark_battle_run_finish_input_type; pub mod bark_battle_run_get_input_type; +pub mod bark_battle_run_snapshot_type; pub mod bark_battle_run_start_input_type; pub mod bark_battle_runtime_config_get_input_type; +pub mod bark_battle_runtime_config_snapshot_type; pub mod bark_battle_runtime_run_row_type; pub mod bark_battle_runtime_run_table; pub mod bark_battle_score_record_row_type; @@ -161,13 +164,16 @@ pub mod big_fish_run_get_input_type; pub mod big_fish_run_procedure_result_type; pub mod big_fish_run_start_input_type; pub mod big_fish_run_status_type; +pub mod big_fish_runtime_entity_snapshot_type; pub mod big_fish_runtime_params_type; pub mod big_fish_runtime_run_table; pub mod big_fish_runtime_run_type; +pub mod big_fish_runtime_snapshot_type; pub mod big_fish_session_create_input_type; pub mod big_fish_session_get_input_type; pub mod big_fish_session_procedure_result_type; pub mod big_fish_session_snapshot_type; +pub mod big_fish_vector_2_type; pub mod big_fish_work_delete_input_type; pub mod big_fish_work_like_record_input_type; pub mod big_fish_work_remix_input_type; @@ -404,32 +410,40 @@ pub mod list_visual_novel_works_procedure; pub mod mark_profile_recharge_order_paid_and_return_procedure; pub mod match_3_d_agent_message_finalize_input_type; pub mod match_3_d_agent_message_row_type; +pub mod match_3_d_agent_message_snapshot_type; pub mod match_3_d_agent_message_submit_input_type; pub mod match_3_d_agent_message_table; pub mod match_3_d_agent_session_create_input_type; pub mod match_3_d_agent_session_get_input_type; pub mod match_3_d_agent_session_procedure_result_type; pub mod match_3_d_agent_session_row_type; +pub mod match_3_d_agent_session_snapshot_type; pub mod match_3_d_agent_session_table; pub mod match_3_d_click_item_procedure_result_type; +pub mod match_3_d_creator_config_snapshot_type; pub mod match_3_d_draft_compile_input_type; +pub mod match_3_d_draft_snapshot_type; pub mod match_3_d_gallery_view_row_type; pub mod match_3_d_gallery_view_table; +pub mod match_3_d_item_snapshot_type; pub mod match_3_d_run_click_input_type; pub mod match_3_d_run_get_input_type; pub mod match_3_d_run_procedure_result_type; pub mod match_3_d_run_restart_input_type; +pub mod match_3_d_run_snapshot_type; pub mod match_3_d_run_start_input_type; pub mod match_3_d_run_stop_input_type; pub mod match_3_d_run_time_up_input_type; pub mod match_3_d_runtime_run_row_type; pub mod match_3_d_runtime_run_table; +pub mod match_3_d_tray_slot_snapshot_type; pub mod match_3_d_work_delete_input_type; pub mod match_3_d_work_get_input_type; pub mod match_3_d_work_procedure_result_type; pub mod match_3_d_work_profile_row_type; pub mod match_3_d_work_profile_table; pub mod match_3_d_work_publish_input_type; +pub mod match_3_d_work_snapshot_type; pub mod match_3_d_work_update_input_type; pub mod match_3_d_works_list_input_type; pub mod match_3_d_works_procedure_result_type; @@ -503,40 +517,58 @@ pub mod puzzle_agent_message_finalize_input_type; pub mod puzzle_agent_message_kind_type; pub mod puzzle_agent_message_role_type; pub mod puzzle_agent_message_row_type; +pub mod puzzle_agent_message_snapshot_type; pub mod puzzle_agent_message_submit_input_type; pub mod puzzle_agent_message_table; pub mod puzzle_agent_session_create_input_type; pub mod puzzle_agent_session_get_input_type; pub mod puzzle_agent_session_procedure_result_type; pub mod puzzle_agent_session_row_type; +pub mod puzzle_agent_session_snapshot_type; pub mod puzzle_agent_session_table; pub mod puzzle_agent_stage_type; +pub mod puzzle_agent_suggested_action_type; pub mod puzzle_anchor_item_type; pub mod puzzle_anchor_pack_type; pub mod puzzle_anchor_status_type; pub mod puzzle_audio_asset_type; +pub mod puzzle_board_snapshot_type; +pub mod puzzle_cell_position_type; +pub mod puzzle_creator_intent_type; pub mod puzzle_draft_compile_input_type; pub mod puzzle_draft_level_type; pub mod puzzle_event_kind_type; pub mod puzzle_event_table; pub mod puzzle_event_type; pub mod puzzle_form_draft_save_input_type; +pub mod puzzle_form_draft_type; pub mod puzzle_gallery_view_table; pub mod puzzle_generated_image_candidate_type; pub mod puzzle_generated_images_save_input_type; pub mod puzzle_leaderboard_entry_row_type; pub mod puzzle_leaderboard_entry_table; +pub mod puzzle_leaderboard_entry_type; pub mod puzzle_leaderboard_submit_input_type; +pub mod puzzle_merged_group_state_type; +pub mod puzzle_piece_state_type; pub mod puzzle_publication_status_type; pub mod puzzle_publish_input_type; +pub mod puzzle_recommended_next_work_type; +pub mod puzzle_result_draft_type; +pub mod puzzle_result_preview_blocker_type; +pub mod puzzle_result_preview_envelope_type; +pub mod puzzle_result_preview_finding_type; pub mod puzzle_run_drag_input_type; pub mod puzzle_run_get_input_type; pub mod puzzle_run_next_level_input_type; pub mod puzzle_run_pause_input_type; pub mod puzzle_run_procedure_result_type; pub mod puzzle_run_prop_input_type; +pub mod puzzle_run_snapshot_type; pub mod puzzle_run_start_input_type; pub mod puzzle_run_swap_input_type; +pub mod puzzle_runtime_level_snapshot_type; +pub mod puzzle_runtime_level_status_type; pub mod puzzle_runtime_run_row_type; pub mod puzzle_runtime_run_table; pub mod puzzle_select_cover_image_input_type; @@ -740,34 +772,43 @@ pub mod seed_analytics_date_dimensions_reducer; pub mod select_puzzle_cover_image_procedure; pub mod square_hole_agent_message_finalize_input_type; pub mod square_hole_agent_message_row_type; +pub mod square_hole_agent_message_snapshot_type; pub mod square_hole_agent_message_submit_input_type; pub mod square_hole_agent_message_table; pub mod square_hole_agent_session_create_input_type; pub mod square_hole_agent_session_get_input_type; pub mod square_hole_agent_session_procedure_result_type; pub mod square_hole_agent_session_row_type; +pub mod square_hole_agent_session_snapshot_type; pub mod square_hole_agent_session_table; +pub mod square_hole_creator_config_snapshot_type; pub mod square_hole_draft_compile_input_type; +pub mod square_hole_draft_snapshot_type; +pub mod square_hole_drop_feedback_snapshot_type; pub mod square_hole_drop_shape_procedure_result_type; pub mod square_hole_gallery_view_row_type; pub mod square_hole_gallery_view_table; pub mod square_hole_hole_option_snapshot_type; +pub mod square_hole_hole_snapshot_type; pub mod square_hole_run_drop_input_type; pub mod square_hole_run_get_input_type; pub mod square_hole_run_procedure_result_type; pub mod square_hole_run_restart_input_type; +pub mod square_hole_run_snapshot_type; pub mod square_hole_run_start_input_type; pub mod square_hole_run_stop_input_type; pub mod square_hole_run_time_up_input_type; pub mod square_hole_runtime_run_row_type; pub mod square_hole_runtime_run_table; pub mod square_hole_shape_option_snapshot_type; +pub mod square_hole_shape_snapshot_type; pub mod square_hole_work_delete_input_type; pub mod square_hole_work_get_input_type; pub mod square_hole_work_procedure_result_type; pub mod square_hole_work_profile_row_type; pub mod square_hole_work_profile_table; pub mod square_hole_work_publish_input_type; +pub mod square_hole_work_snapshot_type; pub mod square_hole_work_update_input_type; pub mod square_hole_works_list_input_type; pub mod square_hole_works_procedure_result_type; @@ -844,26 +885,33 @@ pub mod user_browse_history_table; pub mod user_browse_history_type; pub mod visual_novel_agent_message_finalize_input_type; pub mod visual_novel_agent_message_row_type; +pub mod visual_novel_agent_message_snapshot_type; pub mod visual_novel_agent_message_submit_input_type; pub mod visual_novel_agent_message_table; pub mod visual_novel_agent_session_create_input_type; pub mod visual_novel_agent_session_get_input_type; pub mod visual_novel_agent_session_procedure_result_type; pub mod visual_novel_agent_session_row_type; +pub mod visual_novel_agent_session_snapshot_type; pub mod visual_novel_agent_session_table; pub mod visual_novel_gallery_view_row_type; pub mod visual_novel_gallery_view_table; pub mod visual_novel_history_procedure_result_type; +pub mod visual_novel_json_field_type; +pub mod visual_novel_json_value_type; pub mod visual_novel_run_get_input_type; pub mod visual_novel_run_procedure_result_type; +pub mod visual_novel_run_snapshot_type; pub mod visual_novel_run_snapshot_upsert_input_type; pub mod visual_novel_run_start_input_type; pub mod visual_novel_runtime_event_procedure_result_type; pub mod visual_novel_runtime_event_record_input_type; +pub mod visual_novel_runtime_event_snapshot_type; pub mod visual_novel_runtime_event_table; pub mod visual_novel_runtime_event_type; pub mod visual_novel_runtime_history_append_input_type; pub mod visual_novel_runtime_history_entry_row_type; +pub mod visual_novel_runtime_history_entry_snapshot_type; pub mod visual_novel_runtime_history_entry_table; pub mod visual_novel_runtime_history_list_input_type; pub mod visual_novel_runtime_run_row_type; @@ -875,6 +923,7 @@ pub mod visual_novel_work_procedure_result_type; pub mod visual_novel_work_profile_row_type; pub mod visual_novel_work_profile_table; pub mod visual_novel_work_publish_input_type; +pub mod visual_novel_work_snapshot_type; pub mod visual_novel_work_update_input_type; pub mod visual_novel_works_list_input_type; pub mod visual_novel_works_procedure_result_type; @@ -968,6 +1017,7 @@ pub use auth_store_snapshot_type::AuthStoreSnapshot; pub use auth_store_snapshot_upsert_input_type::AuthStoreSnapshotUpsertInput; pub use authorize_database_migration_operator_procedure::authorize_database_migration_operator; pub use bark_battle_draft_config_row_type::BarkBattleDraftConfigRow; +pub use bark_battle_draft_config_snapshot_type::BarkBattleDraftConfigSnapshot; pub use bark_battle_draft_config_table::*; pub use bark_battle_draft_config_upsert_input_type::BarkBattleDraftConfigUpsertInput; pub use bark_battle_draft_create_input_type::BarkBattleDraftCreateInput; @@ -980,8 +1030,10 @@ pub use bark_battle_published_config_row_type::BarkBattlePublishedConfigRow; pub use bark_battle_published_config_table::*; pub use bark_battle_run_finish_input_type::BarkBattleRunFinishInput; pub use bark_battle_run_get_input_type::BarkBattleRunGetInput; +pub use bark_battle_run_snapshot_type::BarkBattleRunSnapshot; pub use bark_battle_run_start_input_type::BarkBattleRunStartInput; pub use bark_battle_runtime_config_get_input_type::BarkBattleRuntimeConfigGetInput; +pub use bark_battle_runtime_config_snapshot_type::BarkBattleRuntimeConfigSnapshot; pub use bark_battle_runtime_run_row_type::BarkBattleRuntimeRunRow; pub use bark_battle_runtime_run_table::*; pub use bark_battle_score_record_row_type::BarkBattleScoreRecordRow; @@ -1034,13 +1086,16 @@ pub use big_fish_run_get_input_type::BigFishRunGetInput; pub use big_fish_run_procedure_result_type::BigFishRunProcedureResult; pub use big_fish_run_start_input_type::BigFishRunStartInput; pub use big_fish_run_status_type::BigFishRunStatus; +pub use big_fish_runtime_entity_snapshot_type::BigFishRuntimeEntitySnapshot; pub use big_fish_runtime_params_type::BigFishRuntimeParams; pub use big_fish_runtime_run_table::*; pub use big_fish_runtime_run_type::BigFishRuntimeRun; +pub use big_fish_runtime_snapshot_type::BigFishRuntimeSnapshot; pub use big_fish_session_create_input_type::BigFishSessionCreateInput; pub use big_fish_session_get_input_type::BigFishSessionGetInput; pub use big_fish_session_procedure_result_type::BigFishSessionProcedureResult; pub use big_fish_session_snapshot_type::BigFishSessionSnapshot; +pub use big_fish_vector_2_type::BigFishVector2; pub use big_fish_work_delete_input_type::BigFishWorkDeleteInput; pub use big_fish_work_like_record_input_type::BigFishWorkLikeRecordInput; pub use big_fish_work_remix_input_type::BigFishWorkRemixInput; @@ -1277,32 +1332,40 @@ pub use list_visual_novel_works_procedure::list_visual_novel_works; pub use mark_profile_recharge_order_paid_and_return_procedure::mark_profile_recharge_order_paid_and_return; pub use match_3_d_agent_message_finalize_input_type::Match3DAgentMessageFinalizeInput; pub use match_3_d_agent_message_row_type::Match3DAgentMessageRow; +pub use match_3_d_agent_message_snapshot_type::Match3DAgentMessageSnapshot; pub use match_3_d_agent_message_submit_input_type::Match3DAgentMessageSubmitInput; pub use match_3_d_agent_message_table::*; pub use match_3_d_agent_session_create_input_type::Match3DAgentSessionCreateInput; pub use match_3_d_agent_session_get_input_type::Match3DAgentSessionGetInput; pub use match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult; pub use match_3_d_agent_session_row_type::Match3DAgentSessionRow; +pub use match_3_d_agent_session_snapshot_type::Match3DAgentSessionSnapshot; pub use match_3_d_agent_session_table::*; pub use match_3_d_click_item_procedure_result_type::Match3DClickItemProcedureResult; +pub use match_3_d_creator_config_snapshot_type::Match3DCreatorConfigSnapshot; pub use match_3_d_draft_compile_input_type::Match3DDraftCompileInput; +pub use match_3_d_draft_snapshot_type::Match3DDraftSnapshot; pub use match_3_d_gallery_view_row_type::Match3DGalleryViewRow; pub use match_3_d_gallery_view_table::*; +pub use match_3_d_item_snapshot_type::Match3DItemSnapshot; pub use match_3_d_run_click_input_type::Match3DRunClickInput; pub use match_3_d_run_get_input_type::Match3DRunGetInput; pub use match_3_d_run_procedure_result_type::Match3DRunProcedureResult; pub use match_3_d_run_restart_input_type::Match3DRunRestartInput; +pub use match_3_d_run_snapshot_type::Match3DRunSnapshot; pub use match_3_d_run_start_input_type::Match3DRunStartInput; pub use match_3_d_run_stop_input_type::Match3DRunStopInput; pub use match_3_d_run_time_up_input_type::Match3DRunTimeUpInput; pub use match_3_d_runtime_run_row_type::Match3DRuntimeRunRow; pub use match_3_d_runtime_run_table::*; +pub use match_3_d_tray_slot_snapshot_type::Match3DTraySlotSnapshot; pub use match_3_d_work_delete_input_type::Match3DWorkDeleteInput; pub use match_3_d_work_get_input_type::Match3DWorkGetInput; pub use match_3_d_work_procedure_result_type::Match3DWorkProcedureResult; pub use match_3_d_work_profile_row_type::Match3DWorkProfileRow; pub use match_3_d_work_profile_table::*; pub use match_3_d_work_publish_input_type::Match3DWorkPublishInput; +pub use match_3_d_work_snapshot_type::Match3DWorkSnapshot; pub use match_3_d_work_update_input_type::Match3DWorkUpdateInput; pub use match_3_d_works_list_input_type::Match3DWorksListInput; pub use match_3_d_works_procedure_result_type::Match3DWorksProcedureResult; @@ -1376,40 +1439,58 @@ pub use puzzle_agent_message_finalize_input_type::PuzzleAgentMessageFinalizeInpu pub use puzzle_agent_message_kind_type::PuzzleAgentMessageKind; pub use puzzle_agent_message_role_type::PuzzleAgentMessageRole; pub use puzzle_agent_message_row_type::PuzzleAgentMessageRow; +pub use puzzle_agent_message_snapshot_type::PuzzleAgentMessageSnapshot; pub use puzzle_agent_message_submit_input_type::PuzzleAgentMessageSubmitInput; pub use puzzle_agent_message_table::*; pub use puzzle_agent_session_create_input_type::PuzzleAgentSessionCreateInput; pub use puzzle_agent_session_get_input_type::PuzzleAgentSessionGetInput; pub use puzzle_agent_session_procedure_result_type::PuzzleAgentSessionProcedureResult; pub use puzzle_agent_session_row_type::PuzzleAgentSessionRow; +pub use puzzle_agent_session_snapshot_type::PuzzleAgentSessionSnapshot; pub use puzzle_agent_session_table::*; pub use puzzle_agent_stage_type::PuzzleAgentStage; +pub use puzzle_agent_suggested_action_type::PuzzleAgentSuggestedAction; pub use puzzle_anchor_item_type::PuzzleAnchorItem; pub use puzzle_anchor_pack_type::PuzzleAnchorPack; pub use puzzle_anchor_status_type::PuzzleAnchorStatus; pub use puzzle_audio_asset_type::PuzzleAudioAsset; +pub use puzzle_board_snapshot_type::PuzzleBoardSnapshot; +pub use puzzle_cell_position_type::PuzzleCellPosition; +pub use puzzle_creator_intent_type::PuzzleCreatorIntent; pub use puzzle_draft_compile_input_type::PuzzleDraftCompileInput; pub use puzzle_draft_level_type::PuzzleDraftLevel; pub use puzzle_event_kind_type::PuzzleEventKind; pub use puzzle_event_table::*; pub use puzzle_event_type::PuzzleEvent; pub use puzzle_form_draft_save_input_type::PuzzleFormDraftSaveInput; +pub use puzzle_form_draft_type::PuzzleFormDraft; pub use puzzle_gallery_view_table::*; pub use puzzle_generated_image_candidate_type::PuzzleGeneratedImageCandidate; pub use puzzle_generated_images_save_input_type::PuzzleGeneratedImagesSaveInput; pub use puzzle_leaderboard_entry_row_type::PuzzleLeaderboardEntryRow; pub use puzzle_leaderboard_entry_table::*; +pub use puzzle_leaderboard_entry_type::PuzzleLeaderboardEntry; pub use puzzle_leaderboard_submit_input_type::PuzzleLeaderboardSubmitInput; +pub use puzzle_merged_group_state_type::PuzzleMergedGroupState; +pub use puzzle_piece_state_type::PuzzlePieceState; pub use puzzle_publication_status_type::PuzzlePublicationStatus; pub use puzzle_publish_input_type::PuzzlePublishInput; +pub use puzzle_recommended_next_work_type::PuzzleRecommendedNextWork; +pub use puzzle_result_draft_type::PuzzleResultDraft; +pub use puzzle_result_preview_blocker_type::PuzzleResultPreviewBlocker; +pub use puzzle_result_preview_envelope_type::PuzzleResultPreviewEnvelope; +pub use puzzle_result_preview_finding_type::PuzzleResultPreviewFinding; pub use puzzle_run_drag_input_type::PuzzleRunDragInput; pub use puzzle_run_get_input_type::PuzzleRunGetInput; pub use puzzle_run_next_level_input_type::PuzzleRunNextLevelInput; pub use puzzle_run_pause_input_type::PuzzleRunPauseInput; pub use puzzle_run_procedure_result_type::PuzzleRunProcedureResult; pub use puzzle_run_prop_input_type::PuzzleRunPropInput; +pub use puzzle_run_snapshot_type::PuzzleRunSnapshot; pub use puzzle_run_start_input_type::PuzzleRunStartInput; pub use puzzle_run_swap_input_type::PuzzleRunSwapInput; +pub use puzzle_runtime_level_snapshot_type::PuzzleRuntimeLevelSnapshot; +pub use puzzle_runtime_level_status_type::PuzzleRuntimeLevelStatus; pub use puzzle_runtime_run_row_type::PuzzleRuntimeRunRow; pub use puzzle_runtime_run_table::*; pub use puzzle_select_cover_image_input_type::PuzzleSelectCoverImageInput; @@ -1613,34 +1694,43 @@ pub use seed_analytics_date_dimensions_reducer::seed_analytics_date_dimensions; pub use select_puzzle_cover_image_procedure::select_puzzle_cover_image; pub use square_hole_agent_message_finalize_input_type::SquareHoleAgentMessageFinalizeInput; pub use square_hole_agent_message_row_type::SquareHoleAgentMessageRow; +pub use square_hole_agent_message_snapshot_type::SquareHoleAgentMessageSnapshot; pub use square_hole_agent_message_submit_input_type::SquareHoleAgentMessageSubmitInput; pub use square_hole_agent_message_table::*; pub use square_hole_agent_session_create_input_type::SquareHoleAgentSessionCreateInput; pub use square_hole_agent_session_get_input_type::SquareHoleAgentSessionGetInput; pub use square_hole_agent_session_procedure_result_type::SquareHoleAgentSessionProcedureResult; pub use square_hole_agent_session_row_type::SquareHoleAgentSessionRow; +pub use square_hole_agent_session_snapshot_type::SquareHoleAgentSessionSnapshot; pub use square_hole_agent_session_table::*; +pub use square_hole_creator_config_snapshot_type::SquareHoleCreatorConfigSnapshot; pub use square_hole_draft_compile_input_type::SquareHoleDraftCompileInput; +pub use square_hole_draft_snapshot_type::SquareHoleDraftSnapshot; +pub use square_hole_drop_feedback_snapshot_type::SquareHoleDropFeedbackSnapshot; pub use square_hole_drop_shape_procedure_result_type::SquareHoleDropShapeProcedureResult; pub use square_hole_gallery_view_row_type::SquareHoleGalleryViewRow; pub use square_hole_gallery_view_table::*; pub use square_hole_hole_option_snapshot_type::SquareHoleHoleOptionSnapshot; +pub use square_hole_hole_snapshot_type::SquareHoleHoleSnapshot; pub use square_hole_run_drop_input_type::SquareHoleRunDropInput; pub use square_hole_run_get_input_type::SquareHoleRunGetInput; pub use square_hole_run_procedure_result_type::SquareHoleRunProcedureResult; pub use square_hole_run_restart_input_type::SquareHoleRunRestartInput; +pub use square_hole_run_snapshot_type::SquareHoleRunSnapshot; pub use square_hole_run_start_input_type::SquareHoleRunStartInput; pub use square_hole_run_stop_input_type::SquareHoleRunStopInput; pub use square_hole_run_time_up_input_type::SquareHoleRunTimeUpInput; pub use square_hole_runtime_run_row_type::SquareHoleRuntimeRunRow; pub use square_hole_runtime_run_table::*; pub use square_hole_shape_option_snapshot_type::SquareHoleShapeOptionSnapshot; +pub use square_hole_shape_snapshot_type::SquareHoleShapeSnapshot; pub use square_hole_work_delete_input_type::SquareHoleWorkDeleteInput; pub use square_hole_work_get_input_type::SquareHoleWorkGetInput; pub use square_hole_work_procedure_result_type::SquareHoleWorkProcedureResult; pub use square_hole_work_profile_row_type::SquareHoleWorkProfileRow; pub use square_hole_work_profile_table::*; pub use square_hole_work_publish_input_type::SquareHoleWorkPublishInput; +pub use square_hole_work_snapshot_type::SquareHoleWorkSnapshot; pub use square_hole_work_update_input_type::SquareHoleWorkUpdateInput; pub use square_hole_works_list_input_type::SquareHoleWorksListInput; pub use square_hole_works_procedure_result_type::SquareHoleWorksProcedureResult; @@ -1717,26 +1807,33 @@ pub use user_browse_history_table::*; pub use user_browse_history_type::UserBrowseHistory; pub use visual_novel_agent_message_finalize_input_type::VisualNovelAgentMessageFinalizeInput; pub use visual_novel_agent_message_row_type::VisualNovelAgentMessageRow; +pub use visual_novel_agent_message_snapshot_type::VisualNovelAgentMessageSnapshot; pub use visual_novel_agent_message_submit_input_type::VisualNovelAgentMessageSubmitInput; pub use visual_novel_agent_message_table::*; pub use visual_novel_agent_session_create_input_type::VisualNovelAgentSessionCreateInput; pub use visual_novel_agent_session_get_input_type::VisualNovelAgentSessionGetInput; pub use visual_novel_agent_session_procedure_result_type::VisualNovelAgentSessionProcedureResult; pub use visual_novel_agent_session_row_type::VisualNovelAgentSessionRow; +pub use visual_novel_agent_session_snapshot_type::VisualNovelAgentSessionSnapshot; pub use visual_novel_agent_session_table::*; pub use visual_novel_gallery_view_row_type::VisualNovelGalleryViewRow; pub use visual_novel_gallery_view_table::*; pub use visual_novel_history_procedure_result_type::VisualNovelHistoryProcedureResult; +pub use visual_novel_json_field_type::VisualNovelJsonField; +pub use visual_novel_json_value_type::VisualNovelJsonValue; pub use visual_novel_run_get_input_type::VisualNovelRunGetInput; pub use visual_novel_run_procedure_result_type::VisualNovelRunProcedureResult; +pub use visual_novel_run_snapshot_type::VisualNovelRunSnapshot; pub use visual_novel_run_snapshot_upsert_input_type::VisualNovelRunSnapshotUpsertInput; pub use visual_novel_run_start_input_type::VisualNovelRunStartInput; pub use visual_novel_runtime_event_procedure_result_type::VisualNovelRuntimeEventProcedureResult; pub use visual_novel_runtime_event_record_input_type::VisualNovelRuntimeEventRecordInput; +pub use visual_novel_runtime_event_snapshot_type::VisualNovelRuntimeEventSnapshot; pub use visual_novel_runtime_event_table::*; pub use visual_novel_runtime_event_type::VisualNovelRuntimeEvent; pub use visual_novel_runtime_history_append_input_type::VisualNovelRuntimeHistoryAppendInput; pub use visual_novel_runtime_history_entry_row_type::VisualNovelRuntimeHistoryEntryRow; +pub use visual_novel_runtime_history_entry_snapshot_type::VisualNovelRuntimeHistoryEntrySnapshot; pub use visual_novel_runtime_history_entry_table::*; pub use visual_novel_runtime_history_list_input_type::VisualNovelRuntimeHistoryListInput; pub use visual_novel_runtime_run_row_type::VisualNovelRuntimeRunRow; @@ -1748,6 +1845,7 @@ pub use visual_novel_work_procedure_result_type::VisualNovelWorkProcedureResult; pub use visual_novel_work_profile_row_type::VisualNovelWorkProfileRow; pub use visual_novel_work_profile_table::*; pub use visual_novel_work_publish_input_type::VisualNovelWorkPublishInput; +pub use visual_novel_work_snapshot_type::VisualNovelWorkSnapshot; pub use visual_novel_work_update_input_type::VisualNovelWorkUpdateInput; pub use visual_novel_works_list_input_type::VisualNovelWorksListInput; pub use visual_novel_works_procedure_result_type::VisualNovelWorksProcedureResult; diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_message_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_message_snapshot_type.rs new file mode 100644 index 00000000..00dbec45 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_message_snapshot_type.rs @@ -0,0 +1,23 @@ +// 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::puzzle_agent_message_kind_type::PuzzleAgentMessageKind; +use super::puzzle_agent_message_role_type::PuzzleAgentMessageRole; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleAgentMessageSnapshot { + pub message_id: String, + pub session_id: String, + pub role: PuzzleAgentMessageRole, + pub kind: PuzzleAgentMessageKind, + pub text: String, + pub created_at_micros: i64, +} + +impl __sdk::InModule for PuzzleAgentMessageSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_procedure_result_type.rs index 39506659..00de9f76 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::puzzle_agent_session_snapshot_type::PuzzleAgentSessionSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct PuzzleAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_snapshot_type.rs new file mode 100644 index 00000000..d099e6ac --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_session_snapshot_type.rs @@ -0,0 +1,36 @@ +// 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::puzzle_agent_message_snapshot_type::PuzzleAgentMessageSnapshot; +use super::puzzle_agent_stage_type::PuzzleAgentStage; +use super::puzzle_agent_suggested_action_type::PuzzleAgentSuggestedAction; +use super::puzzle_anchor_pack_type::PuzzleAnchorPack; +use super::puzzle_result_draft_type::PuzzleResultDraft; +use super::puzzle_result_preview_envelope_type::PuzzleResultPreviewEnvelope; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleAgentSessionSnapshot { + pub session_id: String, + pub owner_user_id: String, + pub seed_text: String, + pub current_turn: u32, + pub progress_percent: u32, + pub stage: PuzzleAgentStage, + pub anchor_pack: PuzzleAnchorPack, + pub draft: Option, + pub messages: Vec, + pub last_assistant_reply: Option, + pub published_profile_id: Option, + pub suggested_actions: Vec, + pub result_preview: Option, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for PuzzleAgentSessionSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_suggested_action_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_suggested_action_type.rs new file mode 100644 index 00000000..56593222 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_agent_suggested_action_type.rs @@ -0,0 +1,17 @@ +// 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 PuzzleAgentSuggestedAction { + pub id: String, + pub action_type: String, + pub label: String, +} + +impl __sdk::InModule for PuzzleAgentSuggestedAction { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_board_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_board_snapshot_type.rs new file mode 100644 index 00000000..2408ef0c --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_board_snapshot_type.rs @@ -0,0 +1,23 @@ +// 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::puzzle_merged_group_state_type::PuzzleMergedGroupState; +use super::puzzle_piece_state_type::PuzzlePieceState; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleBoardSnapshot { + pub rows: u32, + pub cols: u32, + pub pieces: Vec, + pub merged_groups: Vec, + pub selected_piece_id: Option, + pub all_tiles_resolved: bool, +} + +impl __sdk::InModule for PuzzleBoardSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_cell_position_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_cell_position_type.rs new file mode 100644 index 00000000..92942799 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_cell_position_type.rs @@ -0,0 +1,16 @@ +// 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 PuzzleCellPosition { + pub row: u32, + pub col: u32, +} + +impl __sdk::InModule for PuzzleCellPosition { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_creator_intent_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_creator_intent_type.rs new file mode 100644 index 00000000..9d1cff85 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_creator_intent_type.rs @@ -0,0 +1,22 @@ +// 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 PuzzleCreatorIntent { + pub source_mode: String, + pub raw_messages_summary: String, + pub theme_promise: String, + pub visual_subject: String, + pub visual_mood: Vec, + pub composition_hooks: Vec, + pub theme_tags: Vec, + pub forbidden_directives: Vec, +} + +impl __sdk::InModule for PuzzleCreatorIntent { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_form_draft_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_form_draft_type.rs new file mode 100644 index 00000000..c949aae1 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_form_draft_type.rs @@ -0,0 +1,17 @@ +// 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 PuzzleFormDraft { + pub work_title: Option, + pub work_description: Option, + pub picture_description: Option, +} + +impl __sdk::InModule for PuzzleFormDraft { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_leaderboard_entry_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_leaderboard_entry_type.rs new file mode 100644 index 00000000..474c7ffa --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_leaderboard_entry_type.rs @@ -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}; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleLeaderboardEntry { + pub rank: u32, + pub nickname: String, + pub elapsed_ms: u64, + pub visible_tags: Vec, + pub is_current_player: bool, +} + +impl __sdk::InModule for PuzzleLeaderboardEntry { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_merged_group_state_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_merged_group_state_type.rs new file mode 100644 index 00000000..b6cba30c --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_merged_group_state_type.rs @@ -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::puzzle_cell_position_type::PuzzleCellPosition; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleMergedGroupState { + pub group_id: String, + pub piece_ids: Vec, + pub occupied_cells: Vec, +} + +impl __sdk::InModule for PuzzleMergedGroupState { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_piece_state_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_piece_state_type.rs new file mode 100644 index 00000000..7cb0ef6d --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_piece_state_type.rs @@ -0,0 +1,20 @@ +// 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 PuzzlePieceState { + pub piece_id: String, + pub correct_row: u32, + pub correct_col: u32, + pub current_row: u32, + pub current_col: u32, + pub merged_group_id: Option, +} + +impl __sdk::InModule for PuzzlePieceState { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_recommended_next_work_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_recommended_next_work_type.rs new file mode 100644 index 00000000..69d26ad1 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_recommended_next_work_type.rs @@ -0,0 +1,20 @@ +// 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 PuzzleRecommendedNextWork { + pub profile_id: String, + pub level_name: String, + pub author_display_name: String, + pub theme_tags: Vec, + pub cover_image_src: Option, + pub similarity_score: f32, +} + +impl __sdk::InModule for PuzzleRecommendedNextWork { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_draft_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_draft_type.rs new file mode 100644 index 00000000..adb2dff4 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_draft_type.rs @@ -0,0 +1,35 @@ +// 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::puzzle_anchor_pack_type::PuzzleAnchorPack; +use super::puzzle_creator_intent_type::PuzzleCreatorIntent; +use super::puzzle_draft_level_type::PuzzleDraftLevel; +use super::puzzle_form_draft_type::PuzzleFormDraft; +use super::puzzle_generated_image_candidate_type::PuzzleGeneratedImageCandidate; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleResultDraft { + pub work_title: String, + pub work_description: String, + pub level_name: String, + pub summary: String, + pub theme_tags: Vec, + pub forbidden_directives: Vec, + pub creator_intent: Option, + pub anchor_pack: PuzzleAnchorPack, + pub candidates: Vec, + pub selected_candidate_id: Option, + pub cover_image_src: Option, + pub cover_asset_id: Option, + pub generation_status: String, + pub levels: Vec, + pub form_draft: Option, +} + +impl __sdk::InModule for PuzzleResultDraft { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_blocker_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_blocker_type.rs new file mode 100644 index 00000000..e604eb40 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_blocker_type.rs @@ -0,0 +1,17 @@ +// 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 PuzzleResultPreviewBlocker { + pub id: String, + pub code: String, + pub message: String, +} + +impl __sdk::InModule for PuzzleResultPreviewBlocker { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_envelope_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_envelope_type.rs new file mode 100644 index 00000000..4e09e613 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_envelope_type.rs @@ -0,0 +1,22 @@ +// 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::puzzle_result_draft_type::PuzzleResultDraft; +use super::puzzle_result_preview_blocker_type::PuzzleResultPreviewBlocker; +use super::puzzle_result_preview_finding_type::PuzzleResultPreviewFinding; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleResultPreviewEnvelope { + pub draft: PuzzleResultDraft, + pub blockers: Vec, + pub quality_findings: Vec, + pub publish_ready: bool, +} + +impl __sdk::InModule for PuzzleResultPreviewEnvelope { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_finding_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_finding_type.rs new file mode 100644 index 00000000..a43c4a16 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_result_preview_finding_type.rs @@ -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 PuzzleResultPreviewFinding { + pub id: String, + pub severity: String, + pub code: String, + pub message: String, +} + +impl __sdk::InModule for PuzzleResultPreviewFinding { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_procedure_result_type.rs index 54f6349b..5b1a430c 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::puzzle_run_snapshot_type::PuzzleRunSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct PuzzleRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_snapshot_type.rs new file mode 100644 index 00000000..b32fe5d0 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_run_snapshot_type.rs @@ -0,0 +1,32 @@ +// 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::puzzle_leaderboard_entry_type::PuzzleLeaderboardEntry; +use super::puzzle_recommended_next_work_type::PuzzleRecommendedNextWork; +use super::puzzle_runtime_level_snapshot_type::PuzzleRuntimeLevelSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleRunSnapshot { + pub run_id: String, + pub entry_profile_id: String, + pub cleared_level_count: u32, + pub current_level_index: u32, + pub current_grid_size: u32, + pub played_profile_ids: Vec, + pub previous_level_tags: Vec, + pub current_level: Option, + pub recommended_next_profile_id: Option, + pub next_level_mode: String, + pub next_level_profile_id: Option, + pub next_level_id: Option, + pub recommended_next_works: Vec, + pub leaderboard_entries: Vec, +} + +impl __sdk::InModule for PuzzleRunSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_runtime_level_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_runtime_level_snapshot_type.rs new file mode 100644 index 00000000..3554ed20 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_runtime_level_snapshot_type.rs @@ -0,0 +1,44 @@ +// 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::puzzle_audio_asset_type::PuzzleAudioAsset; +use super::puzzle_board_snapshot_type::PuzzleBoardSnapshot; +use super::puzzle_leaderboard_entry_type::PuzzleLeaderboardEntry; +use super::puzzle_runtime_level_status_type::PuzzleRuntimeLevelStatus; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct PuzzleRuntimeLevelSnapshot { + pub run_id: String, + pub level_index: u32, + pub level_id: Option, + pub grid_size: u32, + pub profile_id: String, + pub level_name: String, + pub author_display_name: String, + pub theme_tags: Vec, + pub cover_image_src: Option, + pub ui_background_image_src: Option, + pub ui_background_image_object_key: Option, + pub background_music: Option, + pub board: PuzzleBoardSnapshot, + pub status: PuzzleRuntimeLevelStatus, + pub started_at_ms: u64, + pub cleared_at_ms: Option, + pub elapsed_ms: Option, + pub time_limit_ms: u64, + pub remaining_ms: u64, + pub paused_accumulated_ms: u64, + pub pause_started_at_ms: Option, + pub freeze_accumulated_ms: u64, + pub freeze_started_at_ms: Option, + pub freeze_until_ms: Option, + pub leaderboard_entries: Vec, +} + +impl __sdk::InModule for PuzzleRuntimeLevelSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_runtime_level_status_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_runtime_level_status_type.rs new file mode 100644 index 00000000..dd491ccf --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_runtime_level_status_type.rs @@ -0,0 +1,20 @@ +// 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 PuzzleRuntimeLevelStatus { + Playing, + + Cleared, + + Failed, +} + +impl __sdk::InModule for PuzzleRuntimeLevelStatus { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_work_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_work_procedure_result_type.rs index d59a56cc..019c8f94 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_work_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_work_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::puzzle_work_profile_type::PuzzleWorkProfile; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct PuzzleWorkProcedureResult { pub ok: bool, - pub item_json: Option, + pub item: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_works_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_works_procedure_result_type.rs index 6a34c60f..53204197 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/puzzle_works_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/puzzle_works_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::puzzle_work_profile_type::PuzzleWorkProfile; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct PuzzleWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_message_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_message_snapshot_type.rs new file mode 100644 index 00000000..8af09de8 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_message_snapshot_type.rs @@ -0,0 +1,20 @@ +// 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 SquareHoleAgentMessageSnapshot { + pub message_id: String, + pub session_id: String, + pub role: String, + pub kind: String, + pub text: String, + pub created_at_micros: i64, +} + +impl __sdk::InModule for SquareHoleAgentMessageSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_procedure_result_type.rs index 5ea89d13..0b7384a7 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::square_hole_agent_session_snapshot_type::SquareHoleAgentSessionSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct SquareHoleAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_snapshot_type.rs new file mode 100644 index 00000000..47130393 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_agent_session_snapshot_type.rs @@ -0,0 +1,31 @@ +// 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::square_hole_agent_message_snapshot_type::SquareHoleAgentMessageSnapshot; +use super::square_hole_creator_config_snapshot_type::SquareHoleCreatorConfigSnapshot; +use super::square_hole_draft_snapshot_type::SquareHoleDraftSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct SquareHoleAgentSessionSnapshot { + pub session_id: String, + pub owner_user_id: String, + pub seed_text: String, + pub current_turn: u32, + pub progress_percent: u32, + pub stage: String, + pub config: SquareHoleCreatorConfigSnapshot, + pub draft: Option, + pub messages: Vec, + pub last_assistant_reply: String, + pub published_profile_id: Option, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for SquareHoleAgentSessionSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_creator_config_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_creator_config_snapshot_type.rs new file mode 100644 index 00000000..b10dd3e9 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_creator_config_snapshot_type.rs @@ -0,0 +1,26 @@ +// 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::square_hole_hole_option_snapshot_type::SquareHoleHoleOptionSnapshot; +use super::square_hole_shape_option_snapshot_type::SquareHoleShapeOptionSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct SquareHoleCreatorConfigSnapshot { + pub theme_text: String, + pub twist_rule: String, + pub shape_count: u32, + pub difficulty: u32, + pub shape_options: Vec, + pub hole_options: Vec, + pub background_prompt: String, + pub cover_image_src: String, + pub background_image_src: String, +} + +impl __sdk::InModule for SquareHoleCreatorConfigSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_draft_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_draft_snapshot_type.rs new file mode 100644 index 00000000..810103ea --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_draft_snapshot_type.rs @@ -0,0 +1,30 @@ +// 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::square_hole_hole_option_snapshot_type::SquareHoleHoleOptionSnapshot; +use super::square_hole_shape_option_snapshot_type::SquareHoleShapeOptionSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct SquareHoleDraftSnapshot { + pub profile_id: String, + pub game_name: String, + pub theme_text: String, + pub twist_rule: String, + pub summary_text: String, + pub tags: Vec, + pub cover_image_src: String, + pub background_prompt: String, + pub background_image_src: String, + pub shape_options: Vec, + pub hole_options: Vec, + pub shape_count: u32, + pub difficulty: u32, +} + +impl __sdk::InModule for SquareHoleDraftSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_feedback_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_feedback_snapshot_type.rs new file mode 100644 index 00000000..3ff25600 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_feedback_snapshot_type.rs @@ -0,0 +1,17 @@ +// 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 SquareHoleDropFeedbackSnapshot { + pub accepted: bool, + pub reject_reason: Option, + pub message: String, +} + +impl __sdk::InModule for SquareHoleDropFeedbackSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_shape_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_shape_procedure_result_type.rs index 06ba3616..0d2b6665 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_shape_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_drop_shape_procedure_result_type.rs @@ -4,13 +4,16 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::square_hole_drop_feedback_snapshot_type::SquareHoleDropFeedbackSnapshot; +use super::square_hole_run_snapshot_type::SquareHoleRunSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct SquareHoleDropShapeProcedureResult { pub ok: bool, pub status: String, - pub run_json: Option, - pub feedback_json: Option, + pub run: Option, + pub feedback: Option, pub failure_reason: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_hole_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_hole_snapshot_type.rs new file mode 100644 index 00000000..5663a23f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_hole_snapshot_type.rs @@ -0,0 +1,20 @@ +// 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 SquareHoleHoleSnapshot { + pub hole_id: String, + pub hole_kind: String, + pub label: String, + pub x: f32, + pub y: f32, + pub image_src: String, +} + +impl __sdk::InModule for SquareHoleHoleSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_procedure_result_type.rs index e4a5817d..ab11a2f4 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::square_hole_run_snapshot_type::SquareHoleRunSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct SquareHoleRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_snapshot_type.rs new file mode 100644 index 00000000..a8d1e8b0 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_run_snapshot_type.rs @@ -0,0 +1,39 @@ +// 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::square_hole_drop_feedback_snapshot_type::SquareHoleDropFeedbackSnapshot; +use super::square_hole_hole_snapshot_type::SquareHoleHoleSnapshot; +use super::square_hole_shape_option_snapshot_type::SquareHoleShapeOptionSnapshot; +use super::square_hole_shape_snapshot_type::SquareHoleShapeSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct SquareHoleRunSnapshot { + pub run_id: String, + pub profile_id: String, + pub owner_user_id: String, + pub status: String, + pub snapshot_version: u64, + pub started_at_ms: i64, + pub duration_limit_ms: i64, + pub server_now_ms: i64, + pub remaining_ms: i64, + pub total_shape_count: u32, + pub completed_shape_count: u32, + pub combo: u32, + pub best_combo: u32, + pub score: u32, + pub rule_label: String, + pub background_image_src: String, + pub shape_options: Vec, + pub current_shape: Option, + pub holes: Vec, + pub last_feedback: Option, +} + +impl __sdk::InModule for SquareHoleRunSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_shape_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_shape_snapshot_type.rs new file mode 100644 index 00000000..2c16b1c9 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_shape_snapshot_type.rs @@ -0,0 +1,20 @@ +// 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 SquareHoleShapeSnapshot { + pub shape_id: String, + pub shape_kind: String, + pub label: String, + pub target_hole_id: String, + pub color: String, + pub image_src: String, +} + +impl __sdk::InModule for SquareHoleShapeSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_procedure_result_type.rs index 0565f0e9..a3682071 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::square_hole_work_snapshot_type::SquareHoleWorkSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct SquareHoleWorkProcedureResult { pub ok: bool, - pub work_json: Option, + pub work: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_snapshot_type.rs new file mode 100644 index 00000000..54786576 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_work_snapshot_type.rs @@ -0,0 +1,41 @@ +// 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::square_hole_creator_config_snapshot_type::SquareHoleCreatorConfigSnapshot; +use super::square_hole_hole_option_snapshot_type::SquareHoleHoleOptionSnapshot; +use super::square_hole_shape_option_snapshot_type::SquareHoleShapeOptionSnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct SquareHoleWorkSnapshot { + pub work_id: String, + pub profile_id: String, + pub owner_user_id: String, + pub source_session_id: String, + pub author_display_name: String, + pub game_name: String, + pub theme_text: String, + pub twist_rule: String, + pub summary_text: String, + pub tags: Vec, + pub cover_image_src: String, + pub background_prompt: String, + pub background_image_src: String, + pub shape_options: Vec, + pub hole_options: Vec, + pub shape_count: u32, + pub difficulty: u32, + pub config: SquareHoleCreatorConfigSnapshot, + pub publication_status: String, + pub publish_ready: bool, + pub play_count: u32, + pub updated_at_micros: i64, + pub published_at_micros: Option, +} + +impl __sdk::InModule for SquareHoleWorkSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_works_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_works_procedure_result_type.rs index 6f7ca3f3..09faad0f 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/square_hole_works_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/square_hole_works_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::square_hole_work_snapshot_type::SquareHoleWorkSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct SquareHoleWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_message_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_message_snapshot_type.rs new file mode 100644 index 00000000..a337915a --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_message_snapshot_type.rs @@ -0,0 +1,20 @@ +// 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 VisualNovelAgentMessageSnapshot { + pub message_id: String, + pub session_id: String, + pub role: String, + pub kind: String, + pub text: String, + pub created_at_micros: i64, +} + +impl __sdk::InModule for VisualNovelAgentMessageSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_procedure_result_type.rs index f04d06eb..7ed44833 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::visual_novel_agent_session_snapshot_type::VisualNovelAgentSessionSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct VisualNovelAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_snapshot_type.rs new file mode 100644 index 00000000..623a380e --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_agent_session_snapshot_type.rs @@ -0,0 +1,32 @@ +// 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::visual_novel_agent_message_snapshot_type::VisualNovelAgentMessageSnapshot; +use super::visual_novel_json_value_type::VisualNovelJsonValue; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct VisualNovelAgentSessionSnapshot { + pub session_id: String, + pub owner_user_id: String, + pub source_mode: String, + pub status: String, + pub seed_text: String, + pub source_asset_ids: Vec, + pub current_turn: u32, + pub progress_percent: u32, + pub messages: Vec, + pub draft: Option, + pub pending_action: Option, + pub last_assistant_reply: Option, + pub published_profile_id: Option, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for VisualNovelAgentSessionSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_history_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_history_procedure_result_type.rs index c5c5935c..f0a3e7cd 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_history_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_history_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::visual_novel_runtime_history_entry_snapshot_type::VisualNovelRuntimeHistoryEntrySnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct VisualNovelHistoryProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_json_field_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_json_field_type.rs new file mode 100644 index 00000000..d0789512 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_json_field_type.rs @@ -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}; + +use super::visual_novel_json_value_type::VisualNovelJsonValue; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct VisualNovelJsonField { + pub key: String, + pub value: VisualNovelJsonValue, +} + +impl __sdk::InModule for VisualNovelJsonField { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_json_value_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_json_value_type.rs new file mode 100644 index 00000000..31bb6ffb --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_json_value_type.rs @@ -0,0 +1,27 @@ +// 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::visual_novel_json_field_type::VisualNovelJsonField; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub enum VisualNovelJsonValue { + Null, + + Bool(bool), + + Number(f64), + + String(String), + + Array(Vec), + + Object(Vec), +} + +impl __sdk::InModule for VisualNovelJsonValue { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_procedure_result_type.rs index 66bbe483..b9bdde61 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::visual_novel_run_snapshot_type::VisualNovelRunSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct VisualNovelRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_snapshot_type.rs new file mode 100644 index 00000000..a4ea47f6 --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_run_snapshot_type.rs @@ -0,0 +1,32 @@ +// 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::visual_novel_json_value_type::VisualNovelJsonValue; +use super::visual_novel_runtime_history_entry_snapshot_type::VisualNovelRuntimeHistoryEntrySnapshot; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct VisualNovelRunSnapshot { + pub run_id: String, + pub owner_user_id: String, + pub profile_id: String, + pub mode: String, + pub status: String, + pub current_scene_id: Option, + pub current_phase_id: Option, + pub visible_character_ids: Vec, + pub flags: VisualNovelJsonValue, + pub metrics: VisualNovelJsonValue, + pub history: Vec, + pub available_choices: VisualNovelJsonValue, + pub text_mode_enabled: bool, + pub created_at_micros: i64, + pub updated_at_micros: i64, +} + +impl __sdk::InModule for VisualNovelRunSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_procedure_result_type.rs index 58bdfbfb..ccabc4be 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::visual_novel_runtime_event_snapshot_type::VisualNovelRuntimeEventSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct VisualNovelRuntimeEventProcedureResult { pub ok: bool, - pub event_json: Option, + pub event: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_snapshot_type.rs new file mode 100644 index 00000000..8749eb5c --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_event_snapshot_type.rs @@ -0,0 +1,25 @@ +// 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::visual_novel_json_value_type::VisualNovelJsonValue; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct VisualNovelRuntimeEventSnapshot { + pub event_id: String, + pub run_id: Option, + pub owner_user_id: String, + pub profile_id: Option, + pub event_kind: String, + pub client_event_id: Option, + pub history_entry_id: Option, + pub payload: VisualNovelJsonValue, + pub occurred_at_micros: i64, +} + +impl __sdk::InModule for VisualNovelRuntimeEventSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_history_entry_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_history_entry_snapshot_type.rs new file mode 100644 index 00000000..af62143e --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_runtime_history_entry_snapshot_type.rs @@ -0,0 +1,27 @@ +// 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::visual_novel_json_value_type::VisualNovelJsonValue; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct VisualNovelRuntimeHistoryEntrySnapshot { + pub entry_id: String, + pub run_id: String, + pub owner_user_id: String, + pub profile_id: String, + pub turn_index: u32, + pub source: String, + pub action_text: Option, + pub steps: VisualNovelJsonValue, + pub snapshot_before_hash: Option, + pub snapshot_after_hash: Option, + pub created_at_micros: i64, +} + +impl __sdk::InModule for VisualNovelRuntimeHistoryEntrySnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_procedure_result_type.rs index f7e63a1c..72535982 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::visual_novel_work_snapshot_type::VisualNovelWorkSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct VisualNovelWorkProcedureResult { pub ok: bool, - pub work_json: Option, + pub work: Option, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_snapshot_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_snapshot_type.rs new file mode 100644 index 00000000..46b8180f --- /dev/null +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_work_snapshot_type.rs @@ -0,0 +1,33 @@ +// 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::visual_novel_json_value_type::VisualNovelJsonValue; + +#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] +#[sats(crate = __lib)] +pub struct VisualNovelWorkSnapshot { + pub work_id: String, + pub profile_id: String, + pub owner_user_id: String, + pub source_session_id: Option, + pub author_display_name: String, + pub work_title: String, + pub work_description: String, + pub tags: Vec, + pub cover_image_src: Option, + pub source_asset_ids: Vec, + pub draft: VisualNovelJsonValue, + pub publication_status: String, + pub publish_ready: bool, + pub play_count: u32, + pub created_at_micros: i64, + pub updated_at_micros: i64, + pub published_at_micros: Option, +} + +impl __sdk::InModule for VisualNovelWorkSnapshot { + type Module = super::RemoteModule; +} diff --git a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_works_procedure_result_type.rs b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_works_procedure_result_type.rs index 72558fcd..d6c89c1c 100644 --- a/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_works_procedure_result_type.rs +++ b/server-rs/crates/spacetime-client/src/module_bindings/visual_novel_works_procedure_result_type.rs @@ -4,11 +4,13 @@ #![allow(unused, clippy::all)] use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; +use super::visual_novel_work_snapshot_type::VisualNovelWorkSnapshot; + #[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)] #[sats(crate = __lib)] pub struct VisualNovelWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } diff --git a/server-rs/crates/spacetime-module/src/ai/snapshots.rs b/server-rs/crates/spacetime-module/src/ai/snapshots.rs index f6a9284c..8ee4c0be 100644 --- a/server-rs/crates/spacetime-module/src/ai/snapshots.rs +++ b/server-rs/crates/spacetime-module/src/ai/snapshots.rs @@ -33,8 +33,8 @@ pub(crate) fn build_ai_task_snapshot_from_row( let mut stages = ctx .db .ai_task_stage() - .iter() - .filter(|stage| stage.task_id == row.task_id) + .by_ai_task_stage_task_id() + .filter(&row.task_id) .map(|stage| build_ai_task_stage_snapshot_from_row(&stage)) .collect::>(); stages.sort_by_key(|stage| stage.order); @@ -42,8 +42,8 @@ pub(crate) fn build_ai_task_snapshot_from_row( let mut result_references = ctx .db .ai_result_reference() - .iter() - .filter(|reference| reference.task_id == row.task_id) + .by_ai_result_reference_task_id() + .filter(&row.task_id) .map(|reference| build_ai_result_reference_snapshot_from_row(&reference)) .collect::>(); result_references.sort_by_key(|reference| reference.created_at_micros); diff --git a/server-rs/crates/spacetime-module/src/ai/stages.rs b/server-rs/crates/spacetime-module/src/ai/stages.rs index ed908daf..8ffea6f2 100644 --- a/server-rs/crates/spacetime-module/src/ai/stages.rs +++ b/server-rs/crates/spacetime-module/src/ai/stages.rs @@ -318,8 +318,8 @@ pub(crate) fn replace_ai_task_stages( let stage_ids = ctx .db .ai_task_stage() - .iter() - .filter(|row| row.task_id == task_id) + .by_ai_task_stage_task_id() + .filter(task_id) .map(|row| row.task_stage_id.clone()) .collect::>(); for stage_id in stage_ids { @@ -341,7 +341,8 @@ pub(crate) fn collect_ai_stage_text_output( let mut chunks = ctx .db .ai_text_chunk() - .iter() + .by_ai_text_chunk_task_id() + .filter(task_id) .filter(|row| row.task_id == task_id && row.stage_kind == stage_kind) .map(|row| build_ai_text_chunk_snapshot_from_row(&row)) .collect::>(); diff --git a/server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs b/server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs index 50a6c649..98bd9b4d 100644 --- a/server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs +++ b/server-rs/crates/spacetime-module/src/asset_metadata/bindings.rs @@ -66,12 +66,16 @@ fn upsert_asset_entity_binding( return Err("asset_entity_binding.asset_object_id 对应的 asset_object 不存在".to_string()); } - // 首版绑定按 entity_kind + entity_id + slot 幂等定位,后续访问量明确后再改为组合索引扫描。 - let current = ctx.db.asset_entity_binding().iter().find(|row| { - row.entity_kind == input.entity_kind - && row.entity_id == input.entity_id - && row.slot == input.slot - }); + let current = ctx + .db + .asset_entity_binding() + .by_entity_slot() + .filter(( + input.entity_kind.as_str(), + input.entity_id.as_str(), + input.slot.as_str(), + )) + .next(); let snapshot = match current { Some(existing) => { diff --git a/server-rs/crates/spacetime-module/src/asset_metadata/objects.rs b/server-rs/crates/spacetime-module/src/asset_metadata/objects.rs index e6650242..01cb9a38 100644 --- a/server-rs/crates/spacetime-module/src/asset_metadata/objects.rs +++ b/server-rs/crates/spacetime-module/src/asset_metadata/objects.rs @@ -128,12 +128,12 @@ pub(crate) fn upsert_asset_object( ) .map_err(|error| error.to_string())?; - // 这里先保持最小可发布实现:查重语义已经冻结,后续再把实现优化回组合索引扫描。 let current = ctx .db .asset_object() - .iter() - .find(|row| row.bucket == input.bucket && row.object_key == input.object_key); + .by_bucket_object_key() + .filter((input.bucket.as_str(), input.object_key.as_str())) + .next(); let snapshot = match current { Some(existing) => { @@ -196,8 +196,9 @@ pub(crate) fn upsert_asset_object( pub(crate) fn has_asset_object(ctx: &ReducerContext, asset_object_id: &str) -> bool { ctx.db .asset_object() - .iter() - .any(|row| row.asset_object_id == asset_object_id) + .asset_object_id() + .find(&asset_object_id.to_string()) + .is_some() } fn list_asset_history( @@ -224,8 +225,8 @@ fn list_asset_history( let mut entries = ctx .db .asset_object() - .iter() - .filter(|row| row.asset_kind == asset_kind) + .asset_kind() + .filter(&asset_kind.to_string()) .map(|row| AssetHistoryEntrySnapshot { asset_object_id: row.asset_object_id, asset_kind: row.asset_kind, diff --git a/server-rs/crates/spacetime-module/src/bark_battle/mod.rs b/server-rs/crates/spacetime-module/src/bark_battle/mod.rs index d4afb89b..2d104b7e 100644 --- a/server-rs/crates/spacetime-module/src/bark_battle/mod.rs +++ b/server-rs/crates/spacetime-module/src/bark_battle/mod.rs @@ -1,6 +1,5 @@ use crate::*; -use serde::Serialize; -use serde::de::DeserializeOwned; +use serde::{Serialize, de::DeserializeOwned}; use sha2::{Digest, Sha256}; pub(crate) mod tables; @@ -15,7 +14,7 @@ pub fn create_bark_battle_draft( input: BarkBattleDraftCreateInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| create_bark_battle_draft_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_draft_config_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -26,7 +25,7 @@ pub fn update_bark_battle_draft_config( input: BarkBattleDraftConfigUpsertInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| update_bark_battle_draft_config_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_draft_config_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -37,7 +36,7 @@ pub fn publish_bark_battle_work( input: BarkBattleWorkPublishInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| publish_bark_battle_work_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_runtime_config_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -48,7 +47,7 @@ pub fn get_bark_battle_runtime_config( input: BarkBattleRuntimeConfigGetInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| get_bark_battle_runtime_config_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_runtime_config_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -59,7 +58,7 @@ pub fn start_bark_battle_run( input: BarkBattleRunStartInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| start_bark_battle_run_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_run_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -70,7 +69,7 @@ pub fn finish_bark_battle_run( input: BarkBattleRunFinishInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| finish_bark_battle_run_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_run_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -81,7 +80,7 @@ pub fn get_bark_battle_run( input: BarkBattleRunGetInput, ) -> BarkBattleProcedureResult { match ctx.try_with_tx(|tx| get_bark_battle_run_tx(tx, input.clone())) { - Ok(snapshot) => bark_battle_json_result(&snapshot), + Ok(snapshot) => bark_battle_run_result(snapshot), Err(error) => bark_battle_error_result(error), } } @@ -584,10 +583,36 @@ fn validate_json(value: &str, field_name: &str) -> Result<( .map_err(|error| format!("bark_battle {field_name} JSON 无效: {error}")) } -fn bark_battle_json_result(value: &T) -> BarkBattleProcedureResult { +fn bark_battle_draft_config_result( + draft_config: BarkBattleDraftConfigSnapshot, +) -> BarkBattleProcedureResult { BarkBattleProcedureResult { ok: true, - row_json: Some(to_json_string(value)), + draft_config: Some(draft_config), + runtime_config: None, + run: None, + error_message: None, + } +} + +fn bark_battle_runtime_config_result( + runtime_config: BarkBattleRuntimeConfigSnapshot, +) -> BarkBattleProcedureResult { + BarkBattleProcedureResult { + ok: true, + draft_config: None, + runtime_config: Some(runtime_config), + run: None, + error_message: None, + } +} + +fn bark_battle_run_result(run: BarkBattleRunSnapshot) -> BarkBattleProcedureResult { + BarkBattleProcedureResult { + ok: true, + draft_config: None, + runtime_config: None, + run: Some(run), error_message: None, } } @@ -595,7 +620,9 @@ fn bark_battle_json_result(value: &T) -> BarkBattleProcedureResult fn bark_battle_error_result(error: String) -> BarkBattleProcedureResult { BarkBattleProcedureResult { ok: false, - row_json: None, + draft_config: None, + runtime_config: None, + run: None, error_message: Some(error), } } @@ -850,7 +877,21 @@ mod tests { let result = BarkBattleProcedureResult { ok: true, - row_json: Some(input.config_json.clone()), + draft_config: Some(BarkBattleDraftConfigSnapshot { + draft_id: input.draft_id.clone(), + owner_user_id: input.owner_user_id.clone(), + work_id: input.work_id.clone(), + config_version: input.config_version, + ruleset_version: input.ruleset_version.clone(), + difficulty_preset: input.difficulty_preset.clone(), + leaderboard_enabled: input.leaderboard_enabled, + config_json: input.config_json.clone(), + editor_state_json: "{}".to_string(), + created_at_micros: 1_700_000, + updated_at_micros: input.updated_at_micros, + }), + runtime_config: None, + run: None, error_message: None, }; diff --git a/server-rs/crates/spacetime-module/src/bark_battle/types.rs b/server-rs/crates/spacetime-module/src/bark_battle/types.rs index e26a2747..a1652d78 100644 --- a/server-rs/crates/spacetime-module/src/bark_battle/types.rs +++ b/server-rs/crates/spacetime-module/src/bark_battle/types.rs @@ -102,14 +102,16 @@ pub struct BarkBattleRunGetInput { pub owner_user_id: String, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct BarkBattleProcedureResult { pub ok: bool, - pub row_json: Option, + pub draft_config: Option, + pub runtime_config: Option, + pub run: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct BarkBattleEditorConfigSnapshot { pub title: String, @@ -121,7 +123,7 @@ pub struct BarkBattleEditorConfigSnapshot { pub leaderboard_enabled: bool, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct BarkBattleDraftConfigSnapshot { pub draft_id: String, @@ -137,7 +139,7 @@ pub struct BarkBattleDraftConfigSnapshot { pub updated_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct BarkBattleRuntimeConfigSnapshot { pub work_id: String, @@ -153,7 +155,7 @@ pub struct BarkBattleRuntimeConfigSnapshot { pub updated_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct BarkBattleRunSnapshot { pub run_id: String, diff --git a/server-rs/crates/spacetime-module/src/big_fish/assets.rs b/server-rs/crates/spacetime-module/src/big_fish/assets.rs index 2f0f1fa4..1da68d3c 100644 --- a/server-rs/crates/spacetime-module/src/big_fish/assets.rs +++ b/server-rs/crates/spacetime-module/src/big_fish/assets.rs @@ -222,8 +222,8 @@ pub(crate) fn list_big_fish_asset_slots( let mut slots = ctx .db .big_fish_asset_slot() - .iter() - .filter(|slot| slot.session_id == session_id) + .by_big_fish_asset_session_id() + .filter(&session_id.to_string()) .map(|slot| BigFishAssetSlotSnapshot { slot_id: slot.slot_id, session_id: slot.session_id, diff --git a/server-rs/crates/spacetime-module/src/big_fish/runtime.rs b/server-rs/crates/spacetime-module/src/big_fish/runtime.rs index fefdadd4..6e0f56f8 100644 --- a/server-rs/crates/spacetime-module/src/big_fish/runtime.rs +++ b/server-rs/crates/spacetime-module/src/big_fish/runtime.rs @@ -16,12 +16,12 @@ pub fn start_big_fish_run( match ctx.try_with_tx(|tx| start_big_fish_run_tx(tx, input.clone())) { Ok(run) => BigFishRunProcedureResult { ok: true, - run_json: Some(serialize_big_fish_run_json(&run)), + run: Some(run), error_message: None, }, Err(message) => BigFishRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -35,12 +35,12 @@ pub fn get_big_fish_run( match ctx.try_with_tx(|tx| get_big_fish_run_tx(tx, input.clone())) { Ok(run) => BigFishRunProcedureResult { ok: true, - run_json: Some(serialize_big_fish_run_json(&run)), + run: Some(run), error_message: None, }, Err(message) => BigFishRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -54,12 +54,12 @@ pub fn submit_big_fish_input( match ctx.try_with_tx(|tx| submit_big_fish_input_tx(tx, input.clone())) { Ok(run) => BigFishRunProcedureResult { ok: true, - run_json: Some(serialize_big_fish_run_json(&run)), + run: Some(run), error_message: None, }, Err(message) => BigFishRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -225,7 +225,3 @@ fn replace_big_fish_runtime_run( }); Ok(()) } - -fn serialize_big_fish_run_json(run: &BigFishRuntimeSnapshot) -> String { - serialize_runtime_snapshot(run).unwrap_or_else(|_| "{}".to_string()) -} diff --git a/server-rs/crates/spacetime-module/src/big_fish/session.rs b/server-rs/crates/spacetime-module/src/big_fish/session.rs index 6673b488..5ae78d2a 100644 --- a/server-rs/crates/spacetime-module/src/big_fish/session.rs +++ b/server-rs/crates/spacetime-module/src/big_fish/session.rs @@ -88,21 +88,14 @@ pub fn list_big_fish_works( input: BigFishWorksListInput, ) -> BigFishWorksProcedureResult { match ctx.try_with_tx(|tx| list_big_fish_works_tx(tx, input.clone())) { - Ok(items) => match serde_json::to_string(&items) { - Ok(items_json) => BigFishWorksProcedureResult { - ok: true, - items_json: Some(items_json), - error_message: None, - }, - Err(error) => BigFishWorksProcedureResult { - ok: false, - items_json: None, - error_message: Some(error.to_string()), - }, + Ok(items) => BigFishWorksProcedureResult { + ok: true, + items, + error_message: None, }, Err(message) => BigFishWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -114,21 +107,14 @@ pub fn delete_big_fish_work( input: BigFishWorkDeleteInput, ) -> BigFishWorksProcedureResult { match ctx.try_with_tx(|tx| delete_big_fish_work_tx(tx, input.clone())) { - Ok(items) => match serde_json::to_string(&items) { - Ok(items_json) => BigFishWorksProcedureResult { - ok: true, - items_json: Some(items_json), - error_message: None, - }, - Err(error) => BigFishWorksProcedureResult { - ok: false, - items_json: None, - error_message: Some(error.to_string()), - }, + Ok(items) => BigFishWorksProcedureResult { + ok: true, + items, + error_message: None, }, Err(message) => BigFishWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -140,21 +126,14 @@ pub fn record_big_fish_play( input: BigFishPlayRecordInput, ) -> BigFishWorksProcedureResult { match ctx.try_with_tx(|tx| record_big_fish_play_tx(tx, input.clone())) { - Ok(items) => match serde_json::to_string(&items) { - Ok(items_json) => BigFishWorksProcedureResult { - ok: true, - items_json: Some(items_json), - error_message: None, - }, - Err(error) => BigFishWorksProcedureResult { - ok: false, - items_json: None, - error_message: Some(error.to_string()), - }, + Ok(items) => BigFishWorksProcedureResult { + ok: true, + items, + error_message: None, }, Err(message) => BigFishWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -166,21 +145,14 @@ pub fn record_big_fish_like( input: BigFishWorkLikeRecordInput, ) -> BigFishWorksProcedureResult { match ctx.try_with_tx(|tx| record_big_fish_like_tx(tx, input.clone())) { - Ok(items) => match serde_json::to_string(&items) { - Ok(items_json) => BigFishWorksProcedureResult { - ok: true, - items_json: Some(items_json), - error_message: None, - }, - Err(error) => BigFishWorksProcedureResult { - ok: false, - items_json: None, - error_message: Some(error.to_string()), - }, + Ok(items) => BigFishWorksProcedureResult { + ok: true, + items, + error_message: None, }, Err(message) => BigFishWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -354,16 +326,20 @@ pub(crate) fn list_big_fish_works_tx( validate_works_list_input(&input).map_err(|error| error.to_string())?; let now_micros = ctx.timestamp.to_micros_since_unix_epoch(); - let mut items = ctx + let rows = ctx .db .big_fish_creation_session() + .by_big_fish_session_owner_user_id() + .filter(&input.owner_user_id) + .collect::>(); + let mut items = rows .iter() .filter(|row| { if input.published_only { return row.stage == BigFishCreationStage::Published; } - row.owner_user_id == input.owner_user_id && should_include_big_fish_work(ctx, row) + should_include_big_fish_work(ctx, row) }) .map(|row| build_big_fish_work_summary(ctx, &row, now_micros)) .collect::, _>>()?; @@ -382,10 +358,11 @@ fn should_include_big_fish_work(ctx: &ReducerContext, row: &BigFishCreationSessi return true; } - ctx.db.big_fish_agent_message().iter().any(|message| { - message.session_id == row.session_id - && matches!(message.role, BigFishAgentMessageRole::User) - }) + ctx.db + .big_fish_agent_message() + .by_big_fish_message_session_id() + .filter(&row.session_id) + .any(|message| matches!(message.role, BigFishAgentMessageRole::User)) } fn big_fish_session_has_direct_work_content(row: &BigFishCreationSession) -> bool { @@ -420,8 +397,8 @@ pub(crate) fn delete_big_fish_work_tx( for message in ctx .db .big_fish_agent_message() - .iter() - .filter(|row| row.session_id == input.session_id) + .by_big_fish_message_session_id() + .filter(&input.session_id) .collect::>() { ctx.db @@ -432,8 +409,8 @@ pub(crate) fn delete_big_fish_work_tx( for slot in ctx .db .big_fish_asset_slot() - .iter() - .filter(|row| row.session_id == input.session_id) + .by_big_fish_asset_session_id() + .filter(&input.session_id) .collect::>() { ctx.db.big_fish_asset_slot().slot_id().delete(&slot.slot_id); @@ -441,8 +418,8 @@ pub(crate) fn delete_big_fish_work_tx( for run in ctx .db .big_fish_runtime_run() - .iter() - .filter(|row| row.session_id == input.session_id) + .by_big_fish_run_session_id() + .filter(&input.session_id) .collect::>() { ctx.db.big_fish_runtime_run().run_id().delete(&run.run_id); @@ -985,8 +962,8 @@ pub(crate) fn build_big_fish_session_snapshot( let mut messages = ctx .db .big_fish_agent_message() - .iter() - .filter(|message| message.session_id == row.session_id) + .by_big_fish_message_session_id() + .filter(&row.session_id) .map(|message| BigFishAgentMessageSnapshot { message_id: message.message_id, session_id: message.session_id, diff --git a/server-rs/crates/spacetime-module/src/custom_world/mod.rs b/server-rs/crates/spacetime-module/src/custom_world/mod.rs index da42008c..36228bfe 100644 --- a/server-rs/crates/spacetime-module/src/custom_world/mod.rs +++ b/server-rs/crates/spacetime-module/src/custom_world/mod.rs @@ -436,7 +436,8 @@ fn delete_custom_world_agent_session_tx( let published_profile = ctx .db .custom_world_profile() - .iter() + .by_custom_world_profile_owner_user_id() + .filter(&input.owner_user_id) .find(|row| { row.owner_user_id == input.owner_user_id && row.source_agent_session_id.as_deref() == Some(input.session_id.as_str()) @@ -471,8 +472,8 @@ fn delete_custom_world_agent_session_tx( for message in ctx .db .custom_world_agent_message() - .iter() - .filter(|row| row.session_id == input.session_id) + .by_custom_world_agent_message_session_id() + .filter(&input.session_id) .collect::>() { ctx.db @@ -483,8 +484,8 @@ fn delete_custom_world_agent_session_tx( for operation in ctx .db .custom_world_agent_operation() - .iter() - .filter(|row| row.session_id == input.session_id) + .by_custom_world_agent_operation_session_id() + .filter(&input.session_id) .collect::>() { ctx.db @@ -495,8 +496,8 @@ fn delete_custom_world_agent_session_tx( for card in ctx .db .custom_world_draft_card() - .iter() - .filter(|row| row.session_id == input.session_id) + .by_custom_world_draft_card_session_id() + .filter(&input.session_id) .collect::>() { ctx.db @@ -1184,9 +1185,17 @@ fn upsert_custom_world_profile_record( .source_agent_session_id .as_ref() .and_then(|session_id| { - ctx.db.custom_world_profile().iter().find(|row| { - is_same_agent_draft_profile_candidate(row, &input.owner_user_id, session_id) - }) + ctx.db + .custom_world_profile() + .by_custom_world_profile_owner_user_id() + .filter(&input.owner_user_id) + .find(|row| { + is_same_agent_draft_profile_candidate( + row, + &input.owner_user_id, + session_id, + ) + }) }) }); @@ -1534,8 +1543,9 @@ fn list_custom_world_profile_snapshots( let mut entries = ctx .db .custom_world_profile() - .iter() - .filter(|row| row.owner_user_id == input.owner_user_id && row.deleted_at.is_none()) + .by_custom_world_profile_owner_user_id() + .filter(&input.owner_user_id) + .filter(|row| row.deleted_at.is_none()) .map(|row| build_custom_world_profile_snapshot(&row)) .collect::>(); @@ -1676,8 +1686,9 @@ fn get_custom_world_gallery_detail_record_by_code( let gallery_entry = ctx .db .custom_world_gallery_entry() - .iter() - .find(|row| row.public_work_code == normalized_public_work_code); + .by_custom_world_gallery_public_work_code() + .filter(&normalized_public_work_code) + .next(); let profile = gallery_entry.as_ref().and_then(|row| { ctx.db @@ -1974,9 +1985,14 @@ fn list_custom_world_work_snapshots( let mut items = Vec::new(); let mut active_agent_session_ids = HashSet::new(); - for session in ctx.db.custom_world_agent_session().iter().filter(|row| { - row.owner_user_id == input.owner_user_id - && row.stage != RpgAgentStage::Published + let sessions = ctx + .db + .custom_world_agent_session() + .by_custom_world_agent_session_owner_user_id() + .filter(&input.owner_user_id) + .collect::>(); + for session in sessions.iter().filter(|row| { + row.stage != RpgAgentStage::Published && should_include_custom_world_agent_session_work(ctx, row) }) { active_agent_session_ids.insert(session.session_id.clone()); @@ -2021,8 +2037,9 @@ fn list_custom_world_work_snapshots( for profile in ctx .db .custom_world_profile() - .iter() - .filter(|row| row.owner_user_id == input.owner_user_id && row.deleted_at.is_none()) + .by_custom_world_profile_owner_user_id() + .filter(&input.owner_user_id) + .filter(|row| row.deleted_at.is_none()) .filter(|row| should_include_custom_world_profile_work(row, &active_agent_session_ids)) { items.push(CustomWorldWorkSummarySnapshot { @@ -2086,16 +2103,20 @@ fn should_include_custom_world_agent_session_work( return true; } - if ctx.db.custom_world_agent_message().iter().any(|message| { - message.session_id == session.session_id - && matches!(message.role, RpgAgentMessageRole::User) - }) { + if ctx + .db + .custom_world_agent_message() + .by_custom_world_agent_message_session_id() + .filter(&session.session_id) + .any(|message| matches!(message.role, RpgAgentMessageRole::User)) + { return true; } ctx.db .custom_world_draft_card() - .iter() + .by_custom_world_draft_card_session_id() + .filter(&session.session_id) .any(|card| card.session_id == session.session_id) } @@ -3446,10 +3467,12 @@ fn update_role_asset_cards( label: &str, updated_at_micros: i64, ) { - for card in - ctx.db.custom_world_draft_card().iter().filter(|row| { - row.session_id == session_id && row.kind == RpgAgentDraftCardKind::Character - }) + for card in ctx + .db + .custom_world_draft_card() + .by_custom_world_draft_card_session_id() + .filter(&session_id.to_string()) + .filter(|row| row.kind == RpgAgentDraftCardKind::Character) { replace_custom_world_draft_card( ctx, @@ -4590,8 +4613,8 @@ fn resolve_session_work_counts( for card in ctx .db .custom_world_draft_card() - .iter() - .filter(|row| row.session_id == session.session_id) + .by_custom_world_draft_card_session_id() + .filter(&session.session_id) { match card.kind { RpgAgentDraftCardKind::Character => { @@ -4827,11 +4850,9 @@ fn sync_missing_custom_world_gallery_entries(ctx: &ReducerContext) -> Result<(), let published_profiles = ctx .db .custom_world_profile() - .iter() - .filter(|profile| { - profile.publication_status == CustomWorldPublicationStatus::Published - && profile.deleted_at.is_none() - }) + .by_custom_world_profile_publication_status() + .filter(CustomWorldPublicationStatus::Published) + .filter(|profile| profile.deleted_at.is_none()) .collect::>(); for profile in published_profiles { @@ -4973,8 +4994,8 @@ fn build_custom_world_agent_session_snapshot( let mut messages = ctx .db .custom_world_agent_message() - .iter() - .filter(|message| message.session_id == row.session_id) + .by_custom_world_agent_message_session_id() + .filter(&row.session_id) .map(|message| build_custom_world_agent_message_snapshot(&message)) .collect::>(); messages.sort_by_key(|message| (message.created_at_micros, message.message_id.clone())); @@ -4982,8 +5003,8 @@ fn build_custom_world_agent_session_snapshot( let mut draft_cards = ctx .db .custom_world_draft_card() - .iter() - .filter(|card| card.session_id == row.session_id) + .by_custom_world_draft_card_session_id() + .filter(&row.session_id) .map(|card| build_custom_world_draft_card_snapshot(&card)) .collect::>(); draft_cards.sort_by_key(|card| (card.created_at_micros, card.card_id.clone())); @@ -4991,8 +5012,8 @@ fn build_custom_world_agent_session_snapshot( let mut operations = ctx .db .custom_world_agent_operation() - .iter() - .filter(|operation| operation.session_id == row.session_id) + .by_custom_world_agent_operation_session_id() + .filter(&row.session_id) .map(|operation| build_custom_world_agent_operation_snapshot(&operation)) .collect::>(); operations diff --git a/server-rs/crates/spacetime-module/src/gameplay/mod.rs b/server-rs/crates/spacetime-module/src/gameplay/mod.rs index db62e53a..5202342f 100644 --- a/server-rs/crates/spacetime-module/src/gameplay/mod.rs +++ b/server-rs/crates/spacetime-module/src/gameplay/mod.rs @@ -415,11 +415,9 @@ fn apply_inventory_mutation_tx( let current_slots = ctx .db .inventory_slot() - .iter() - .filter(|slot| { - slot.runtime_session_id == input.runtime_session_id - && slot.actor_user_id == input.actor_user_id - }) + .by_inventory_runtime_session_id() + .filter(&input.runtime_session_id) + .filter(|slot| slot.actor_user_id == input.actor_user_id) .map(|row| build_inventory_slot_snapshot_from_row(&row)) .collect::>(); @@ -587,11 +585,9 @@ fn get_runtime_inventory_state_tx( let slots = ctx .db .inventory_slot() - .iter() - .filter(|row| { - row.runtime_session_id == validated_input.runtime_session_id - && row.actor_user_id == validated_input.actor_user_id - }) + .by_inventory_runtime_session_id() + .filter(&validated_input.runtime_session_id) + .filter(|row| row.actor_user_id == validated_input.actor_user_id) .map(|row| build_inventory_slot_snapshot_from_row(&row)) .collect::>(); @@ -926,8 +922,8 @@ fn get_story_session_state_tx( let mut events = ctx .db .story_event() - .iter() - .filter(|row| row.story_session_id == input.story_session_id) + .by_story_session_id() + .filter(&input.story_session_id) .map(|row| build_story_event_snapshot_from_row(&row)) .collect::>(); events.sort_by_key(|event| (event.created_at_micros, event.event_id.clone())); @@ -1439,11 +1435,9 @@ fn inventory_reward_source_already_granted( ctx.db .inventory_slot() - .iter() - .filter(|row| { - row.runtime_session_id == first_mutation.runtime_session_id - && row.actor_user_id == first_mutation.actor_user_id - }) + .by_inventory_runtime_session_id() + .filter(&first_mutation.runtime_session_id) + .filter(|row| row.actor_user_id == first_mutation.actor_user_id) .any(|row| row.source_reference_id.as_deref() == Some(source_reference_id)) } diff --git a/server-rs/crates/spacetime-module/src/match3d/mod.rs b/server-rs/crates/spacetime-module/src/match3d/mod.rs index e7c641b7..b4154fc2 100644 --- a/server-rs/crates/spacetime-module/src/match3d/mod.rs +++ b/server-rs/crates/spacetime-module/src/match3d/mod.rs @@ -161,12 +161,12 @@ pub fn list_match3d_works( match ctx.try_with_tx(|tx| list_match3d_works_tx(tx, input.clone())) { Ok(items) => Match3DWorksProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => Match3DWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -191,12 +191,12 @@ pub fn delete_match3d_work( match ctx.try_with_tx(|tx| delete_match3d_work_tx(tx, input.clone())) { Ok(items) => Match3DWorksProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => Match3DWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -234,7 +234,7 @@ pub fn click_match3d_item( Err(message) => Match3DClickItemProcedureResult { ok: false, status: MATCH3D_CLICK_REJECTED_NOT_CLICKABLE.to_string(), - run_json: None, + run: None, accepted_item_instance_id: None, cleared_item_instance_ids: Vec::new(), failure_reason: None, @@ -690,17 +690,22 @@ fn list_match3d_works_tx( ctx: &ReducerContext, input: Match3DWorksListInput, ) -> Result, String> { - let mut items = ctx - .db - .match3d_work_profile() + let rows = if input.published_only { + ctx.db + .match3d_work_profile() + .by_match3d_work_publication_status() + .filter(&MATCH3D_PUBLICATION_PUBLISHED.to_string()) + .collect::>() + } else { + require_non_empty(&input.owner_user_id, "match3d owner_user_id")?; + ctx.db + .match3d_work_profile() + .by_match3d_work_owner_user_id() + .filter(&input.owner_user_id) + .collect::>() + }; + let mut items = rows .iter() - .filter(|row| { - if input.published_only { - row.publication_status == MATCH3D_PUBLICATION_PUBLISHED - } else { - row.owner_user_id == input.owner_user_id - } - }) .map(|row| build_work_snapshot(&row)) .collect::, _>>()?; items.sort_by(|left, right| { @@ -741,10 +746,9 @@ fn delete_match3d_work_tx( for run in ctx .db .match3d_runtime_run() - .iter() - .filter(|row| { - row.profile_id == input.profile_id && row.owner_user_id == input.owner_user_id - }) + .by_match3d_run_profile_id() + .filter(&input.profile_id) + .filter(|row| row.owner_user_id == input.owner_user_id) .collect::>() { ctx.db.match3d_runtime_run().run_id().delete(&run.run_id); @@ -987,8 +991,8 @@ fn build_session_snapshot( let mut messages = ctx .db .match3d_agent_message() - .iter() - .filter(|message| message.session_id == row.session_id) + .by_match3d_agent_message_session_id() + .filter(&row.session_id) .map(|message| Match3DAgentMessageSnapshot { message_id: message.message_id, session_id: message.session_id, @@ -1241,10 +1245,10 @@ fn click_result( Match3DClickItemProcedureResult { ok: true, status: status.to_string(), - run_json: Some(to_json_string(&snapshot)), + failure_reason: snapshot.failure_reason.clone(), + run: Some(snapshot), accepted_item_instance_id, cleared_item_instance_ids, - failure_reason: snapshot.failure_reason, error_message: None, } } @@ -1802,7 +1806,7 @@ fn to_json_string(value: &T) -> String { fn session_result(session: Match3DAgentSessionSnapshot) -> Match3DAgentSessionProcedureResult { Match3DAgentSessionProcedureResult { ok: true, - session_json: Some(to_json_string(&session)), + session: Some(session), error_message: None, } } @@ -1810,7 +1814,7 @@ fn session_result(session: Match3DAgentSessionSnapshot) -> Match3DAgentSessionPr fn session_error(message: String) -> Match3DAgentSessionProcedureResult { Match3DAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), } } @@ -1818,7 +1822,7 @@ fn session_error(message: String) -> Match3DAgentSessionProcedureResult { fn work_result(work: Match3DWorkSnapshot) -> Match3DWorkProcedureResult { Match3DWorkProcedureResult { ok: true, - work_json: Some(to_json_string(&work)), + work: Some(work), error_message: None, } } @@ -1826,7 +1830,7 @@ fn work_result(work: Match3DWorkSnapshot) -> Match3DWorkProcedureResult { fn work_error(message: String) -> Match3DWorkProcedureResult { Match3DWorkProcedureResult { ok: false, - work_json: None, + work: None, error_message: Some(message), } } @@ -1834,7 +1838,7 @@ fn work_error(message: String) -> Match3DWorkProcedureResult { fn run_result(run: Match3DRunSnapshot) -> Match3DRunProcedureResult { Match3DRunProcedureResult { ok: true, - run_json: Some(to_json_string(&run)), + run: Some(run), error_message: None, } } @@ -1842,7 +1846,7 @@ fn run_result(run: Match3DRunSnapshot) -> Match3DRunProcedureResult { fn run_error(message: String) -> Match3DRunProcedureResult { Match3DRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), } } diff --git a/server-rs/crates/spacetime-module/src/match3d/types.rs b/server-rs/crates/spacetime-module/src/match3d/types.rs index ab79903f..4d17b024 100644 --- a/server-rs/crates/spacetime-module/src/match3d/types.rs +++ b/server-rs/crates/spacetime-module/src/match3d/types.rs @@ -182,43 +182,43 @@ pub struct Match3DRunTimeUpInput { #[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] pub struct Match3DAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } #[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] pub struct Match3DWorkProcedureResult { pub ok: bool, - pub work_json: Option, + pub work: Option, pub error_message: Option, } #[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] pub struct Match3DWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct Match3DRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct Match3DClickItemProcedureResult { pub ok: bool, pub status: String, - pub run_json: Option, + pub run: Option, pub accepted_item_instance_id: Option, pub cleared_item_instance_ids: Vec, pub failure_reason: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DCreatorConfigSnapshot { pub theme_text: String, @@ -235,7 +235,7 @@ pub struct Match3DCreatorConfigSnapshot { pub generate_click_sound: bool, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DAgentMessageSnapshot { pub message_id: String, @@ -246,7 +246,7 @@ pub struct Match3DAgentMessageSnapshot { pub created_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DDraftSnapshot { pub profile_id: String, @@ -260,7 +260,7 @@ pub struct Match3DDraftSnapshot { pub generated_item_assets_json: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DAgentSessionSnapshot { pub session_id: String, @@ -278,7 +278,7 @@ pub struct Match3DAgentSessionSnapshot { pub updated_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DWorkSnapshot { pub profile_id: String, @@ -302,7 +302,7 @@ pub struct Match3DWorkSnapshot { pub generated_item_assets_json: Option, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DItemSnapshot { pub item_instance_id: String, @@ -316,7 +316,7 @@ pub struct Match3DItemSnapshot { pub clickable: bool, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DTraySlotSnapshot { pub slot_index: u32, @@ -325,7 +325,7 @@ pub struct Match3DTraySlotSnapshot { pub visual_key: Option, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct Match3DRunSnapshot { pub run_id: String, diff --git a/server-rs/crates/spacetime-module/src/puzzle.rs b/server-rs/crates/spacetime-module/src/puzzle.rs index 9f0e2c3d..28f75c1e 100644 --- a/server-rs/crates/spacetime-module/src/puzzle.rs +++ b/server-rs/crates/spacetime-module/src/puzzle.rs @@ -125,19 +125,17 @@ pub fn puzzle_gallery_view(ctx: &AnonymousViewContext) -> Vec .puzzle_work_profile() .by_puzzle_work_publication_status() .filter(PuzzlePublicationStatus::Published) - .filter_map( - |row| match build_puzzle_work_profile_from_row_without_recent_count(&row) { - Ok(profile) => Some(profile), - Err(error) => { - log::warn!( - "拼图广场 view 跳过损坏的作品投影 profile_id={}: {}", - row.profile_id, - error - ); - None - } - }, - ) + .filter_map(|row| match build_puzzle_work_profile_from_row_without_recent_count(&row) { + Ok(profile) => Some(profile), + Err(error) => { + log::warn!( + "拼图广场 view 跳过损坏的作品投影 profile_id={}: {}", + row.profile_id, + error + ); + None + } + }) .collect::>(); items.sort_by(|left, right| right.updated_at_micros.cmp(&left.updated_at_micros)); items @@ -218,12 +216,12 @@ pub fn create_puzzle_agent_session( match ctx.try_with_tx(|tx| create_puzzle_agent_session_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -237,12 +235,12 @@ pub fn get_puzzle_agent_session( match ctx.try_with_tx(|tx| get_puzzle_agent_session_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -256,12 +254,12 @@ pub fn submit_puzzle_agent_message( match ctx.try_with_tx(|tx| submit_puzzle_agent_message_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -275,12 +273,12 @@ pub fn finalize_puzzle_agent_message_turn( match ctx.try_with_tx(|tx| finalize_puzzle_agent_message_turn_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -294,12 +292,12 @@ pub fn compile_puzzle_agent_draft( match ctx.try_with_tx(|tx| compile_puzzle_agent_draft_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -315,12 +313,12 @@ pub fn save_puzzle_form_draft( match ctx.try_with_tx(|tx| save_puzzle_form_draft_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -334,12 +332,12 @@ pub fn save_puzzle_generated_images( match ctx.try_with_tx(|tx| save_puzzle_generated_images_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -353,12 +351,12 @@ pub fn save_puzzle_ui_background( match ctx.try_with_tx(|tx| save_puzzle_ui_background_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -372,12 +370,12 @@ pub fn select_puzzle_cover_image( match ctx.try_with_tx(|tx| select_puzzle_cover_image_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -391,12 +389,12 @@ pub fn publish_puzzle_work( match ctx.try_with_tx(|tx| publish_puzzle_work_tx(tx, input.clone())) { Ok(item) => PuzzleWorkProcedureResult { ok: true, - item_json: Some(serialize_json(&item)), + item: Some(item), error_message: None, }, Err(message) => PuzzleWorkProcedureResult { ok: false, - item_json: None, + item: None, error_message: Some(message), }, } @@ -410,12 +408,12 @@ pub fn list_puzzle_works( match ctx.try_with_tx(|tx| list_puzzle_works_tx(tx, input.clone())) { Ok(items) => PuzzleWorksProcedureResult { ok: true, - items_json: Some(serialize_json(&items)), + items, error_message: None, }, Err(message) => PuzzleWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -429,12 +427,12 @@ pub fn get_puzzle_work_detail( match ctx.try_with_tx(|tx| get_puzzle_work_detail_tx(tx, input.clone())) { Ok(item) => PuzzleWorkProcedureResult { ok: true, - item_json: Some(serialize_json(&item)), + item: Some(item), error_message: None, }, Err(message) => PuzzleWorkProcedureResult { ok: false, - item_json: None, + item: None, error_message: Some(message), }, } @@ -448,12 +446,12 @@ pub fn update_puzzle_work( match ctx.try_with_tx(|tx| update_puzzle_work_tx(tx, input.clone())) { Ok(item) => PuzzleWorkProcedureResult { ok: true, - item_json: Some(serialize_json(&item)), + item: Some(item), error_message: None, }, Err(message) => PuzzleWorkProcedureResult { ok: false, - item_json: None, + item: None, error_message: Some(message), }, } @@ -467,12 +465,12 @@ pub fn delete_puzzle_work( match ctx.try_with_tx(|tx| delete_puzzle_work_tx(tx, input.clone())) { Ok(items) => PuzzleWorksProcedureResult { ok: true, - items_json: Some(serialize_json(&items)), + items, error_message: None, }, Err(message) => PuzzleWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -483,12 +481,12 @@ pub fn list_puzzle_gallery(ctx: &mut ProcedureContext) -> PuzzleWorksProcedureRe match ctx.try_with_tx(|tx| list_puzzle_gallery_tx(tx)) { Ok(items) => PuzzleWorksProcedureResult { ok: true, - items_json: Some(serialize_json(&items)), + items, error_message: None, }, Err(message) => PuzzleWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -502,12 +500,12 @@ pub fn get_puzzle_gallery_detail( match ctx.try_with_tx(|tx| get_puzzle_gallery_detail_tx(tx, input.clone())) { Ok(item) => PuzzleWorkProcedureResult { ok: true, - item_json: Some(serialize_json(&item)), + item: Some(item), error_message: None, }, Err(message) => PuzzleWorkProcedureResult { ok: false, - item_json: None, + item: None, error_message: Some(message), }, } @@ -521,12 +519,12 @@ pub fn record_puzzle_work_like( match ctx.try_with_tx(|tx| record_puzzle_work_like_tx(tx, input.clone())) { Ok(item) => PuzzleWorkProcedureResult { ok: true, - item_json: Some(serialize_json(&item)), + item: Some(item), error_message: None, }, Err(message) => PuzzleWorkProcedureResult { ok: false, - item_json: None, + item: None, error_message: Some(message), }, } @@ -540,12 +538,12 @@ pub fn remix_puzzle_work( match ctx.try_with_tx(|tx| remix_puzzle_work_tx(tx, input.clone())) { Ok(session) => PuzzleAgentSessionProcedureResult { ok: true, - session_json: Some(serialize_json(&session)), + session: Some(session), error_message: None, }, Err(message) => PuzzleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), }, } @@ -559,12 +557,12 @@ pub fn start_puzzle_run( match ctx.try_with_tx(|tx| start_puzzle_run_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -578,12 +576,12 @@ pub fn get_puzzle_run( match ctx.try_with_tx(|tx| get_puzzle_run_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -597,12 +595,12 @@ pub fn swap_puzzle_pieces( match ctx.try_with_tx(|tx| swap_puzzle_pieces_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -616,12 +614,12 @@ pub fn drag_puzzle_piece_or_group( match ctx.try_with_tx(|tx| drag_puzzle_piece_or_group_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -635,12 +633,12 @@ pub fn advance_puzzle_next_level( match ctx.try_with_tx(|tx| advance_puzzle_next_level_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -654,12 +652,12 @@ pub fn update_puzzle_run_pause( match ctx.try_with_tx(|tx| update_puzzle_run_pause_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -673,12 +671,12 @@ pub fn use_puzzle_runtime_prop( match ctx.try_with_tx(|tx| use_puzzle_runtime_prop_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -692,12 +690,12 @@ pub fn claim_puzzle_work_point_incentive( match ctx.try_with_tx(|tx| claim_puzzle_work_point_incentive_tx(tx, input.clone())) { Ok(item) => PuzzleWorkProcedureResult { ok: true, - item_json: Some(serialize_json(&item)), + item: Some(item), error_message: None, }, Err(message) => PuzzleWorkProcedureResult { ok: false, - item_json: None, + item: None, error_message: Some(message), }, } @@ -711,12 +709,12 @@ pub fn submit_puzzle_leaderboard_entry( match ctx.try_with_tx(|tx| submit_puzzle_leaderboard_entry_tx(tx, input.clone())) { Ok(run) => PuzzleRunProcedureResult { ok: true, - run_json: Some(serialize_json(&run)), + run: Some(run), error_message: None, }, Err(message) => PuzzleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), }, } @@ -901,10 +899,7 @@ fn compile_puzzle_agent_draft_tx( } let anchor_pack = infer_anchor_pack(&row.seed_text, Some(&row.seed_text)); let messages = list_session_messages(ctx, &row.session_id); - let draft = mark_puzzle_draft_generation_status( - compile_result_draft_from_seed(&anchor_pack, &messages, Some(&row.seed_text)), - "generating", - ); + let draft = compile_result_draft_from_seed(&anchor_pack, &messages, Some(&row.seed_text)); // 创作中心的拼图草稿卡只是 Agent session 的列表投影, // 每次编译结果页时同步 upsert,保证后续能按 source_session_id 恢复聊天。 upsert_puzzle_draft_work_profile( @@ -2505,52 +2500,10 @@ fn profile_for_single_level( level: &module_puzzle::PuzzleDraftLevel, ) -> PuzzleWorkProfile { let mut next_profile = profile.clone(); - let ui_background_carrier = profile.levels.iter().find(|candidate| { - candidate - .ui_background_image_src - .as_deref() - .map(str::trim) - .map(|value| !value.is_empty()) - .unwrap_or(false) - || candidate - .ui_background_image_object_key - .as_deref() - .map(str::trim) - .map(|value| !value.is_empty()) - .unwrap_or(false) - }); - let mut single_level = level.clone(); - if single_level - .ui_background_image_src - .as_deref() - .map(str::trim) - .unwrap_or("") - .is_empty() - && single_level - .ui_background_image_object_key - .as_deref() - .map(str::trim) - .unwrap_or("") - .is_empty() - && let Some(carrier) = ui_background_carrier - { - single_level.ui_background_image_src = carrier - .ui_background_image_src - .as_deref() - .map(str::trim) - .filter(|value| !value.is_empty()) - .map(str::to_string); - single_level.ui_background_image_object_key = carrier - .ui_background_image_object_key - .as_deref() - .map(str::trim) - .filter(|value| !value.is_empty()) - .map(|value| value.trim_start_matches('/').to_string()); - } next_profile.level_name = level.level_name.clone(); next_profile.cover_image_src = level.cover_image_src.clone(); next_profile.cover_asset_id = level.cover_asset_id.clone(); - next_profile.levels = vec![single_level]; + next_profile.levels = vec![level.clone()]; next_profile } @@ -2571,17 +2524,6 @@ fn micros_to_millis(value: i64) -> u64 { (value as u64).saturating_div(1_000) } -fn mark_puzzle_draft_generation_status( - mut draft: PuzzleResultDraft, - generation_status: &str, -) -> PuzzleResultDraft { - draft.generation_status = generation_status.to_string(); - for level in &mut draft.levels { - level.generation_status = generation_status.to_string(); - } - draft -} - fn upsert_puzzle_draft_work_profile( ctx: &TxContext, session_id: &str, @@ -3552,37 +3494,6 @@ mod tests { assert!(preview.publish_ready); } - #[test] - fn puzzle_draft_generation_status_updates_all_levels() { - let anchor_pack = infer_anchor_pack("蒸汽城市雨夜猫咪", Some("蒸汽城市雨夜猫咪")); - let mut draft = compile_result_draft(&anchor_pack, &[]); - draft.levels.push(module_puzzle::PuzzleDraftLevel { - level_id: "puzzle-level-2".to_string(), - level_name: "第二关".to_string(), - picture_description: "第二关画面".to_string(), - picture_reference: None, - ui_background_prompt: None, - ui_background_image_src: None, - ui_background_image_object_key: None, - background_music: None, - candidates: Vec::new(), - selected_candidate_id: None, - cover_image_src: None, - cover_asset_id: None, - generation_status: "idle".to_string(), - }); - - let draft = mark_puzzle_draft_generation_status(draft, "generating"); - - assert_eq!(draft.generation_status, "generating"); - assert!( - draft - .levels - .iter() - .all(|level| level.generation_status == "generating") - ); - } - #[test] fn puzzle_generated_images_replace_existing_candidate() { let anchor_pack = infer_anchor_pack("蒸汽城市雨夜猫咪", Some("蒸汽城市雨夜猫咪")); diff --git a/server-rs/crates/spacetime-module/src/runtime/browse_history.rs b/server-rs/crates/spacetime-module/src/runtime/browse_history.rs index a4886067..7183fa2b 100644 --- a/server-rs/crates/spacetime-module/src/runtime/browse_history.rs +++ b/server-rs/crates/spacetime-module/src/runtime/browse_history.rs @@ -95,8 +95,8 @@ fn list_platform_browse_history_rows( let mut entries = ctx .db .user_browse_history() - .iter() - .filter(|row| row.user_id == validated_input.user_id) + .by_browse_history_user_id() + .filter(&validated_input.user_id) .map(|row| build_runtime_browse_history_snapshot_from_row(&row)) .collect::>(); @@ -165,8 +165,8 @@ fn clear_platform_browse_history_rows( let row_ids = ctx .db .user_browse_history() - .iter() - .filter(|row| row.user_id == validated_input.user_id) + .by_browse_history_user_id() + .filter(&validated_input.user_id) .map(|row| row.browse_history_id.clone()) .collect::>(); diff --git a/server-rs/crates/spacetime-module/src/runtime/profile.rs b/server-rs/crates/spacetime-module/src/runtime/profile.rs index c4ba135f..10f3c59e 100644 --- a/server-rs/crates/spacetime-module/src/runtime/profile.rs +++ b/server-rs/crates/spacetime-module/src/runtime/profile.rs @@ -1079,8 +1079,8 @@ pub(crate) fn list_profile_save_archive_rows( let mut entries = ctx .db .profile_save_archive() - .iter() - .filter(|row| row.user_id == validated_input.user_id) + .by_profile_save_archive_user_id() + .filter(&validated_input.user_id) .map(|row| build_profile_save_archive_snapshot_from_row(&row)) .collect::>(); @@ -1104,10 +1104,12 @@ pub(crate) fn resume_profile_save_archive_record( let archive = ctx .db .profile_save_archive() - .iter() - .find(|row| { - row.user_id == validated_input.user_id && row.world_key == validated_input.world_key - }) + .by_profile_save_archive_user_world_key() + .filter(( + validated_input.user_id.as_str(), + validated_input.world_key.as_str(), + )) + .next() .ok_or_else(|| "profile_save_archive 对应 world_key 不存在".to_string())?; let existing_snapshot = ctx @@ -2052,8 +2054,8 @@ fn get_profile_dashboard_snapshot( let played_world_count = ctx .db .profile_played_world() - .iter() - .filter(|row| row.user_id == validated_input.user_id) + .by_profile_played_world_user_id() + .filter(&validated_input.user_id) .count() as u32; Ok(match state { @@ -2084,8 +2086,8 @@ fn list_profile_wallet_ledger_entries( let mut entries = ctx .db .profile_wallet_ledger() - .iter() - .filter(|row| row.user_id == validated_input.user_id) + .by_profile_wallet_ledger_user_id() + .filter(&validated_input.user_id) .map(|row| build_profile_wallet_ledger_snapshot_from_row(&row)) .collect::>(); @@ -2114,8 +2116,8 @@ fn get_profile_play_stats_snapshot( let mut played_works = ctx .db .profile_played_world() - .iter() - .filter(|row| row.user_id == validated_input.user_id) + .by_profile_played_world_user_id() + .filter(&validated_input.user_id) .map(|row| build_profile_played_world_snapshot_from_row(&row)) .collect::>(); @@ -2727,17 +2729,16 @@ fn build_profile_referral_invite_center_snapshot( let code = ensure_profile_invite_code(ctx, user_id); let today_inviter_reward_count = count_today_profile_referral_inviter_rewards(ctx, user_id, ctx.timestamp); - let invited_count = ctx + let invited_relations = ctx .db .profile_referral_relation() + .by_profile_referral_inviter_user_id() + .filter(user_id) + .collect::>(); + let invited_count = invited_relations.len() as u32; + let rewarded_invite_count = invited_relations .iter() - .filter(|row| row.inviter_user_id == user_id) - .count() as u32; - let rewarded_invite_count = ctx - .db - .profile_referral_relation() - .iter() - .filter(|row| row.inviter_user_id == user_id && row.inviter_reward_granted) + .filter(|row| row.inviter_reward_granted) .count() as u32; let bound_relation = ctx .db @@ -2918,7 +2919,8 @@ fn count_today_profile_referral_inviter_rewards( let day_start_micros = runtime_profile_day_start_micros(now.to_micros_since_unix_epoch()); ctx.db .profile_wallet_ledger() - .iter() + .by_profile_wallet_ledger_user_id() + .filter(user_id) .filter(|row| { row.user_id == user_id && row.source_type == RuntimeProfileWalletLedgerSourceType::InviteInviterReward @@ -3422,7 +3424,11 @@ fn query_analytics_metric_buckets( let stats = ctx .db .tracking_daily_stat() - .iter() + .by_tracking_daily_stat_scope_day() + .filter(( + validated_input.scope_kind, + validated_input.scope_id.as_str(), + )) .filter(|row| { row.event_key.trim() == validated_input.event_key && row.scope_kind == validated_input.scope_kind @@ -4023,27 +4029,39 @@ fn apply_profile_wallet_signed_delta( } fn has_profile_points_recharged(ctx: &ReducerContext, user_id: &str) -> bool { - ctx.db.profile_recharge_order().iter().any(|row| { - row.user_id == user_id - && row.kind == RuntimeProfileRechargeProductKind::Points - && row.status == RuntimeProfileRechargeOrderStatus::Paid - }) + ctx.db + .profile_recharge_order() + .by_profile_recharge_order_user_id() + .filter(user_id) + .any(|row| { + row.user_id == user_id + && row.kind == RuntimeProfileRechargeProductKind::Points + && row.status == RuntimeProfileRechargeOrderStatus::Paid + }) } fn has_profile_product_recharged(ctx: &ReducerContext, user_id: &str, product_id: &str) -> bool { - ctx.db.profile_recharge_order().iter().any(|row| { - row.user_id == user_id - && row.product_id == product_id - && row.kind == RuntimeProfileRechargeProductKind::Points - && row.status == RuntimeProfileRechargeOrderStatus::Paid - }) + ctx.db + .profile_recharge_order() + .by_profile_recharge_order_user_id() + .filter(user_id) + .any(|row| { + row.user_id == user_id + && row.product_id == product_id + && row.kind == RuntimeProfileRechargeProductKind::Points + && row.status == RuntimeProfileRechargeOrderStatus::Paid + }) } fn has_profile_business_wallet_ledger(ctx: &ReducerContext, user_id: &str) -> bool { - ctx.db.profile_wallet_ledger().iter().any(|row| { - row.user_id == user_id - && row.source_type != RuntimeProfileWalletLedgerSourceType::SnapshotSync - }) + ctx.db + .profile_wallet_ledger() + .by_profile_wallet_ledger_user_id() + .filter(user_id) + .any(|row| { + row.user_id == user_id + && row.source_type != RuntimeProfileWalletLedgerSourceType::SnapshotSync + }) } fn latest_profile_recharge_order( @@ -4053,8 +4071,8 @@ fn latest_profile_recharge_order( let mut orders = ctx .db .profile_recharge_order() - .iter() - .filter(|row| row.user_id == user_id) + .by_profile_recharge_order_user_id() + .filter(user_id) .collect::>(); orders.sort_by(|left, right| { right diff --git a/server-rs/crates/spacetime-module/src/square_hole/mod.rs b/server-rs/crates/spacetime-module/src/square_hole/mod.rs index 8fb909e4..4358722a 100644 --- a/server-rs/crates/spacetime-module/src/square_hole/mod.rs +++ b/server-rs/crates/spacetime-module/src/square_hole/mod.rs @@ -171,12 +171,12 @@ pub fn list_square_hole_works( match ctx.try_with_tx(|tx| list_square_hole_works_tx(tx, input.clone())) { Ok(items) => SquareHoleWorksProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => SquareHoleWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -201,12 +201,12 @@ pub fn delete_square_hole_work( match ctx.try_with_tx(|tx| delete_square_hole_work_tx(tx, input.clone())) { Ok(items) => SquareHoleWorksProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => SquareHoleWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -244,8 +244,8 @@ pub fn drop_square_hole_shape( Err(message) => SquareHoleDropShapeProcedureResult { ok: false, status: SQUARE_HOLE_DROP_REJECTED.to_string(), - run_json: None, - feedback_json: None, + run: None, + feedback: None, failure_reason: None, error_message: Some(message), }, @@ -802,10 +802,8 @@ fn drop_square_hole_shape_tx( Ok(SquareHoleDropShapeProcedureResult { ok: true, status: status.to_string(), - run_json: Some(to_json_string(&next)), - feedback_json: Some(to_json_string(&feedback_from_domain( - &confirmation.feedback, - ))), + run: Some(next), + feedback: Some(feedback_from_domain(&confirmation.feedback)), failure_reason: confirmation .feedback .reject_reason @@ -1593,7 +1591,7 @@ fn session_result( ) -> SquareHoleAgentSessionProcedureResult { SquareHoleAgentSessionProcedureResult { ok: true, - session_json: Some(to_json_string(&session)), + session: Some(session), error_message: None, } } @@ -1601,7 +1599,7 @@ fn session_result( fn session_error(message: String) -> SquareHoleAgentSessionProcedureResult { SquareHoleAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), } } @@ -1609,7 +1607,7 @@ fn session_error(message: String) -> SquareHoleAgentSessionProcedureResult { fn work_result(work: SquareHoleWorkSnapshot) -> SquareHoleWorkProcedureResult { SquareHoleWorkProcedureResult { ok: true, - work_json: Some(to_json_string(&work)), + work: Some(work), error_message: None, } } @@ -1617,7 +1615,7 @@ fn work_result(work: SquareHoleWorkSnapshot) -> SquareHoleWorkProcedureResult { fn work_error(message: String) -> SquareHoleWorkProcedureResult { SquareHoleWorkProcedureResult { ok: false, - work_json: None, + work: None, error_message: Some(message), } } @@ -1625,7 +1623,7 @@ fn work_error(message: String) -> SquareHoleWorkProcedureResult { fn run_result(run: SquareHoleRunSnapshot) -> SquareHoleRunProcedureResult { SquareHoleRunProcedureResult { ok: true, - run_json: Some(to_json_string(&run)), + run: Some(run), error_message: None, } } @@ -1633,7 +1631,7 @@ fn run_result(run: SquareHoleRunSnapshot) -> SquareHoleRunProcedureResult { fn run_error(message: String) -> SquareHoleRunProcedureResult { SquareHoleRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), } } diff --git a/server-rs/crates/spacetime-module/src/square_hole/types.rs b/server-rs/crates/spacetime-module/src/square_hole/types.rs index ae8a1766..70a86c66 100644 --- a/server-rs/crates/spacetime-module/src/square_hole/types.rs +++ b/server-rs/crates/spacetime-module/src/square_hole/types.rs @@ -168,42 +168,42 @@ pub struct SquareHoleRunTimeUpInput { #[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] pub struct SquareHoleAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } #[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] pub struct SquareHoleWorkProcedureResult { pub ok: bool, - pub work_json: Option, + pub work: Option, pub error_message: Option, } #[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] pub struct SquareHoleWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct SquareHoleRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct SquareHoleDropShapeProcedureResult { pub ok: bool, pub status: String, - pub run_json: Option, - pub feedback_json: Option, + pub run: Option, + pub feedback: Option, pub failure_reason: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleCreatorConfigSnapshot { pub theme_text: String, @@ -222,7 +222,7 @@ pub struct SquareHoleCreatorConfigSnapshot { pub background_image_src: String, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleShapeOptionSnapshot { pub option_id: String, @@ -235,7 +235,7 @@ pub struct SquareHoleShapeOptionSnapshot { pub image_src: String, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleHoleOptionSnapshot { pub hole_id: String, @@ -247,7 +247,7 @@ pub struct SquareHoleHoleOptionSnapshot { pub image_src: String, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleAgentMessageSnapshot { pub message_id: String, @@ -258,7 +258,7 @@ pub struct SquareHoleAgentMessageSnapshot { pub created_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleDraftSnapshot { pub profile_id: String, @@ -281,7 +281,7 @@ pub struct SquareHoleDraftSnapshot { pub difficulty: u32, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleAgentSessionSnapshot { pub session_id: String, @@ -299,7 +299,7 @@ pub struct SquareHoleAgentSessionSnapshot { pub updated_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleWorkSnapshot { pub work_id: String, @@ -331,7 +331,7 @@ pub struct SquareHoleWorkSnapshot { pub published_at_micros: Option, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleShapeSnapshot { pub shape_id: String, @@ -344,7 +344,7 @@ pub struct SquareHoleShapeSnapshot { pub image_src: String, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleHoleSnapshot { pub hole_id: String, @@ -356,7 +356,7 @@ pub struct SquareHoleHoleSnapshot { pub image_src: String, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleDropFeedbackSnapshot { pub accepted: bool, @@ -364,7 +364,7 @@ pub struct SquareHoleDropFeedbackSnapshot { pub message: String, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct SquareHoleRunSnapshot { pub run_id: String, diff --git a/server-rs/crates/spacetime-module/src/visual_novel.rs b/server-rs/crates/spacetime-module/src/visual_novel.rs index 2fe82fa7..f377e312 100644 --- a/server-rs/crates/spacetime-module/src/visual_novel.rs +++ b/server-rs/crates/spacetime-module/src/visual_novel.rs @@ -379,49 +379,65 @@ pub struct VisualNovelRuntimeEventRecordInput { pub occurred_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct VisualNovelAgentSessionProcedureResult { pub ok: bool, - pub session_json: Option, + pub session: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct VisualNovelWorkProcedureResult { pub ok: bool, - pub work_json: Option, + pub work: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct VisualNovelWorksProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct VisualNovelRunProcedureResult { pub ok: bool, - pub run_json: Option, + pub run: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct VisualNovelHistoryProcedureResult { pub ok: bool, - pub items_json: Option, + pub items: Vec, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)] +#[derive(Clone, Debug, PartialEq, SpacetimeType)] pub struct VisualNovelRuntimeEventProcedureResult { pub ok: bool, - pub event_json: Option, + pub event: Option, pub error_message: Option, } -#[derive(Clone, Debug, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] +pub struct VisualNovelJsonField { + pub key: String, + pub value: VisualNovelJsonValue, +} + +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] +pub enum VisualNovelJsonValue { + Null, + Bool(bool), + Number(f64), + String(String), + Array(Vec), + Object(Vec), +} + +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct VisualNovelAgentMessageSnapshot { pub message_id: String, @@ -432,7 +448,7 @@ pub struct VisualNovelAgentMessageSnapshot { pub created_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct VisualNovelAgentSessionSnapshot { pub session_id: String, @@ -444,15 +460,15 @@ pub struct VisualNovelAgentSessionSnapshot { pub current_turn: u32, pub progress_percent: u32, pub messages: Vec, - pub draft: Option, - pub pending_action: Option, + pub draft: Option, + pub pending_action: Option, pub last_assistant_reply: Option, pub published_profile_id: Option, pub created_at_micros: i64, pub updated_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct VisualNovelWorkSnapshot { pub work_id: String, @@ -465,7 +481,7 @@ pub struct VisualNovelWorkSnapshot { pub tags: Vec, pub cover_image_src: Option, pub source_asset_ids: Vec, - pub draft: JsonValue, + pub draft: VisualNovelJsonValue, pub publication_status: String, pub publish_ready: bool, pub play_count: u32, @@ -474,7 +490,7 @@ pub struct VisualNovelWorkSnapshot { pub published_at_micros: Option, } -#[derive(Clone, Debug, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct VisualNovelRuntimeHistoryEntrySnapshot { pub entry_id: String, @@ -484,13 +500,13 @@ pub struct VisualNovelRuntimeHistoryEntrySnapshot { pub turn_index: u32, pub source: String, pub action_text: Option, - pub steps: JsonValue, + pub steps: VisualNovelJsonValue, pub snapshot_before_hash: Option, pub snapshot_after_hash: Option, pub created_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct VisualNovelRunSnapshot { pub run_id: String, @@ -501,16 +517,16 @@ pub struct VisualNovelRunSnapshot { pub current_scene_id: Option, pub current_phase_id: Option, pub visible_character_ids: Vec, - pub flags: JsonValue, - pub metrics: JsonValue, + pub flags: VisualNovelJsonValue, + pub metrics: VisualNovelJsonValue, pub history: Vec, - pub available_choices: JsonValue, + pub available_choices: VisualNovelJsonValue, pub text_mode_enabled: bool, pub created_at_micros: i64, pub updated_at_micros: i64, } -#[derive(Clone, Debug, PartialEq, Serialize)] +#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)] #[serde(rename_all = "camelCase")] pub struct VisualNovelRuntimeEventSnapshot { pub event_id: String, @@ -520,7 +536,7 @@ pub struct VisualNovelRuntimeEventSnapshot { pub event_kind: String, pub client_event_id: Option, pub history_entry_id: Option, - pub payload: JsonValue, + pub payload: VisualNovelJsonValue, pub occurred_at_micros: i64, } @@ -609,12 +625,12 @@ pub fn list_visual_novel_works( match ctx.try_with_tx(|tx| list_visual_novel_works_tx(tx, input.clone())) { Ok(items) => VisualNovelWorksProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => VisualNovelWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -639,12 +655,12 @@ pub fn delete_visual_novel_work( match ctx.try_with_tx(|tx| delete_visual_novel_work_tx(tx, input.clone())) { Ok(items) => VisualNovelWorksProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => VisualNovelWorksProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -691,12 +707,12 @@ pub fn append_visual_novel_runtime_history_entry( match ctx.try_with_tx(|tx| append_visual_novel_runtime_history_entry_tx(tx, input.clone())) { Ok(items) => VisualNovelHistoryProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => VisualNovelHistoryProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -710,12 +726,12 @@ pub fn list_visual_novel_runtime_history( match ctx.try_with_tx(|tx| list_visual_novel_runtime_history_tx(tx, input.clone())) { Ok(items) => VisualNovelHistoryProcedureResult { ok: true, - items_json: Some(to_json_string(&items)), + items, error_message: None, }, Err(message) => VisualNovelHistoryProcedureResult { ok: false, - items_json: None, + items: Vec::new(), error_message: Some(message), }, } @@ -729,12 +745,12 @@ pub fn record_visual_novel_runtime_event( match ctx.try_with_tx(|tx| record_visual_novel_runtime_event_tx(tx, input.clone())) { Ok(event) => VisualNovelRuntimeEventProcedureResult { ok: true, - event_json: Some(to_json_string(&event)), + event: Some(event), error_message: None, }, Err(message) => VisualNovelRuntimeEventProcedureResult { ok: false, - event_json: None, + event: None, error_message: Some(message), }, } @@ -1105,17 +1121,22 @@ fn list_visual_novel_works_tx( ctx: &ReducerContext, input: VisualNovelWorksListInput, ) -> Result, String> { - let mut items = ctx - .db - .visual_novel_work_profile() + let rows = if input.published_only { + ctx.db + .visual_novel_work_profile() + .by_visual_novel_work_publication_status() + .filter(&VISUAL_NOVEL_PUBLICATION_PUBLISHED.to_string()) + .collect::>() + } else { + require_non_empty(&input.owner_user_id, "visual_novel owner_user_id")?; + ctx.db + .visual_novel_work_profile() + .by_visual_novel_work_owner_user_id() + .filter(&input.owner_user_id) + .collect::>() + }; + let mut items = rows .iter() - .filter(|row| { - if input.published_only { - row.publication_status == VISUAL_NOVEL_PUBLICATION_PUBLISHED - } else { - row.owner_user_id == input.owner_user_id - } - }) .map(|row| build_work_snapshot(&row)) .collect::, _>>()?; items.sort_by(|left, right| { @@ -1156,10 +1177,9 @@ fn delete_visual_novel_work_tx( for run in ctx .db .visual_novel_runtime_run() - .iter() - .filter(|row| { - row.profile_id == input.profile_id && row.owner_user_id == input.owner_user_id - }) + .by_visual_novel_run_profile_id() + .filter(&input.profile_id) + .filter(|row| row.owner_user_id == input.owner_user_id) .collect::>() { delete_run_children(ctx, &run.run_id, &input.owner_user_id); @@ -1438,8 +1458,8 @@ fn build_session_snapshot( let mut messages = ctx .db .visual_novel_agent_message() - .iter() - .filter(|message| message.session_id == row.session_id) + .by_visual_novel_agent_message_session_id() + .filter(&row.session_id) .map(|message| VisualNovelAgentMessageSnapshot { message_id: message.message_id, session_id: message.session_id, @@ -1465,8 +1485,9 @@ fn build_session_snapshot( current_turn: row.current_turn, progress_percent: row.progress_percent, messages, - draft: parse_optional_json_value(&row.draft_json)?, - pending_action: parse_optional_json_value(&row.pending_action_json)?, + draft: parse_optional_json_value(&row.draft_json)?.map(visual_novel_json_from_serde), + pending_action: parse_optional_json_value(&row.pending_action_json)? + .map(visual_novel_json_from_serde), last_assistant_reply: empty_to_none(&row.last_assistant_reply), published_profile_id: empty_to_none(&row.published_profile_id), created_at_micros: row.created_at.to_micros_since_unix_epoch(), @@ -1486,7 +1507,7 @@ fn build_work_snapshot(row: &VisualNovelWorkProfileRow) -> Result, _>>()?; items.sort_by(|left, right| { @@ -1578,7 +1602,7 @@ fn build_history_snapshot( turn_index: row.turn_index, source: row.source.clone(), action_text: empty_to_none(&row.action_text), - steps: parse_json_value_or_array(&row.steps_json)?, + steps: visual_novel_json_from_serde(parse_json_value_or_array(&row.steps_json)?), snapshot_before_hash: empty_to_none(&row.snapshot_before_hash), snapshot_after_hash: empty_to_none(&row.snapshot_after_hash), created_at_micros: row.created_at.to_micros_since_unix_epoch(), @@ -1596,7 +1620,7 @@ fn build_event_snapshot( event_kind: row.event_kind.clone(), client_event_id: empty_to_none(&row.client_event_id), history_entry_id: empty_to_none(&row.history_entry_id), - payload: parse_json_value_or_object(&row.payload_json)?, + payload: visual_novel_json_from_serde(parse_json_value_or_object(&row.payload_json)?), occurred_at_micros: row.occurred_at.to_micros_since_unix_epoch(), }) } @@ -1657,8 +1681,9 @@ fn delete_run_children(ctx: &ReducerContext, run_id: &str, owner_user_id: &str) for history in ctx .db .visual_novel_runtime_history_entry() - .iter() - .filter(|row| row.run_id == run_id && row.owner_user_id == owner_user_id) + .by_visual_novel_history_run_id() + .filter(&run_id.to_string()) + .filter(|row| row.owner_user_id == owner_user_id) .collect::>() { ctx.db @@ -1836,6 +1861,30 @@ fn parse_json_value_or_array(value: &str) -> Result { parse_json_value(value) } +fn visual_novel_json_from_serde(value: JsonValue) -> VisualNovelJsonValue { + match value { + JsonValue::Null => VisualNovelJsonValue::Null, + JsonValue::Bool(value) => VisualNovelJsonValue::Bool(value), + JsonValue::Number(value) => VisualNovelJsonValue::Number(value.as_f64().unwrap_or(0.0)), + JsonValue::String(value) => VisualNovelJsonValue::String(value), + JsonValue::Array(items) => VisualNovelJsonValue::Array( + items + .into_iter() + .map(visual_novel_json_from_serde) + .collect(), + ), + JsonValue::Object(object) => VisualNovelJsonValue::Object( + object + .into_iter() + .map(|(key, value)| VisualNovelJsonField { + key, + value: visual_novel_json_from_serde(value), + }) + .collect(), + ), + } +} + fn draft_string_field(draft: &JsonValue, key: &str) -> Option { draft .get(key) @@ -1931,7 +1980,7 @@ fn session_result( ) -> VisualNovelAgentSessionProcedureResult { VisualNovelAgentSessionProcedureResult { ok: true, - session_json: Some(to_json_string(&session)), + session: Some(session), error_message: None, } } @@ -1939,7 +1988,7 @@ fn session_result( fn session_error(message: String) -> VisualNovelAgentSessionProcedureResult { VisualNovelAgentSessionProcedureResult { ok: false, - session_json: None, + session: None, error_message: Some(message), } } @@ -1947,7 +1996,7 @@ fn session_error(message: String) -> VisualNovelAgentSessionProcedureResult { fn work_result(work: VisualNovelWorkSnapshot) -> VisualNovelWorkProcedureResult { VisualNovelWorkProcedureResult { ok: true, - work_json: Some(to_json_string(&work)), + work: Some(work), error_message: None, } } @@ -1955,7 +2004,7 @@ fn work_result(work: VisualNovelWorkSnapshot) -> VisualNovelWorkProcedureResult fn work_error(message: String) -> VisualNovelWorkProcedureResult { VisualNovelWorkProcedureResult { ok: false, - work_json: None, + work: None, error_message: Some(message), } } @@ -1963,7 +2012,7 @@ fn work_error(message: String) -> VisualNovelWorkProcedureResult { fn run_result(run: VisualNovelRunSnapshot) -> VisualNovelRunProcedureResult { VisualNovelRunProcedureResult { ok: true, - run_json: Some(to_json_string(&run)), + run: Some(run), error_message: None, } } @@ -1971,7 +2020,7 @@ fn run_result(run: VisualNovelRunSnapshot) -> VisualNovelRunProcedureResult { fn run_error(message: String) -> VisualNovelRunProcedureResult { VisualNovelRunProcedureResult { ok: false, - run_json: None, + run: None, error_message: Some(message), } }