//! API routes for user UI. //! //! This router provides READ-ONLY access to realms, scenes, and spots. //! All create/update/delete operations are handled by the admin-ui. //! Channel presence is handled via WebSocket. use axum::{Router, routing::get}; use super::{auth, avatars, inventory, realms, scenes, websocket}; use crate::app::AppState; /// Build the API router for user UI. /// /// Note: This router is READ-ONLY for realms/scenes/spots. /// Auth routes (login, logout, signup, join-realm) are allowed. /// Channel presence (join, leave, position, emotion, members) is handled via WebSocket. pub fn api_router() -> Router { Router::new() // Auth routes (these are user-facing operations) .route("/auth/me", get(auth::get_current_user)) .route("/auth/login", axum::routing::post(auth::login)) .route("/auth/logout", axum::routing::post(auth::logout)) .route("/auth/signup", axum::routing::post(auth::signup)) .route("/auth/guest", axum::routing::post(auth::guest_login)) .route("/auth/join-realm", axum::routing::post(auth::join_realm)) .route( "/auth/reset-password", axum::routing::post(auth::reset_password), ) .route( "/auth/register-guest", axum::routing::post(auth::register_guest), ) .route( "/auth/preferences", axum::routing::put(auth::update_preferences), ) // Realm routes (READ-ONLY) .route("/realms", get(realms::list_realms)) .route("/realms/{slug}", get(realms::get_realm)) .route( "/realms/{slug}/available", get(realms::check_slug_available), ) // Scene routes (READ-ONLY) .route("/realms/{slug}/entry-scene", get(scenes::get_entry_scene)) .route("/realms/{slug}/scenes", get(scenes::list_scenes)) .route("/realms/{slug}/scenes/{scene_slug}", get(scenes::get_scene)) // Spot routes (READ-ONLY) .route( "/realms/{slug}/scenes/{scene_slug}/spots", get(scenes::list_spots), ) .route( "/realms/{slug}/scenes/{scene_slug}/spots/{spot_id}", get(scenes::get_spot), ) // WebSocket route for channel presence (handles join, leave, position, emotion, members) .route( "/realms/{slug}/channels/{channel_id}/ws", get(websocket::ws_handler::), ) // Avatar routes (require authentication) .route("/realms/{slug}/avatar", get(avatars::get_avatar)) .route( "/realms/{slug}/avatar/slot", axum::routing::put(avatars::assign_slot).delete(avatars::clear_slot), ) // Avatar store routes .route("/server/avatars", get(avatars::list_server_avatars)) .route("/realms/{slug}/avatars", get(avatars::list_realm_avatars)) .route( "/realms/{slug}/avatar/select", axum::routing::post(avatars::select_avatar), ) .route( "/realms/{slug}/avatar/selection", axum::routing::delete(avatars::clear_avatar_selection), ) // User inventory routes .route("/user/{uuid}/inventory", get(inventory::get_user_inventory)) .route( "/user/{uuid}/inventory/{item_id}", axum::routing::delete(inventory::drop_item), ) // Server prop catalog (enriched if authenticated) .route("/server/inventory", get(inventory::get_server_props)) .route( "/server/inventory/request", axum::routing::post(inventory::acquire_server_prop), ) // Realm prop catalog (enriched if authenticated) .route("/realms/{slug}/inventory", get(inventory::get_realm_props)) .route( "/realms/{slug}/inventory/request", axum::routing::post(inventory::acquire_realm_prop), ) }