diff options
Diffstat (limited to 'src/api/tasks.rs')
-rw-r--r-- | src/api/tasks.rs | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/api/tasks.rs b/src/api/tasks.rs new file mode 100644 index 0000000..9a3e1ab --- /dev/null +++ b/src/api/tasks.rs @@ -0,0 +1,104 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, + Json, +}; +use axum_extra::routing::Resource; +use serde::{Deserialize, Serialize}; +use sqlx::PgPool; +use time::OffsetDateTime; +use uuid::Uuid; + +use crate::{auth::AccessClaims, state::AppState}; + +use super::error::Error; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Task { + pub id: Uuid, + pub user_id: Option<Uuid>, + pub title: String, + pub description: Option<String>, + pub remote: bool, + pub location: Option<String>, + pub start_at: Option<OffsetDateTime>, + pub end_at: Option<OffsetDateTime>, + pub created_at: OffsetDateTime, + pub updated_at: OffsetDateTime, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CreateTaskSchema { + pub user_id: Uuid, + pub title: String, + pub description: Option<String>, + pub remote: bool, + pub location: Option<String>, + pub start_at: Option<OffsetDateTime>, + pub end_at: Option<OffsetDateTime>, +} + +pub fn router() -> Resource<AppState> { + Resource::named("tasks") + .create(create) + .show(show) + .destroy(destroy) +} + +pub async fn create( + State(pool): State<PgPool>, + _: AccessClaims, + Json(CreateTaskSchema { + user_id, + title, + description, + remote, + location, + start_at, + end_at, + }): Json<CreateTaskSchema>, +) -> Result<(StatusCode, Json<Task>), Error> { + let task = sqlx::query_as!(Task, + "INSERT INTO task (user_id, title, description, remote, location, start_at, end_at) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *", + user_id, + title, + description, + remote, + location, + start_at, + end_at, + ) + .fetch_one(&pool) + .await?; + + Ok((StatusCode::CREATED, Json(task))) +} + +pub async fn show( + State(pool): State<PgPool>, + Path(uuid): Path<Uuid>, + _: AccessClaims, +) -> Result<Json<Task>, Error> { + sqlx::query_as!(Task, "SELECT * FROM task WHERE id = $1 LIMIT 1", uuid) + .fetch_optional(&pool) + .await? + .ok_or_else(|| Error::TaskNotFound) + .map(Json) +} + +pub async fn destroy( + State(pool): State<PgPool>, + Path(uuid): Path<Uuid>, + AccessClaims { sub, .. }: AccessClaims, +) -> Result<Json<Task>, Error> { + sqlx::query_as!( + Task, + "SELECT * FROM task WHERE id = $1 AND user_id = $2 LIMIT 1", + uuid, + sub + ) + .fetch_optional(&pool) + .await? + .ok_or_else(|| Error::TaskNotFound) + .map(Json) +} |