Skip to content

Commit

Permalink
Merge pull request #67 from Jim-Hodapp-Coaching/fix_up_action_behavior
Browse files Browse the repository at this point in the history
Improve Action update behavior, and add the ability to delete an action
  • Loading branch information
jhodapp committed Sep 27, 2024
2 parents c54ffb8 + b0ab5bb commit 3a880e8
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 28 deletions.
10 changes: 5 additions & 5 deletions docs/db/refactor_platform_rs.dbml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Table refactor_platform.notes {
body varchar [note: 'Main text of the note supporting Markdown']
user_id uuid [not null, note: 'User that created (owns) the note']
created_at timestamptz [not null, default: `now()`]
updated_at timestamptz [not null, default: `now()`, note: 'The last date and time an overarching note\'s fields were changed']
updated_at timestamptz [not null, default: `now()`, note: 'The last date and time a note\'s fields were changed']
}

Table refactor_platform.agreements {
Expand All @@ -70,7 +70,7 @@ Table refactor_platform.agreements {
body varchar [note: 'Either a short or long description of an agreement reached between coach and coachee in a coaching session']
user_id uuid [not null, note: 'User that created (owns) the agreement']
created_at timestamptz [not null, default: `now()`]
updated_at timestamptz [not null, default: `now()`, note: 'The last date and time an overarching agreement\'s fields were changed']
updated_at timestamptz [not null, default: `now()`, note: 'The last date and time an agreement\'s fields were changed']
}

Table refactor_platform.actions {
Expand All @@ -83,9 +83,9 @@ Table refactor_platform.actions {
user_id uuid [not null, note: 'User that created (owns) the action']
due_by timestamptz
status status [not null]
status_changed_at timestamptz
created_at timestamp [not null, default: `now()`]
updated_at timestamp [not null, default: `now()`]
status_changed_at timestamptz [not null, default: `now()`]
created_at timestamptz [not null, default: `now()`]
updated_at timestamptz [not null, default: `now()`]
}

enum status {
Expand Down
Binary file modified docs/db/refactor_platform_rs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions entity/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ pub struct Model {
pub user_id: Id,
pub body: Option<String>,
pub due_by: Option<DateTimeWithTimeZone>,
#[serde(skip_deserializing)]
pub status: status::Status,
#[serde(skip_deserializing)]
pub status_changed_at: Option<DateTimeWithTimeZone>,
pub status_changed_at: DateTimeWithTimeZone,
#[serde(skip_deserializing)]
pub created_at: DateTimeWithTimeZone,
#[serde(skip_deserializing)]
Expand Down
39 changes: 29 additions & 10 deletions entity_api/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ pub async fn create(
let action_active_model: ActiveModel = ActiveModel {
coaching_session_id: Set(action_model.coaching_session_id),
user_id: Set(user_id),
due_by: Set(action_model.due_by),
body: Set(action_model.body),
status: Set(action_model.status),
due_by: Set(action_model.due_by),
status_changed_at: Set(now.into()),
created_at: Set(now.into()),
updated_at: Set(now.into()),
..Default::default()
Expand All @@ -41,15 +43,15 @@ pub async fn update(db: &DatabaseConnection, id: Id, model: Model) -> Result<Mod
debug!("Existing Action model to be Updated: {:?}", action);

let active_model: ActiveModel = ActiveModel {
id: Unchanged(model.id),
coaching_session_id: Unchanged(model.coaching_session_id),
id: Unchanged(action.id),
coaching_session_id: Unchanged(action.coaching_session_id),
user_id: Unchanged(model.user_id),
body: Set(model.body),
due_by: Set(model.due_by),
status: Set(model.status),
status_changed_at: Set(model.status_changed_at),
status_changed_at: Set(chrono::Utc::now().into()),
updated_at: Set(chrono::Utc::now().into()),
created_at: Unchanged(model.created_at),
created_at: Unchanged(action.created_at),
};

Ok(active_model.update(db).await?.try_into_model()?)
Expand Down Expand Up @@ -83,7 +85,7 @@ pub async fn update_status(
body: Unchanged(action.body),
due_by: Unchanged(action.due_by),
status: Set(status),
status_changed_at: Set(Some(chrono::Utc::now().into())),
status_changed_at: Set(chrono::Utc::now().into()),
updated_at: Set(chrono::Utc::now().into()),
created_at: Unchanged(action.created_at),
};
Expand All @@ -101,6 +103,23 @@ pub async fn update_status(
}
}

pub async fn delete_by_id(db: &DatabaseConnection, id: Id) -> Result<(), Error> {
let result = find_by_id(db, id).await?;

match result {
Some(action_model) => {
debug!("Existing Action model to be deleted: {:?}", action_model);

action_model.delete(db).await?;
Ok(())
}
None => Err(Error {
inner: None,
error_code: EntityApiErrorCode::RecordNotFound,
}),
}
}

pub async fn find_by_id(db: &DatabaseConnection, id: Id) -> Result<Option<Model>, Error> {
match Entity::find_by_id(id).one(db).await {
Ok(Some(action)) => {
Expand Down Expand Up @@ -171,7 +190,7 @@ mod tests {
coaching_session_id: Id::new_v4(),
body: Some("This is a action".to_owned()),
due_by: Some(now.into()),
status_changed_at: None,
status_changed_at: now.into(),
status: Default::default(),
created_at: now.into(),
updated_at: now.into(),
Expand All @@ -198,7 +217,7 @@ mod tests {
due_by: Some(now.into()),
body: Some("This is a action".to_owned()),
user_id: Id::new_v4(),
status_changed_at: None,
status_changed_at: now.into(),
status: Default::default(),
created_at: now.into(),
updated_at: now.into(),
Expand All @@ -225,7 +244,7 @@ mod tests {
due_by: Some(now.into()),
body: Some("This is a action".to_owned()),
user_id: Id::new_v4(),
status_changed_at: None,
status_changed_at: now.into(),
status: Default::default(),
created_at: now.into(),
updated_at: now.into(),
Expand All @@ -237,7 +256,7 @@ mod tests {
due_by: Some(now.into()),
body: Some("This is a action".to_owned()),
user_id: Id::new_v4(),
status_changed_at: None,
status_changed_at: now.into(),
status: Status::Completed,
created_at: now.into(),
updated_at: now.into(),
Expand Down
13 changes: 6 additions & 7 deletions migration/src/refactor_platform_rs.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
-- SQL dump generated using DBML (dbml.dbdiagram.io)
-- Database: PostgreSQL
-- Generated at: 2024-09-25T08:10:38.833Z

-- Generated at: 2024-09-26T18:27:03.587Z

CREATE TYPE "status" AS ENUM (
'not_started',
Expand Down Expand Up @@ -87,9 +86,9 @@ CREATE TABLE "refactor_platform"."actions" (
"user_id" uuid NOT NULL,
"due_by" timestamptz,
"status" status NOT NULL,
"status_changed_at" timestamptz,
"created_at" timestamp NOT NULL DEFAULT (now()),
"updated_at" timestamp NOT NULL DEFAULT (now())
"status_changed_at" timestamptz NOT NULL DEFAULT (now()),
"created_at" timestamptz NOT NULL DEFAULT (now()),
"updated_at" timestamptz NOT NULL DEFAULT (now())
);

COMMENT ON COLUMN "refactor_platform"."organizations"."name" IS 'The name of the organization that the coach <--> coachee belong to';
Expand Down Expand Up @@ -134,13 +133,13 @@ COMMENT ON COLUMN "refactor_platform"."notes"."body" IS 'Main text of the note s

COMMENT ON COLUMN "refactor_platform"."notes"."user_id" IS 'User that created (owns) the note';

COMMENT ON COLUMN "refactor_platform"."notes"."updated_at" IS 'The last date and time an overarching note''s fields were changed';
COMMENT ON COLUMN "refactor_platform"."notes"."updated_at" IS 'The last date and time a note''s fields were changed';

COMMENT ON COLUMN "refactor_platform"."agreements"."body" IS 'Either a short or long description of an agreement reached between coach and coachee in a coaching session';

COMMENT ON COLUMN "refactor_platform"."agreements"."user_id" IS 'User that created (owns) the agreement';

COMMENT ON COLUMN "refactor_platform"."agreements"."updated_at" IS 'The last date and time an overarching agreement''s fields were changed';
COMMENT ON COLUMN "refactor_platform"."agreements"."updated_at" IS 'The last date and time an agreement''s fields were changed';

COMMENT ON COLUMN "refactor_platform"."actions"."body" IS 'Main text of the action supporting Markdown';

Expand Down
33 changes: 30 additions & 3 deletions web/src/controller/action_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use axum::response::IntoResponse;
use axum::Json;
use entity::{actions::Model, Id};
use entity_api::action as ActionApi;
use serde_json::json;
use service::config::ApiVersion;
use std::collections::HashMap;

Expand All @@ -30,7 +31,6 @@ use log::*;
("cookie_auth" = [])
)
)]

pub async fn create(
CompareApiVersion(_v): CompareApiVersion,
AuthenticatedUser(user): AuthenticatedUser,
Expand All @@ -43,8 +43,6 @@ pub async fn create(

let action = ActionApi::create(app_state.db_conn_ref(), action_model, user.id).await?;

debug!("New Action: {:?}", action);

Ok(Json(ApiResponse::new(StatusCode::CREATED.into(), action)))
}

Expand Down Expand Up @@ -181,3 +179,32 @@ pub async fn index(

Ok(Json(ApiResponse::new(StatusCode::OK.into(), actions)))
}

/// DELETE an Action specified by its primary key.
#[utoipa::path(
delete,
path = "/actions/{id}",
params(
ApiVersion,
("id" = i32, Path, description = "Action id to delete")
),
responses(
(status = 200, description = "Successfully deleted a certain Action by its id", body = [i32]),
(status = 401, description = "Unauthorized"),
(status = 404, description = "Action not found"),
(status = 405, description = "Method not allowed")
),
security(
("cookie_auth" = [])
)
)]
pub async fn delete(
CompareApiVersion(_v): CompareApiVersion,
State(app_state): State<AppState>,
Path(id): Path<Id>,
) -> Result<impl IntoResponse, Error> {
debug!("DELETE Action by id: {}", id);

ActionApi::delete_by_id(app_state.db_conn_ref(), id).await?;
Ok(Json(json!({"id": id})))
}
2 changes: 1 addition & 1 deletion web/src/controller/organization_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ pub async fn update(
path = "/organizations/{id}",
params(
ApiVersion,
("id" = i32, Path, description = "Organization id to update")
("id" = i32, Path, description = "Organization id to delete")
),
responses(
(status = 200, description = "Successfully deleted a certain Organization by its id", body = [i32]),
Expand Down
2 changes: 2 additions & 0 deletions web/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use utoipa_rapidoc::RapiDoc;
action_controller::index,
action_controller::read,
action_controller::update_status,
action_controller::delete,
agreement_controller::create,
agreement_controller::update,
agreement_controller::index,
Expand Down Expand Up @@ -126,6 +127,7 @@ fn action_routes(app_state: AppState) -> Router {
.route("/actions", get(action_controller::index))
.route("/actions/:id", get(action_controller::read))
.route("/actions/:id/status", put(action_controller::update_status))
.route("/actions/:id", delete(action_controller::delete))
.route_layer(login_required!(Backend, login_url = "/login"))
.with_state(app_state)
}
Expand Down

0 comments on commit 3a880e8

Please sign in to comment.