raisfast 0.2.23

The last backend you'll ever need. Rust-powered headless CMS with built-in blog, ecommerce, wallet, payment and 4 plugin engines.
//! OpenAPI specification and Swagger UI configuration
//!
//! Uses `utoipa` to auto-generate OpenAPI 3.0 specs from handler annotations,
//! served via `/api/docs/openapi.json` as JSON spec,
//! and `/api/docs` redirects to the online Swagger UI.

use axum::http::StatusCode;
#[cfg(feature = "openapi")]
use axum::response::Redirect;
use axum::response::{IntoResponse, Response};
use utoipa::OpenApi;

use crate::dto;

/// OpenAPI specification definition
///
/// Auto-collected from handler `#[utoipa::path]` annotations and DTO `ToSchema` implementations.
#[derive(OpenApi)]
#[openapi(
    paths(
        crate::handlers::health::health,
        crate::handlers::health::liveness,
        crate::handlers::health::readiness,
        crate::handlers::auth::register,
        crate::handlers::auth::login,
        crate::handlers::auth::refresh,
        crate::handlers::auth::logout,
        crate::handlers::auth::forgot_password,
        crate::handlers::auth::reset_password,
        crate::handlers::auth::set_password,
        crate::handlers::api_token::create,
        crate::handlers::api_token::list,
        crate::handlers::api_token::delete,
        crate::handlers::user::get_me,
        crate::handlers::user::update_me,
        crate::handlers::user::change_password,
        crate::handlers::user::list_users,
        crate::handlers::user::get_user,
        crate::handlers::user::update_role,
        crate::handlers::category::list,
        crate::handlers::category::create,
        crate::handlers::category::update,
        crate::handlers::category::delete,
        crate::handlers::tag::list,
        crate::handlers::tag::create,
        crate::handlers::tag::update,
        crate::handlers::tag::delete,
        crate::handlers::post::list,
        crate::handlers::post::get,
        crate::handlers::post::create,
        crate::handlers::post::update,
        crate::handlers::post::delete,
        crate::handlers::comment::list,
        crate::handlers::comment::list_all,
        crate::handlers::comment::create,
        crate::handlers::comment::create_guest,
        crate::handlers::comment::delete,
        crate::handlers::comment::update_status,
        crate::handlers::comment::admin_list,
        crate::handlers::comment::admin_update_status,
        crate::handlers::comment::admin_delete,
        crate::handlers::comment::admin_batch,
        crate::handlers::media::upload,
        crate::handlers::media::list,
        crate::handlers::media::delete,
        crate::handlers::media::stats,
        crate::handlers::media::admin_upload,
        crate::handlers::media::admin_list,
        crate::handlers::media::admin_delete,
        crate::handlers::media::admin_batch,
        crate::handlers::page::list,
        crate::handlers::page::get_by_slug,
        crate::handlers::page::sitemap,
        crate::handlers::page::admin_list,
        crate::handlers::page::admin_get,
        crate::handlers::page::create,
        crate::handlers::page::update,
        crate::handlers::page::delete,
        crate::handlers::page::update_status,
        crate::handlers::page::reorder,
        crate::handlers::page::admin_batch,
        crate::handlers::reusable_block::list_reusable,
        crate::handlers::reusable_block::get_reusable,
        crate::handlers::reusable_block::create_reusable,
        crate::handlers::reusable_block::update_reusable,
        crate::handlers::reusable_block::delete_reusable,
        crate::handlers::reusable_block::admin_batch,
        crate::handlers::rbac::list_roles,
        crate::handlers::rbac::create_role,
        crate::handlers::rbac::update_role,
        crate::handlers::rbac::delete_role,
        crate::handlers::rbac::get_permissions,
        crate::handlers::rbac::set_permissions,
        crate::handlers::rbac::admin_batch,
        crate::handlers::tenant::list_tenants,
        crate::handlers::tenant::get_tenant,
        crate::handlers::tenant::create_tenant,
        crate::handlers::tenant::update_tenant,
        crate::handlers::tenant::delete_tenant,
        crate::handlers::tenant::admin_batch,
        crate::handlers::options::get_public_options,
        crate::handlers::options::list_options,
        crate::handlers::options::get_option,
        crate::handlers::options::update_options,
        crate::handlers::options::set_option,
        crate::handlers::options::delete_option,
        crate::handlers::product::list_active,
        crate::handlers::product::get_product,
        crate::handlers::product::admin_list,
        crate::handlers::product::admin_create,
        crate::handlers::product::admin_update,
        crate::handlers::product::admin_delete,
        crate::handlers::order::create_order,
        crate::handlers::order::list_orders,
        crate::handlers::order::get_order,
        crate::handlers::order::cancel_order_handler,
        crate::handlers::order::confirm_receipt,
        crate::handlers::order::admin_list,
        crate::handlers::order::admin_get,
        crate::handlers::order::admin_ship,
        crate::handlers::order::admin_cancel,
        crate::handlers::order::admin_pay,
        crate::handlers::order::admin_refund,
        crate::handlers::order::admin_update_remark,
        crate::handlers::order::admin_stats,
        crate::handlers::payment::create_payment_order_handler,
        crate::handlers::payment::list_user_orders,
        crate::handlers::payment::get_payment_order_handler,
        crate::handlers::payment::cancel_payment_order_handler,
        crate::handlers::payment::list_order_transactions,
        crate::handlers::payment::list_order_refunds,
        crate::handlers::payment::handle_callback,
        crate::handlers::payment::list_available_channels_handler,
        crate::handlers::payment::admin_list_channels,
        crate::handlers::payment::admin_create_channel,
        crate::handlers::payment::admin_get_channel,
        crate::handlers::payment::admin_update_channel,
        crate::handlers::payment::admin_delete_channel,
        crate::handlers::payment::admin_list_orders,
        crate::handlers::payment::admin_get_order,
        crate::handlers::payment::admin_refund_order,
        crate::handlers::payment::admin_list_transactions,
        crate::handlers::payment::admin_list_refunds,
        crate::handlers::wallet::list_wallets,
        crate::handlers::wallet::get_wallet,
        crate::handlers::wallet::list_transactions,
        crate::handlers::wallet::list_all_transactions,
        crate::handlers::wallet::list_all_wallets,
        crate::handlers::wallet::list_all_transactions_admin,
        crate::handlers::wallet::admin_credit,
        crate::handlers::wallet::admin_debit,
        crate::handlers::wallet::list_user_transactions,
        crate::handlers::wallet::list_user_all_transactions,
        crate::handlers::wallet::admin_reversal,
        crate::handlers::stats::overview,
        crate::handlers::stats::content_stats,
        crate::handlers::stats::trends,
        crate::handlers::oauth::redirect_to_provider,
        crate::handlers::oauth::callback,
        crate::handlers::oauth::list_providers,
        crate::handlers::oauth::list_bindings,
        crate::handlers::oauth::unbind,
        crate::handlers::cron::list,
        crate::handlers::cron::get,
        crate::handlers::cron::create,
        crate::handlers::cron::update,
        crate::handlers::cron::toggle,
        crate::handlers::cron::delete,
        crate::handlers::cron::logs,
        crate::handlers::cron::cleanup_logs,
        crate::handlers::cron::admin_batch,
        crate::handlers::currencies::list_currencies,
        crate::handlers::currencies::get_currency,
        crate::handlers::currencies::create_currency,
        crate::handlers::currencies::update_currency,
        crate::handlers::rss::feed,
        crate::handlers::content_revision::list_revisions,
        crate::handlers::content_revision::get_revision,
        crate::handlers::content_revision::restore_revision,
        crate::handlers::content_revision::diff_revisions,
        crate::handlers::plugin::list,
        crate::handlers::plugin::get,
        crate::handlers::plugin::enable,
        crate::handlers::plugin::disable,
        crate::handlers::plugin::reload,
        crate::handlers::plugin::remove,
        crate::handlers::plugin::admin_batch,
    ),
    components(
        schemas(
            dto::RegisterRequest,
            dto::LoginRequest,
            dto::RefreshRequest,
            dto::UpdateUserRequest,
            dto::UpdatePasswordRequest,
            dto::UpdateRoleRequest,
            dto::UserResponse,
            dto::LoginResponse,
            dto::CreatePostRequest,
            dto::UpdatePostRequest,
            dto::PostResponse,
            dto::CreateCategoryRequest,
            dto::UpdateCategoryRequest,
            dto::CreateTagRequest,
            dto::CreateCommentRequest,
            dto::UpdateCommentStatusRequest,
            dto::MediaResponse,
            dto::CreateTokenRequest,
            crate::models::post::TagBrief,
        )
    ),
    modifiers(&SecurityAddon),
    tags(
        (name = "health", description = "Health Check"),
        (name = "auth", description = "Authentication"),
        (name = "tokens", description = "API Token Management"),
        (name = "users", description = "Users"),
        (name = "posts", description = "Posts"),
        (name = "categories", description = "Categories"),
        (name = "tags", description = "Tags"),
        (name = "comments", description = "Comments"),
        (name = "media", description = "Media"),
        (name = "pages", description = "Pages"),
        (name = "reusable_blocks", description = "Reusable Blocks"),
        (name = "rbac", description = "RBAC"),
        (name = "tenants", description = "Tenants"),
        (name = "options", description = "Options"),
        (name = "products", description = "Products"),
        (name = "orders", description = "Orders"),
        (name = "payments", description = "Payments"),
        (name = "wallets", description = "Wallets"),
        (name = "stats", description = "Statistics"),
        (name = "oauth", description = "OAuth"),
        (name = "cron", description = "Cron Schedules"),
        (name = "currencies", description = "Currencies"),
        (name = "rss", description = "RSS"),
        (name = "revisions", description = "Content Revisions"),
        (name = "plugins", description = "Plugins"),
    )
)]
pub struct ApiDoc;

/// JWT Bearer Auth security scheme
struct SecurityAddon;

impl utoipa::Modify for SecurityAddon {
    fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) {
        if let Some(components) = openapi.components.as_mut() {
            components.add_security_scheme(
                "bearer_auth",
                utoipa::openapi::security::SecurityScheme::Http(
                    utoipa::openapi::security::Http::new(
                        utoipa::openapi::security::HttpAuthScheme::Bearer,
                    ),
                ),
            );
        }
    }
}

/// Serve the OpenAPI JSON specification
pub async fn serve_openapi_json() -> Response {
    let spec = ApiDoc::openapi();
    let json = serde_json::to_string_pretty(&spec).unwrap_or_default();
    (StatusCode::OK, [("Content-Type", "application/json")], json).into_response()
}

/// Redirect to the online Swagger UI (only compiled when `openapi` feature is enabled)
#[cfg(feature = "openapi")]
pub async fn redirect_to_swagger() -> Redirect {
    let spec_url = "http://localhost:9898/api/docs/openapi.json";
    Redirect::temporary(&format!("https://petstore.swagger.io/?url={spec_url}"))
}