feat: grades

This commit is contained in:
Sebastian Pravda 2023-01-16 15:11:27 +01:00
parent b7f8b16003
commit 35b6c19af0
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
11 changed files with 68 additions and 16 deletions

View file

@ -317,7 +317,8 @@ mod tests {
\"sex\": \"MALE\",
\"personalIdNumber\": \"0101010000\",
\"schoolName\": \"29988383\",
\"healthInsurance\": \"000\"
\"healthInsurance\": \"000\",
\"grades\": []
},
\"parents\": [
{
@ -376,8 +377,7 @@ mod tests {
assert_eq!(response.status(), Status::Ok);
let details_resp: ApplicationDetails =
serde_json::from_str(&response.into_string().unwrap()).unwrap();
let details_resp: ApplicationDetails = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert_eq!(details_orig, details_resp);
}

View file

@ -33,7 +33,7 @@ impl Mutation {
Ok(delete)
}
pub async fn update_candidate_details(
pub async fn update_candidate_opt_details(
db: &DbConn,
candidate: candidate::Model,
enc_candidate: EncryptedCandidateDetails,
@ -51,9 +51,9 @@ impl Mutation {
candidate.citizenship = Set(enc_candidate.citizenship.map(|e| e.into()));
candidate.email = Set(enc_candidate.email.map(|e| e.into()));
candidate.sex = Set(enc_candidate.sex.map(|e| e.into()));
// candidate.personal_identification_number = Set(enc_candidate.personal_id_number.map(|e| e.into()).unwrap_or_default()); // TODO: do not set this here, it is already set in the create_candidate mutation???
candidate.school_name = Set(enc_candidate.school_name.map(|e| e.into()));
candidate.health_insurance = Set(enc_candidate.health_insurance.map(|e| e.into()));
candidate.grades_json = Set(enc_candidate.grades_json.map(|e| e.into()));
candidate.encrypted_by_id = Set(Some(encrypted_by_id));
candidate.updated_at = Set(chrono::offset::Local::now().naive_local());
@ -120,7 +120,7 @@ mod tests {
vec!["age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_string()],
).await.unwrap();
let candidate = Mutation::update_candidate_details(&db, candidate, encrypted_details.candidate, 1).await.unwrap();
let candidate = Mutation::update_candidate_opt_details(&db, candidate, encrypted_details.candidate, 1).await.unwrap();
let candidate = Query::find_candidate_by_id(&db, candidate.id)
.await

View file

@ -6,7 +6,7 @@ use crate::{
error::ServiceError,
};
use super::candidate_details::{EncryptedString, EncryptedCandidateDetails};
use super::{candidate_details::{EncryptedString, EncryptedCandidateDetails}, grade::GradeList};
pub enum FieldOfStudy {
G,
@ -57,7 +57,7 @@ pub struct CreateCandidateResponse {
pub password: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct CandidateDetails {
pub name: String,
@ -72,8 +72,9 @@ pub struct CandidateDetails {
pub personal_id_number: String,
pub school_name: String,
pub health_insurance: String,
pub grades: GradeList,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ParentDetails {
pub name: String,
@ -83,7 +84,7 @@ pub struct ParentDetails {
}
/// Candidate details (admin and candidate endpoints)
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct ApplicationDetails {
// Candidate

View file

@ -5,7 +5,7 @@ use futures::future;
use crate::{crypto, models::candidate::{ApplicationDetails}, error::ServiceError, utils::date::parse_naive_date_from_opt_str};
use super::{candidate::{CandidateDetails, ParentDetails}, application::ApplicationRow};
use super::{candidate::{CandidateDetails, ParentDetails}, application::ApplicationRow, grade::GradeList};
pub const NAIVE_DATE_FMT: &str = "%Y-%m-%d";
@ -26,6 +26,7 @@ pub struct EncryptedCandidateDetails {
pub personal_id_number: Option<EncryptedString>,
pub school_name: Option<EncryptedString>,
pub health_insurance: Option<EncryptedString>,
pub grades_json: Option<EncryptedString>,
}
#[derive(Debug, Clone)]
@ -118,6 +119,7 @@ impl EncryptedCandidateDetails {
recipients: &Vec<String>,
) -> Result<EncryptedCandidateDetails, ServiceError> {
let birthdate_str = form.birthdate.format(NAIVE_DATE_FMT).to_string();
let grades_str = form.grades.to_string();
let d = tokio::try_join!(
EncryptedString::new_option(&form.name, recipients),
EncryptedString::new_option(&form.surname, recipients),
@ -131,6 +133,7 @@ impl EncryptedCandidateDetails {
EncryptedString::new_option(&form.personal_id_number, recipients),
EncryptedString::new_option(&form.school_name, recipients),
EncryptedString::new_option(&form.health_insurance, recipients),
EncryptedString::new_option(&grades_str, recipients),
)?;
Ok(
@ -147,6 +150,7 @@ impl EncryptedCandidateDetails {
personal_id_number: d.9,
school_name: d.10,
health_insurance: d.11,
grades_json: d.12,
}
)
}
@ -165,6 +169,7 @@ impl EncryptedCandidateDetails {
EncryptedString::decrypt_option(&self.personal_id_number, priv_key),// 9
EncryptedString::decrypt_option(&self.school_name, priv_key), // 10
EncryptedString::decrypt_option(&self.health_insurance, priv_key), // 11
EncryptedString::decrypt_option(&self.grades_json, priv_key), // 12
)?;
Ok(CandidateDetails {
@ -180,6 +185,7 @@ impl EncryptedCandidateDetails {
personal_id_number: d.9.unwrap_or_default(),
school_name: d.10.unwrap_or_default(),
health_insurance: d.11.unwrap_or_default(),
grades: GradeList::from_opt_str(d.12).unwrap_or_default(),
}
)
}
@ -214,6 +220,7 @@ impl From<&candidate::Model> for EncryptedCandidateDetails {
personal_id_number: Some(EncryptedString::from(candidate.personal_identification_number.to_owned())),
school_name: EncryptedString::try_from(&candidate.school_name).ok(),
health_insurance: EncryptedString::try_from(&candidate.health_insurance).ok(),
grades_json: EncryptedString::try_from(&candidate.grades_json).ok(),
}
}
}
@ -351,6 +358,7 @@ impl TryFrom<ApplicationRow> for EncryptedApplicationDetails {
personal_id_number: EncryptedString::try_from(&cp.personal_identification_number).ok(),
school_name: EncryptedString::try_from(&cp.school_name).ok(),
health_insurance: EncryptedString::try_from(&cp.health_insurance).ok(),
grades_json: None, // TODO
},
parents: vec![EncryptedParentDetails {
name: EncryptedString::try_from(&cp.parent_name).ok(),
@ -382,7 +390,7 @@ pub mod tests {
use once_cell::sync::Lazy;
use sea_orm::{DbConn, Set, ActiveModelTrait};
use crate::{crypto, models::candidate::{CandidateDetails, ParentDetails}, utils::db::get_memory_sqlite_connection, services::candidate_service::tests::put_user_data};
use crate::{crypto, models::{candidate::{CandidateDetails, ParentDetails}, grade::GradeList}, utils::db::get_memory_sqlite_connection, services::candidate_service::tests::put_user_data};
use super::{ApplicationDetails, EncryptedApplicationDetails, EncryptedString};
@ -404,6 +412,7 @@ pub mod tests {
personal_id_number: "personal_id_number".to_string(),
school_name: "school_name".to_string(),
health_insurance: "health_insurance".to_string(),
grades: GradeList::from(vec![]),
},
parents: vec![ParentDetails {
name: "parent_name".to_string(),

37
core/src/models/grade.rs Normal file
View file

@ -0,0 +1,37 @@
use serde::{Serialize, Deserialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Grade {
subject: String,
value: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct GradeList(Vec<Grade>);
impl GradeList {
pub fn from_opt_str(grades: Option<String>) -> Option<Self> {
println!("grades: {:?}", grades);
grades.map(
|grades| serde_json::from_str(&grades).unwrap() // TODO: handle error
)
}
}
impl Default for GradeList {
fn default() -> Self {
Self(vec![])
}
}
impl From<Vec<Grade>> for GradeList {
fn from(grades: Vec<Grade>) -> Self {
Self(grades)
}
}
impl ToString for GradeList {
fn to_string(&self) -> String {
serde_json::to_string(&self.0).unwrap()
}
}

View file

@ -1,4 +1,5 @@
pub mod candidate_details;
pub mod candidate;
pub mod auth;
pub mod application;
pub mod application;
pub mod grade;

View file

@ -324,7 +324,7 @@ impl ApplicationService {
.ok_or(ServiceError::CandidateDetailsNotSet)?.to_string()
).await?;
Mutation::update_candidate_details(db,
Mutation::update_candidate_opt_details(db,
candidate,
enc_details.candidate,
application.id

View file

@ -48,7 +48,7 @@ impl CandidateService {
encrypted_by: i32,
) -> Result<entity::candidate::Model, ServiceError> {
let enc_details = EncryptedCandidateDetails::new(&details, recipients).await?;
let model = Mutation::update_candidate_details(
let model = Mutation::update_candidate_opt_details(
db,
candidate,
enc_details,

View file

@ -54,7 +54,7 @@ mod tests {
use once_cell::sync::Lazy;
use crate::{utils::db::get_memory_sqlite_connection, models::{candidate::{ParentDetails, ApplicationDetails, CandidateDetails}, candidate_details::EncryptedApplicationDetails}, services::{candidate_service::{CandidateService, tests::put_user_data}, application_service::ApplicationService, parent_service::ParentService}, crypto};
use crate::{utils::db::get_memory_sqlite_connection, models::{candidate::{ParentDetails, ApplicationDetails, CandidateDetails}, candidate_details::EncryptedApplicationDetails, grade::GradeList}, services::{candidate_service::{CandidateService, tests::put_user_data}, application_service::ApplicationService, parent_service::ParentService}, crypto};
pub static APPLICATION_DETAILS_TWO_PARENTS: Lazy<Mutex<ApplicationDetails>> = Lazy::new(||
Mutex::new(ApplicationDetails {
@ -71,6 +71,7 @@ mod tests {
personal_id_number: "personal_id_number".to_string(),
school_name: "school_name".to_string(),
health_insurance: "health_insurance".to_string(),
grades: GradeList::from(vec![]),
},
parents: vec![ParentDetails {
name: "parent_name".to_string(),

View file

@ -20,6 +20,7 @@ pub struct Model {
pub personal_identification_number: String,
pub school_name: Option<String>,
pub health_insurance: Option<String>,
pub grades_json: Option<String>,
pub encrypted_by_id: Option<i32>,
pub created_at: DateTime,
pub updated_at: DateTime,

View file

@ -31,6 +31,7 @@ impl MigrationTrait for Migration {
.col(ColumnDef::new(Candidate::PersonalIdentificationNumber).string().not_null())
.col(ColumnDef::new(Candidate::SchoolName).string())
.col(ColumnDef::new(Candidate::HealthInsurance).string())
.col(ColumnDef::new(Candidate::GradesJson).string())
.col(ColumnDef::new(Candidate::EncryptedById).integer())
.col(ColumnDef::new(Candidate::CreatedAt).date_time().not_null())
.col(ColumnDef::new(Candidate::UpdatedAt).date_time().not_null())
@ -63,6 +64,7 @@ pub enum Candidate {
PersonalIdentificationNumber,
SchoolName,
HealthInsurance,
GradesJson,
EncryptedById,
CreatedAt,
UpdatedAt,