use axum::{ Router, middleware, routing::{delete, get, post}, }; use crate::{ auth::{require_session, require_workspace_session}, rate_limit::apply_api_rate_limit, request_context::apply_request_context, routes::{ access::export_workspace, agents::{ archive_agent, create_agent, create_agent_platform_api_key, delete_agent, delete_agent_platform_api_key, get_agent, get_agent_version, list_agent_platform_api_keys, list_agents, publish_agent, revoke_agent_platform_api_key, save_agent_bindings, unpublish_agent, update_agent, }, auth::{change_password, get_profile, get_session, login, logout, update_profile}, auth_profiles::{create_auth_profile, get_auth_profile, list_auth_profiles}, capabilities::get_capabilities, imports::{create_openapi_import, preview_openapi_import}, observability::{get_agent_usage, get_log, get_operation_usage, get_usage, list_logs}, operations::{ analyze_operation_quality, archive_operation, create_operation, create_version, delete_operation, export_operation, generate_draft, get_operation, get_operation_version, list_operations, publish_operation, run_test, update_operation, upload_input_json, upload_output_json, }, secrets::{create_secret, delete_secret, get_secret, list_secrets, rotate_secret}, upstreams::{create_upstream, list_upstreams, update_upstream}, workspaces::{get_workspace, list_workspaces, update_workspace}, }, state::AppState, }; pub fn build_app(state: AppState) -> Router { let workspace_router = Router::new() .route("/operations", get(list_operations).post(create_operation)) .route("/imports/openapi/preview", post(preview_openapi_import)) .route( "/imports/openapi/{job_id}/create", post(create_openapi_import), ) .route( "/operations/analyze-quality", post(analyze_operation_quality), ) .route("/operations/import", post(import_operation)) .route( "/operations/{operation_id}", get(get_operation) .patch(update_operation) .delete(delete_operation), ) .route("/operations/{operation_id}/versions", post(create_version)) .route( "/operations/{operation_id}/versions/{version}", get(get_operation_version), ) .route( "/operations/{operation_id}/publish", post(publish_operation), ) .route( "/operations/{operation_id}/archive", post(archive_operation), ) .route("/operations/{operation_id}/test-runs", post(run_test)) .route( "/operations/{operation_id}/samples/input-json", post(upload_input_json), ) .route( "/operations/{operation_id}/samples/output-json", post(upload_output_json), ) .route( "/operations/{operation_id}/drafts/generate", post(generate_draft), ) .route("/operations/{operation_id}/export", get(export_operation)) .route("/agents", get(list_agents).post(create_agent)) .route( "/agents/{agent_id}", get(get_agent).patch(update_agent).delete(delete_agent), ) .route( "/agents/{agent_id}/versions/{version}", get(get_agent_version), ) .route("/agents/{agent_id}/bindings", post(save_agent_bindings)) .route("/agents/{agent_id}/publish", post(publish_agent)) .route("/agents/{agent_id}/unpublish", post(unpublish_agent)) .route("/agents/{agent_id}/archive", post(archive_agent)) .route( "/agents/{agent_id}/platform-api-keys", get(list_agent_platform_api_keys).post(create_agent_platform_api_key), ) .route( "/agents/{agent_id}/platform-api-keys/{key_id}/revoke", post(revoke_agent_platform_api_key), ) .route( "/agents/{agent_id}/platform-api-keys/{key_id}", delete(delete_agent_platform_api_key), ) .route( "/auth-profiles", get(list_auth_profiles).post(create_auth_profile), ) .route("/auth-profiles/{auth_profile_id}", get(get_auth_profile)) .route("/upstreams", get(list_upstreams).post(create_upstream)) .route( "/upstreams/{upstream_id}", axum::routing::patch(update_upstream), ) .route("/secrets", get(list_secrets).post(create_secret)) .route( "/secrets/{secret_id}", get(get_secret).delete(delete_secret), ) .route("/secrets/{secret_id}/rotate", post(rotate_secret)) .route("/export", get(export_workspace)) .route("/logs", get(list_logs)) .route("/logs/{log_id}", get(get_log)) .route("/usage", get(get_usage)) .route("/usage/operations/{operation_id}", get(get_operation_usage)) .route("/usage/agents/{agent_id}", get(get_agent_usage)); let workspace_root_router = Router::new() .route("/capabilities", get(get_capabilities)) .route("/workspaces", get(list_workspaces)) .layer(middleware::from_fn_with_state( state.clone(), require_session, )); let workspace_scoped_router = Router::new() .route( "/workspaces/{workspace_id}", get(get_workspace).patch(update_workspace), ) .nest("/workspaces/{workspace_id}", workspace_router) .layer(middleware::from_fn_with_state( state.clone(), require_workspace_session, )); let admin_router = workspace_root_router.merge(workspace_scoped_router); let protected_auth_router = Router::new() .route("/logout", post(logout)) .route("/session", get(get_session)) .route("/profile", get(get_profile).patch(update_profile)) .route("/password", post(change_password)) .layer(middleware::from_fn_with_state( state.clone(), require_session, )); Router::new() .route("/health", get(crate::routes::health)) .nest( "/api/auth", Router::new() .route("/login", post(login)) .merge(protected_auth_router), ) .nest("/api/admin", admin_router) .layer(middleware::from_fn_with_state( state.clone(), apply_api_rate_limit, )) .layer(middleware::from_fn(apply_request_context)) .with_state(state) } use crate::routes::operations::import_operation;