feat: add utoipa path annotations to all API handlers and wire OpenAPI spec
- Add #[utoipa::path] annotations to all 70+ handler functions across auth, config, workflow, and message modules - Add IntoParams/ToSchema derives to Pagination, PaginatedResponse, ApiResponse in erp-core, and MessageQuery/TemplateQuery in erp-message - Collect all module paths into OpenAPI spec via AuthApiDoc, ConfigApiDoc, WorkflowApiDoc, MessageApiDoc structs in erp-server main.rs - Update openapi_spec handler to merge all module specs - The /docs/openapi.json endpoint now returns complete API documentation with all endpoints, request/response schemas, and security requirements
This commit is contained in:
@@ -2,6 +2,7 @@ use axum::Extension;
|
||||
use axum::extract::{FromRef, Path, Query, State};
|
||||
use axum::response::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
@@ -14,7 +15,7 @@ use crate::service::user_service::UserService;
|
||||
use erp_core::rbac::require_permission;
|
||||
|
||||
/// Query parameters for user list endpoint.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(Debug, Deserialize, IntoParams)]
|
||||
pub struct UserListParams {
|
||||
pub page: Option<u64>,
|
||||
pub page_size: Option<u64>,
|
||||
@@ -22,6 +23,18 @@ pub struct UserListParams {
|
||||
pub search: Option<String>,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/users",
|
||||
params(UserListParams),
|
||||
responses(
|
||||
(status = 200, description = "成功", body = ApiResponse<PaginatedResponse<UserResp>>),
|
||||
(status = 401, description = "未授权"),
|
||||
(status = 403, description = "权限不足"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "用户管理"
|
||||
)]
|
||||
/// GET /api/v1/users
|
||||
///
|
||||
/// List users within the current tenant with pagination and optional search.
|
||||
@@ -62,6 +75,18 @@ where
|
||||
})))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/users",
|
||||
request_body = CreateUserReq,
|
||||
responses(
|
||||
(status = 200, description = "创建成功", body = ApiResponse<UserResp>),
|
||||
(status = 401, description = "未授权"),
|
||||
(status = 403, description = "权限不足"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "用户管理"
|
||||
)]
|
||||
/// POST /api/v1/users
|
||||
///
|
||||
/// Create a new user within the current tenant.
|
||||
@@ -92,6 +117,19 @@ where
|
||||
Ok(Json(ApiResponse::ok(user)))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/v1/users/{id}",
|
||||
params(("id" = Uuid, Path, description = "用户ID")),
|
||||
responses(
|
||||
(status = 200, description = "成功", body = ApiResponse<UserResp>),
|
||||
(status = 401, description = "未授权"),
|
||||
(status = 403, description = "权限不足"),
|
||||
(status = 404, description = "用户不存在"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "用户管理"
|
||||
)]
|
||||
/// GET /api/v1/users/:id
|
||||
///
|
||||
/// Fetch a single user by ID within the current tenant.
|
||||
@@ -111,6 +149,20 @@ where
|
||||
Ok(Json(ApiResponse::ok(user)))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
put,
|
||||
path = "/api/v1/users/{id}",
|
||||
params(("id" = Uuid, Path, description = "用户ID")),
|
||||
request_body = UpdateUserReq,
|
||||
responses(
|
||||
(status = 200, description = "更新成功", body = ApiResponse<UserResp>),
|
||||
(status = 401, description = "未授权"),
|
||||
(status = 403, description = "权限不足"),
|
||||
(status = 404, description = "用户不存在"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "用户管理"
|
||||
)]
|
||||
/// PUT /api/v1/users/:id
|
||||
///
|
||||
/// Update editable user fields.
|
||||
@@ -131,6 +183,19 @@ where
|
||||
Ok(Json(ApiResponse::ok(user)))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
delete,
|
||||
path = "/api/v1/users/{id}",
|
||||
params(("id" = Uuid, Path, description = "用户ID")),
|
||||
responses(
|
||||
(status = 200, description = "用户已删除"),
|
||||
(status = 401, description = "未授权"),
|
||||
(status = 403, description = "权限不足"),
|
||||
(status = 404, description = "用户不存在"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "用户管理"
|
||||
)]
|
||||
/// DELETE /api/v1/users/:id
|
||||
///
|
||||
/// Soft-delete a user by ID within the current tenant.
|
||||
@@ -156,17 +221,31 @@ where
|
||||
}
|
||||
|
||||
/// Assign roles request body.
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(Debug, Deserialize, ToSchema)]
|
||||
pub struct AssignRolesReq {
|
||||
pub role_ids: Vec<Uuid>,
|
||||
}
|
||||
|
||||
/// Assign roles response.
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub struct AssignRolesResp {
|
||||
pub roles: Vec<RoleResp>,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/v1/users/{id}/roles",
|
||||
params(("id" = Uuid, Path, description = "用户ID")),
|
||||
request_body = AssignRolesReq,
|
||||
responses(
|
||||
(status = 200, description = "角色分配成功", body = ApiResponse<AssignRolesResp>),
|
||||
(status = 401, description = "未授权"),
|
||||
(status = 403, description = "权限不足"),
|
||||
(status = 404, description = "用户不存在"),
|
||||
),
|
||||
security(("bearer_auth" = [])),
|
||||
tag = "用户管理"
|
||||
)]
|
||||
/// POST /api/v1/users/:id/roles
|
||||
///
|
||||
/// Replace all role assignments for a user within the current tenant.
|
||||
|
||||
Reference in New Issue
Block a user