use axum::{ middleware, routing::{get, post}, Router, }; use tower_http::cors::{Any, CorsLayer}; use tower_http::trace::TraceLayer; pub mod api; pub mod app_state; pub mod camera_auth; pub mod config; pub mod credential_crypto; pub mod db; pub mod event_bus; pub mod event_narrator; pub mod gpu_scheduler; pub mod gpu_telemetry; pub mod inference; pub mod jwt_auth; pub mod onvif_discovery; pub mod orchestrator; pub mod snapshot_store; pub mod utils; pub mod vendor_compat; pub mod vision_runtime; pub mod vision_store; pub use app_state::AppState; pub use config::Settings; pub use jwt_auth::AuthClaims; pub fn build_app(state: AppState) -> Router { let cors = CorsLayer::new() .allow_origin(Any) .allow_methods(Any) .allow_headers(Any); let protected = Router::new() .route("/api/system", get(api::system::system_info)) .route("/api/ops/console", get(api::ops::operations_console)) .route("/api/ops/evals", post(api::ops::submit_task_outcome)) .route("/api/admin/users", get(api::admin::list_users)) .route("/api/admin/users", post(api::admin::create_user)) .route("/api/admin/sessions", get(api::admin::list_sessions)) .route( "/api/admin/sessions/:session_id/revoke", post(api::admin::revoke_session), ) .route( "/api/admin/audit/credentials", get(api::admin::list_credential_audit), ) .route("/api/auth/me", get(api::auth::me)) .route("/api/auth/logout", post(api::auth::logout)) .route("/api/chat", post(api::chat::chat)) .route("/api/voice/synthesize", post(api::voice::synthesize)) .route("/api/voice/transcribe", post(api::voice::transcribe)) .route("/api/images", post(api::images::generate_image)) .route("/api/vision/analyze", post(api::vision::analyze_image)) .route("/api/vision/ocr", post(api::vision::ocr_image)) .route( "/api/vision/pose-estimate", post(api::vision::estimate_pose), ) .route("/api/vision/segment", post(api::vision::segment_image)) .route( "/api/vision/action-recognize", post(api::vision::recognize_action), ) .route("/api/vision/tracking", post(api::vision::track_objects)) .route( "/api/vision/frame-analysis", post(api::vision::analyze_frames), ) .route( "/api/vision/scene-timeline", post(api::vision::scene_timeline), ) .route("/api/vision/cameras", get(api::vision::list_live_cameras)) .route("/api/vision/dashboard", get(api::vision::vision_dashboard)) .route( "/api/vision/onvif/discover", post(api::vision::discover_onvif_devices), ) .route( "/api/vision/cameras/connect", post(api::vision::connect_live_camera), ) .route( "/api/vision/cameras/:camera_id/start", post(api::vision::start_live_camera), ) .route( "/api/vision/cameras/:camera_id/pause", post(api::vision::pause_live_camera), ) .route( "/api/vision/cameras/:camera_id/stop", post(api::vision::stop_live_camera), ) .route( "/api/vision/cameras/:camera_id/snapshot", get(api::vision::live_camera_snapshot), ) .route( "/api/vision/cameras/:camera_id/state", get(api::vision::live_camera_state), ) .route( "/api/vision/cameras/:camera_id/events", get(api::vision::live_camera_events), ) .route( "/api/vision/cameras/:camera_id/config", post(api::vision::update_live_camera_config), ) .route( "/api/vision/cameras/:camera_id/timeline/snapshots", get(api::vision::camera_timeline_snapshots), ) .route( "/api/vision/cameras/:camera_id/snapshot/:frame_index", get(api::vision::camera_frame_snapshot), ) .route( "/api/vision/cameras/:camera_id/access", get(api::vision::list_camera_access), ) .route( "/api/vision/cameras/:camera_id/access/grant", post(api::vision::grant_camera_access), ) .route( "/api/vision/cameras/:camera_id/access/:access_id/revoke", post(api::vision::revoke_camera_access), ) .route( "/api/vision/credentials/rotate", post(api::vision::rotate_camera_credentials), ) .route( "/api/vision/cameras/:camera_id/events/:event_id/narrate", post(api::vision::generate_camera_event_narration), ) .route( "/api/vision/cameras/:camera_id/narrations", get(api::vision::list_camera_narrations), ) .route("/api/vision/gpu/jobs", get(api::vision::list_gpu_jobs)) .route( "/api/vision/gpu/resources", get(api::vision::list_gpu_resources), ) .route("/api/vision/events/subscribe", get(api::events::subscribe)) .route( "/api/vision/cameras/:camera_id/ws", get(api::vision::live_camera_ws), ) .route( "/api/vision/cameras/:camera_id/events/ws", get(api::vision::live_camera_ws), ) .route("/api/music", post(api::music::generate_music)) .route( "/api/music/providers/search", post(api::music::search_music_providers), ) .route("/api/video", post(api::video::generate_video)) .route("/api/code", post(api::code::generate_code)) .route("/api/code/fix", post(api::code::fix_code)) .route("/api/code/download", get(api::code::download_project_zip)) .route("/api/code/preview", get(api::code::preview_code_changes)) .route("/api/code/apply", post(api::code::apply_workspace_to_repo)) .route("/api/code/import", post(api::code::import_bundle_to_repo)) .route("/api/chat/stream", post(api::chat::chat_stream)) .route( "/api/autonomous/start", post(api::autonomous::start_session), ) .route( "/api/autonomous/status/:id", get(api::autonomous::get_status), ) .route( "/api/autonomous/status/:id/stream", get(api::autonomous::stream_status), ); Router::new() .route("/health", get(api::health::health_check)) .route("/ready", get(api::health::readiness_check)) .route("/api/auth/bootstrap", post(api::auth::bootstrap)) .route("/api/auth/login", post(api::auth::login)) .route("/api/auth/refresh", post(api::auth::refresh)) .merge(protected.route_layer(middleware::from_fn_with_state( state.clone(), app_state::jwt_auth_middleware, ))) .layer(cors) .layer(TraceLayer::new_for_http()) .with_state(state) }