Skip to content

Commit

Permalink
Merge pull request #74 from Jim-Hodapp-Coaching/add_user_create_route
Browse files Browse the repository at this point in the history
  • Loading branch information
jhodapp authored Oct 28, 2024
2 parents 405f4e3 + a92694f commit db1bf84
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 10 deletions.
1 change: 1 addition & 0 deletions entity/src/coaching_sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
use utoipa::ToSchema;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize, ToSchema)]
#[schema(as = entity::coaching_sessions::Model)]
#[sea_orm(schema_name = "refactor_platform", table_name = "coaching_sessions")]
pub struct Model {
#[sea_orm(primary_key)]
Expand Down
55 changes: 53 additions & 2 deletions entity_api/src/coaching_session.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
use super::error::{EntityApiErrorCode, Error};
use crate::{naive_date_parse_str, uuid_parse_str};
use entity::coaching_sessions::{self, Entity, Model};
use sea_orm::{entity::prelude::*, DatabaseConnection};
use entity::coaching_sessions::{self, ActiveModel, Entity, Model};
use log::debug;
use sea_orm::{entity::prelude::*, DatabaseConnection, Set, TryIntoModel};
use std::collections::HashMap;

pub async fn create(
db: &DatabaseConnection,
coaching_session_model: Model,
) -> Result<Model, Error> {
debug!(
"New Coaching Session Model to be inserted: {:?}",
coaching_session_model
);

let now = chrono::Utc::now();

let coaching_session_active_model: ActiveModel = ActiveModel {
coaching_relationship_id: Set(coaching_session_model.coaching_relationship_id),
date: Set(coaching_session_model.date),
timezone: Set(coaching_session_model.timezone),
created_at: Set(now.into()),
updated_at: Set(now.into()),
..Default::default()
};

Ok(coaching_session_active_model
.save(db)
.await?
.try_into_model()?)
}

pub async fn find_by(
db: &DatabaseConnection,
params: HashMap<String, String>,
Expand Down Expand Up @@ -49,6 +76,30 @@ mod tests {
use entity::Id;
use sea_orm::{DatabaseBackend, MockDatabase, Transaction};

#[tokio::test]
async fn create_returns_a_new_coaching_session_model() -> Result<(), Error> {
let now = chrono::Utc::now();

let coaching_session_model = Model {
id: Id::new_v4(),
coaching_relationship_id: Id::new_v4(),
date: chrono::Local::now().naive_utc(),
timezone: "Americas/Chicago".to_owned(),
created_at: now.into(),
updated_at: now.into(),
};

let db = MockDatabase::new(DatabaseBackend::Postgres)
.append_query_results(vec![vec![coaching_session_model.clone()]])
.into_connection();

let coaching_session = create(&db, coaching_session_model.clone().into()).await?;

assert_eq!(coaching_session.id, coaching_session_model.id);

Ok(())
}

#[tokio::test]
async fn find_by_coaching_relationships_returns_all_records_associated_with_coaching_relationship(
) -> Result<(), Error> {
Expand Down
41 changes: 41 additions & 0 deletions web/src/controller/coaching_session_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use axum::extract::{Query, State};
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::Json;
use entity::coaching_sessions::Model;
use entity_api::coaching_session as CoachingSessionApi;
use service::config::ApiVersion;
use std::collections::HashMap;
Expand Down Expand Up @@ -51,3 +52,43 @@ pub async fn index(
coaching_sessions,
)))
}

/// POST create a new Coaching Session
#[utoipa::path(
post,
path = "/coaching_sessions",
params(ApiVersion),
request_body = entity::coaching_sessions::Model,
responses(
(status = 201, description = "Successfully Created a new Coaching Session", body = [entity::coaching_sessions::Model]),
(status= 422, description = "Unprocessable Entity"),
(status = 401, description = "Unauthorized"),
(status = 405, description = "Method not allowed")
),
security(
("cookie_auth" = [])
)
)]
pub async fn create(
CompareApiVersion(_v): CompareApiVersion,
AuthenticatedUser(_user): AuthenticatedUser,
// TODO: create a new Extractor to authorize the user to access
// the data requested
State(app_state): State<AppState>,
Json(coaching_sessions_model): Json<Model>,
) -> Result<impl IntoResponse, Error> {
debug!(
"POST Create a new Coaching Session from: {:?}",
coaching_sessions_model
);

let coaching_session =
CoachingSessionApi::create(app_state.db_conn_ref(), coaching_sessions_model).await?;

debug!("New Coaching Session: {:?}", coaching_session);

Ok(Json(ApiResponse::new(
StatusCode::CREATED.into(),
coaching_session,
)))
}
1 change: 0 additions & 1 deletion web/src/controller/overarching_goal_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use log::*;
("cookie_auth" = [])
)
)]

pub async fn create(
CompareApiVersion(_v): CompareApiVersion,
AuthenticatedUser(user): AuthenticatedUser,
Expand Down
19 changes: 12 additions & 7 deletions web/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ use utoipa_rapidoc::RapiDoc;
agreement_controller::index,
agreement_controller::read,
agreement_controller::delete,
coaching_session_controller::index,
coaching_session_controller::create,
note_controller::create,
note_controller::update,
note_controller::index,
Expand All @@ -46,16 +48,15 @@ use utoipa_rapidoc::RapiDoc;
organization_controller::create,
organization_controller::update,
organization_controller::delete,
organization::coaching_relationship_controller::index,
organization::coaching_relationship_controller::read,
overarching_goal_controller::create,
overarching_goal_controller::update,
overarching_goal_controller::index,
overarching_goal_controller::read,
overarching_goal_controller::update_status,
user_session_controller::login,
user_session_controller::logout,
organization::coaching_relationship_controller::index,
organization::coaching_relationship_controller::read,
coaching_session_controller::index,
),
components(
schemas(
Expand Down Expand Up @@ -103,8 +104,8 @@ pub fn define_routes(app_state: AppState) -> Router {
.merge(note_routes(app_state.clone()))
.merge(organization_coaching_relationship_routes(app_state.clone()))
.merge(overarching_goal_routes(app_state.clone()))
.merge(session_routes())
.merge(protected_routes())
.merge(user_session_routes())
.merge(user_session_protected_routes())
.merge(coaching_sessions_routes(app_state.clone()))
// FIXME: protect the OpenAPI web UI
.merge(RapiDoc::with_openapi("/api-docs/openapi2.json", ApiDoc::openapi()).path("/rapidoc"))
Expand Down Expand Up @@ -204,6 +205,10 @@ pub fn overarching_goal_routes(app_state: AppState) -> Router {

pub fn coaching_sessions_routes(app_state: AppState) -> Router {
Router::new()
.route(
"/coaching_sessions",
post(coaching_session_controller::create),
)
.route(
"/coaching_sessions",
get(coaching_session_controller::index),
Expand All @@ -212,14 +217,14 @@ pub fn coaching_sessions_routes(app_state: AppState) -> Router {
.with_state(app_state)
}

pub fn protected_routes() -> Router {
pub fn user_session_protected_routes() -> Router {
Router::new()
.route("/protected", get(user_session_controller::protected))
.route("/logout", get(user_session_controller::logout))
.route_layer(login_required!(Backend, login_url = "/login"))
}

pub fn session_routes() -> Router {
pub fn user_session_routes() -> Router {
Router::new().route("/login", post(user_session_controller::login))
}

Expand Down

0 comments on commit db1bf84

Please sign in to comment.