aboutsummaryrefslogtreecommitdiff
path: root/src/routers/queue/manage.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/routers/queue/manage.rs')
-rw-r--r--src/routers/queue/manage.rs233
1 files changed, 233 insertions, 0 deletions
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 @@
1use axum::extract::State;
2use entity::{queues, users};
3use sea_orm::{
4 ActiveModelTrait, ActiveValue::Set, ColumnTrait, DatabaseConnection, EntityTrait,
5 IntoActiveModel, ModelTrait, QueryFilter,
6};
7use serde::Deserialize;
8use utoipa::ToSchema;
9use utoipa_axum::{router::OpenApiRouter, routes};
10
11use crate::{
12 ApiError, ApiResult, AppState, ClientError, GlobalResponses, SuccessResponse,
13 extract::{ApiJson, Auth},
14 models::Queue,
15 tags::QUEUE,
16};
17
18async fn user_exists(id: i64, db: &DatabaseConnection) -> Result<bool, ApiError> {
19 Ok(users::Entity::find_by_id(id).one(db).await?.is_some())
20}
21
22async fn get_owned_queue(
23 id: i64,
24 owner_id: i64,
25 db: &DatabaseConnection,
26) -> Result<queues::Model, ApiError> {
27 let queue = queues::Entity::find_by_id(id)
28 .one(db)
29 .await?
30 .ok_or(ClientError::QueueNotFound { id })?;
31
32 if queue.owner_id != owner_id {
33 return Err(ClientError::NotQueueOwner { id: queue.id }.into());
34 }
35
36 Ok(queue)
37}
38
39#[derive(Deserialize, ToSchema)]
40#[schema(description = "Body of the create queue request")]
41struct CreateQueueRequest {
42 #[schema(examples("John's queue", "Очередь Ивана"))]
43 name: String,
44}
45
46#[derive(Deserialize, ToSchema)]
47#[schema(description = "Body of the change queue name request")]
48struct ChangeQueueNameRequest {
49 #[schema(examples(1))]
50 id: i64,
51 #[schema(examples("John's queue", "Очередь Ивана"))]
52 new_name: String,
53}
54
55#[derive(Deserialize, ToSchema)]
56#[schema(description = "Body of the change queue ownership request")]
57struct ChangeQueueOwnershipRequest {
58 #[schema(examples(1))]
59 id: i64,
60 #[schema(examples(1))]
61 new_owner_id: i64,
62}
63
64#[derive(Deserialize, ToSchema)]
65#[schema(description = "Body of the delete queue request")]
66struct DeleteQueueRequest {
67 #[schema(examples(1))]
68 id: i64,
69}
70
71#[utoipa::path(
72 get,
73 path = "/owned",
74 tag = QUEUE,
75 summary = "Get owned",
76 description = "Get your queues",
77 responses(
78 (
79 status = 200, body = SuccessResponse<Vec<Queue>>,
80 description = "Success response with your queues"
81 ),
82 GlobalResponses
83 ),
84 security(("auth" = [])),
85)]
86async fn owned(State(state): State<AppState>, Auth(user): Auth) -> ApiResult<Vec<Queue>> {
87 return Ok(SuccessResponse::ok(
88 queues::Entity::find()
89 .filter(queues::Column::OwnerId.eq(user.id))
90 .all(&state.db)
91 .await?
92 .into_iter()
93 .map(Into::into)
94 .collect(),
95 ));
96}
97
98#[utoipa::path(
99 post,
100 path = "/create",
101 tag = QUEUE,
102 summary = "Create",
103 description = "Create a new queue",
104 request_body = CreateQueueRequest,
105 responses(
106 (
107 status = 200, body = SuccessResponse<Queue>,
108 description = "Success response with the created queue"
109 ),
110 GlobalResponses
111 ),
112 security(("auth" = [])),
113)]
114async fn create(
115 State(state): State<AppState>,
116 Auth(user): Auth,
117 ApiJson(req): ApiJson<CreateQueueRequest>,
118) -> ApiResult<Queue> {
119 Ok(SuccessResponse::ok(
120 queues::ActiveModel {
121 owner_id: Set(user.id),
122 name: Set(req.name),
123 ..Default::default()
124 }
125 .insert(&state.db)
126 .await?
127 .into(),
128 ))
129}
130
131#[utoipa::path(
132 put,
133 path = "/change/name",
134 tag = QUEUE,
135 summary = "Change name",
136 description = "Change queue name",
137 request_body = ChangeQueueNameRequest,
138 responses(
139 (
140 status = 200, body = SuccessResponse<Queue>,
141 description = "Success response with the changed queue data"
142 ),
143 GlobalResponses
144 ),
145 security(("auth" = [])),
146)]
147async fn change_name(
148 State(state): State<AppState>,
149 Auth(user): Auth,
150 ApiJson(req): ApiJson<ChangeQueueNameRequest>,
151) -> ApiResult<Queue> {
152 let mut active_queue = get_owned_queue(req.id, user.id, &state.db)
153 .await?
154 .into_active_model();
155
156 active_queue.name = Set(req.new_name);
157
158 let queue = active_queue.update(&state.db).await?;
159 Ok(SuccessResponse::ok(queue.into()))
160}
161
162#[utoipa::path(
163 put,
164 path = "/change/owner",
165 tag = QUEUE,
166 summary = "Change owner",
167 description = "Reassign queue ownership",
168 request_body = ChangeQueueOwnershipRequest,
169 responses(
170 (
171 status = 200, body = SuccessResponse<Queue>,
172 description = "Success response with the changed queue data"
173 ),
174 GlobalResponses
175 ),
176 security(("auth" = [])),
177)]
178async fn change_owner(
179 State(state): State<AppState>,
180 Auth(user): Auth,
181 ApiJson(req): ApiJson<ChangeQueueOwnershipRequest>,
182) -> ApiResult<Queue> {
183 if !user_exists(req.new_owner_id, &state.db).await? {
184 return Err(ClientError::UserNotFound {
185 id: req.new_owner_id,
186 }
187 .into());
188 }
189
190 let mut active_queue = get_owned_queue(req.id, user.id, &state.db)
191 .await?
192 .into_active_model();
193
194 active_queue.owner_id = Set(req.new_owner_id);
195
196 let queue = active_queue.update(&state.db).await?;
197 Ok(SuccessResponse::ok(queue.into()))
198}
199
200#[utoipa::path(
201 delete,
202 path = "/delete",
203 tag = QUEUE,
204 summary = "Delete",
205 description = "Delete the queue",
206 request_body = DeleteQueueRequest,
207 responses(
208 (
209 status = 200, body = SuccessResponse<Queue>,
210 description = "Success response with the deleted queue data"
211 ),
212 GlobalResponses
213 ),
214 security(("auth" = [])),
215)]
216async fn delete(
217 State(state): State<AppState>,
218 Auth(user): Auth,
219 ApiJson(req): ApiJson<DeleteQueueRequest>,
220) -> ApiResult<Queue> {
221 let queue = get_owned_queue(req.id, user.id, &state.db).await?;
222 queue.clone().delete(&state.db).await?;
223 Ok(SuccessResponse::ok(queue.into()))
224}
225
226pub fn router() -> OpenApiRouter<AppState> {
227 OpenApiRouter::new()
228 .routes(routes!(owned))
229 .routes(routes!(create))
230 .routes(routes!(change_name))
231 .routes(routes!(change_owner))
232 .routes(routes!(delete))
233}