postgress
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
//! SeaORM entity for Mentors table
|
||||
//! Corresponding to ResourceEnum::Mentors
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::{ActiveModelBehavior, DeriveEntityModel, DeriveRelation};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize, imphnen_macros::Builder)]
|
||||
#[sea_orm(table_name = "app_mentors")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, default = "gen_random_uuid()", auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
|
||||
#[sea_orm(unique, not_null)]
|
||||
pub user_id: Uuid,
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub industries: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub expertise: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub languages: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub current_company: Option<String>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub current_role: Option<String>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub years_of_experience: Option<i32>,
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub topics_of_interest: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub preferred_mentee_level: Option<String>,
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub preferred_mentoring_formats: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub availability_commitment: Option<String>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub mentoring_rate: Option<f64>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub status: Option<String>,
|
||||
|
||||
#[sea_orm(default = "false")]
|
||||
pub is_deleted: bool,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, sea_orm::EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(belongs_to = "super::users::Entity", from = "Column::UserId", to = "super::users::Column::Id")]
|
||||
User,
|
||||
}
|
||||
|
||||
impl Related<super::users::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::User.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
// Default implementation - SeaORM will handle timestamps automatically
|
||||
}
|
||||
|
||||
// Builder pattern for Mentor creation
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct MentorBuilder {
|
||||
user_id: Option<Uuid>,
|
||||
industries: Option<Vec<String>>,
|
||||
expertise: Option<Vec<String>>,
|
||||
languages: Option<Vec<String>>,
|
||||
current_company: Option<String>,
|
||||
current_role: Option<String>,
|
||||
years_of_experience: Option<i32>,
|
||||
topics_of_interest: Option<Vec<String>>,
|
||||
preferred_mentee_level: Option<String>,
|
||||
preferred_mentoring_formats: Option<Vec<String>>,
|
||||
availability_commitment: Option<String>,
|
||||
mentoring_rate: Option<f64>,
|
||||
status: Option<String>,
|
||||
is_deleted: Option<bool>,
|
||||
}
|
||||
|
||||
impl MentorBuilder {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn user_id(mut self, user_id: Uuid) -> Self {
|
||||
self.user_id = Some(user_id);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn industries(mut self, industries: Vec<String>) -> Self {
|
||||
self.industries = Some(industries);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn expertise(mut self, expertise: Vec<String>) -> Self {
|
||||
self.expertise = Some(expertise);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn languages(mut self, languages: Vec<String>) -> Self {
|
||||
self.languages = Some(languages);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn current_company(mut self, current_company: String) -> Self {
|
||||
self.current_company = Some(current_company);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn current_role(mut self, current_role: String) -> Self {
|
||||
self.current_role = Some(current_role);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn years_of_experience(mut self, years_of_experience: i32) -> Self {
|
||||
self.years_of_experience = Some(years_of_experience);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn topics_of_interest(mut self, topics_of_interest: Vec<String>) -> Self {
|
||||
self.topics_of_interest = Some(topics_of_interest);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn preferred_mentee_level(mut self, preferred_mentee_level: String) -> Self {
|
||||
self.preferred_mentee_level = Some(preferred_mentee_level);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn preferred_mentoring_formats(mut self, preferred_mentoring_formats: Vec<String>) -> Self {
|
||||
self.preferred_mentoring_formats = Some(preferred_mentoring_formats);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn availability_commitment(mut self, availability_commitment: String) -> Self {
|
||||
self.availability_commitment = Some(availability_commitment);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn mentoring_rate(mut self, mentoring_rate: f64) -> Self {
|
||||
self.mentoring_rate = Some(mentoring_rate);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn status(mut self, status: String) -> Self {
|
||||
self.status = Some(status);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_deleted(mut self, is_deleted: bool) -> Self {
|
||||
self.is_deleted = Some(is_deleted);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<ActiveModel, String> {
|
||||
let mut active_model = <ActiveModel as std::default::Default>::default();
|
||||
|
||||
if let Some(user_id) = self.user_id {
|
||||
active_model.user_id = Set(user_id);
|
||||
} else {
|
||||
return Err("User ID is required".to_string());
|
||||
}
|
||||
|
||||
if let Some(industries) = self.industries {
|
||||
active_model.industries = Set(Some(serde_json::to_value(industries).map_err(|e| format!("Failed to serialize industries: {}", e))?));
|
||||
}
|
||||
|
||||
if let Some(expertise) = self.expertise {
|
||||
active_model.expertise = Set(Some(serde_json::to_value(expertise).map_err(|e| format!("Failed to serialize expertise: {}", e))?));
|
||||
}
|
||||
|
||||
if let Some(languages) = self.languages {
|
||||
active_model.languages = Set(Some(serde_json::to_value(languages).map_err(|e| format!("Failed to serialize languages: {}", e))?));
|
||||
}
|
||||
|
||||
if let Some(current_company) = self.current_company {
|
||||
active_model.current_company = Set(Some(current_company));
|
||||
}
|
||||
|
||||
if let Some(current_role) = self.current_role {
|
||||
active_model.current_role = Set(Some(current_role));
|
||||
}
|
||||
|
||||
if let Some(years_of_experience) = self.years_of_experience {
|
||||
active_model.years_of_experience = Set(Some(years_of_experience));
|
||||
}
|
||||
|
||||
if let Some(topics_of_interest) = self.topics_of_interest {
|
||||
active_model.topics_of_interest = Set(Some(serde_json::to_value(topics_of_interest).map_err(|e| format!("Failed to serialize topics_of_interest: {}", e))?));
|
||||
}
|
||||
|
||||
if let Some(preferred_mentee_level) = self.preferred_mentee_level {
|
||||
active_model.preferred_mentee_level = Set(Some(preferred_mentee_level));
|
||||
}
|
||||
|
||||
if let Some(preferred_mentoring_formats) = self.preferred_mentoring_formats {
|
||||
active_model.preferred_mentoring_formats = Set(Some(serde_json::to_value(preferred_mentoring_formats).map_err(|e| format!("Failed to serialize preferred_mentoring_formats: {}", e))?));
|
||||
}
|
||||
|
||||
if let Some(availability_commitment) = self.availability_commitment {
|
||||
active_model.availability_commitment = Set(Some(availability_commitment));
|
||||
}
|
||||
|
||||
if let Some(mentoring_rate) = self.mentoring_rate {
|
||||
active_model.mentoring_rate = Set(Some(mentoring_rate));
|
||||
}
|
||||
|
||||
if let Some(status) = self.status {
|
||||
active_model.status = Set(Some(status));
|
||||
}
|
||||
|
||||
if let Some(is_deleted) = self.is_deleted {
|
||||
active_model.is_deleted = Set(is_deleted);
|
||||
}
|
||||
|
||||
Ok(active_model)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::seaorm::common::utils::generate_uuid;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test_mentor_model_creation() {
|
||||
let uid = generate_uuid();
|
||||
let mentor = MentorBuilder::new()
|
||||
.user_id(uid)
|
||||
.industries(vec!["Technology".to_string(), "Finance".to_string()])
|
||||
.expertise(vec!["Blockchain".to_string(), "AI".to_string()])
|
||||
.languages(vec!["English".to_string(), "Spanish".to_string()])
|
||||
.current_company("Tech Corp".to_string())
|
||||
.current_role("Senior Engineer".to_string())
|
||||
.years_of_experience(10)
|
||||
.topics_of_interest(vec!["Web3".to_string(), "Machine Learning".to_string()])
|
||||
.preferred_mentee_level("Intermediate".to_string())
|
||||
.preferred_mentoring_formats(vec!["1:1".to_string(), "Group".to_string()])
|
||||
.availability_commitment("Weekly".to_string())
|
||||
.mentoring_rate(150.0)
|
||||
.status("active".to_string())
|
||||
.build();
|
||||
|
||||
assert!(mentor.is_ok());
|
||||
let mentor_model = mentor.unwrap();
|
||||
assert_eq!(mentor_model.user_id, Set(uid));
|
||||
assert_eq!(mentor_model.industries, Set(Some(json!(["Technology", "Finance"]))));
|
||||
assert_eq!(mentor_model.expertise, Set(Some(json!(["Blockchain", "AI"]))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mentor_model_missing_required_fields() {
|
||||
let mentor = MentorBuilder::new()
|
||||
// Missing user_id
|
||||
.industries(vec!["Technology".to_string()])
|
||||
.build();
|
||||
|
||||
assert!(mentor.is_err());
|
||||
assert_eq!(mentor.unwrap_err(), "User ID is required");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
pub mod users;
|
||||
pub mod roles;
|
||||
pub mod permissions;
|
||||
pub mod roles_permissions;
|
||||
pub mod mentors;
|
||||
pub mod sessions;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//! SeaORM entity for Permissions table
|
||||
//! Corresponding to ResourceEnum::Permissions
|
||||
//! Represents system permissions
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::{ActiveModelBehavior, DeriveEntityModel, DeriveRelation};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "app_permissions")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, default = "gen_random_uuid()", auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub name: String,
|
||||
|
||||
#[sea_orm(not_null, default = "false")]
|
||||
pub is_deleted: bool,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, sea_orm::EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_many = "super::roles_permissions::Entity")]
|
||||
RolesPermissions,
|
||||
}
|
||||
|
||||
impl Related<super::roles_permissions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::RolesPermissions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
impl Entity {
|
||||
pub fn find_by_id(id: Uuid) -> Select<Entity> {
|
||||
Self::find().filter(Column::Id.eq(id))
|
||||
}
|
||||
|
||||
pub fn find_by_name(name: &str) -> Select<Entity> {
|
||||
Self::find().filter(Column::Name.eq(name))
|
||||
}
|
||||
|
||||
pub fn find_active() -> Select<Entity> {
|
||||
Self::find().filter(Column::IsDeleted.eq(false))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
//! SeaORM entity for Roles table
|
||||
//! Corresponding to ResourceEnum::Roles
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::{ActiveModelBehavior, DeriveEntityModel, DeriveRelation};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "app_roles")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, default = "gen_random_uuid()", auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
|
||||
#[sea_orm(unique, not_null)]
|
||||
pub name: String,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub description: String,
|
||||
|
||||
#[sea_orm(default = "false")]
|
||||
pub is_system_role: bool,
|
||||
|
||||
#[sea_orm(default = "false")]
|
||||
pub is_default: bool,
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub permissions: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, sea_orm::EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
// Default implementation - SeaORM will handle timestamps automatically
|
||||
}
|
||||
|
||||
// Builder pattern for Role creation
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct RoleBuilder {
|
||||
name: Option<String>,
|
||||
description: Option<String>,
|
||||
is_system_role: Option<bool>,
|
||||
is_default: Option<bool>,
|
||||
permissions: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl RoleBuilder {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn name(mut self, name: String) -> Self {
|
||||
self.name = Some(name);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn description(mut self, description: String) -> Self {
|
||||
self.description = Some(description);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_system_role(mut self, is_system_role: bool) -> Self {
|
||||
self.is_system_role = Some(is_system_role);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_default(mut self, is_default: bool) -> Self {
|
||||
self.is_default = Some(is_default);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn permissions(mut self, permissions: Vec<String>) -> Self {
|
||||
self.permissions = Some(permissions);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<ActiveModel, String> {
|
||||
let mut active_model = <ActiveModel as std::default::Default>::default();
|
||||
|
||||
if let Some(name) = self.name {
|
||||
active_model.name = Set(name);
|
||||
} else {
|
||||
return Err("Role name is required".to_string());
|
||||
}
|
||||
|
||||
if let Some(description) = self.description {
|
||||
active_model.description = Set(description);
|
||||
} else {
|
||||
return Err("Role description is required".to_string());
|
||||
}
|
||||
|
||||
if let Some(is_system_role) = self.is_system_role {
|
||||
active_model.is_system_role = Set(is_system_role);
|
||||
}
|
||||
|
||||
if let Some(is_default) = self.is_default {
|
||||
active_model.is_default = Set(is_default);
|
||||
}
|
||||
|
||||
if let Some(permissions) = self.permissions {
|
||||
active_model.permissions = Set(Some(serde_json::Value::Array(
|
||||
permissions.into_iter().map(serde_json::Value::String).collect()
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(active_model)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_role_model_creation() {
|
||||
let role = RoleBuilder::new()
|
||||
.name("admin".to_string())
|
||||
.description("Administrator role".to_string())
|
||||
.is_system_role(true)
|
||||
.is_default(false)
|
||||
.build();
|
||||
|
||||
assert!(role.is_ok());
|
||||
let role_model = role.unwrap();
|
||||
assert_eq!(role_model.name, Set("admin".to_string()));
|
||||
assert_eq!(role_model.description, Set("Administrator role".to_string()));
|
||||
assert_eq!(role_model.is_system_role, Set(true));
|
||||
assert_eq!(role_model.is_default, Set(false));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
//! SeaORM entity for RolesPermissions table
|
||||
//! Corresponding to ResourceEnum::RolesPermissions
|
||||
//! Represents the many-to-many relationship between Users and Roles
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::{ActiveModelBehavior, DeriveEntityModel, DeriveRelation};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "app_roles_permissions")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, default = "gen_random_uuid()", auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub user_id: Uuid,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub role_id: Uuid,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub permission_id: Uuid,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub assigned_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(not_null, default = "false")]
|
||||
pub is_active: bool,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, sea_orm::EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(belongs_to = "super::users::Entity", from = "Column::UserId", to = "super::users::Column::Id")]
|
||||
User,
|
||||
#[sea_orm(belongs_to = "super::roles::Entity", from = "Column::RoleId", to = "super::roles::Column::Id")]
|
||||
Role,
|
||||
#[sea_orm(belongs_to = "super::permissions::Entity", from = "Column::PermissionId", to = "super::permissions::Column::Id")]
|
||||
Permission,
|
||||
}
|
||||
|
||||
impl Related<super::users::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::User.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::roles::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Role.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::permissions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Permission.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
// Default implementation - SeaORM will handle timestamps automatically
|
||||
}
|
||||
|
||||
// Builder pattern for RolePermission creation
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
pub struct RolePermissionBuilder {
|
||||
user_id: Option<Uuid>,
|
||||
role_id: Option<Uuid>,
|
||||
permission_id: Option<Uuid>,
|
||||
is_active: Option<bool>,
|
||||
}
|
||||
|
||||
impl RolePermissionBuilder {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn user_id(mut self, user_id: Uuid) -> Self {
|
||||
self.user_id = Some(user_id);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn role_id(mut self, role_id: Uuid) -> Self {
|
||||
self.role_id = Some(role_id);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn permission_id(mut self, permission_id: Uuid) -> Self {
|
||||
self.permission_id = Some(permission_id);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_active(mut self, is_active: bool) -> Self {
|
||||
self.is_active = Some(is_active);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<ActiveModel, String> {
|
||||
let mut active_model = <ActiveModel as std::default::Default>::default();
|
||||
|
||||
if let (Some(user_id), Some(role_id), Some(permission_id)) = (self.user_id, self.role_id, self.permission_id) {
|
||||
active_model.user_id = Set(user_id);
|
||||
active_model.role_id = Set(role_id);
|
||||
active_model.permission_id = Set(permission_id);
|
||||
} else {
|
||||
return Err("User ID, Role ID, and Permission ID are required".to_string());
|
||||
}
|
||||
|
||||
if let Some(is_active) = self.is_active {
|
||||
active_model.is_active = Set(is_active);
|
||||
}
|
||||
|
||||
Ok(active_model)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::seaorm::common::utils::generate_uuid;
|
||||
|
||||
#[test]
|
||||
fn test_role_permission_model_creation() {
|
||||
let user_id = generate_uuid();
|
||||
let role_id = generate_uuid();
|
||||
let permission_id = generate_uuid();
|
||||
|
||||
let role_permission = RolePermissionBuilder::new()
|
||||
.user_id(user_id)
|
||||
.role_id(role_id)
|
||||
.permission_id(permission_id)
|
||||
.is_active(true)
|
||||
.build();
|
||||
|
||||
assert!(role_permission.is_ok());
|
||||
let role_permission_model = role_permission.unwrap();
|
||||
assert_eq!(role_permission_model.user_id, Set(user_id));
|
||||
assert_eq!(role_permission_model.role_id, Set(role_id));
|
||||
assert_eq!(role_permission_model.permission_id, Set(permission_id));
|
||||
assert_eq!(role_permission_model.is_active, Set(true));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
use sea_orm::entity::prelude::*;
|
||||
use chrono::{DateTime, Utc};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "sessions")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, default = "gen_random_uuid()", auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
|
||||
#[sea_orm(column_type = "Uuid")]
|
||||
pub mentor_id: Uuid,
|
||||
|
||||
#[sea_orm(column_type = "Uuid")]
|
||||
pub mentee_id: Uuid,
|
||||
|
||||
pub topic: String,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub description: Option<String>,
|
||||
|
||||
pub scheduled_at: DateTime<Utc>,
|
||||
|
||||
pub duration_minutes: i32,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub meeting_link: Option<String>,
|
||||
|
||||
pub session_type: String, // "video_call", "phone_call", "chat"
|
||||
|
||||
pub status: String, // "pending", "confirmed", "completed", "cancelled", "no_show"
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub feedback: Option<String>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub rating: Option<i32>, // 1-5
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub feedback_submitted_at: Option<DateTime<Utc>>,
|
||||
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::users::Entity",
|
||||
from = "Column::MentorId",
|
||||
to = "super::users::Column::Id"
|
||||
)]
|
||||
Mentor,
|
||||
|
||||
#[sea_orm(
|
||||
belongs_to = "super::users::Entity",
|
||||
from = "Column::MenteeId",
|
||||
to = "super::users::Column::Id"
|
||||
)]
|
||||
Mentee,
|
||||
}
|
||||
|
||||
impl Related<super::users::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Mentor.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
@@ -0,0 +1,178 @@
|
||||
//! SeaORM entity for Users table
|
||||
//! Corresponding to ResourceEnum::Users
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize, imphnen_macros::Builder)]
|
||||
#[sea_orm(table_name = "app_users")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key, default = "gen_random_uuid()", auto_increment = false)]
|
||||
pub id: Uuid,
|
||||
|
||||
#[sea_orm(unique, not_null)]
|
||||
pub email: String,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub password_hash: String,
|
||||
|
||||
#[sea_orm(not_null)]
|
||||
pub username: String,
|
||||
|
||||
#[sea_orm(column_name = "role_id", nullable)]
|
||||
pub role_id: Option<Uuid>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub first_name: Option<String>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub last_name: Option<String>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub avatar_url: Option<String>,
|
||||
|
||||
#[sea_orm(default = "false")]
|
||||
pub is_verified: bool,
|
||||
|
||||
#[sea_orm(default = "false")]
|
||||
pub is_active: bool,
|
||||
|
||||
|
||||
#[sea_orm(type = "jsonb", nullable)]
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub created_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(not_null, default = "now()")]
|
||||
pub updated_at: DateTime<Utc>,
|
||||
|
||||
#[sea_orm(nullable)]
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, sea_orm::EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_many = "super::roles_permissions::Entity")]
|
||||
RolesPermissions,
|
||||
#[sea_orm(belongs_to = "super::roles::Entity", from = "Column::RoleId", to = "super::roles::Column::Id")]
|
||||
Role,
|
||||
}
|
||||
|
||||
impl Related<super::roles_permissions::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::RolesPermissions.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::roles::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Role.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
// Default implementation - SeaORM will handle timestamps automatically
|
||||
}
|
||||
|
||||
// Builder pattern for User creation
|
||||
// Generated by #[derive(Builder)]
|
||||
pub type UserBuilder = ModelBuilder;
|
||||
|
||||
impl ModelBuilder {
|
||||
pub fn build(self) -> Result<ActiveModel, String> {
|
||||
let mut active_model = <ActiveModel as std::default::Default>::default();
|
||||
|
||||
if let Some(email) = self.email {
|
||||
active_model.email = Set(email);
|
||||
} else {
|
||||
return Err("Email is required".to_string());
|
||||
}
|
||||
|
||||
if let Some(password_hash) = self.password_hash {
|
||||
active_model.password_hash = Set(password_hash);
|
||||
} else {
|
||||
return Err("Password hash is required".to_string());
|
||||
}
|
||||
|
||||
if let Some(username) = self.username {
|
||||
active_model.username = Set(username);
|
||||
} else {
|
||||
return Err("Username is required".to_string());
|
||||
}
|
||||
|
||||
if let Some(role_id) = self.role_id {
|
||||
active_model.role_id = Set(Some(role_id));
|
||||
}
|
||||
|
||||
if let Some(first_name) = self.first_name {
|
||||
active_model.first_name = Set(Some(first_name));
|
||||
}
|
||||
|
||||
if let Some(last_name) = self.last_name {
|
||||
active_model.last_name = Set(Some(last_name));
|
||||
}
|
||||
|
||||
if let Some(avatar_url) = self.avatar_url {
|
||||
active_model.avatar_url = Set(Some(avatar_url));
|
||||
}
|
||||
|
||||
if let Some(is_verified) = self.is_verified {
|
||||
active_model.is_verified = Set(is_verified);
|
||||
}
|
||||
|
||||
if let Some(is_active) = self.is_active {
|
||||
active_model.is_active = Set(is_active);
|
||||
}
|
||||
|
||||
if let Some(metadata) = self.metadata {
|
||||
active_model.metadata = Set(Some(metadata));
|
||||
}
|
||||
|
||||
Ok(active_model)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_user_model_creation() {
|
||||
let user = UserBuilder::new()
|
||||
.email("test@example.com".to_string())
|
||||
.password_hash("hashed_password".to_string())
|
||||
.username("testuser".to_string())
|
||||
.first_name("Test".to_string())
|
||||
.last_name("User".to_string())
|
||||
.is_verified(true)
|
||||
.is_active(true)
|
||||
.build();
|
||||
|
||||
assert!(user.is_ok());
|
||||
let user_model = user.unwrap();
|
||||
assert_eq!(user_model.email, Set("test@example.com".to_string()));
|
||||
assert_eq!(user_model.password_hash, Set("hashed_password".to_string()));
|
||||
assert_eq!(user_model.username, Set("testuser".to_string()));
|
||||
assert_eq!(user_model.first_name, Set(Some("Test".to_string())));
|
||||
assert_eq!(user_model.last_name, Set(Some("User".to_string())));
|
||||
assert_eq!(user_model.is_verified, Set(true));
|
||||
assert_eq!(user_model.is_active, Set(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_model_missing_required_fields() {
|
||||
let user = UserBuilder::new()
|
||||
.email("test@example.com".to_string())
|
||||
// Missing password_hash
|
||||
.username("testuser".to_string())
|
||||
.build();
|
||||
|
||||
assert!(user.is_err());
|
||||
assert_eq!(user.unwrap_err(), "Password hash is required");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user