summaryrefslogtreecommitdiffstats
path: root/src/api/tasks.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/tasks.rs')
-rw-r--r--src/api/tasks.rs104
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)
+}