fix(jump-hop): isolate draft runs from public leaderboard
This commit is contained in:
@@ -52,6 +52,7 @@ pub fn jump_hop_gallery_card_view(ctx: &AnonymousViewContext) -> Vec<JumpHopGall
|
||||
profile_id: row.profile_id,
|
||||
owner_user_id: row.owner_user_id,
|
||||
author_display_name: row.author_display_name,
|
||||
theme_text: row.theme_text,
|
||||
work_title: row.work_title,
|
||||
work_description: row.work_description,
|
||||
theme_tags: row.theme_tags,
|
||||
@@ -74,6 +75,7 @@ pub struct JumpHopGalleryViewRow {
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: String,
|
||||
pub author_display_name: String,
|
||||
pub theme_text: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
@@ -103,6 +105,7 @@ pub struct JumpHopGalleryCardViewRow {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub author_display_name: String,
|
||||
pub theme_text: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
@@ -295,6 +298,7 @@ fn create_jump_hop_agent_session_tx(
|
||||
template_id: JUMP_HOP_TEMPLATE_ID.to_string(),
|
||||
template_name: JUMP_HOP_TEMPLATE_NAME.to_string(),
|
||||
profile_id: None,
|
||||
theme_text: config.theme_text.clone(),
|
||||
work_title: input.work_title.clone(),
|
||||
work_description: input.work_description.clone(),
|
||||
theme_tags: parse_tags(input.theme_tags_json.as_deref().unwrap_or("[]"))?,
|
||||
@@ -360,6 +364,7 @@ fn compile_jump_hop_draft_tx(
|
||||
template_id: JUMP_HOP_TEMPLATE_ID.to_string(),
|
||||
template_name: JUMP_HOP_TEMPLATE_NAME.to_string(),
|
||||
profile_id: Some(input.profile_id.clone()),
|
||||
theme_text: clean_string(&config.theme_text, &input.work_title),
|
||||
work_title: clean_string(&input.work_title, "跳一跳作品"),
|
||||
work_description: input.work_description.trim().to_string(),
|
||||
theme_tags: tags.clone(),
|
||||
@@ -426,6 +431,7 @@ fn compile_jump_hop_draft_tx(
|
||||
updated_at: compiled_at,
|
||||
published_at: None,
|
||||
visible: true,
|
||||
theme_text: Some(draft.theme_text.clone()),
|
||||
};
|
||||
upsert_work(ctx, row);
|
||||
replace_session(
|
||||
@@ -567,6 +573,9 @@ fn start_jump_hop_run_tx(
|
||||
require_non_empty(&input.run_id, "jump_hop run_id")?;
|
||||
let work = find_work(ctx, &input.profile_id)?;
|
||||
let runtime_mode = normalize_runtime_mode(&input.runtime_mode);
|
||||
if runtime_mode == JUMP_HOP_RUNTIME_MODE_DRAFT && work.owner_user_id != input.owner_user_id {
|
||||
return Err("jump_hop draft runtime 只能由作品所有者启动".to_string());
|
||||
}
|
||||
if runtime_mode == JUMP_HOP_RUNTIME_MODE_PUBLISHED
|
||||
&& work.publication_status != JUMP_HOP_PUBLICATION_PUBLISHED
|
||||
{
|
||||
@@ -582,7 +591,7 @@ fn start_jump_hop_run_tx(
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let snapshot = domain_run;
|
||||
upsert_run(ctx, &snapshot, input.started_at_ms);
|
||||
upsert_run(ctx, &snapshot, input.started_at_ms, runtime_mode);
|
||||
if runtime_mode == JUMP_HOP_RUNTIME_MODE_PUBLISHED {
|
||||
increment_work_play_count(ctx, &work, input.started_at_ms);
|
||||
}
|
||||
@@ -623,7 +632,10 @@ fn jump_hop_jump_tx(
|
||||
.map_err(|error| error.to_string())?;
|
||||
let next = domain_next;
|
||||
replace_run(ctx, &row, &next, input.jumped_at_ms);
|
||||
if next.status == module_jump_hop::JumpHopRunStatus::Failed {
|
||||
if next.status == module_jump_hop::JumpHopRunStatus::Failed
|
||||
&& normalize_runtime_mode(row.runtime_mode.as_deref().unwrap_or_default())
|
||||
== JUMP_HOP_RUNTIME_MODE_PUBLISHED
|
||||
{
|
||||
upsert_jump_hop_leaderboard_entry(ctx, &next, input.jumped_at_ms);
|
||||
}
|
||||
insert_event(
|
||||
@@ -654,7 +666,10 @@ fn get_jump_hop_leaderboard_tx(
|
||||
String,
|
||||
> {
|
||||
require_non_empty(&input.profile_id, "jump_hop profile_id")?;
|
||||
let _ = find_work(ctx, &input.profile_id)?;
|
||||
let work = find_work(ctx, &input.profile_id)?;
|
||||
if work.publication_status != JUMP_HOP_PUBLICATION_PUBLISHED {
|
||||
return Err("jump_hop leaderboard 只开放已发布作品".to_string());
|
||||
}
|
||||
let limit = input.limit.clamp(1, 50) as usize;
|
||||
let mut rows = ctx
|
||||
.db
|
||||
@@ -696,7 +711,8 @@ fn restart_jump_hop_run_tx(
|
||||
)
|
||||
.map_err(|error| error.to_string())?;
|
||||
let next = domain_next;
|
||||
upsert_run(ctx, &next, input.restarted_at_ms);
|
||||
let runtime_mode = normalize_runtime_mode(source.runtime_mode.as_deref().unwrap_or_default());
|
||||
upsert_run(ctx, &next, input.restarted_at_ms, runtime_mode);
|
||||
insert_event(
|
||||
ctx,
|
||||
input.client_action_id,
|
||||
@@ -718,6 +734,7 @@ fn build_gallery_view_row(row: &JumpHopWorkProfileRow) -> Result<JumpHopGalleryV
|
||||
owner_user_id: work.owner_user_id,
|
||||
source_session_id: work.source_session_id,
|
||||
author_display_name: work.author_display_name,
|
||||
theme_text: work.theme_text,
|
||||
work_title: work.work_title,
|
||||
work_description: work.work_description,
|
||||
theme_tags: work.theme_tags,
|
||||
@@ -783,12 +800,18 @@ fn build_session_snapshot(
|
||||
|
||||
fn build_work_snapshot(row: &JumpHopWorkProfileRow) -> Result<JumpHopWorkSnapshot, String> {
|
||||
let path = parse_json(&row.path_json)?;
|
||||
let theme_text = row
|
||||
.theme_text
|
||||
.as_deref()
|
||||
.and_then(clean_optional)
|
||||
.unwrap_or_else(|| row.work_title.trim().to_string());
|
||||
Ok(JumpHopWorkSnapshot {
|
||||
work_id: row.work_id.clone(),
|
||||
profile_id: row.profile_id.clone(),
|
||||
owner_user_id: row.owner_user_id.clone(),
|
||||
source_session_id: row.source_session_id.clone(),
|
||||
author_display_name: row.author_display_name.clone(),
|
||||
theme_text,
|
||||
work_title: row.work_title.clone(),
|
||||
work_description: row.work_description.clone(),
|
||||
theme_tags: parse_tags(&row.theme_tags_json)?,
|
||||
@@ -833,7 +856,11 @@ fn sync_session_from_work_update(
|
||||
};
|
||||
|
||||
let mut config = parse_config(&session.config_json)?;
|
||||
config.theme_text = work.work_title.clone();
|
||||
config.theme_text = work
|
||||
.theme_text
|
||||
.as_deref()
|
||||
.and_then(clean_optional)
|
||||
.unwrap_or_else(|| work.work_title.trim().to_string());
|
||||
config.difficulty = work.difficulty.clone();
|
||||
config.style_preset = work.style_preset.clone();
|
||||
config.character_prompt = work.character_prompt.clone();
|
||||
@@ -844,6 +871,7 @@ fn sync_session_from_work_update(
|
||||
template_id: JUMP_HOP_TEMPLATE_ID.to_string(),
|
||||
template_name: JUMP_HOP_TEMPLATE_NAME.to_string(),
|
||||
profile_id: Some(work.profile_id.clone()),
|
||||
theme_text: config.theme_text.clone(),
|
||||
work_title: work.work_title.clone(),
|
||||
work_description: work.work_description.clone(),
|
||||
theme_tags: parse_tags(&work.theme_tags_json)?,
|
||||
@@ -957,7 +985,12 @@ fn replace_session(
|
||||
ctx.db.jump_hop_agent_session().insert(next);
|
||||
}
|
||||
|
||||
fn upsert_run(ctx: &ReducerContext, snapshot: &JumpHopRunSnapshot, updated_at_ms: i64) {
|
||||
fn upsert_run(
|
||||
ctx: &ReducerContext,
|
||||
snapshot: &JumpHopRunSnapshot,
|
||||
updated_at_ms: i64,
|
||||
runtime_mode: &str,
|
||||
) {
|
||||
if let Some(old) = ctx
|
||||
.db
|
||||
.jump_hop_runtime_run()
|
||||
@@ -967,9 +1000,12 @@ fn upsert_run(ctx: &ReducerContext, snapshot: &JumpHopRunSnapshot, updated_at_ms
|
||||
ctx.db.jump_hop_runtime_run().delete(old);
|
||||
}
|
||||
let created_at = Timestamp::from_micros_since_unix_epoch(updated_at_ms.saturating_mul(1000));
|
||||
ctx.db
|
||||
.jump_hop_runtime_run()
|
||||
.insert(run_row_from_snapshot(snapshot, created_at, created_at));
|
||||
ctx.db.jump_hop_runtime_run().insert(run_row_from_snapshot(
|
||||
snapshot,
|
||||
created_at,
|
||||
created_at,
|
||||
runtime_mode,
|
||||
));
|
||||
}
|
||||
|
||||
fn replace_run(
|
||||
@@ -983,6 +1019,7 @@ fn replace_run(
|
||||
snapshot,
|
||||
old.created_at,
|
||||
Timestamp::from_micros_since_unix_epoch(updated_at_ms.saturating_mul(1000)),
|
||||
normalize_runtime_mode(old.runtime_mode.as_deref().unwrap_or_default()),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -990,6 +1027,7 @@ fn run_row_from_snapshot(
|
||||
snapshot: &JumpHopRunSnapshot,
|
||||
created_at: Timestamp,
|
||||
updated_at: Timestamp,
|
||||
runtime_mode: &str,
|
||||
) -> JumpHopRuntimeRunRow {
|
||||
JumpHopRuntimeRunRow {
|
||||
run_id: snapshot.run_id.clone(),
|
||||
@@ -1007,6 +1045,7 @@ fn run_row_from_snapshot(
|
||||
snapshot_json: to_json_string(snapshot),
|
||||
created_at,
|
||||
updated_at,
|
||||
runtime_mode: Some(normalize_runtime_mode(runtime_mode).to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1359,6 +1398,7 @@ fn clone_work(row: &JumpHopWorkProfileRow) -> JumpHopWorkProfileRow {
|
||||
updated_at: row.updated_at,
|
||||
published_at: row.published_at,
|
||||
visible: row.visible,
|
||||
theme_text: row.theme_text.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1376,6 +1416,7 @@ fn clone_run(row: &JumpHopRuntimeRunRow) -> JumpHopRuntimeRunRow {
|
||||
snapshot_json: row.snapshot_json.clone(),
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at,
|
||||
runtime_mode: row.runtime_mode.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user