feat: refresh creation config and visual assets

This commit is contained in:
2026-05-20 14:02:36 +08:00
parent 83e92fc3c4
commit ef09a23c35
509 changed files with 19470 additions and 43 deletions

View File

@@ -8,8 +8,8 @@ use axum::{
};
use serde_json::{Value, json};
#[cfg(test)]
use module_runtime::build_creation_entry_config_response;
use shared_contracts::creation_entry_config::CreationEntryConfigResponse;
use crate::{
api_response::json_success_body, http_error::AppError, request_context::RequestContext,
@@ -115,9 +115,8 @@ fn creation_entry_error_response(request_context: &RequestContext, error: AppErr
error.into_response_with_context(Some(request_context))
}
#[cfg(test)]
pub(crate) fn test_creation_entry_config_response()
-> shared_contracts::creation_entry_config::CreationEntryConfigResponse {
/// 中文注释:本地 debug 兜底也来自后端领域默认种子,避免前端恢复硬编码入口配置。
pub(crate) fn default_creation_entry_config_response() -> CreationEntryConfigResponse {
build_creation_entry_config_response(module_runtime::CreationEntryConfigSnapshot {
config_id: module_runtime::CREATION_ENTRY_CONFIG_GLOBAL_ID.to_string(),
start_card: module_runtime::CreationEntryStartCardSnapshot {
@@ -135,6 +134,11 @@ pub(crate) fn test_creation_entry_config_response()
})
}
#[cfg(test)]
pub(crate) fn test_creation_entry_config_response() -> CreationEntryConfigResponse {
default_creation_entry_config_response()
}
#[cfg(test)]
mod tests {
use super::*;
@@ -181,7 +185,7 @@ mod tests {
}
#[test]
fn test_creation_entry_config_response_keeps_baby_object_match_coming_soon() {
fn test_creation_entry_config_response_keeps_baby_object_match_visible() {
let config = test_creation_entry_config_response();
let baby_object_match = config
.creation_types
@@ -191,8 +195,8 @@ mod tests {
assert_eq!(baby_object_match.title, "宝贝识物");
assert!(baby_object_match.visible);
assert!(!baby_object_match.open);
assert_eq!(baby_object_match.badge, "敬请期待");
assert!(baby_object_match.open);
assert_eq!(baby_object_match.badge, "可创建");
assert_eq!(baby_object_match.sort_order, 90);
}
}

View File

@@ -383,6 +383,14 @@ impl AppState {
self.cache_test_creation_entry_config(config.clone());
Ok(config)
}
#[cfg(debug_assertions)]
Err(error) if is_missing_creation_entry_config_procedure(&error) => {
warn!(
error = %error,
"本地 SpacetimeDB 缺少创作入口配置 procedure使用后端默认入口配置兜底"
);
Ok(crate::creation_entry_config::default_creation_entry_config_response())
}
#[cfg(test)]
Err(_) => Ok(self.read_test_creation_entry_config()),
#[cfg(not(test))]
@@ -1247,12 +1255,37 @@ fn build_admin_runtime(
}))
}
#[cfg(debug_assertions)]
fn is_missing_creation_entry_config_procedure(error: &SpacetimeClientError) -> bool {
match error {
SpacetimeClientError::Procedure(message) => {
message.contains("No such procedure")
}
_ => false,
}
}
#[cfg(test)]
mod tests {
use module_ai::{AiTaskKind, generate_ai_task_id};
use super::*;
#[test]
fn detects_missing_creation_entry_config_procedure_for_debug_fallback() {
assert!(is_missing_creation_entry_config_procedure(
&SpacetimeClientError::Procedure(
"No such procedure: get_creation_entry_config".to_string(),
),
));
assert!(is_missing_creation_entry_config_procedure(
&SpacetimeClientError::Procedure("No such procedure".to_string()),
));
assert!(!is_missing_creation_entry_config_procedure(
&SpacetimeClientError::Timeout,
));
}
#[test]
fn app_state_exposes_usable_ai_task_service() {
let state = AppState::new(AppConfig::default()).expect("state should build");