feat: unify phase one creation flow

This commit is contained in:
2026-05-30 05:05:02 +08:00
parent 3a87b2d966
commit 26975644b5
33 changed files with 2037 additions and 539 deletions

View File

@@ -51,4 +51,113 @@ pub struct CreationEntryTypeResponse {
pub category_label: String,
pub category_sort_order: i32,
pub updated_at_micros: i64,
#[serde(skip_serializing_if = "Option::is_none")]
pub unified_creation_spec: Option<UnifiedCreationSpecResponse>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct UnifiedCreationSpecResponse {
pub play_id: String,
pub title: String,
pub workspace_stage: String,
pub generation_stage: String,
pub result_stage: String,
pub fields: Vec<UnifiedCreationFieldResponse>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct UnifiedCreationFieldResponse {
pub id: String,
pub kind: String,
pub label: String,
pub required: bool,
}
pub fn build_phase1_unified_creation_spec(play_id: &str) -> Option<UnifiedCreationSpecResponse> {
let (workspace_stage, generation_stage, result_stage, fields) = match play_id {
"puzzle" => (
"puzzle-agent-workspace",
"puzzle-generating",
"puzzle-result",
vec![
unified_creation_field("pictureDescription", "text", "画面描述", true),
unified_creation_field("referenceImage", "image", "拼图画面", false),
unified_creation_field("promptReferenceImages", "image", "参考图", false),
],
),
"match3d" => (
"match3d-agent-workspace",
"match3d-generating",
"match3d-result",
vec![
unified_creation_field("themeText", "text", "题材", true),
unified_creation_field("difficulty", "select", "难度", true),
],
),
"wooden-fish" => (
"wooden-fish-workspace",
"wooden-fish-generating",
"wooden-fish-result",
vec![
unified_creation_field("hitObjectPrompt", "text", "敲什么", false),
unified_creation_field("hitObjectReferenceImage", "image", "参考图", false),
unified_creation_field("hitSoundAsset", "audio", "敲击音效", false),
unified_creation_field("floatingWords", "text", "功德有什么", true),
],
),
_ => return None,
};
Some(UnifiedCreationSpecResponse {
play_id: play_id.to_string(),
title: "想做个什么玩法?".to_string(),
workspace_stage: workspace_stage.to_string(),
generation_stage: generation_stage.to_string(),
result_stage: result_stage.to_string(),
fields,
})
}
fn unified_creation_field(
id: &str,
kind: &str,
label: &str,
required: bool,
) -> UnifiedCreationFieldResponse {
UnifiedCreationFieldResponse {
id: id.to_string(),
kind: kind.to_string(),
label: label.to_string(),
required,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn phase1_unified_creation_specs_only_cover_three_templates() {
let puzzle = build_phase1_unified_creation_spec("puzzle").expect("puzzle spec");
assert_eq!(puzzle.fields[0].id, "pictureDescription");
assert_eq!(puzzle.fields[1].kind, "image");
let match3d = build_phase1_unified_creation_spec("match3d").expect("match3d spec");
assert_eq!(
match3d
.fields
.iter()
.filter(|field| field.kind == "select")
.count(),
1
);
let wooden_fish =
build_phase1_unified_creation_spec("wooden-fish").expect("wooden-fish spec");
assert!(wooden_fish.fields.iter().any(|field| field.kind == "audio"));
assert!(build_phase1_unified_creation_spec("visual-novel").is_none());
assert!(build_phase1_unified_creation_spec("bark-battle").is_none());
}
}