188 lines
7.0 KiB
Rust
188 lines
7.0 KiB
Rust
use axum::{
|
||
Router,
|
||
extract::{DefaultBodyLimit, FromRef},
|
||
middleware,
|
||
routing::{get, post},
|
||
};
|
||
|
||
use crate::{
|
||
auth::require_bearer_auth,
|
||
puzzle::{
|
||
advance_puzzle_next_level, claim_puzzle_work_point_incentive, create_puzzle_agent_session,
|
||
delete_puzzle_work, drag_puzzle_piece_or_group, execute_puzzle_agent_action,
|
||
generate_puzzle_onboarding_work, get_puzzle_agent_session, get_puzzle_gallery_detail,
|
||
get_puzzle_run, get_puzzle_work_detail, get_puzzle_works, list_puzzle_gallery,
|
||
put_puzzle_work, record_puzzle_gallery_like, remix_puzzle_gallery_work,
|
||
save_puzzle_onboarding_work, start_puzzle_run, stream_puzzle_agent_message,
|
||
submit_puzzle_agent_message, submit_puzzle_leaderboard, swap_puzzle_pieces,
|
||
update_puzzle_run_pause, use_puzzle_runtime_prop,
|
||
},
|
||
state::{AppState, PuzzleApiState},
|
||
};
|
||
|
||
const PUZZLE_REFERENCE_IMAGE_BODY_LIMIT_BYTES: usize = 12 * 1024 * 1024;
|
||
|
||
pub fn router(state: AppState) -> Router<AppState> {
|
||
// 中文注释:拼图 handler 只接收 PuzzleApiState,鉴权层仍使用全局 AppState。
|
||
Router::new()
|
||
.route(
|
||
"/api/runtime/puzzle/agent/sessions",
|
||
post(create_puzzle_agent_session)
|
||
// 中文注释:拼图表单会携带单张参考图 Data URL,需只给该写入入口放宽 body 上限。
|
||
.layer(DefaultBodyLimit::max(
|
||
PUZZLE_REFERENCE_IMAGE_BODY_LIMIT_BYTES,
|
||
))
|
||
.route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/agent/sessions/{session_id}",
|
||
get(get_puzzle_agent_session).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/agent/sessions/{session_id}/messages",
|
||
post(submit_puzzle_agent_message).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/agent/sessions/{session_id}/messages/stream",
|
||
post(stream_puzzle_agent_message).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/agent/sessions/{session_id}/actions",
|
||
post(execute_puzzle_agent_action)
|
||
// 中文注释:生成草稿/重新出图会复用 referenceImageSrc,避免默认 2MB JSON limit 拦截。
|
||
.layer(DefaultBodyLimit::max(
|
||
PUZZLE_REFERENCE_IMAGE_BODY_LIMIT_BYTES,
|
||
))
|
||
.route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/onboarding/generate",
|
||
post(generate_puzzle_onboarding_work).layer(DefaultBodyLimit::max(
|
||
PUZZLE_REFERENCE_IMAGE_BODY_LIMIT_BYTES,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/onboarding/save",
|
||
post(save_puzzle_onboarding_work).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/works",
|
||
get(get_puzzle_works).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/works/{profile_id}",
|
||
get(get_puzzle_work_detail)
|
||
.put(put_puzzle_work)
|
||
.delete(delete_puzzle_work)
|
||
.route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/works/{profile_id}/point-incentive/claim",
|
||
post(claim_puzzle_work_point_incentive).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route("/api/runtime/puzzle/gallery", get(list_puzzle_gallery))
|
||
.route(
|
||
"/api/runtime/puzzle/gallery/{profile_id}",
|
||
get(get_puzzle_gallery_detail),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/gallery/{profile_id}/remix",
|
||
post(remix_puzzle_gallery_work).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/gallery/{profile_id}/like",
|
||
post(record_puzzle_gallery_like).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs",
|
||
post(start_puzzle_run).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}",
|
||
get(get_puzzle_run).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}/swap",
|
||
post(swap_puzzle_pieces).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}/drag",
|
||
post(drag_puzzle_piece_or_group).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}/next-level",
|
||
post(advance_puzzle_next_level).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}/pause",
|
||
post(update_puzzle_run_pause).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}/props",
|
||
post(use_puzzle_runtime_prop).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.route(
|
||
"/api/runtime/puzzle/runs/{run_id}/leaderboard",
|
||
post(submit_puzzle_leaderboard).route_layer(middleware::from_fn_with_state(
|
||
state.clone(),
|
||
require_bearer_auth,
|
||
)),
|
||
)
|
||
.with_state(PuzzleApiState::from_ref(&state))
|
||
.with_state(state)
|
||
}
|