mirror of
https://github.com/danbulant/Portfolio
synced 2026-05-26 13:31:45 +00:00
feat: grades
This commit is contained in:
parent
b7f8b16003
commit
35b6c19af0
11 changed files with 68 additions and 16 deletions
|
|
@ -317,7 +317,8 @@ mod tests {
|
||||||
\"sex\": \"MALE\",
|
\"sex\": \"MALE\",
|
||||||
\"personalIdNumber\": \"0101010000\",
|
\"personalIdNumber\": \"0101010000\",
|
||||||
\"schoolName\": \"29988383\",
|
\"schoolName\": \"29988383\",
|
||||||
\"healthInsurance\": \"000\"
|
\"healthInsurance\": \"000\",
|
||||||
|
\"grades\": []
|
||||||
},
|
},
|
||||||
\"parents\": [
|
\"parents\": [
|
||||||
{
|
{
|
||||||
|
|
@ -376,8 +377,7 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(response.status(), Status::Ok);
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
|
||||||
let details_resp: ApplicationDetails =
|
let details_resp: ApplicationDetails = serde_json::from_str(&response.into_string().unwrap()).unwrap();
|
||||||
serde_json::from_str(&response.into_string().unwrap()).unwrap();
|
|
||||||
assert_eq!(details_orig, details_resp);
|
assert_eq!(details_orig, details_resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ impl Mutation {
|
||||||
Ok(delete)
|
Ok(delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_candidate_details(
|
pub async fn update_candidate_opt_details(
|
||||||
db: &DbConn,
|
db: &DbConn,
|
||||||
candidate: candidate::Model,
|
candidate: candidate::Model,
|
||||||
enc_candidate: EncryptedCandidateDetails,
|
enc_candidate: EncryptedCandidateDetails,
|
||||||
|
|
@ -51,9 +51,9 @@ impl Mutation {
|
||||||
candidate.citizenship = Set(enc_candidate.citizenship.map(|e| e.into()));
|
candidate.citizenship = Set(enc_candidate.citizenship.map(|e| e.into()));
|
||||||
candidate.email = Set(enc_candidate.email.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.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.school_name = Set(enc_candidate.school_name.map(|e| e.into()));
|
||||||
candidate.health_insurance = Set(enc_candidate.health_insurance.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.encrypted_by_id = Set(Some(encrypted_by_id));
|
||||||
|
|
||||||
candidate.updated_at = Set(chrono::offset::Local::now().naive_local());
|
candidate.updated_at = Set(chrono::offset::Local::now().naive_local());
|
||||||
|
|
@ -120,7 +120,7 @@ mod tests {
|
||||||
vec!["age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_string()],
|
vec!["age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_string()],
|
||||||
).await.unwrap();
|
).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)
|
let candidate = Query::find_candidate_by_id(&db, candidate.id)
|
||||||
.await
|
.await
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
error::ServiceError,
|
error::ServiceError,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::candidate_details::{EncryptedString, EncryptedCandidateDetails};
|
use super::{candidate_details::{EncryptedString, EncryptedCandidateDetails}, grade::GradeList};
|
||||||
|
|
||||||
pub enum FieldOfStudy {
|
pub enum FieldOfStudy {
|
||||||
G,
|
G,
|
||||||
|
|
@ -57,7 +57,7 @@ pub struct CreateCandidateResponse {
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CandidateDetails {
|
pub struct CandidateDetails {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -72,8 +72,9 @@ pub struct CandidateDetails {
|
||||||
pub personal_id_number: String,
|
pub personal_id_number: String,
|
||||||
pub school_name: String,
|
pub school_name: String,
|
||||||
pub health_insurance: 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")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ParentDetails {
|
pub struct ParentDetails {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
@ -83,7 +84,7 @@ pub struct ParentDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Candidate details (admin and candidate endpoints)
|
/// Candidate details (admin and candidate endpoints)
|
||||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ApplicationDetails {
|
pub struct ApplicationDetails {
|
||||||
// Candidate
|
// Candidate
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use futures::future;
|
||||||
|
|
||||||
use crate::{crypto, models::candidate::{ApplicationDetails}, error::ServiceError, utils::date::parse_naive_date_from_opt_str};
|
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";
|
pub const NAIVE_DATE_FMT: &str = "%Y-%m-%d";
|
||||||
|
|
||||||
|
|
@ -26,6 +26,7 @@ pub struct EncryptedCandidateDetails {
|
||||||
pub personal_id_number: Option<EncryptedString>,
|
pub personal_id_number: Option<EncryptedString>,
|
||||||
pub school_name: Option<EncryptedString>,
|
pub school_name: Option<EncryptedString>,
|
||||||
pub health_insurance: Option<EncryptedString>,
|
pub health_insurance: Option<EncryptedString>,
|
||||||
|
pub grades_json: Option<EncryptedString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
@ -118,6 +119,7 @@ impl EncryptedCandidateDetails {
|
||||||
recipients: &Vec<String>,
|
recipients: &Vec<String>,
|
||||||
) -> Result<EncryptedCandidateDetails, ServiceError> {
|
) -> Result<EncryptedCandidateDetails, ServiceError> {
|
||||||
let birthdate_str = form.birthdate.format(NAIVE_DATE_FMT).to_string();
|
let birthdate_str = form.birthdate.format(NAIVE_DATE_FMT).to_string();
|
||||||
|
let grades_str = form.grades.to_string();
|
||||||
let d = tokio::try_join!(
|
let d = tokio::try_join!(
|
||||||
EncryptedString::new_option(&form.name, recipients),
|
EncryptedString::new_option(&form.name, recipients),
|
||||||
EncryptedString::new_option(&form.surname, 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.personal_id_number, recipients),
|
||||||
EncryptedString::new_option(&form.school_name, recipients),
|
EncryptedString::new_option(&form.school_name, recipients),
|
||||||
EncryptedString::new_option(&form.health_insurance, recipients),
|
EncryptedString::new_option(&form.health_insurance, recipients),
|
||||||
|
EncryptedString::new_option(&grades_str, recipients),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
|
|
@ -147,6 +150,7 @@ impl EncryptedCandidateDetails {
|
||||||
personal_id_number: d.9,
|
personal_id_number: d.9,
|
||||||
school_name: d.10,
|
school_name: d.10,
|
||||||
health_insurance: d.11,
|
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.personal_id_number, priv_key),// 9
|
||||||
EncryptedString::decrypt_option(&self.school_name, priv_key), // 10
|
EncryptedString::decrypt_option(&self.school_name, priv_key), // 10
|
||||||
EncryptedString::decrypt_option(&self.health_insurance, priv_key), // 11
|
EncryptedString::decrypt_option(&self.health_insurance, priv_key), // 11
|
||||||
|
EncryptedString::decrypt_option(&self.grades_json, priv_key), // 12
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(CandidateDetails {
|
Ok(CandidateDetails {
|
||||||
|
|
@ -180,6 +185,7 @@ impl EncryptedCandidateDetails {
|
||||||
personal_id_number: d.9.unwrap_or_default(),
|
personal_id_number: d.9.unwrap_or_default(),
|
||||||
school_name: d.10.unwrap_or_default(),
|
school_name: d.10.unwrap_or_default(),
|
||||||
health_insurance: d.11.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())),
|
personal_id_number: Some(EncryptedString::from(candidate.personal_identification_number.to_owned())),
|
||||||
school_name: EncryptedString::try_from(&candidate.school_name).ok(),
|
school_name: EncryptedString::try_from(&candidate.school_name).ok(),
|
||||||
health_insurance: EncryptedString::try_from(&candidate.health_insurance).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(),
|
personal_id_number: EncryptedString::try_from(&cp.personal_identification_number).ok(),
|
||||||
school_name: EncryptedString::try_from(&cp.school_name).ok(),
|
school_name: EncryptedString::try_from(&cp.school_name).ok(),
|
||||||
health_insurance: EncryptedString::try_from(&cp.health_insurance).ok(),
|
health_insurance: EncryptedString::try_from(&cp.health_insurance).ok(),
|
||||||
|
grades_json: None, // TODO
|
||||||
},
|
},
|
||||||
parents: vec![EncryptedParentDetails {
|
parents: vec![EncryptedParentDetails {
|
||||||
name: EncryptedString::try_from(&cp.parent_name).ok(),
|
name: EncryptedString::try_from(&cp.parent_name).ok(),
|
||||||
|
|
@ -382,7 +390,7 @@ pub mod tests {
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use sea_orm::{DbConn, Set, ActiveModelTrait};
|
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};
|
use super::{ApplicationDetails, EncryptedApplicationDetails, EncryptedString};
|
||||||
|
|
||||||
|
|
@ -404,6 +412,7 @@ pub mod tests {
|
||||||
personal_id_number: "personal_id_number".to_string(),
|
personal_id_number: "personal_id_number".to_string(),
|
||||||
school_name: "school_name".to_string(),
|
school_name: "school_name".to_string(),
|
||||||
health_insurance: "health_insurance".to_string(),
|
health_insurance: "health_insurance".to_string(),
|
||||||
|
grades: GradeList::from(vec![]),
|
||||||
},
|
},
|
||||||
parents: vec![ParentDetails {
|
parents: vec![ParentDetails {
|
||||||
name: "parent_name".to_string(),
|
name: "parent_name".to_string(),
|
||||||
|
|
|
||||||
37
core/src/models/grade.rs
Normal file
37
core/src/models/grade.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,3 +2,4 @@ pub mod candidate_details;
|
||||||
pub mod candidate;
|
pub mod candidate;
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod application;
|
pub mod application;
|
||||||
|
pub mod grade;
|
||||||
|
|
@ -324,7 +324,7 @@ impl ApplicationService {
|
||||||
.ok_or(ServiceError::CandidateDetailsNotSet)?.to_string()
|
.ok_or(ServiceError::CandidateDetailsNotSet)?.to_string()
|
||||||
).await?;
|
).await?;
|
||||||
|
|
||||||
Mutation::update_candidate_details(db,
|
Mutation::update_candidate_opt_details(db,
|
||||||
candidate,
|
candidate,
|
||||||
enc_details.candidate,
|
enc_details.candidate,
|
||||||
application.id
|
application.id
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ impl CandidateService {
|
||||||
encrypted_by: i32,
|
encrypted_by: i32,
|
||||||
) -> Result<entity::candidate::Model, ServiceError> {
|
) -> Result<entity::candidate::Model, ServiceError> {
|
||||||
let enc_details = EncryptedCandidateDetails::new(&details, recipients).await?;
|
let enc_details = EncryptedCandidateDetails::new(&details, recipients).await?;
|
||||||
let model = Mutation::update_candidate_details(
|
let model = Mutation::update_candidate_opt_details(
|
||||||
db,
|
db,
|
||||||
candidate,
|
candidate,
|
||||||
enc_details,
|
enc_details,
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ mod tests {
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
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(||
|
pub static APPLICATION_DETAILS_TWO_PARENTS: Lazy<Mutex<ApplicationDetails>> = Lazy::new(||
|
||||||
Mutex::new(ApplicationDetails {
|
Mutex::new(ApplicationDetails {
|
||||||
|
|
@ -71,6 +71,7 @@ mod tests {
|
||||||
personal_id_number: "personal_id_number".to_string(),
|
personal_id_number: "personal_id_number".to_string(),
|
||||||
school_name: "school_name".to_string(),
|
school_name: "school_name".to_string(),
|
||||||
health_insurance: "health_insurance".to_string(),
|
health_insurance: "health_insurance".to_string(),
|
||||||
|
grades: GradeList::from(vec![]),
|
||||||
},
|
},
|
||||||
parents: vec![ParentDetails {
|
parents: vec![ParentDetails {
|
||||||
name: "parent_name".to_string(),
|
name: "parent_name".to_string(),
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ pub struct Model {
|
||||||
pub personal_identification_number: String,
|
pub personal_identification_number: String,
|
||||||
pub school_name: Option<String>,
|
pub school_name: Option<String>,
|
||||||
pub health_insurance: Option<String>,
|
pub health_insurance: Option<String>,
|
||||||
|
pub grades_json: Option<String>,
|
||||||
pub encrypted_by_id: Option<i32>,
|
pub encrypted_by_id: Option<i32>,
|
||||||
pub created_at: DateTime,
|
pub created_at: DateTime,
|
||||||
pub updated_at: DateTime,
|
pub updated_at: DateTime,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ impl MigrationTrait for Migration {
|
||||||
.col(ColumnDef::new(Candidate::PersonalIdentificationNumber).string().not_null())
|
.col(ColumnDef::new(Candidate::PersonalIdentificationNumber).string().not_null())
|
||||||
.col(ColumnDef::new(Candidate::SchoolName).string())
|
.col(ColumnDef::new(Candidate::SchoolName).string())
|
||||||
.col(ColumnDef::new(Candidate::HealthInsurance).string())
|
.col(ColumnDef::new(Candidate::HealthInsurance).string())
|
||||||
|
.col(ColumnDef::new(Candidate::GradesJson).string())
|
||||||
.col(ColumnDef::new(Candidate::EncryptedById).integer())
|
.col(ColumnDef::new(Candidate::EncryptedById).integer())
|
||||||
.col(ColumnDef::new(Candidate::CreatedAt).date_time().not_null())
|
.col(ColumnDef::new(Candidate::CreatedAt).date_time().not_null())
|
||||||
.col(ColumnDef::new(Candidate::UpdatedAt).date_time().not_null())
|
.col(ColumnDef::new(Candidate::UpdatedAt).date_time().not_null())
|
||||||
|
|
@ -63,6 +64,7 @@ pub enum Candidate {
|
||||||
PersonalIdentificationNumber,
|
PersonalIdentificationNumber,
|
||||||
SchoolName,
|
SchoolName,
|
||||||
HealthInsurance,
|
HealthInsurance,
|
||||||
|
GradesJson,
|
||||||
EncryptedById,
|
EncryptedById,
|
||||||
CreatedAt,
|
CreatedAt,
|
||||||
UpdatedAt,
|
UpdatedAt,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue