Codex worktree snapshot: settings-delete-targeted

Co-authored-by: Codex
This commit is contained in:
kdletters
2026-05-16 22:52:10 +08:00
parent 7f16e88e57
commit 01af298c07
115 changed files with 2831 additions and 1324 deletions

View File

@@ -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::<Vec<_>>();
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::<Vec<_>>();
result_references.sort_by_key(|reference| reference.created_at_micros);

View File

@@ -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::<Vec<_>>();
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::<Vec<_>>();

View File

@@ -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) => {

View File

@@ -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,

View File

@@ -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<T: DeserializeOwned>(value: &str, field_name: &str) -> Result<(
.map_err(|error| format!("bark_battle {field_name} JSON 无效: {error}"))
}
fn bark_battle_json_result<T: Serialize>(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<T: Serialize>(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,
};

View File

@@ -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<String>,
pub draft_config: Option<BarkBattleDraftConfigSnapshot>,
pub runtime_config: Option<BarkBattleRuntimeConfigSnapshot>,
pub run: Option<BarkBattleRunSnapshot>,
pub error_message: Option<String>,
}
#[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,

View File

@@ -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,

View File

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

View File

@@ -55,21 +55,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),
},
}
@@ -81,21 +74,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),
},
}
@@ -107,21 +93,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),
},
}
@@ -133,21 +112,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),
},
}
@@ -321,16 +293,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::<Vec<_>>();
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::<Result<Vec<_>, _>>()?;
@@ -349,10 +325,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 {
@@ -387,8 +364,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::<Vec<_>>()
{
ctx.db
@@ -399,8 +376,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::<Vec<_>>()
{
ctx.db.big_fish_asset_slot().slot_id().delete(&slot.slot_id);
@@ -408,8 +385,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::<Vec<_>>()
{
ctx.db.big_fish_runtime_run().run_id().delete(&run.run_id);
@@ -952,8 +929,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,

View File

@@ -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::<Vec<_>>()
{
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::<Vec<_>>()
{
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::<Vec<_>>()
{
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::<Vec<_>>();
@@ -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::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
operations

View File

@@ -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::<Vec<_>>();
@@ -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::<Vec<_>>();
@@ -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::<Vec<_>>();
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))
}

View File

@@ -105,12 +105,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),
},
}
@@ -135,12 +135,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),
},
}
@@ -178,7 +178,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,
@@ -632,17 +632,22 @@ fn list_match3d_works_tx(
ctx: &ReducerContext,
input: Match3DWorksListInput,
) -> Result<Vec<Match3DWorkSnapshot>, 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::<Vec<_>>()
} 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::<Vec<_>>()
};
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::<Result<Vec<_>, _>>()?;
items.sort_by(|left, right| {
@@ -683,10 +688,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::<Vec<_>>()
{
ctx.db.match3d_runtime_run().run_id().delete(&run.run_id);
@@ -929,8 +933,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,
@@ -1154,10 +1158,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,
}
}
@@ -1715,7 +1719,7 @@ fn to_json_string<T: Serialize>(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,
}
}
@@ -1723,7 +1727,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),
}
}
@@ -1731,7 +1735,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,
}
}
@@ -1739,7 +1743,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),
}
}
@@ -1747,7 +1751,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,
}
}
@@ -1755,7 +1759,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),
}
}

View File

@@ -182,43 +182,43 @@ pub struct Match3DRunTimeUpInput {
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct Match3DAgentSessionProcedureResult {
pub ok: bool,
pub session_json: Option<String>,
pub session: Option<Match3DAgentSessionSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct Match3DWorkProcedureResult {
pub ok: bool,
pub work_json: Option<String>,
pub work: Option<Match3DWorkSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct Match3DWorksProcedureResult {
pub ok: bool,
pub items_json: Option<String>,
pub items: Vec<Match3DWorkSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct Match3DRunProcedureResult {
pub ok: bool,
pub run_json: Option<String>,
pub run: Option<Match3DRunSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct Match3DClickItemProcedureResult {
pub ok: bool,
pub status: String,
pub run_json: Option<String>,
pub run: Option<Match3DRunSnapshot>,
pub accepted_item_instance_id: Option<String>,
pub cleared_item_instance_ids: Vec<String>,
pub failure_reason: Option<String>,
pub error_message: Option<String>,
}
#[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,
@@ -258,7 +258,7 @@ pub struct Match3DDraftSnapshot {
pub difficulty: u32,
}
#[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,
@@ -276,7 +276,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,
@@ -300,7 +300,7 @@ pub struct Match3DWorkSnapshot {
pub generated_item_assets_json: Option<String>,
}
#[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,
@@ -314,7 +314,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,
@@ -323,7 +323,7 @@ pub struct Match3DTraySlotSnapshot {
pub visual_key: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, SpacetimeType)]
#[serde(rename_all = "camelCase")]
pub struct Match3DRunSnapshot {
pub run_id: String,

View File

@@ -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::<Vec<_>>();
@@ -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::<Vec<_>>();

View File

@@ -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::<Vec<_>>();
@@ -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::<Vec<_>>();
@@ -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::<Vec<_>>();
@@ -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::<Vec<_>>();
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::<Vec<_>>();
orders.sort_by(|left, right| {
right

View File

@@ -112,12 +112,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),
},
}
@@ -142,12 +142,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),
},
}
@@ -185,8 +185,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),
},
@@ -743,10 +743,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
@@ -1502,7 +1500,7 @@ fn session_result(
) -> SquareHoleAgentSessionProcedureResult {
SquareHoleAgentSessionProcedureResult {
ok: true,
session_json: Some(to_json_string(&session)),
session: Some(session),
error_message: None,
}
}
@@ -1510,7 +1508,7 @@ fn session_result(
fn session_error(message: String) -> SquareHoleAgentSessionProcedureResult {
SquareHoleAgentSessionProcedureResult {
ok: false,
session_json: None,
session: None,
error_message: Some(message),
}
}
@@ -1518,7 +1516,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,
}
}
@@ -1526,7 +1524,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),
}
}
@@ -1534,7 +1532,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,
}
}
@@ -1542,7 +1540,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),
}
}

View File

@@ -168,42 +168,42 @@ pub struct SquareHoleRunTimeUpInput {
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct SquareHoleAgentSessionProcedureResult {
pub ok: bool,
pub session_json: Option<String>,
pub session: Option<SquareHoleAgentSessionSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct SquareHoleWorkProcedureResult {
pub ok: bool,
pub work_json: Option<String>,
pub work: Option<SquareHoleWorkSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
pub struct SquareHoleWorksProcedureResult {
pub ok: bool,
pub items_json: Option<String>,
pub items: Vec<SquareHoleWorkSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct SquareHoleRunProcedureResult {
pub ok: bool,
pub run_json: Option<String>,
pub run: Option<SquareHoleRunSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct SquareHoleDropShapeProcedureResult {
pub ok: bool,
pub status: String,
pub run_json: Option<String>,
pub feedback_json: Option<String>,
pub run: Option<SquareHoleRunSnapshot>,
pub feedback: Option<SquareHoleDropFeedbackSnapshot>,
pub failure_reason: Option<String>,
pub error_message: Option<String>,
}
#[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, 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, 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<i64>,
}
#[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,

View File

@@ -326,49 +326,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<String>,
pub session: Option<VisualNovelAgentSessionSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct VisualNovelWorkProcedureResult {
pub ok: bool,
pub work_json: Option<String>,
pub work: Option<VisualNovelWorkSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct VisualNovelWorksProcedureResult {
pub ok: bool,
pub items_json: Option<String>,
pub items: Vec<VisualNovelWorkSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct VisualNovelRunProcedureResult {
pub ok: bool,
pub run_json: Option<String>,
pub run: Option<VisualNovelRunSnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct VisualNovelHistoryProcedureResult {
pub ok: bool,
pub items_json: Option<String>,
pub items: Vec<VisualNovelRuntimeHistoryEntrySnapshot>,
pub error_message: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
pub struct VisualNovelRuntimeEventProcedureResult {
pub ok: bool,
pub event_json: Option<String>,
pub event: Option<VisualNovelRuntimeEventSnapshot>,
pub error_message: Option<String>,
}
#[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<VisualNovelJsonValue>),
Object(Vec<VisualNovelJsonField>),
}
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
#[serde(rename_all = "camelCase")]
pub struct VisualNovelAgentMessageSnapshot {
pub message_id: String,
@@ -379,7 +395,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,
@@ -391,15 +407,15 @@ pub struct VisualNovelAgentSessionSnapshot {
pub current_turn: u32,
pub progress_percent: u32,
pub messages: Vec<VisualNovelAgentMessageSnapshot>,
pub draft: Option<JsonValue>,
pub pending_action: Option<JsonValue>,
pub draft: Option<VisualNovelJsonValue>,
pub pending_action: Option<VisualNovelJsonValue>,
pub last_assistant_reply: Option<String>,
pub published_profile_id: Option<String>,
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,
@@ -412,7 +428,7 @@ pub struct VisualNovelWorkSnapshot {
pub tags: Vec<String>,
pub cover_image_src: Option<String>,
pub source_asset_ids: Vec<String>,
pub draft: JsonValue,
pub draft: VisualNovelJsonValue,
pub publication_status: String,
pub publish_ready: bool,
pub play_count: u32,
@@ -421,7 +437,7 @@ pub struct VisualNovelWorkSnapshot {
pub published_at_micros: Option<i64>,
}
#[derive(Clone, Debug, PartialEq, Serialize)]
#[derive(Clone, Debug, PartialEq, Serialize, SpacetimeType)]
#[serde(rename_all = "camelCase")]
pub struct VisualNovelRuntimeHistoryEntrySnapshot {
pub entry_id: String,
@@ -431,13 +447,13 @@ pub struct VisualNovelRuntimeHistoryEntrySnapshot {
pub turn_index: u32,
pub source: String,
pub action_text: Option<String>,
pub steps: JsonValue,
pub steps: VisualNovelJsonValue,
pub snapshot_before_hash: Option<String>,
pub snapshot_after_hash: Option<String>,
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,
@@ -448,16 +464,16 @@ pub struct VisualNovelRunSnapshot {
pub current_scene_id: Option<String>,
pub current_phase_id: Option<String>,
pub visible_character_ids: Vec<String>,
pub flags: JsonValue,
pub metrics: JsonValue,
pub flags: VisualNovelJsonValue,
pub metrics: VisualNovelJsonValue,
pub history: Vec<VisualNovelRuntimeHistoryEntrySnapshot>,
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,
@@ -467,7 +483,7 @@ pub struct VisualNovelRuntimeEventSnapshot {
pub event_kind: String,
pub client_event_id: Option<String>,
pub history_entry_id: Option<String>,
pub payload: JsonValue,
pub payload: VisualNovelJsonValue,
pub occurred_at_micros: i64,
}
@@ -556,12 +572,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),
},
}
@@ -586,12 +602,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),
},
}
@@ -638,12 +654,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),
},
}
@@ -657,12 +673,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),
},
}
@@ -676,12 +692,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),
},
}
@@ -1052,17 +1068,22 @@ fn list_visual_novel_works_tx(
ctx: &ReducerContext,
input: VisualNovelWorksListInput,
) -> Result<Vec<VisualNovelWorkSnapshot>, 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::<Vec<_>>()
} 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::<Vec<_>>()
};
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::<Result<Vec<_>, _>>()?;
items.sort_by(|left, right| {
@@ -1103,10 +1124,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::<Vec<_>>()
{
delete_run_children(ctx, &run.run_id, &input.owner_user_id);
@@ -1385,8 +1405,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,
@@ -1412,8 +1432,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(),
@@ -1433,7 +1454,7 @@ fn build_work_snapshot(row: &VisualNovelWorkProfileRow) -> Result<VisualNovelWor
tags: parse_string_vec_or_empty(&row.tags_json)?,
cover_image_src: empty_to_none(&row.cover_image_src),
source_asset_ids: parse_string_vec_or_empty(&row.source_asset_ids_json)?,
draft: parse_json_value(&row.draft_json)?,
draft: visual_novel_json_from_serde(parse_json_value(&row.draft_json)?),
publication_status: row.publication_status.clone(),
publish_ready: row.publish_ready,
play_count: row.play_count,
@@ -1458,10 +1479,12 @@ fn build_run_snapshot(
current_scene_id: empty_to_none(&row.current_scene_id),
current_phase_id: empty_to_none(&row.current_phase_id),
visible_character_ids: parse_string_vec_or_empty(&row.visible_character_ids_json)?,
flags: parse_json_value_or_object(&row.flags_json)?,
metrics: parse_json_value_or_object(&row.metrics_json)?,
flags: visual_novel_json_from_serde(parse_json_value_or_object(&row.flags_json)?),
metrics: visual_novel_json_from_serde(parse_json_value_or_object(&row.metrics_json)?),
history: build_history_snapshots(ctx, &row.run_id, &row.owner_user_id)?,
available_choices: parse_json_value_or_array(&row.available_choices_json)?,
available_choices: visual_novel_json_from_serde(parse_json_value_or_array(
&row.available_choices_json,
)?),
text_mode_enabled: row.text_mode_enabled,
created_at_micros: row.created_at.to_micros_since_unix_epoch(),
updated_at_micros: row.updated_at.to_micros_since_unix_epoch(),
@@ -1476,8 +1499,9 @@ fn build_history_snapshots(
let mut items = 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)
.map(|row| build_history_snapshot(&row))
.collect::<Result<Vec<_>, _>>()?;
items.sort_by(|left, right| {
@@ -1500,7 +1524,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(),
@@ -1518,7 +1542,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(),
})
}
@@ -1579,8 +1603,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::<Vec<_>>()
{
ctx.db
@@ -1758,6 +1783,30 @@ fn parse_json_value_or_array(value: &str) -> Result<JsonValue, String> {
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<String> {
draft
.get(key)
@@ -1853,7 +1902,7 @@ fn session_result(
) -> VisualNovelAgentSessionProcedureResult {
VisualNovelAgentSessionProcedureResult {
ok: true,
session_json: Some(to_json_string(&session)),
session: Some(session),
error_message: None,
}
}
@@ -1861,7 +1910,7 @@ fn session_result(
fn session_error(message: String) -> VisualNovelAgentSessionProcedureResult {
VisualNovelAgentSessionProcedureResult {
ok: false,
session_json: None,
session: None,
error_message: Some(message),
}
}
@@ -1869,7 +1918,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,
}
}
@@ -1877,7 +1926,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),
}
}
@@ -1885,7 +1934,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,
}
}
@@ -1893,7 +1942,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),
}
}