合并最新主分支并同步资源管理修复
Project CI / Repository checks (pull_request) Failing after 42s
Project CI / Frontend tests (pull_request) Successful in 3m17s
Project CI / Backend tests (pull_request) Successful in 4m14s
Project CI / Native shell tests (pull_request) Failing after 9m50s

合入智能体协作提示词与游戏验收边界更新
保留资源管理审核修复与合并后门禁整理

# Conflicts:
#	docs/project-memory/shared-memory/pitfalls.md
This commit is contained in:
2026-08-04 19:06:25 +08:00
81 changed files with 33586 additions and 1589 deletions
@@ -543,18 +543,20 @@ pub(crate) fn map_asset_operation_wallet_error(error: SpacetimeClientError) -> A
);
let is_insufficient_balance = matches!(
&error,
SpacetimeClientError::Procedure(message) if message.contains("泥点余额不足")
SpacetimeClientError::Procedure(message)
if message.contains("泥点余额不足") || message.contains("可消费泥点不足:")
);
let status = if is_insufficient_balance {
StatusCode::CONFLICT
} else {
StatusCode::BAD_GATEWAY
};
let public_message = is_insufficient_balance.then(|| message.clone());
let public_message = is_insufficient_balance.then_some("泥点余额不足");
let public_detail_message = public_message.unwrap_or(message.as_str());
let app_error = AppError::from_status(status).with_details(json!({
"provider": "profile-wallet",
"message": message,
"message": public_detail_message,
}));
if let Some(public_message) = public_message {
@@ -740,20 +742,25 @@ mod tests {
#[test]
fn asset_operation_wallet_insufficient_balance_is_public_message() {
let error = map_asset_operation_wallet_error(SpacetimeClientError::Procedure(
"泥点余额不足".to_string(),
));
for domain_message in [
"泥点余额不足",
"可消费泥点不足:需要 10,扣除退款占用后可用 2",
] {
let error = map_asset_operation_wallet_error(SpacetimeClientError::Procedure(
domain_message.to_string(),
));
assert_eq!(error.status_code(), StatusCode::CONFLICT);
assert_eq!(error.code(), "CONFLICT");
assert_eq!(error.message(), "泥点余额不足");
assert_eq!(
error
.details()
.and_then(|details| details.get("message"))
.and_then(serde_json::Value::as_str),
Some("泥点余额不足"),
);
assert_eq!(error.status_code(), StatusCode::CONFLICT);
assert_eq!(error.code(), "CONFLICT");
assert_eq!(error.message(), "泥点余额不足");
assert_eq!(
error
.details()
.and_then(|details| details.get("message"))
.and_then(serde_json::Value::as_str),
Some("泥点余额不足"),
);
}
}
#[test]
@@ -1276,8 +1276,12 @@ fn compact_editor_generation_result(mut result: Value) -> Value {
let Some(resource) = object.get_mut(field).and_then(Value::as_object_mut) else {
continue;
};
resource
.retain(|key, _| matches!(key.as_str(), "resourceId" | "objectKey" | "assetObjectId"));
resource.retain(|key, _| {
matches!(
key.as_str(),
"resourceId" | "objectKey" | "assetObjectId" | "sourceResourceId"
)
});
}
if let Some(icon_image_srcs) = object
.get_mut("iconImageSrcs")
@@ -1289,7 +1293,10 @@ fn compact_editor_generation_result(mut result: Value) -> Value {
};
if let Some(resource) = icon.get_mut("resource").and_then(Value::as_object_mut) {
resource.retain(|key, _| {
matches!(key.as_str(), "resourceId" | "objectKey" | "assetObjectId")
matches!(
key.as_str(),
"resourceId" | "objectKey" | "assetObjectId" | "sourceResourceId"
)
});
}
icon.retain(|key, _| {
@@ -1417,6 +1424,7 @@ fn compact_external_generation_resource(resource: &mut serde_json::Map<String, V
| "sourceType"
| "assetKind"
| "taskId"
| "sourceResourceId"
)
});
remove_unstable_external_generation_media_fields(resource);
@@ -2088,6 +2096,7 @@ mod tests {
"resourceId": "icon-resource-1",
"objectKey": "users/user-1/backpack.png",
"assetObjectId": "icon-object-1",
"sourceResourceId": "sheet-resource",
"imageSrc": "data:image/png;base64,SHOULD_NOT_PERSIST",
},
"asset": { "assetId": "icon-asset-1" },
@@ -2101,6 +2110,7 @@ mod tests {
"resourceId": "icon-resource-2",
"objectKey": "users/user-1/map.png",
"assetObjectId": "icon-object-2",
"sourceResourceId": "sheet-resource",
},
},
],
@@ -2122,6 +2132,7 @@ mod tests {
"resourceId": "icon-resource-1",
"objectKey": "users/user-1/backpack.png",
"assetObjectId": "icon-object-1",
"sourceResourceId": "sheet-resource",
})
);
assert!(
@@ -2263,6 +2274,7 @@ mod tests {
"projectId": "project-1",
"objectKey": "users/user-1/generated/main.png",
"assetObjectId": "asset-object-main",
"sourceResourceId": "source-resource-main",
"imageSrc": "https://cdn.example.test/main.png?signature=secret",
"width": 1024,
"height": 1024,
@@ -2318,6 +2330,10 @@ mod tests {
);
assert_eq!(result["assetObjectId"], json!("asset-object-main"));
assert_eq!(result["resource"]["resourceId"], json!("resource-main"));
assert_eq!(
result["resource"]["sourceResourceId"],
json!("source-resource-main")
);
assert_eq!(
result["resource"]["objectKey"],
json!("users/user-1/generated/main.png")