diff --git a/backend/migrations/20240406031915_create_applications.sql b/backend/migrations/20240406031915_create_applications.sql index b62d6c1a..ffcbba42 100644 --- a/backend/migrations/20240406031915_create_applications.sql +++ b/backend/migrations/20240406031915_create_applications.sql @@ -22,8 +22,8 @@ CREATE TABLE applications ( CREATE TABLE application_roles ( id BIGSERIAL PRIMARY KEY, - application_id INTEGER NOT NULL, - campaign_role_id INTEGER NOT NULL, + application_id BIGINT NOT NULL, + campaign_role_id BIGINT NOT NULL, CONSTRAINT FK_application_roles_applications FOREIGN KEY(application_id) REFERENCES applications(id) diff --git a/backend/server/src/models/application.rs b/backend/server/src/models/application.rs new file mode 100644 index 00000000..f3bff5ff --- /dev/null +++ b/backend/server/src/models/application.rs @@ -0,0 +1,87 @@ +use crate::models::error::ChaosError; +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; +use snowflake::SnowflakeIdGenerator; +use sqlx::{FromRow, Pool, Postgres, Transaction}; +use std::ops::DerefMut; + +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct Application { + pub id: i64, + pub campaign_id: i64, + pub user_id: i64, + pub status: ApplicationStatus, + pub private_status: ApplicationStatus, + pub created_at: DateTime, + pub updated_at: DateTime, +} + +/* + User could apply for more than one roles at a time, for each application + into a role it will be represented by row in application_roles table which + is linked to the main Application body through application_id +*/ +#[derive(Deserialize, Serialize, Clone, FromRow, Debug)] +pub struct ApplicationRole { + pub id: i64, + pub application_id: i64, + pub campaign_role_id: i64, +} + +pub struct NewApplication { + pub user_id: i64, + pub status: ApplicationStatus, + pub private_status: ApplicationStatus, + pub applied_roles: Vec, +} + + +#[derive(Deserialize, Serialize, sqlx::Type, Clone, Debug)] +#[sqlx(type_name = "application_status", rename_all = "PascalCase")] +pub enum ApplicationStatus { + Pending, + Rejected, + Successful, +} + +impl Application { + pub async fn create( + campaign_id: i64, + application_data: NewApplication, + mut snowflake_generator: SnowflakeIdGenerator, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result<(), ChaosError> { + let id = snowflake_generator.generate(); + + // Insert into table applications + sqlx::query!( + " + INSERT INTO applications (id, campaign_id, user_id, status, private_status) + VALUES ($1, $2, $3, $4, $5) + ", + id, + campaign_id, + application_data.user_id, + application_data.status as ApplicationStatus, + application_data.private_status as ApplicationStatus, + ) + .execute(transaction.deref_mut()) + .await?; + + // Insert into table application_roles + for role_applied in application_data.applied_roles { + sqlx::query!( + " + INSERT INTO application_roles (application_id, campaign_role_id) + VALUES ($1, $2) + ", + id, + role_applied.campaign_role_id + ) + .execute(transaction.deref_mut()) + .await?; + } + + Ok(()) + } +} \ No newline at end of file diff --git a/backend/server/src/models/mod.rs b/backend/server/src/models/mod.rs index 76102f22..0af7da1a 100644 --- a/backend/server/src/models/mod.rs +++ b/backend/server/src/models/mod.rs @@ -7,3 +7,4 @@ pub mod role; pub mod storage; pub mod transaction; pub mod user; +pub mod application; diff --git a/backend/server/src/models/role.rs b/backend/server/src/models/role.rs index 1d5386c7..bddc6cae 100644 --- a/backend/server/src/models/role.rs +++ b/backend/server/src/models/role.rs @@ -6,7 +6,7 @@ use sqlx::{FromRow, Pool, Postgres}; #[derive(Deserialize, Serialize, Clone, FromRow, Debug)] pub struct Role { - pub id: i32, + pub id: i64, pub campaign_id: i64, pub name: Option, pub description: String,