Source code for mud_server.api.models

"""
Pydantic models for API requests and responses.

This module defines all the data models used for API communication between
the FastAPI backend and the Gradio frontend. Pydantic models provide:
- Automatic request/response validation
- Type checking and conversion
- Clear API documentation via FastAPI's automatic OpenAPI schema generation
- Serialization/deserialization to/from JSON

Models are organized into two categories:
1. Request models: Data sent FROM the client TO the server
2. Response models: Data sent FROM the server TO the client
"""

from typing import Any

from pydantic import BaseModel

# ============================================================================
# REQUEST MODELS (Client → Server)
# ============================================================================


[docs] class LoginRequest(BaseModel): """ Login request with username and password. Attributes: username: Account username (case-sensitive for database lookup) password: Plain text password (will be verified against bcrypt hash) world_id: Optional world id used to filter characters on login """ username: str password: str world_id: str | None = None
[docs] class RegisterRequest(BaseModel): """ Registration request for creating a new player account. Attributes: username: Desired username (2-20 characters, must be unique) password: Desired password (minimum 8 characters) password_confirm: Password confirmation (must match password) """ username: str password: str password_confirm: str
[docs] class RegisterGuestRequest(BaseModel): """ Registration request for creating a temporary guest account. Attributes: password: Desired password (validated against STANDARD policy) password_confirm: Password confirmation (must match password) character_name: Initial character name for the guest account """ password: str password_confirm: str character_name: str
[docs] class SelectCharacterRequest(BaseModel): """ Request to select an active character for a session. Attributes: session_id: Active session ID for authentication character_id: Character id to bind to the session world_id: World id to bind to the session (must match character's world) """ session_id: str character_id: int world_id: str | None = None
[docs] class LoginDirectRequest(BaseModel): """ Direct login request that binds a session to a world + character. Attributes: username: Account username (case-sensitive for database lookup) password: Plain text password (will be verified against bcrypt hash) world_id: Target world id (must be accessible by the user) character_name: Existing character name (optional) create_character: When true, create the character if missing """ username: str password: str world_id: str character_name: str | None = None create_character: bool = False
[docs] class ChangePasswordRequest(BaseModel): """ Request to change the current user's password. Attributes: session_id: Active session ID for authentication old_password: Current password (verified before change) new_password: New password (minimum 8 characters, must differ from old) """ session_id: str old_password: str new_password: str
[docs] class UserManagementRequest(BaseModel): """ Admin request to manage user accounts. Requires admin or superuser permissions. Allows role changes, banning, unbanning, and password changes of user accounts. Superusers can manage all users, admins can only manage users with lower permissions. Attributes: session_id: Active session ID (must have appropriate permission) target_username: Username of the account to manage action: Management action - one of: - "change_role": Change user's role (requires new_role parameter) - "ban" or "deactivate": Deactivate user account (prevents login, removes active session) - "delete": Permanently delete user and related data (superuser only) - "unban": Reactivate previously banned account - "change_password": Change user's password (requires new_password parameter) new_role: (Optional) New role when action is "change_role" Valid roles: "player", "worldbuilder", "admin", "superuser" new_password: (Optional) New password when action is "change_password" Must be at least 8 characters """ session_id: str target_username: str action: str # "change_role", "ban", "deactivate", "unban", "change_password" new_role: str | None = None new_password: str | None = None
[docs] class CreateUserRequest(BaseModel): """ Admin request to create a new user account. Requires admin or superuser permissions. Admins may create Player or WorldBuilder accounts. Superusers may create any role, including Admin and Superuser. Passwords must meet the STANDARD password policy, and password_confirm must match password. Attributes: session_id: Active session ID (must have appropriate permission) username: Desired username (2-20 characters, must be unique) password: Desired password (must meet STANDARD policy) password_confirm: Password confirmation (must match password) role: Role to assign to the new account Valid roles: "player", "worldbuilder", "admin", "superuser" """ session_id: str username: str password: str password_confirm: str role: str
[docs] class ServerStopRequest(BaseModel): """ Admin request to stop the server gracefully. Requires STOP_SERVER permission (admin or superuser only). Server will shutdown 0.5 seconds after sending response to allow the HTTP response to be delivered. Attributes: session_id: Active session ID (must have STOP_SERVER permission) """ session_id: str
[docs] class LogoutRequest(BaseModel): """ Request to logout and end the current session. Attributes: session_id: Active session ID to be terminated """ session_id: str
[docs] class CommandRequest(BaseModel): """ Request to execute a game command. Supports all game commands including movement, inventory management, chat, and special commands. Commands can be prefixed with "/" or not. Attributes: session_id: Active session ID for authentication command: Game command to execute, examples: - Movement: "north", "n", "south", "s", "east", "e", "west", "w", "up", "u", "down", "d" - Actions: "look", "inventory", "get <item>", "drop <item>" - Chat: "say <message>", "yell <message>", "whisper <player> <message>" - Info: "who", "help" """ session_id: str command: str
[docs] class ChatRequest(BaseModel): """ Request to send a chat message. Note: This model is defined but may not be actively used. Chat is typically sent via CommandRequest with "/say" command. Attributes: session_id: Active session ID for authentication message: Chat message text """ session_id: str message: str
# ============================================================================ # RESPONSE MODELS (Server → Client) # ============================================================================
[docs] class LoginResponse(BaseModel): """ Response to login request. Attributes: success: True if login succeeded, False otherwise message: Welcome message on success, error message on failure session_id: (Optional) UUID session identifier on successful login role: (Optional) User's role on successful login ("player", "worldbuilder", "admin", or "superuser") characters: List of available characters for selection available_worlds: List of available worlds for selection """ success: bool message: str session_id: str | None = None role: str | None = None characters: list[dict[str, Any]] = [] available_worlds: list[dict[str, Any]] = []
[docs] class LoginDirectResponse(BaseModel): """ Response to direct login request. Attributes: success: True if login succeeded, False otherwise message: Welcome message on success, error message on failure session_id: Session identifier on successful login role: User's role on successful login character_name: Selected character name on success world_id: World bound to the session """ success: bool message: str session_id: str | None = None role: str | None = None character_name: str | None = None world_id: str | None = None
[docs] class SelectCharacterResponse(BaseModel): """ Response to character selection request. Attributes: success: True if character selected message: Success or error message character_name: Selected character name on success """ success: bool message: str character_name: str | None = None
[docs] class CharactersResponse(BaseModel): """ Response containing the user's characters. Attributes: characters: List of character summaries """ characters: list[dict[str, Any]]
[docs] class RegisterResponse(BaseModel): """ Response to registration request. Attributes: success: True if account created, False otherwise message: Success confirmation or error details """ success: bool message: str
[docs] class RegisterGuestResponse(BaseModel): """ Response to guest registration request. Attributes: success: True if account created, False otherwise message: Success confirmation or error details username: Generated guest username for login """ success: bool message: str username: str | None = None
[docs] class CreateUserResponse(BaseModel): """ Response to admin user creation request. Attributes: success: True if account created, False otherwise message: Success confirmation or error details """ success: bool message: str
[docs] class CommandResponse(BaseModel): """ Response to game command execution. Attributes: success: True if command executed successfully, False for errors message: Command result, room description, error message, etc. For movement: includes new room description For inventory: lists items in inventory For chat: confirmation message For errors: explanation of what went wrong """ success: bool message: str
[docs] class StatusResponse(BaseModel): """ Response containing player's current game status. Used for periodic status updates to keep the UI synchronized. Attributes: active_players: List of usernames currently online current_room: Player's current room ID (e.g., "spawn", "forest_1") inventory: Formatted inventory string (e.g., "Your inventory:\n - Torch\n - Rope") """ active_players: list[str] current_room: str | None inventory: str
[docs] class UserListResponse(BaseModel): """ Response containing list of user accounts. Used for admin user management interfaces. Attributes: users: List of user data dictionaries with account information """ users: list[dict[str, Any]]
[docs] class DatabasePlayersResponse(BaseModel): """ Admin response containing all user records from database. Requires VIEW_LOGS permission. Includes account details and character counts. Attributes: players: List of user data dictionaries with fields: - id: Database record ID - username: Account username - password_hash: Truncated password hash (first 20 chars + "...") - role: User role - account_origin: Account provenance ("visitor", "admin", "superuser", "system", "legacy") - is_guest: Guest flag - guest_expires_at: Guest expiry timestamp - character_count: Number of linked characters - created_at: Account creation timestamp - last_login: Last login timestamp - is_active: Account status (True=active, False=banned) """ players: list[dict[str, Any]]
[docs] class DatabaseTableInfo(BaseModel): """ Metadata about a single database table. Attributes: name: Table name. columns: List of column names in order. row_count: Number of rows in the table. """ name: str columns: list[str] row_count: int
[docs] class DatabaseTablesResponse(BaseModel): """ Admin response containing database table metadata. Requires VIEW_LOGS permission. Used for table discovery in the admin UI. Attributes: tables: List of DatabaseTableInfo entries. """ tables: list[DatabaseTableInfo]
[docs] class DatabaseTableRowsResponse(BaseModel): """ Admin response containing rows for a specific database table. Requires VIEW_LOGS permission. Includes column names and raw row values. Attributes: table: Table name. columns: Column names in order. rows: Row values as a list of rows (each row is a list of values). """ table: str columns: list[str] rows: list[list[Any]]
[docs] class DatabasePlayerLocationsResponse(BaseModel): """ Admin response containing character locations with names. Requires VIEW_LOGS permission. Useful for cross-referencing room occupancy. Attributes: locations: List of dicts with fields: - character_id - character_name - zone_id - room_id - updated_at """ locations: list[dict[str, Any]]
[docs] class DatabaseConnectionsResponse(BaseModel): """ Admin response containing active session connections. Requires VIEW_LOGS permission. Includes activity age for dashboards. Attributes: connections: List of session dictionaries with fields: - id - username - session_id - created_at - last_activity - expires_at - client_type - age_seconds """ connections: list[dict[str, Any]]
[docs] class KickSessionRequest(BaseModel): """ Request to force-disconnect a session. Requires KICK_USERS permission. Attributes: session_id: Admin's active session id. target_session_id: Session id to disconnect. reason: Optional reason for audit/logging. """ session_id: str target_session_id: str reason: str | None = None
[docs] class KickSessionResponse(BaseModel): """ Response for a kick session request. Attributes: success: True if session was removed. message: Human-readable result. """ success: bool message: str
[docs] class DatabaseSessionsResponse(BaseModel): """ Admin response containing all active sessions from database. Requires VIEW_LOGS permission. Shows who is currently logged in. Attributes: sessions: List of session data dictionaries with fields: - id: Database record ID - username: Logged in account - character_name: Active character for the session (if selected) - session_id: UUID session identifier - created_at: Login timestamp - last_activity: Most recent API request timestamp - expires_at: Session expiry timestamp (NULL means no expiry) - client_type: Client identifier (tui, browser, api) """ sessions: list[dict[str, Any]]
[docs] class DatabaseChatResponse(BaseModel): """ Admin response containing recent chat messages across all rooms. Requires VIEW_LOGS permission. Useful for moderation and monitoring. Attributes: messages: List of chat message dictionaries with fields: - id: Database record ID - username: Message sender - message: Message text (includes [WHISPER], [YELL] prefixes) - room: Room ID where message was sent - timestamp: Message timestamp """ messages: list[dict[str, Any]]
[docs] class UserManagementResponse(BaseModel): """ Response to user management action (role change, ban, unban). Attributes: success: True if action completed successfully message: Confirmation message or error details """ success: bool message: str
[docs] class ServerStopResponse(BaseModel): """ Response to server stop request. Server will shutdown shortly after sending this response. Attributes: success: True if shutdown initiated message: Confirmation message indicating who initiated shutdown """ success: bool message: str
[docs] class OllamaCommandRequest(BaseModel): """ Request to execute an Ollama command. Requires VIEW_LOGS permission (admin or superuser only). Attributes: session_id: Active session ID (must have appropriate permission) server_url: URL of the Ollama server (e.g., "http://localhost:11434") command: Ollama command to execute (e.g., "list", "ps", "run llama2") """ session_id: str server_url: str command: str
[docs] class OllamaCommandResponse(BaseModel): """ Response to Ollama command execution. Attributes: success: True if command executed successfully output: Command output or error message """ success: bool output: str
[docs] class ClearOllamaContextRequest(BaseModel): """ Request to clear Ollama conversation context for the current session. Requires VIEW_LOGS permission (admin or superuser only). Attributes: session_id: Active session ID (must have appropriate permission) """ session_id: str
[docs] class ClearOllamaContextResponse(BaseModel): """ Response to clear Ollama context request. Attributes: success: True if context was cleared successfully message: Confirmation message """ success: bool message: str