feat: unify phase one creation flow
This commit is contained in:
@@ -147,26 +147,34 @@ pub async fn execute_wooden_fish_action(
|
||||
wooden_fish_json(payload, &request_context, WOODEN_FISH_CREATION_PROVIDER)?;
|
||||
let owner_user_id = authenticated.claims().user_id().to_string();
|
||||
let author_display_name = resolve_author_display_name(&state, &authenticated);
|
||||
maybe_generate_hit_object_asset(
|
||||
let result = execute_wooden_fish_action_with_generated_assets(
|
||||
&state,
|
||||
&request_context,
|
||||
&session_id,
|
||||
owner_user_id.as_str(),
|
||||
&owner_user_id,
|
||||
&author_display_name,
|
||||
&mut payload,
|
||||
)
|
||||
.await?;
|
||||
maybe_generate_hit_sound_asset(&mut payload);
|
||||
let response = state
|
||||
.spacetime_client()
|
||||
.execute_wooden_fish_action(session_id, owner_user_id, author_display_name, payload)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
wooden_fish_error_response(
|
||||
&request_context,
|
||||
WOODEN_FISH_CREATION_PROVIDER,
|
||||
map_wooden_fish_client_error(error),
|
||||
)
|
||||
})?;
|
||||
.await;
|
||||
if result
|
||||
.as_ref()
|
||||
.err()
|
||||
.is_some_and(|response| response.status().is_server_error())
|
||||
&& matches!(
|
||||
payload.action_type,
|
||||
shared_contracts::wooden_fish::WoodenFishActionType::CompileDraft
|
||||
)
|
||||
{
|
||||
mark_wooden_fish_generation_failed(
|
||||
&state,
|
||||
&request_context,
|
||||
&session_id,
|
||||
owner_user_id.as_str(),
|
||||
author_display_name.as_str(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
let response = result?;
|
||||
|
||||
Ok(json_success_body(Some(&request_context), response))
|
||||
}
|
||||
@@ -372,16 +380,24 @@ async fn build_wooden_fish_draft(
|
||||
payload: &WoodenFishWorkspaceCreateRequest,
|
||||
state: &AppState,
|
||||
) -> Result<WoodenFishDraftResponse, Response> {
|
||||
Ok(WoodenFishDraftResponse {
|
||||
let work_title = resolve_wooden_fish_work_title(
|
||||
state,
|
||||
&payload.work_description,
|
||||
&payload.hit_object_prompt,
|
||||
)
|
||||
.await?;
|
||||
Ok(build_wooden_fish_draft_response(payload, work_title))
|
||||
}
|
||||
|
||||
fn build_wooden_fish_draft_response(
|
||||
payload: &WoodenFishWorkspaceCreateRequest,
|
||||
work_title: String,
|
||||
) -> WoodenFishDraftResponse {
|
||||
WoodenFishDraftResponse {
|
||||
template_id: WOODEN_FISH_TEMPLATE_ID.to_string(),
|
||||
template_name: WOODEN_FISH_TEMPLATE_NAME.to_string(),
|
||||
profile_id: None,
|
||||
work_title: resolve_wooden_fish_work_title(
|
||||
state,
|
||||
&payload.work_description,
|
||||
&payload.hit_object_prompt,
|
||||
)
|
||||
.await?,
|
||||
work_title,
|
||||
work_description: payload.work_description.trim().to_string(),
|
||||
theme_tags: normalize_tags(payload.theme_tags.clone()),
|
||||
hit_object_prompt: clean_string(&payload.hit_object_prompt, DEFAULT_HIT_OBJECT_PROMPT),
|
||||
@@ -401,7 +417,7 @@ async fn build_wooden_fish_draft(
|
||||
.or_else(|| Some(default_wooden_fish_hit_sound_asset())),
|
||||
cover_image_src: None,
|
||||
generation_status: WoodenFishGenerationStatus::Draft,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_workspace_request(
|
||||
@@ -543,6 +559,62 @@ async fn maybe_generate_hit_object_asset(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn execute_wooden_fish_action_with_generated_assets(
|
||||
state: &AppState,
|
||||
request_context: &RequestContext,
|
||||
session_id: &str,
|
||||
owner_user_id: &str,
|
||||
author_display_name: &str,
|
||||
payload: &mut WoodenFishActionRequest,
|
||||
) -> Result<shared_contracts::wooden_fish::WoodenFishActionResponse, Response> {
|
||||
maybe_generate_hit_object_asset(state, request_context, session_id, owner_user_id, payload)
|
||||
.await?;
|
||||
maybe_generate_hit_sound_asset(payload);
|
||||
state
|
||||
.spacetime_client()
|
||||
.execute_wooden_fish_action(
|
||||
session_id.to_string(),
|
||||
owner_user_id.to_string(),
|
||||
author_display_name.to_string(),
|
||||
payload.clone(),
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
wooden_fish_error_response(
|
||||
request_context,
|
||||
WOODEN_FISH_CREATION_PROVIDER,
|
||||
map_wooden_fish_client_error(error),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async fn mark_wooden_fish_generation_failed(
|
||||
state: &AppState,
|
||||
request_context: &RequestContext,
|
||||
session_id: &str,
|
||||
owner_user_id: &str,
|
||||
author_display_name: &str,
|
||||
) {
|
||||
if let Err(error) = state
|
||||
.spacetime_client()
|
||||
.mark_wooden_fish_generation_failed(
|
||||
session_id.to_string(),
|
||||
owner_user_id.to_string(),
|
||||
author_display_name.to_string(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
tracing::error!(
|
||||
provider = WOODEN_FISH_CREATION_PROVIDER,
|
||||
session_id,
|
||||
owner_user_id,
|
||||
request_id = request_context.request_id(),
|
||||
error = %error,
|
||||
"敲木鱼草稿生成失败后的状态回写失败"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn default_wooden_fish_hit_object_asset() -> WoodenFishImageAsset {
|
||||
WoodenFishImageAsset {
|
||||
asset_id: DEFAULT_HIT_OBJECT_ASSET_ID.to_string(),
|
||||
@@ -1475,7 +1547,8 @@ mod tests {
|
||||
floating_words: vec![],
|
||||
};
|
||||
|
||||
let draft = build_wooden_fish_draft(&payload);
|
||||
let draft =
|
||||
build_wooden_fish_draft_response(&payload, WOODEN_FISH_TEMPLATE_NAME.to_string());
|
||||
|
||||
assert!(draft.hit_sound_prompt.is_none());
|
||||
let asset = draft
|
||||
|
||||
Reference in New Issue
Block a user