1
This commit is contained in:
@@ -5,7 +5,7 @@ use axum::{
|
||||
http::Request,
|
||||
middleware,
|
||||
response::Response,
|
||||
routing::{delete, get, post},
|
||||
routing::{delete, get, post, put},
|
||||
};
|
||||
use tower_http::{
|
||||
classify::ServerErrorsFailureClass,
|
||||
@@ -92,8 +92,8 @@ use crate::{
|
||||
delete_match3d_work, execute_match3d_agent_action, finish_match3d_time_up,
|
||||
generate_match3d_work_tags, get_match3d_agent_session, get_match3d_run,
|
||||
get_match3d_work_detail, get_match3d_works, list_match3d_gallery, publish_match3d_work,
|
||||
put_match3d_work, restart_match3d_run, start_match3d_run, stop_match3d_run,
|
||||
stream_match3d_agent_message, submit_match3d_agent_message,
|
||||
put_match3d_audio_assets, put_match3d_work, restart_match3d_run, start_match3d_run,
|
||||
stop_match3d_run, stream_match3d_agent_message, submit_match3d_agent_message,
|
||||
},
|
||||
password_entry::password_entry,
|
||||
password_management::{change_password, reset_password},
|
||||
@@ -156,7 +156,9 @@ use crate::{
|
||||
},
|
||||
tracking::record_route_tracking_event_after_success,
|
||||
vector_engine_audio_generation::{
|
||||
create_background_music_task, create_sound_effect_task,
|
||||
create_visual_novel_background_music_task, create_visual_novel_sound_effect_task,
|
||||
publish_background_music_asset, publish_sound_effect_asset,
|
||||
publish_visual_novel_background_music_asset, publish_visual_novel_sound_effect_asset,
|
||||
},
|
||||
visual_novel::{
|
||||
@@ -942,6 +944,13 @@ pub fn build_router(state: AppState) -> Router {
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/match3d/works/{profile_id}/audio-assets",
|
||||
put(put_match3d_audio_assets).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/match3d/works/{profile_id}/publish",
|
||||
post(publish_match3d_work).route_layer(middleware::from_fn_with_state(
|
||||
@@ -1517,7 +1526,7 @@ pub fn build_router(state: AppState) -> Router {
|
||||
)),
|
||||
)
|
||||
.route("/api/auth/password/reset", post(reset_password))
|
||||
// 后端 runtime/API 路由只按 open 做熔断;visible 仅控制创作页入口展示。
|
||||
// 后端创作/运行态 API 路由只按 open 做熔断;visible 仅控制创作页入口展示。
|
||||
.layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_creation_entry_route_enabled,
|
||||
@@ -1770,6 +1779,34 @@ fn visual_novel_router(state: AppState) -> Router<AppState> {
|
||||
middleware::from_fn_with_state(state.clone(), require_bearer_auth),
|
||||
),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/audio/background-music",
|
||||
post(create_background_music_task).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/audio/background-music/{task_id}/asset",
|
||||
post(publish_background_music_asset).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/audio/sound-effect",
|
||||
post(create_sound_effect_task).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/audio/sound-effect/{task_id}/asset",
|
||||
post(publish_sound_effect_asset).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/visual-novel/gallery",
|
||||
get(list_visual_novel_gallery),
|
||||
@@ -2007,6 +2044,38 @@ mod tests {
|
||||
assert_eq!(body["error"]["details"]["creationTypeId"], "puzzle");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn disabled_visual_novel_creation_route_returns_service_unavailable() {
|
||||
let app = build_router(AppState::new(AppConfig::default()).expect("state should build"));
|
||||
|
||||
let response = app
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("POST")
|
||||
.uri("/api/creation/visual-novel/sessions")
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
serde_json::json!({
|
||||
"sourceMode": "idea",
|
||||
"seedText": "雨夜书店",
|
||||
"sourceAssetIds": []
|
||||
})
|
||||
.to_string(),
|
||||
))
|
||||
.expect("request should build"),
|
||||
)
|
||||
.await
|
||||
.expect("request should succeed");
|
||||
|
||||
assert_eq!(response.status(), StatusCode::SERVICE_UNAVAILABLE);
|
||||
let body = read_json_response(response).await;
|
||||
assert_eq!(
|
||||
body["error"]["details"]["reason"],
|
||||
"creation_entry_disabled"
|
||||
);
|
||||
assert_eq!(body["error"]["details"]["creationTypeId"], "visual-novel");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn healthz_returns_standard_envelope_when_requested() {
|
||||
let app = build_router(AppState::new(AppConfig::default()).expect("state should build"));
|
||||
@@ -4693,7 +4762,9 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn visual_novel_creation_route_requires_authentication() {
|
||||
let app = build_router(AppState::new(AppConfig::default()).expect("state should build"));
|
||||
let state = AppState::new(AppConfig::default()).expect("state should build");
|
||||
state.set_test_creation_entry_route_enabled("visual-novel", true);
|
||||
let app = build_router(state);
|
||||
|
||||
let response = app
|
||||
.oneshot(
|
||||
|
||||
Reference in New Issue
Block a user