use utoipa::openapi::security::{HttpAuthScheme, HttpBuilder, SecurityScheme}; use utoipa::{Modify, OpenApi}; struct BearerAuth; impl Modify for BearerAuth { fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { if let Some(components) = openapi.components.as_mut() { components.add_security_scheme( "bearer", SecurityScheme::Http( HttpBuilder::new() .scheme(HttpAuthScheme::Bearer) .bearer_format("JWT") .build(), ), ); } } } #[derive(OpenApi)] #[openapi( info( title = "K-TV API", version = "1.0.0", description = "Self-hosted linear TV channel orchestration", ), modifiers(&BearerAuth), paths( crate::handlers::auth::register, crate::handlers::auth::login, crate::handlers::auth::logout, crate::handlers::auth::me, crate::handlers::auth::refresh_token, crate::handlers::channels::list_channels, crate::handlers::channels::list_my_channels, crate::handlers::channels::create_channel, crate::handlers::channels::get_channel, crate::handlers::channels::update_channel, crate::handlers::channels::delete_channel, crate::handlers::channels::save_snapshot, crate::handlers::channels::list_snapshots, crate::handlers::channels::get_snapshot, crate::handlers::channels::patch_snapshot, crate::handlers::channels::restore_snapshot, crate::handlers::schedule::generate_schedule, crate::handlers::schedule::get_active_schedule, crate::handlers::schedule::get_current_broadcast, crate::handlers::schedule::get_epg, crate::handlers::schedule::get_stream, crate::handlers::schedule::list_schedule_history, crate::handlers::admin::get_settings, crate::handlers::admin::update_settings, crate::handlers::admin::get_activity_log, crate::handlers::providers::list_providers, crate::handlers::providers::get_provider, crate::handlers::providers::upsert_provider, crate::handlers::providers::delete_provider, crate::handlers::config::get_config, crate::handlers::iptv::m3u_playlist, crate::handlers::iptv::xmltv_epg, crate::handlers::library::search_items, crate::handlers::library::get_item, crate::handlers::library::list_collections, crate::handlers::library::list_shows, crate::handlers::library::list_seasons, crate::handlers::library::list_genres, crate::handlers::library::sync_status, crate::handlers::library::trigger_sync, ), components(schemas( api_types::LoginRequest, api_types::RegisterRequest, api_types::RefreshRequest, api_types::TokenResponse, api_types::UserResponse, api_types::ChannelResponse, api_types::CreateChannelRequest, api_types::UpdateChannelRequest, api_types::ConfigSnapshotResponse, api_types::PatchSnapshotRequest, api_types::ScheduleResponse, api_types::SlotResponse, api_types::MediaItemResponse, api_types::CurrentBroadcastResponse, api_types::ScheduleHistoryEntry, api_types::SettingsResponse, api_types::ActivityEventResponse, api_types::ActivityLogParams, api_types::ProviderConfigRequest, api_types::ProviderConfigResponse, api_types::ConfigResponse, api_types::ProviderCapabilitiesResponse, api_types::ProviderInfo, api_types::IptvParams, api_types::LibraryItemResponse, api_types::CollectionResponse, api_types::ShowResponse, api_types::SeasonResponse, api_types::SyncStatusEntry, api_types::LibrarySearchParams, api_types::ProviderParam, api_types::ShowsParams, api_types::SeasonsParams, api_types::GenresParams, api_types::PaginatedResponse, api_types::ErrorResponse, )), security( ("bearer" = []), ), tags( (name = "auth", description = "Authentication"), (name = "channels", description = "Channel management"), (name = "schedule", description = "Schedule generation and playback"), (name = "admin", description = "Admin settings and activity"), (name = "providers", description = "Media provider configuration"), (name = "config", description = "Public system configuration"), (name = "iptv", description = "IPTV playlist and EPG feeds"), (name = "library", description = "Media library browsing and sync"), ), )] pub struct ApiDoc;