Skip to content

Commit

Permalink
Fix POST /ratings (#189)
Browse files Browse the repository at this point in the history
Fixes the POST `/ratings` endpoint by adding the missing `score` field.

The Open API Specifications and the bna client were updated accordingly.

A new integration test was added into the scenario tests.

Signed-off-by: Rémy Greinhofer <[email protected]>
  • Loading branch information
rgreinho authored Jan 19, 2025
1 parent cfce7b7 commit a780893
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 100 deletions.
21 changes: 21 additions & 0 deletions bnaclient/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2237,6 +2237,7 @@ pub mod types {
/// "people",
/// "recreation",
/// "retail",
/// "score",
/// "transit",
/// "version"
/// ],
Expand Down Expand Up @@ -2264,6 +2265,11 @@ pub mod types {
/// "retail": {
/// "$ref": "#/components/schemas/Retail"
/// },
/// "score": {
/// "description": "City rating score",
/// "type": "number",
/// "format": "double"
/// },
/// "transit": {
/// "$ref": "#/components/schemas/Transit"
/// },
Expand All @@ -2285,6 +2291,7 @@ pub mod types {
pub people: People,
pub recreation: Recreation,
pub retail: Retail,
pub score: f64,
pub transit: Transit,
///Rating version
///The format follows the [calver](https://calver.org) specification with
Expand Down Expand Up @@ -5134,6 +5141,7 @@ pub mod types {
people: ::std::result::Result<super::People, ::std::string::String>,
recreation: ::std::result::Result<super::Recreation, ::std::string::String>,
retail: ::std::result::Result<super::Retail, ::std::string::String>,
score: ::std::result::Result<f64, ::std::string::String>,
transit: ::std::result::Result<super::Transit, ::std::string::String>,
version: ::std::result::Result<::std::string::String, ::std::string::String>,
}
Expand All @@ -5148,6 +5156,7 @@ pub mod types {
people: Err("no value supplied for people".to_string()),
recreation: Err("no value supplied for recreation".to_string()),
retail: Err("no value supplied for retail".to_string()),
score: Err("no value supplied for score".to_string()),
transit: Err("no value supplied for transit".to_string()),
version: Err("no value supplied for version".to_string()),
}
Expand Down Expand Up @@ -5225,6 +5234,16 @@ pub mod types {
.map_err(|e| format!("error converting supplied value for retail: {}", e));
self
}
pub fn score<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<f64>,
T::Error: ::std::fmt::Display,
{
self.score = value
.try_into()
.map_err(|e| format!("error converting supplied value for score: {}", e));
self
}
pub fn transit<T>(mut self, value: T) -> Self
where
T: ::std::convert::TryInto<super::Transit>,
Expand Down Expand Up @@ -5260,6 +5279,7 @@ pub mod types {
people: value.people?,
recreation: value.recreation?,
retail: value.retail?,
score: value.score?,
transit: value.transit?,
version: value.version?,
})
Expand All @@ -5276,6 +5296,7 @@ pub mod types {
people: Ok(value.people),
recreation: Ok(value.recreation),
retail: Ok(value.retail),
score: Ok(value.score),
transit: Ok(value.transit),
version: Ok(value.version),
}
Expand Down
22 changes: 10 additions & 12 deletions lambdas/requests.rest
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ content-type: application/json
Authorization: Bearer {{cognito_access}}

{
"city_id": "09c049b6-213b-405c-bc4e-178346ff814d",
"core_services": {
"dentists": 0,
"doctors": 0,
Expand All @@ -228,27 +229,24 @@ Authorization: Bearer {{cognito_access}}
"technical_vocational_college": 0
},
"people": {
"score": 19.17
"people": 19.17
},
"recreation": {
"community_centers": 0,
"parks": 7.13,
"recreation_trails": 0,
"score": 7.13
"score": 7.13,
"trails": 0
},
"retail": {
"score": 0
},
"summary": {
"city_id": "aac22433-37d4-4cb7-b6b8-e7e77cbbcf41",
"rating_id": "7b80ac57-f32e-44db-8442-e9cbf449b306",
"score": 0,
"version": "24.12"
"retail": 0
},
"transit": {
"score": 0
}
"transit": 0
},
"version": "24.12",
"score": 8.93
}

### Create a new city.
POST {{host}}/cities/
content-type: application/json
Expand Down
87 changes: 52 additions & 35 deletions lambdas/src/core/resource/ratings/adaptor.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use super::db::{fetch_rating, fetch_ratings, fetch_ratings_city, fetch_ratings_summaries, Bna};
use super::{
db::{fetch_rating, fetch_ratings, fetch_ratings_city, fetch_ratings_summaries, Bna},
schema::RatingPost,
};
use crate::{database_connect, Context, ExecutionError};
use entity::{
core_services, infrastructure, opportunity, people, recreation, retail, summary, transit,
wrappers::bna::BNAPost,
};
use sea_orm::{ActiveModelTrait, ActiveValue};
use tracing::info;
Expand Down Expand Up @@ -67,65 +69,80 @@ pub(crate) async fn get_ratings_city_adaptor(
}
}

pub(crate) async fn post_ratings_adaptor(bna: BNAPost) -> Result<Bna, ExecutionError> {
pub(crate) async fn post_ratings_adaptor(rating: RatingPost) -> Result<Bna, ExecutionError> {
// Generate a rating id.
let rating_id = Uuid::new_v4();

// Turn the model wrapper into active models.
let summary = summary::ActiveModel {
id: ActiveValue::NotSet,
city_id: ActiveValue::Set(bna.summary.city_id),
id: ActiveValue::Set(rating_id),
city_id: ActiveValue::Set(rating.city_id),
created_at: ActiveValue::NotSet,
score: ActiveValue::NotSet,
version: ActiveValue::Set(bna.summary.version),
score: ActiveValue::Set(rating.score),
version: ActiveValue::Set(rating.version),
};
info!("{:?}", summary);
let core_services = core_services::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
dentists: ActiveValue::Set(bna.core_services.dentists),
doctors: ActiveValue::Set(bna.core_services.doctors),
grocery: ActiveValue::Set(bna.core_services.grocery),
hospitals: ActiveValue::Set(bna.core_services.hospitals),
pharmacies: ActiveValue::Set(bna.core_services.pharmacies),
score: ActiveValue::Set(bna.core_services.score),
social_services: ActiveValue::Set(bna.core_services.social_services),
id: ActiveValue::Set(rating_id),
dentists: ActiveValue::Set(rating.core_services.dentists),
doctors: ActiveValue::Set(rating.core_services.doctors),
grocery: ActiveValue::Set(rating.core_services.grocery),
hospitals: ActiveValue::Set(rating.core_services.hospitals),
pharmacies: ActiveValue::Set(rating.core_services.pharmacies),
score: ActiveValue::Set(rating.core_services.score),
social_services: ActiveValue::Set(rating.core_services.social_services),
};
info!("{:?}", core_services);
let people = people::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
score: ActiveValue::Set(bna.people.score),
id: ActiveValue::Set(rating_id),
score: rating
.people
.people
.map_or(ActiveValue::NotSet, |v| ActiveValue::Set(Some(v))),
};
info!("{:?}", people);
let retail = retail::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
score: ActiveValue::Set(bna.retail.score),
id: ActiveValue::Set(rating_id),
score: rating
.retail
.retail
.map_or(ActiveValue::NotSet, |v| ActiveValue::Set(Some(v))),
};
info!("{:?}", people);
let transit = transit::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
score: ActiveValue::Set(bna.transit.score),
id: ActiveValue::Set(rating_id),
score: rating
.transit
.transit
.map_or(ActiveValue::NotSet, |v| ActiveValue::Set(Some(v))),
};
info!("{:?}", people);
let infrastructure = infrastructure::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
low_stress_miles: ActiveValue::Set(bna.infrastructure.low_stress_miles),
high_stress_miles: ActiveValue::Set(bna.infrastructure.high_stress_miles),
id: ActiveValue::Set(rating_id),
low_stress_miles: ActiveValue::Set(rating.infrastructure.low_stress_miles),
high_stress_miles: ActiveValue::Set(rating.infrastructure.high_stress_miles),
};
info!("{:?}", infrastructure);
let opportunity = opportunity::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
employment: ActiveValue::Set(bna.opportunity.employment),
higher_education: ActiveValue::Set(bna.opportunity.higher_education),
k12_education: ActiveValue::Set(bna.opportunity.k12_education),
score: ActiveValue::Set(bna.opportunity.score),
id: ActiveValue::Set(rating_id),
employment: ActiveValue::Set(rating.opportunity.employment),
higher_education: ActiveValue::Set(rating.opportunity.higher_education),
k12_education: ActiveValue::Set(rating.opportunity.k12_education),
score: ActiveValue::Set(rating.opportunity.score),
technical_vocational_college: ActiveValue::Set(
bna.opportunity.technical_vocational_college,
rating.opportunity.technical_vocational_college,
),
};
info!("{:?}", opportunity);
let recreation = recreation::ActiveModel {
id: ActiveValue::Set(bna.summary.rating_id),
community_centers: ActiveValue::Set(bna.recreation.community_centers),
parks: ActiveValue::Set(bna.recreation.parks),
recreation_trails: ActiveValue::Set(bna.recreation.recreation_trails),
score: ActiveValue::Set(bna.recreation.score),
id: ActiveValue::Set(rating_id),
community_centers: ActiveValue::Set(rating.recreation.community_centers),
parks: ActiveValue::Set(rating.recreation.parks),
recreation_trails: rating
.recreation
.trails
.map_or(ActiveValue::NotSet, |v| ActiveValue::Set(Some(v))),
score: ActiveValue::Set(rating.recreation.score),
};
info!("{:?}", recreation);

Expand Down
3 changes: 1 addition & 2 deletions lambdas/src/core/resource/ratings/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use axum::{
Json,
};
use effortless::api::PaginationParameters;
use entity::wrappers::bna::BNAPost;
use tracing::debug;
use utoipa_axum::{router::OpenApiRouter, routes};
use uuid::Uuid;
Expand Down Expand Up @@ -90,7 +89,7 @@ async fn get_ratings(
ErrorResponses,
))]
async fn post_rating(
Json(bna): Json<BNAPost>,
Json(bna): Json<RatingPost>,
) -> Result<(StatusCode, Json<Rating>), ExecutionError> {
post_ratings_adaptor(bna)
.await
Expand Down
Loading

0 comments on commit a780893

Please sign in to comment.