From 5df718af71cc861f7b7ced5635a38ed9e76cb0f1 Mon Sep 17 00:00:00 2001 From: Tolmachev Igor Date: Thu, 25 Sep 2025 15:51:38 +0300 Subject: Separate queue module --- src/routers/mod.rs | 2 +- src/routers/queue.rs | 233 -------------------------------------------- src/routers/queue/manage.rs | 233 ++++++++++++++++++++++++++++++++++++++++++++ src/routers/queue/mod.rs | 9 ++ 4 files changed, 243 insertions(+), 234 deletions(-) delete mode 100644 src/routers/queue.rs create mode 100644 src/routers/queue/manage.rs create mode 100644 src/routers/queue/mod.rs (limited to 'src/routers') diff --git a/src/routers/mod.rs b/src/routers/mod.rs index c73e1f8..b7bc1e6 100644 --- a/src/routers/mod.rs +++ b/src/routers/mod.rs @@ -9,5 +9,5 @@ use crate::{AppOpenApi, AppState}; pub fn router() -> OpenApiRouter { OpenApiRouter::with_openapi(AppOpenApi::openapi()) .nest("/account", account::router()) - .nest("/queue", queue::routes()) + .nest("/queue", queue::router()) } diff --git a/src/routers/queue.rs b/src/routers/queue.rs deleted file mode 100644 index 021fbe5..0000000 --- a/src/routers/queue.rs +++ /dev/null @@ -1,233 +0,0 @@ -use axum::extract::State; -use entity::{queues, users}; -use sea_orm::{ - ActiveModelTrait, ActiveValue::Set, ColumnTrait, DatabaseConnection, EntityTrait, - IntoActiveModel, ModelTrait, QueryFilter, -}; -use serde::Deserialize; -use utoipa::ToSchema; -use utoipa_axum::{router::OpenApiRouter, routes}; - -use crate::{ - ApiError, ApiResult, AppState, ClientError, GlobalResponses, SuccessResponse, - extract::{ApiJson, Auth}, - models::Queue, - tags::QUEUE, -}; - -async fn user_exists(id: i64, db: &DatabaseConnection) -> Result { - Ok(users::Entity::find_by_id(id).one(db).await?.is_some()) -} - -async fn get_owned_queue( - id: i64, - owner_id: i64, - db: &DatabaseConnection, -) -> Result { - let queue = queues::Entity::find_by_id(id) - .one(db) - .await? - .ok_or(ClientError::QueueNotFound { id })?; - - if queue.owner_id != owner_id { - return Err(ClientError::NotQueueOwner { id: queue.id }.into()); - } - - Ok(queue) -} - -#[derive(Deserialize, ToSchema)] -#[schema(description = "Body of the create queue request")] -struct CreateQueueRequest { - #[schema(examples("John's queue", "Очередь Ивана"))] - name: String, -} - -#[derive(Deserialize, ToSchema)] -#[schema(description = "Body of the change queue name request")] -struct ChangeQueueNameRequest { - #[schema(examples(1))] - id: i64, - #[schema(examples("John's queue", "Очередь Ивана"))] - new_name: String, -} - -#[derive(Deserialize, ToSchema)] -#[schema(description = "Body of the change queue ownership request")] -struct ChangeQueueOwnershipRequest { - #[schema(examples(1))] - id: i64, - #[schema(examples(1))] - new_owner_id: i64, -} - -#[derive(Deserialize, ToSchema)] -#[schema(description = "Body of the delete queue request")] -struct DeleteQueueRequest { - #[schema(examples(1))] - id: i64, -} - -#[utoipa::path( - get, - path = "/owned", - tag = QUEUE, - summary = "Get owned", - description = "Get your queues", - responses( - ( - status = 200, body = SuccessResponse>, - description = "Success response with your queues" - ), - GlobalResponses - ), - security(("auth" = [])), -)] -async fn owned(State(state): State, Auth(user): Auth) -> ApiResult> { - return Ok(SuccessResponse::ok( - queues::Entity::find() - .filter(queues::Column::OwnerId.eq(user.id)) - .all(&state.db) - .await? - .into_iter() - .map(Into::into) - .collect(), - )); -} - -#[utoipa::path( - post, - path = "/create", - tag = QUEUE, - summary = "Create", - description = "Create a new queue", - request_body = CreateQueueRequest, - responses( - ( - status = 200, body = SuccessResponse, - description = "Success response with the created queue" - ), - GlobalResponses - ), - security(("auth" = [])), -)] -async fn create( - State(state): State, - Auth(user): Auth, - ApiJson(req): ApiJson, -) -> ApiResult { - Ok(SuccessResponse::ok( - queues::ActiveModel { - owner_id: Set(user.id), - name: Set(req.name), - ..Default::default() - } - .insert(&state.db) - .await? - .into(), - )) -} - -#[utoipa::path( - put, - path = "/change/name", - tag = QUEUE, - summary = "Change name", - description = "Change queue name", - request_body = ChangeQueueNameRequest, - responses( - ( - status = 200, body = SuccessResponse, - description = "Success response with the changed queue data" - ), - GlobalResponses - ), - security(("auth" = [])), -)] -async fn change_name( - State(state): State, - Auth(user): Auth, - ApiJson(req): ApiJson, -) -> ApiResult { - let mut active_queue = get_owned_queue(req.id, user.id, &state.db) - .await? - .into_active_model(); - - active_queue.name = Set(req.new_name); - - let queue = active_queue.update(&state.db).await?; - Ok(SuccessResponse::ok(queue.into())) -} - -#[utoipa::path( - put, - path = "/change/owner", - tag = QUEUE, - summary = "Change owner", - description = "Reassign queue ownership", - request_body = ChangeQueueOwnershipRequest, - responses( - ( - status = 200, body = SuccessResponse, - description = "Success response with the changed queue data" - ), - GlobalResponses - ), - security(("auth" = [])), -)] -async fn change_owner( - State(state): State, - Auth(user): Auth, - ApiJson(req): ApiJson, -) -> ApiResult { - if !user_exists(req.new_owner_id, &state.db).await? { - return Err(ClientError::UserNotFound { - id: req.new_owner_id, - } - .into()); - } - - let mut active_queue = get_owned_queue(req.id, user.id, &state.db) - .await? - .into_active_model(); - - active_queue.owner_id = Set(req.new_owner_id); - - let queue = active_queue.update(&state.db).await?; - Ok(SuccessResponse::ok(queue.into())) -} - -#[utoipa::path( - delete, - path = "/delete", - tag = QUEUE, - summary = "Delete", - description = "Delete the queue", - request_body = DeleteQueueRequest, - responses( - ( - status = 200, body = SuccessResponse, - description = "Success response with the deleted queue data" - ), - GlobalResponses - ), - security(("auth" = [])), -)] -async fn delete( - State(state): State, - Auth(user): Auth, - ApiJson(req): ApiJson, -) -> ApiResult { - let queue = get_owned_queue(req.id, user.id, &state.db).await?; - queue.clone().delete(&state.db).await?; - Ok(SuccessResponse::ok(queue.into())) -} - -pub fn routes() -> OpenApiRouter { - OpenApiRouter::new() - .routes(routes!(owned)) - .routes(routes!(create)) - .routes(routes!(change_name)) - .routes(routes!(change_owner)) - .routes(routes!(delete)) -} diff --git a/src/routers/queue/manage.rs b/src/routers/queue/manage.rs new file mode 100644 index 0000000..f174bd5 --- /dev/null +++ b/src/routers/queue/manage.rs @@ -0,0 +1,233 @@ +use axum::extract::State; +use entity::{queues, users}; +use sea_orm::{ + ActiveModelTrait, ActiveValue::Set, ColumnTrait, DatabaseConnection, EntityTrait, + IntoActiveModel, ModelTrait, QueryFilter, +}; +use serde::Deserialize; +use utoipa::ToSchema; +use utoipa_axum::{router::OpenApiRouter, routes}; + +use crate::{ + ApiError, ApiResult, AppState, ClientError, GlobalResponses, SuccessResponse, + extract::{ApiJson, Auth}, + models::Queue, + tags::QUEUE, +}; + +async fn user_exists(id: i64, db: &DatabaseConnection) -> Result { + Ok(users::Entity::find_by_id(id).one(db).await?.is_some()) +} + +async fn get_owned_queue( + id: i64, + owner_id: i64, + db: &DatabaseConnection, +) -> Result { + let queue = queues::Entity::find_by_id(id) + .one(db) + .await? + .ok_or(ClientError::QueueNotFound { id })?; + + if queue.owner_id != owner_id { + return Err(ClientError::NotQueueOwner { id: queue.id }.into()); + } + + Ok(queue) +} + +#[derive(Deserialize, ToSchema)] +#[schema(description = "Body of the create queue request")] +struct CreateQueueRequest { + #[schema(examples("John's queue", "Очередь Ивана"))] + name: String, +} + +#[derive(Deserialize, ToSchema)] +#[schema(description = "Body of the change queue name request")] +struct ChangeQueueNameRequest { + #[schema(examples(1))] + id: i64, + #[schema(examples("John's queue", "Очередь Ивана"))] + new_name: String, +} + +#[derive(Deserialize, ToSchema)] +#[schema(description = "Body of the change queue ownership request")] +struct ChangeQueueOwnershipRequest { + #[schema(examples(1))] + id: i64, + #[schema(examples(1))] + new_owner_id: i64, +} + +#[derive(Deserialize, ToSchema)] +#[schema(description = "Body of the delete queue request")] +struct DeleteQueueRequest { + #[schema(examples(1))] + id: i64, +} + +#[utoipa::path( + get, + path = "/owned", + tag = QUEUE, + summary = "Get owned", + description = "Get your queues", + responses( + ( + status = 200, body = SuccessResponse>, + description = "Success response with your queues" + ), + GlobalResponses + ), + security(("auth" = [])), +)] +async fn owned(State(state): State, Auth(user): Auth) -> ApiResult> { + return Ok(SuccessResponse::ok( + queues::Entity::find() + .filter(queues::Column::OwnerId.eq(user.id)) + .all(&state.db) + .await? + .into_iter() + .map(Into::into) + .collect(), + )); +} + +#[utoipa::path( + post, + path = "/create", + tag = QUEUE, + summary = "Create", + description = "Create a new queue", + request_body = CreateQueueRequest, + responses( + ( + status = 200, body = SuccessResponse, + description = "Success response with the created queue" + ), + GlobalResponses + ), + security(("auth" = [])), +)] +async fn create( + State(state): State, + Auth(user): Auth, + ApiJson(req): ApiJson, +) -> ApiResult { + Ok(SuccessResponse::ok( + queues::ActiveModel { + owner_id: Set(user.id), + name: Set(req.name), + ..Default::default() + } + .insert(&state.db) + .await? + .into(), + )) +} + +#[utoipa::path( + put, + path = "/change/name", + tag = QUEUE, + summary = "Change name", + description = "Change queue name", + request_body = ChangeQueueNameRequest, + responses( + ( + status = 200, body = SuccessResponse, + description = "Success response with the changed queue data" + ), + GlobalResponses + ), + security(("auth" = [])), +)] +async fn change_name( + State(state): State, + Auth(user): Auth, + ApiJson(req): ApiJson, +) -> ApiResult { + let mut active_queue = get_owned_queue(req.id, user.id, &state.db) + .await? + .into_active_model(); + + active_queue.name = Set(req.new_name); + + let queue = active_queue.update(&state.db).await?; + Ok(SuccessResponse::ok(queue.into())) +} + +#[utoipa::path( + put, + path = "/change/owner", + tag = QUEUE, + summary = "Change owner", + description = "Reassign queue ownership", + request_body = ChangeQueueOwnershipRequest, + responses( + ( + status = 200, body = SuccessResponse, + description = "Success response with the changed queue data" + ), + GlobalResponses + ), + security(("auth" = [])), +)] +async fn change_owner( + State(state): State, + Auth(user): Auth, + ApiJson(req): ApiJson, +) -> ApiResult { + if !user_exists(req.new_owner_id, &state.db).await? { + return Err(ClientError::UserNotFound { + id: req.new_owner_id, + } + .into()); + } + + let mut active_queue = get_owned_queue(req.id, user.id, &state.db) + .await? + .into_active_model(); + + active_queue.owner_id = Set(req.new_owner_id); + + let queue = active_queue.update(&state.db).await?; + Ok(SuccessResponse::ok(queue.into())) +} + +#[utoipa::path( + delete, + path = "/delete", + tag = QUEUE, + summary = "Delete", + description = "Delete the queue", + request_body = DeleteQueueRequest, + responses( + ( + status = 200, body = SuccessResponse, + description = "Success response with the deleted queue data" + ), + GlobalResponses + ), + security(("auth" = [])), +)] +async fn delete( + State(state): State, + Auth(user): Auth, + ApiJson(req): ApiJson, +) -> ApiResult { + let queue = get_owned_queue(req.id, user.id, &state.db).await?; + queue.clone().delete(&state.db).await?; + Ok(SuccessResponse::ok(queue.into())) +} + +pub fn router() -> OpenApiRouter { + OpenApiRouter::new() + .routes(routes!(owned)) + .routes(routes!(create)) + .routes(routes!(change_name)) + .routes(routes!(change_owner)) + .routes(routes!(delete)) +} diff --git a/src/routers/queue/mod.rs b/src/routers/queue/mod.rs new file mode 100644 index 0000000..bf2acb5 --- /dev/null +++ b/src/routers/queue/mod.rs @@ -0,0 +1,9 @@ +mod manage; + +use utoipa_axum::router::OpenApiRouter; + +use crate::AppState; + +pub fn router() -> OpenApiRouter { + OpenApiRouter::new().merge(manage::router()) +} -- cgit v1.2.3