pub mod request { use serde::{Deserialize, Serialize}; use utoipa::ToSchema; #[derive(Debug, Deserialize, Serialize, ToSchema)] pub struct ScheduleMessageRequest { #[serde(with = "time::serde::rfc3339::option")] pub scheduled: Option, pub status: String, pub user_id: uuid::Uuid, } impl ScheduleMessageRequest { pub fn is_valid(&self) -> bool { self.scheduled.is_some() || !self.status.is_empty() || !self.user_id.is_nil() } } } pub mod response { use serde::{Deserialize, Serialize}; use utoipa::ToSchema; #[derive(Debug, Default, Deserialize, Serialize, ToSchema)] pub struct ScheduleMessageResponse { pub message: String, pub data: Vec } } pub mod endpoint { use crate::repo::scheduling as scheduling_repo; /// Endpoint to create a Scheudled Message #[utoipa::path( post, path = crate::caller::endpoints::SCHEDULE_MESSAGE, request_body( content = super::request::ScheduleMessageRequest, description = "Data needed to create a Scheduled Message", content_type = "application/json" ), responses( (status = 201, description = "Scheduled Message created", body = super::response::ScheduleMessageResponse), (status = 400, description = "Error", body = super::response::ScheduleMessageResponse), (status = 500, description = "Error creating Scheduled Message", body = super::response::ScheduleMessageResponse) ) )] pub async fn schedule_message( axum::Extension(pool): axum::Extension, axum::Json(payload): axum::Json, ) -> ( axum::http::StatusCode, axum::Json, ) { let mut response = super::response::ScheduleMessageResponse::default(); if payload.is_valid() { if payload.status != textsender_models::message::scheduling::PENDING { response.message = String::from("scheduled message must be pending"); (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) } else { if can_schedule(&payload.scheduled) { let mut scheduled_message = textsender_models::message::scheduling::ScheduledMessage { user_id: payload.user_id, ..Default::default() }; match scheduling_repo::insert(&pool, &scheduled_message, &payload.user_id).await { Ok((id, created)) => { scheduled_message.id = id; scheduled_message.created = Some(created); response.message = String::from("Message scheduled"); (axum::http::StatusCode::CREATED, axum::Json(response)) } Err(err) => { eprintln!("Error: {err:?}"); response.message = String::from("Error inserting"); (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(response)) } } } else { response.message = String::from("Cannot schedule message"); (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) } } } else { response.message = String::from("Request body is not valid"); (axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) } } fn can_schedule(scheduled_time: &Option) -> bool { scheduled_time.is_some_and(|t| t - time::OffsetDateTime::now_utc() >= time::Duration::minutes(10)) } }