Adds action CRUD

This commit is contained in:
2026-07-08 19:30:41 +02:00
parent eb078be3c6
commit c93e35b216
5 changed files with 133 additions and 6 deletions
+104 -1
View File
@@ -1,5 +1,5 @@
use crate::auth::Authenticated; use crate::auth::Authenticated;
use crate::dtos::action::ActionDTO; use crate::dtos::action::{ActionDTO, NewActionDTO, UpdateActionDTO};
use crate::models::action::Action; use crate::models::action::Action;
use crate::models::{AppState, DEFAULT_QUERY_LIMIT}; use crate::models::{AppState, DEFAULT_QUERY_LIMIT};
use crate::schema::actions::dsl::actions; use crate::schema::actions::dsl::actions;
@@ -7,6 +7,7 @@ use diesel::{QueryDsl, RunQueryDsl, SelectableHelper};
use rocket::State; use rocket::State;
use rocket::http::Status; use rocket::http::Status;
use rocket::serde::json::Json; use rocket::serde::json::Json;
use uuid::Uuid;
#[get("/?<offset>&<limit>")] #[get("/?<offset>&<limit>")]
pub fn index( pub fn index(
@@ -32,3 +33,105 @@ pub fn index(
None => Err(Status::InternalServerError), None => Err(Status::InternalServerError),
} }
} }
#[put("/", format = "json", data = "<data>")]
pub fn create(
data: Json<NewActionDTO>,
_auth: Authenticated,
state: &State<AppState>,
) -> Result<Json<ActionDTO>, Status> {
let mut db = state.db.get().unwrap();
let new = Action {
id: Uuid::new_v4(),
name: data.name.clone(),
source: data.source.clone(),
created_at: chrono::Local::now().naive_local(),
updated_at: chrono::Local::now().naive_local(),
};
let result = diesel::insert_into(actions)
.values(&new)
.returning(Action::as_returning())
.get_result(&mut db)
.ok();
match result {
Some(result) => Ok(Json(ActionDTO::from(&result))),
None => Err(Status::InternalServerError),
}
}
// TODO: add execute
#[get("/<id>")]
pub fn get(
id: &str,
_auth: Authenticated,
state: &State<AppState>,
) -> Result<Json<ActionDTO>, Status> {
let mut db = state.db.get().unwrap();
let id = match Uuid::parse_str(id).ok() {
Some(id) => id,
None => return Err(Status::BadRequest),
};
let result = actions.find(id).first(&mut db).ok();
match result {
Some(result) => Ok(Json(ActionDTO::from(&result))),
None => Err(Status::NotFound),
}
}
#[patch("/<id>", format = "json", data = "<data>")]
pub fn update(
id: &str,
data: Json<UpdateActionDTO>,
_auth: Authenticated,
state: &State<AppState>,
) -> Result<Status, Status> {
let mut db = state.db.get().unwrap();
let id = match Uuid::parse_str(id).ok() {
Some(id) => id,
None => return Err(Status::BadRequest),
};
let rows = diesel::update(actions.find(id))
.set(&*data)
.execute(&mut db)
.ok();
match rows {
Some(rows) => {
if rows == 0 {
return Err(Status::NotFound);
}
Ok(Status::NoContent)
}
None => Err(Status::InternalServerError),
}
}
#[delete("/<id>")]
pub fn delete(id: &str, _auth: Authenticated, state: &State<AppState>) -> Result<Status, Status> {
let mut db = state.db.get().unwrap();
let id = match Uuid::parse_str(id).ok() {
Some(id) => id,
None => return Err(Status::BadRequest),
};
let rows = diesel::delete(actions.find(id)).execute(&mut db).ok();
match rows {
Some(rows) => {
if rows == 0 {
return Err(Status::NotFound);
}
Ok(Status::NoContent)
}
None => Err(Status::InternalServerError),
}
}
+16 -1
View File
@@ -1,5 +1,7 @@
use crate::models::action::Action; use crate::models::action::Action;
use serde::Serialize; use crate::schema::actions;
use diesel::AsChangeset;
use serde::{Deserialize, Serialize};
#[derive(Serialize)] #[derive(Serialize)]
pub struct ActionDTO { pub struct ActionDTO {
@@ -21,3 +23,16 @@ impl ActionDTO {
} }
} }
} }
#[derive(Deserialize)]
pub struct NewActionDTO {
pub name: String,
pub source: String,
}
#[derive(Deserialize, AsChangeset)]
#[diesel(table_name = actions)]
pub struct UpdateActionDTO {
pub name: Option<String>,
pub source: Option<String>,
}
+10 -1
View File
@@ -67,5 +67,14 @@ fn rocket() -> _ {
.manage(app_data) .manage(app_data)
.attach(CORS {}) .attach(CORS {})
.mount("/", routes![index]) .mount("/", routes![index])
.mount("/action", routes![action::index]) .mount(
"/action",
routes![
action::index,
action::create,
action::get,
action::update,
action::delete
],
)
} }
+2 -2
View File
@@ -1,8 +1,8 @@
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use diesel::{Queryable, Selectable}; use diesel::{Insertable, Queryable, Selectable};
use uuid::Uuid; use uuid::Uuid;
#[derive(Queryable, Selectable)] #[derive(Queryable, Selectable, Insertable)]
#[diesel(table_name = crate::schema::actions)] #[diesel(table_name = crate::schema::actions)]
#[diesel(check_for_backend(diesel::pg::Pg))] #[diesel(check_for_backend(diesel::pg::Pg))]
pub struct Action { pub struct Action {
+1 -1
View File
@@ -1,5 +1,5 @@
use diesel::r2d2::{ConnectionManager, Pool};
use diesel::PgConnection; use diesel::PgConnection;
use diesel::r2d2::{ConnectionManager, Pool};
pub const DEFAULT_QUERY_LIMIT: i64 = 100; pub const DEFAULT_QUERY_LIMIT: i64 = 100;