use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize, Deserializer}; use rust_decimal::Decimal; /// Represents a user in the system #[derive(Debug, Clone, Serialize, Deserialize)] pub struct User { /// Unique identifier for the user pub id: Option, /// User's full name pub name: String, /// User's email address pub email: String, /// User's role in the system pub role: UserRole, /// User's country pub country: Option, /// User's timezone pub timezone: Option, /// When the user was created pub created_at: Option>, /// When the user was last updated pub updated_at: Option>, } /// Represents the possible roles a user can have #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum UserRole { /// Regular user with limited permissions User, /// Administrator with full permissions Admin, } impl User { /// Creates a new user with default values pub fn new(name: String, email: String) -> Self { Self { id: None, name, email, role: UserRole::User, country: None, timezone: None, created_at: Some(Utc::now()), updated_at: Some(Utc::now()), } } /// Get wallet balance for user from persistent data pub fn get_wallet_balance(&self) -> Result> { let persistent_data = crate::services::user_persistence::UserPersistence::load_user_data(&self.email) .ok_or("User data not found")?; Ok(persistent_data.wallet_balance_usd) } /// Get owned products for user from persistent data pub fn get_owned_products(&self) -> Result, Box> { let persistent_data = crate::services::user_persistence::UserPersistence::load_user_data(&self.email) .ok_or("User data not found")?; Ok(persistent_data.owned_products) } } /// Product in the marketplace #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Product { pub id: String, pub name: String, pub description: String, pub price: Decimal, pub category: String, pub status: String, #[serde(default)] pub product_type: String, #[serde(default)] pub created_at: Option>, #[serde(default)] pub updated_at: Option>, } /// Product rental information #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProductRental { pub id: String, pub product_id: String, pub customer_email: String, pub monthly_cost: Decimal, pub status: String, pub rental_id: String, #[serde(default)] pub start_date: Option>, #[serde(default)] pub end_date: Option>, } /// Represents user login credentials #[derive(Debug, Deserialize)] pub struct LoginCredentials { pub email: String, pub password: String, } /// Represents user registration data #[derive(Debug, Deserialize)] pub struct RegistrationData { pub name: String, pub email: String, pub password: String, pub password_confirmation: String, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct ResourceUtilization { pub cpu: i32, pub memory: i32, pub storage: i32, pub network: i32, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct UserActivityStats { pub deployments: Vec, pub resource_reservations: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RecentActivity { pub date: String, pub action: String, pub status: String, pub details: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DeploymentDistribution { pub regions: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RegionDeployments { pub region: String, pub deployments: i32, pub compute: i32, pub storage: i32, pub gateways: i32, } /// Node information for resource_provider dashboard #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeInfo { pub id: String, pub location: String, pub status: NodeStatus, pub monthly_earnings_usd: i32, pub cpu_total: i32, pub memory_total_gb: i32, pub ssd_storage_gb: i32, pub hdd_storage_gb: i32, pub cpu_used: i32, pub memory_used_gb: i32, pub ssd_used_gb: i32, pub hdd_used_gb: i32, pub uptime_percentage: f32, pub network_bandwidth_mbps: i32, pub farming_start_date: DateTime, pub last_updated: DateTime, pub utilization_7_day_avg: f32, pub slice_formats_supported: Vec, pub slice_last_calculated: Option>, #[serde(default)] pub name: String, #[serde(default)] pub capacity: NodeCapacity, } /// Node status enum #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeStatus { Online, Offline, Maintenance, Standby, } impl Default for NodeStatus { fn default() -> Self { Self::Offline } } impl std::fmt::Display for NodeStatus { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { NodeStatus::Online => write!(f, "Online"), NodeStatus::Offline => write!(f, "Offline"), NodeStatus::Maintenance => write!(f, "Maintenance"), NodeStatus::Standby => write!(f, "Standby"), } } } /// Default maintenance window for resource_provider settings pub fn default_maintenance_window() -> String { "02:00-04:00 UTC".to_string() } /// ResourceProvider configuration settings #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ResourceProviderSettings { pub auto_accept_reserved_slices: bool, pub maintenance_window: String, // e.g., "02:00-04:00 UTC" pub notification_email: Option, pub slack_webhook: Option, pub max_slice_commitment_months: Option, pub emergency_contact: Option, pub automated_updates: Option, pub performance_notifications: Option, pub maintenance_reminders: Option, #[serde(default)] pub auto_accept_deployments: bool, #[serde(default)] pub default_slice_customizations: Option, #[serde(default)] pub minimum_deployment_duration: u32, #[serde(default)] pub notification_preferences: Option, #[serde(default)] pub preferred_regions: Vec, } impl Default for ResourceProviderSettings { fn default() -> Self { Self { auto_accept_reserved_slices: true, maintenance_window: default_maintenance_window(), notification_email: None, slack_webhook: None, max_slice_commitment_months: Some(12), auto_accept_deployments: false, default_slice_customizations: None, minimum_deployment_duration: 24, notification_preferences: None, preferred_regions: Vec::new(), emergency_contact: None, automated_updates: Some(true), performance_notifications: Some(true), maintenance_reminders: Some(true), } } } /// Performance metrics for nodes #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodePerformanceMetrics { pub average_uptime: f32, pub resource_efficiency: f32, pub last_updated: chrono::DateTime, } impl Default for NodePerformanceMetrics { fn default() -> Self { Self { average_uptime: 99.0, resource_efficiency: 85.0, last_updated: chrono::Utc::now(), } } } /// Pool staking position #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PoolPosition { pub pool_id: String, pub amount_staked: rust_decimal::Decimal, pub stake_date: chrono::DateTime, pub lock_duration_months: u32, pub expected_apy: f32, pub auto_compound: bool, pub auto_renewal_enabled: bool, } impl Default for PoolPosition { fn default() -> Self { Self { pool_id: String::new(), amount_staked: rust_decimal::Decimal::ZERO, stake_date: chrono::Utc::now(), lock_duration_months: 6, expected_apy: 8.5, auto_compound: true, auto_renewal_enabled: true, } } } /// Liquidity pool configuration #[derive(Debug, Clone, Serialize, Deserialize)] pub struct LiquidityPoolConfig { pub pool_id: String, pub base_token: String, pub quote_token: String, pub fee_tier: f32, pub minimum_liquidity: rust_decimal::Decimal, pub maximum_liquidity: Option, pub lock_duration_days: u32, pub penalty_rate: f32, pub early_withdrawal_penalty_percent: f32, } impl Default for LiquidityPoolConfig { fn default() -> Self { Self { pool_id: String::new(), base_token: "MC".to_string(), quote_token: "USD".to_string(), fee_tier: 0.3, minimum_liquidity: rust_decimal_macros::dec!(100.0), maximum_liquidity: None, lock_duration_days: 30, penalty_rate: 2.5, early_withdrawal_penalty_percent: 5.0, } } } impl Default for ResourceProviderData { fn default() -> Self { Self { total_nodes: 0, active_nodes: 0, total_monthly_earnings_usd: 0, nodes: Vec::new(), revenue_history: Vec::new(), total_capacity: NodeCapacity::default(), used_capacity: NodeCapacity::default(), online_nodes: 0, uptime_percentage: 0.0, total_earnings_usd: Decimal::ZERO, monthly_earnings_usd: Decimal::ZERO, earnings_history: Vec::new(), active_slices: 0, slice_templates: Vec::new(), } } } /// Yield farming configuration #[derive(Debug, Clone, Serialize, Deserialize)] pub struct YieldFarmConfig { pub farm_id: String, pub reward_token: String, pub staked_token: String, pub apr: f32, pub lock_duration_days: u32, pub minimum_stake: rust_decimal::Decimal, pub maximum_stake: Option, pub compound_frequency_days: u32, pub auto_compound: bool, pub yearly_discount_percent: f32, } impl Default for YieldFarmConfig { fn default() -> Self { Self { farm_id: String::new(), reward_token: "MC".to_string(), staked_token: "MC".to_string(), apr: 12.0, lock_duration_days: 365, minimum_stake: rust_decimal_macros::dec!(1000.0), maximum_stake: None, compound_frequency_days: 7, auto_compound: true, yearly_discount_percent: 10.0, } } } /// Service-level agreement template #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ServiceLevelAgreement { pub id: String, pub name: String, pub uptime_guarantee: f32, // percentage (e.g., 99.9) pub response_time_hours: u32, pub resolution_time_hours: u32, pub penalty_rate: f32, // percentage of service cost pub monitoring_frequency_minutes: u32, } impl Default for ServiceLevelAgreement { fn default() -> Self { Self { id: uuid::Uuid::new_v4().to_string(), name: "Standard SLA".to_string(), uptime_guarantee: 99.5, response_time_hours: 4, resolution_time_hours: 24, penalty_rate: 10.0, monitoring_frequency_minutes: 15, } } } /// Application deployment configuration #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApplicationDeployment { pub id: String, pub app_id: String, pub customer_email: String, pub deployment_status: ApplicationDeploymentStatus, pub resource_allocation: ResourceUtilization, pub monthly_cost: rust_decimal::Decimal, pub deployed_at: Option>, pub auto_scaling: bool, pub backup_enabled: bool, pub monitoring_enabled: bool, } /// Application deployment status #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ApplicationDeploymentStatus { Pending, Deploying, Running, Stopped, Failed, Maintenance, } impl Default for ApplicationDeploymentStatus { fn default() -> Self { Self::Pending } } /// Node assignment for slice rentals #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeAssignment { pub node_id: String, pub slice_format: String, pub resource_allocation: ResourceUtilization, pub assigned_at: DateTime, pub status: NodeAssignmentStatus, } /// Node assignment status #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeAssignmentStatus { Assigned, Active, Released, Reserved, } impl Default for NodeAssignmentStatus { fn default() -> Self { Self::Assigned } } /// Slice rental details including node assignments #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SliceRentalDetail { pub rental_id: String, pub customer_email: String, pub slice_format: String, pub duration_months: u32, pub monthly_cost: rust_decimal::Decimal, pub node_assignments: Vec, pub start_date: DateTime, pub end_date: DateTime, pub auto_renewal: bool, pub payment_status: PaymentStatus, } /// Slice rental information #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SliceRental { pub rental_id: String, pub customer_email: String, pub slice_format: String, pub duration_months: u32, pub monthly_cost: rust_decimal::Decimal, pub start_date: DateTime, pub end_date: DateTime, pub auto_renewal: bool, pub payment_status: PaymentStatus, #[serde(default)] pub id: String, #[serde(default)] pub user_email: String, #[serde(default)] pub status: String, #[serde(default)] pub rental_duration_days: u32, #[serde(default)] pub monthly_cost_usd: Decimal, } /// Payment status for rentals #[derive(Debug, Clone, Serialize, Deserialize)] pub enum PaymentStatus { Pending, Paid, Overdue, Refunded, Completed, } impl Default for PaymentStatus { fn default() -> Self { Self::Pending } } /// Full node rental (alternative to slice rental) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeRental { pub rental_id: String, pub customer_email: String, pub node_id: String, pub rental_type: NodeRentalType, pub monthly_cost: rust_decimal::Decimal, pub start_date: DateTime, pub end_date: DateTime, pub auto_renewal: bool, pub payment_status: PaymentStatus, pub sla_id: Option, pub custom_configuration: Option, pub metadata: std::collections::HashMap, #[serde(default)] pub id: String, #[serde(default)] pub status: NodeRentalStatus, #[serde(default)] pub renter_email: String, #[serde(default)] pub payment_method: String, } impl NodeRental { /// Check if the rental is currently active pub fn is_active(&self) -> bool { matches!(self.status, NodeRentalStatus::Active) } } /// Type of node rental #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeRentalType { SliceRental, FullNode, Slice, } impl Default for NodeRentalType { fn default() -> Self { Self::SliceRental } } /// Node rental payment status #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeRentalStatus { Active, Paused, Cancelled, Suspended, Pending, } impl Default for NodeRentalStatus { fn default() -> Self { Self::Pending } } /// User activity for audit trail #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserActivity { pub id: String, pub user_email: String, pub activity_type: ActivityType, pub description: String, pub metadata: Option, pub timestamp: DateTime, pub ip_address: Option, pub user_agent: Option, pub session_id: Option, pub importance: ActivityImportance, #[serde(default)] pub category: String, } /// Types of user activities for tracking #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ActivityType { Login, Logout, ProfileUpdate, PasswordChange, CreditsTopup, NodeDeployment, AppDeployment, SliceRental, SliceRentalCancelled, Purchase, Deployment, ServiceCreated, AppPublished, NodeAdded, NodeUpdated, ServiceRequested, WalletTopup, ServiceCompleted, WalletTransaction, SettingsChange, MarketplaceView, SliceCreated, SliceAllocated, SliceReleased, SliceRentalStarted, SliceRentalStopped, SliceRentalRestarted, } /// Importance level for activities #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ActivityImportance { Low, Medium, High, Critical, } /// User session information #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserSession { pub session_id: String, pub user_email: String, pub created_at: DateTime, pub expires_at: DateTime, pub ip_address: String, pub user_agent: String, pub is_active: bool, pub last_activity: DateTime, } fn default_subscription_multiplier() -> f32 { 1.0 } fn default_last_activity() -> DateTime { Utc::now() } /// App provider settings and data #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AppProviderData { pub published_apps: i32, pub total_deployments: i32, pub monthly_revenue_usd: i32, pub total_revenue_usd: i32, pub apps: Vec, pub deployment_stats: Vec, pub revenue_history: Vec, #[serde(default)] pub active_deployments: i32, } /// Revenue tracking record #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RevenueRecord { pub date: String, pub amount: f32, pub change_percentage: f32, } /// Service provider settings and data #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ServiceProviderData { pub active_services: i32, pub total_clients: i32, pub monthly_revenue_usd: i32, pub total_revenue_usd: i32, pub service_rating: f32, pub services: Vec, pub client_requests: Vec, pub availability: Option, pub hourly_rate_range: Option, pub last_payment_method: Option, #[serde(default)] pub revenue_history: Vec, } /// User preferences for UI and notifications #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserPreferences { pub theme: String, // "light", "dark", "auto" pub language: String, pub currency_display: String, pub email_notifications: bool, pub push_notifications: bool, pub marketing_emails: bool, pub data_sharing: bool, #[serde(default)] pub preferred_currency: String, #[serde(default)] pub preferred_language: String, #[serde(default)] pub timezone: String, #[serde(default)] pub notification_settings: Option, #[serde(default)] pub privacy_settings: Option, #[serde(default)] pub dashboard_layout: String, #[serde(default)] pub last_payment_method: Option, } impl Default for UserPreferences { fn default() -> Self { Self { theme: "light".to_string(), language: "en".to_string(), currency_display: "USD".to_string(), email_notifications: true, push_notifications: true, marketing_emails: false, data_sharing: false, preferred_currency: "USD".to_string(), preferred_language: "en".to_string(), timezone: "UTC".to_string(), notification_settings: Some(NotificationSettings::default()), privacy_settings: Some(PrivacySettings::default()), dashboard_layout: "grid".to_string(), last_payment_method: None, } } } /// Quick action for dashboard #[derive(Debug, Clone, Serialize, Deserialize)] pub struct QuickAction { pub id: String, pub label: String, pub description: String, pub icon: String, pub url: String, pub category: String, pub importance: i32, pub last_updated: DateTime, #[serde(default)] pub title: String, #[serde(default)] pub action_url: String, #[serde(default)] pub enabled: bool, } /// ResourceProvider-specific data #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ResourceProviderData { pub total_nodes: i32, pub active_nodes: i32, pub total_monthly_earnings_usd: i32, pub nodes: Vec, pub revenue_history: Vec, #[serde(default)] pub total_capacity: NodeCapacity, #[serde(default)] pub used_capacity: NodeCapacity, #[serde(default)] pub online_nodes: i32, #[serde(default)] pub uptime_percentage: f32, #[serde(default)] pub total_earnings_usd: Decimal, #[serde(default)] pub monthly_earnings_usd: Decimal, #[serde(default)] pub earnings_history: Vec, #[serde(default)] pub active_slices: i32, #[serde(default)] pub slice_templates: Vec, } /// Customer service stats and data #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CustomerServiceData { pub active_bookings: i32, pub total_spent_usd: i32, pub service_bookings: Vec, pub spending_history: Vec, pub pending_transactions: i32, #[serde(default)] pub total_spent: Decimal, #[serde(default)] pub monthly_spending: Decimal, #[serde(default)] pub favorite_providers: Vec, #[serde(default)] pub completed_bookings: i32, #[serde(default)] pub average_rating_given: f32, } /// Spending record for customer service tracking #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SpendingRecord { pub date: String, pub amount: f32, pub provider_name: String, #[serde(default)] pub service_name: String, } /// Notification preferences #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NotificationSettings { pub email_enabled: bool, pub push_enabled: bool, pub sms_enabled: bool, pub slack_webhook: Option, pub discord_webhook: Option, pub enabled: bool, #[serde(default)] pub push: bool, #[serde(default)] pub node_offline_alerts: bool, #[serde(default)] pub maintenance_reminders: bool, #[serde(default)] pub earnings_reports: bool, } impl Default for NotificationSettings { fn default() -> Self { Self { email_enabled: true, push_enabled: true, sms_enabled: false, slack_webhook: None, discord_webhook: None, enabled: true, push: true, node_offline_alerts: true, maintenance_reminders: true, earnings_reports: true, } } } /// User profile information for dashboards #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserInfo { pub name: String, pub email: String, pub member_since: String, pub account_type: String, pub verification_status: String, } /// Wallet summary information for dashboards #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WalletSummary { pub balance: Decimal, pub currency: String, pub recent_transactions: i32, pub pending_transactions: i32, } /// User recommendation for dashboard #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Recommendation { pub id: String, pub title: String, pub description: String, pub action_url: String, pub priority: String, pub category: String, } /// Privacy settings for user profile #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PrivacySettings { pub profile_public: bool, pub email_public: bool, pub activity_public: bool, pub stats_public: bool, #[serde(default)] pub profile_visibility: String, #[serde(default)] pub marketing_emails: bool, #[serde(default)] pub data_sharing: bool, #[serde(default)] pub activity_tracking: bool, } impl Default for PrivacySettings { fn default() -> Self { Self { profile_public: false, email_public: false, activity_public: false, stats_public: false, profile_visibility: "private".to_string(), marketing_emails: false, data_sharing: false, activity_tracking: false, } } } /// Default group types for node grouping #[derive(Debug, Clone, Serialize, Deserialize)] pub enum DefaultGroupType { Compute, Storage, AiGpu, } impl DefaultGroupType { pub fn get_id(&self) -> &str { match self { DefaultGroupType::Compute => "compute", DefaultGroupType::Storage => "storage", DefaultGroupType::AiGpu => "ai-gpu", } } pub fn get_name(&self) -> &str { match self { DefaultGroupType::Compute => "Compute", DefaultGroupType::Storage => "Storage", DefaultGroupType::AiGpu => "AI/GPU", } } pub fn get_description(&self) -> &str { match self { DefaultGroupType::Compute => "General compute workloads", DefaultGroupType::Storage => "Storage and data workloads", DefaultGroupType::AiGpu => "AI and GPU-intensive workloads", } } pub fn get_default_config(&self) -> NodeGroupConfig { match self { DefaultGroupType::Compute => NodeGroupConfig { group_name: "Compute Nodes".to_string(), max_nodes: 100, allocation_strategy: "balanced".to_string(), auto_scaling: true, preferred_slice_formats: vec!["1x1".to_string(), "2x2".to_string()], default_pricing: Some(serde_json::to_value(rust_decimal::Decimal::from(50)).unwrap_or_default()), resource_optimization: ResourceOptimization::Balanced, }, DefaultGroupType::Storage => NodeGroupConfig { group_name: "Storage Nodes".to_string(), max_nodes: 50, allocation_strategy: "storage_optimized".to_string(), auto_scaling: false, preferred_slice_formats: vec!["1x1".to_string()], default_pricing: Some(serde_json::to_value(rust_decimal::Decimal::from(30)).unwrap_or_default()), resource_optimization: ResourceOptimization::Storage, }, DefaultGroupType::AiGpu => NodeGroupConfig { group_name: "AI/GPU Nodes".to_string(), max_nodes: 20, allocation_strategy: "gpu_optimized".to_string(), auto_scaling: true, preferred_slice_formats: vec!["4x4".to_string(), "8x8".to_string()], default_pricing: Some(serde_json::to_value(rust_decimal::Decimal::from(200)).unwrap_or_default()), resource_optimization: ResourceOptimization::Compute, }, } } } /// Published application by app provider #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PublishedApp { pub id: String, pub name: String, pub description: Option, pub version: String, pub category: String, pub price_usd: rust_decimal::Decimal, pub deployment_count: i32, pub rating: f32, pub status: String, pub created_at: DateTime, pub updated_at: DateTime, pub auto_scaling: Option, pub auto_healing: Option, pub revenue_history: Vec, #[serde(default)] pub deployments: i32, #[serde(default)] pub monthly_revenue_usd: Decimal, #[serde(default)] pub last_updated: DateTime, } impl PublishedApp { } /// Deployment statistics for published apps #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DeploymentStat { pub app_name: String, pub region: String, pub active_instances: i32, pub total_instances: i32, pub avg_response_time_ms: Option, pub uptime_percentage: Option, pub status: String, #[serde(default)] pub instances: i32, #[serde(default)] pub resource_usage: Option, #[serde(default)] pub customer_name: Option, #[serde(default)] pub deployed_date: Option>, #[serde(default)] pub deployment_id: Option, pub last_deployment: Option>, pub auto_healing: Option, } impl DeploymentStat { } /// Service offered by service provider #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Service { pub id: String, pub name: String, pub description: String, pub category: String, pub price_usd: rust_decimal::Decimal, pub hourly_rate_usd: Option, pub availability: bool, pub created_at: DateTime, pub updated_at: DateTime, #[serde(default)] pub clients: i32, #[serde(default)] pub price_per_hour_usd: i32, #[serde(default)] pub status: String, #[serde(default)] pub rating: f32, #[serde(default)] pub total_hours: Option, } impl Service { pub fn builder() -> crate::models::builders::ServiceBuilder { crate::models::builders::ServiceBuilder::new() } } /// Service request from customer to provider #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ServiceRequest { pub id: String, pub customer_email: String, pub service_id: String, pub description: Option, pub status: String, pub estimated_hours: Option, pub hourly_rate_usd: Option, pub total_cost_usd: Option, pub progress_percentage: Option, pub created_date: Option, pub completed_date: Option, #[serde(default)] pub progress: Option, #[serde(default)] pub priority: String, #[serde(default)] pub hours_worked: Option, #[serde(default)] pub notes: Option, #[serde(default)] pub service_name: String, #[serde(default)] pub budget: Decimal, #[serde(default)] pub requested_date: String, #[serde(default)] pub client_phone: Option, #[serde(default)] pub client_name: Option, #[serde(default)] pub client_email: Option, } impl ServiceRequest { pub fn builder() -> crate::models::builders::ServiceRequestBuilder { crate::models::builders::ServiceRequestBuilder::new() } } /// Service booking by customer #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ServiceBooking { pub id: String, pub provider_email: String, pub service_id: String, pub description: Option, pub status: String, pub estimated_hours: Option, pub hourly_rate_usd: Option, pub total_cost_usd: Option, pub progress_percentage: Option, pub created_date: Option, pub completed_date: Option, #[serde(default)] pub customer_email: String, #[serde(default)] pub service_name: String, #[serde(default)] pub budget: Decimal, #[serde(default)] pub requested_date: String, #[serde(default)] pub priority: String, #[serde(default)] pub progress: Option, #[serde(default)] pub client_phone: Option, #[serde(default)] pub booking_date: Option>, } impl ServiceBooking { } /// Transaction record #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Transaction { pub id: String, pub user_id: String, pub transaction_type: TransactionType, pub amount: rust_decimal::Decimal, pub currency: Option, pub exchange_rate_usd: Option, pub amount_usd: Option, pub description: Option, pub reference_id: Option, pub metadata: Option>, pub timestamp: DateTime, pub status: TransactionStatus, } /// Transaction types #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TransactionType { Purchase { product_id: String }, Earning { source: String }, Refund { original_transaction_id: String }, PoolStake { pool_id: String }, PoolUnstake { pool_id: String }, PoolReward { pool_id: String }, SliceRental { rental_id: String }, NodeRental { rental_id: String, node_id: String }, ServicePayment { service_id: String, provider_email: String }, AppRevenue { app_id: String, deployment_id: String }, FarmingReward { node_id: String }, CreditsTopup { payment_method: String, payment_id: Option }, CreditsTransfer { to_user: String, note: Option }, // Missing variants from error patterns Stake { pool_id: String, amount: rust_decimal::Decimal }, Rental { rental_id: String, rental_type: String }, InstantPurchase { product_id: String, quantity: Option }, Exchange { from_currency: String, to_currency: String, rate: rust_decimal::Decimal }, CreditsSale { amount_usd: rust_decimal::Decimal, rate: rust_decimal::Decimal }, CreditsPurchase { amount_usd: rust_decimal::Decimal, payment_method: String }, AutoTopUp { amount_usd: rust_decimal::Decimal, trigger_balance: rust_decimal::Decimal }, } /// Transaction status #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TransactionStatus { Pending, Completed, Failed, Refunded, Cancelled, } /// Slice format pricing #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SliceFormatPricing { pub slice_format: String, pub monthly_cost: rust_decimal::Decimal, } /// Node group organization status #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeGroupStatus { Active, Inactive, Pending, } /// Function to deserialize datetime with error handling pub fn deserialize_datetime<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let s: String = Deserialize::deserialize(deserializer)?; DateTime::parse_from_rfc3339(&s) .map(|dt| dt.with_timezone(&Utc)) .map_err(serde::de::Error::custom) } /// Node group for resource_provider organization #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeGroup { pub id: String, pub name: String, pub description: Option, pub node_ids: Vec, pub group_type: NodeGroupType, #[serde(default)] pub updated_at: DateTime, #[serde(default)] pub created_at: DateTime, #[serde(default)] pub group_config: NodeGroupConfig, } /// Node group types #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeGroupType { Storage, // group_1 - Storage Group Compute, // group_2 - Compute Group AiGpu, // group_3 - AI/GPU Group Custom, // Custom user-defined group Default(String), // Default group with custom name } impl Default for NodeGroupType { fn default() -> Self { Self::Compute } } /// Resource allocation settings for node groups #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeGroupSettings { pub max_allocation_percentage: f32, pub priority_level: u8, pub auto_scaling: bool, } /// Deployment type categorization #[derive(Debug, Clone, Serialize, Deserialize)] pub enum DeploymentType { Standard, HighPerformance, Custom, } /// User deployment information for dashboard #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserDeployment { pub id: String, pub app_name: String, pub status: DeploymentStatus, pub cost_per_month: Decimal, #[serde(deserialize_with = "deserialize_datetime")] pub deployed_at: DateTime, pub provider: String, pub region: String, pub resource_usage: ResourceUtilization, } /// Deployment status enum #[derive(Debug, Clone, Serialize, Deserialize)] pub enum DeploymentStatus { Active, Pending, Stopped, Error, Maintenance, } impl Default for DeploymentStatus { fn default() -> Self { Self::Pending } } /// Comprehensive user metrics for dashboard #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserMetrics { pub total_spent_this_month: Decimal, pub active_deployments_count: i32, pub resource_utilization: ResourceUtilization, pub cost_trend: Vec, pub wallet_balance: Decimal, pub total_transactions: i32, } impl Default for UserMetrics { fn default() -> Self { Self { total_spent_this_month: Decimal::ZERO, active_deployments_count: 0, resource_utilization: ResourceUtilization { cpu: 0, memory: 0, storage: 0, network: 0, }, cost_trend: vec![0; 6], wallet_balance: Decimal::ZERO, total_transactions: 0, } } } /// User compute resource for dashboard display #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserComputeResource { pub id: String, pub resource_type: String, // "Compute", "Storage", "AI/GPU" pub specs: String, pub location: String, pub status: String, pub sla: String, pub monthly_cost: Decimal, pub provider: String, pub resource_usage: ResourceUtilization, } /// Node capacity information #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct NodeCapacity { pub cpu_cores: i32, pub memory_gb: i32, pub storage_gb: i32, pub bandwidth_mbps: i32, pub ssd_storage_gb: i32, pub hdd_storage_gb: i32, #[serde(default)] pub ram_gb: i32, } /// ResourceProvider node information #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FarmNode { pub id: String, pub location: String, pub status: NodeStatus, pub capacity: NodeCapacity, pub used_capacity: NodeCapacity, pub uptime_percentage: f32, pub farming_start_date: DateTime, pub last_updated: DateTime, pub utilization_7_day_avg: f32, pub slice_formats_supported: Vec, pub rental_options: Option, #[serde(default)] pub total_base_slices: i32, #[serde(default)] pub allocated_base_slices: i32, #[serde(default)] pub earnings_today_usd: Decimal, #[serde(default)] pub grid_node_id: Option, #[serde(default)] pub available_combinations: Vec, #[serde(default)] pub slice_allocations: Vec, #[serde(default)] pub slice_last_calculated: Option>, #[serde(default)] pub marketplace_sla: Option, #[serde(default)] pub slice_pricing: Option, #[serde(default)] pub grid_data: Option, #[serde(default)] pub slice_formats: Option>, #[serde(default)] pub name: String, #[serde(default)] pub region: String, #[serde(default)] pub node_type: String, #[serde(default)] pub staking_options: Option, #[serde(default)] pub availability_status: NodeAvailabilityStatus, #[serde(default)] pub node_group_id: Option, #[serde(default)] pub group_assignment_date: Option>, #[serde(default)] pub group_slice_format: Option, #[serde(default)] pub group_slice_price: Option, #[serde(default)] pub last_seen: Option>, #[serde(default)] pub health_score: f32, } /// Earnings record for resource_provider data #[derive(Debug, Clone, Serialize, Deserialize)] pub struct EarningsRecord { pub date: String, pub amount_usd: Decimal, #[serde(default)] pub amount: Decimal, // Additional amount field for backward compatibility pub source: String, } /// Group statistics for resource_provider dashboard #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GroupStatistics { pub group_name: String, pub total_nodes: i32, pub active_nodes: i32, pub total_earnings_usd: Decimal, #[serde(default)] pub group_id: String, #[serde(default)] pub group_type: NodeGroupType, #[serde(default)] pub total_capacity: NodeCapacity, #[serde(default)] pub online_nodes: i32, #[serde(default)] pub average_uptime: f32, } /// Marketplace SLA template #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MarketplaceSLA { pub id: String, pub name: String, pub uptime_guarantee: f32, pub response_time_hours: u32, pub resolution_time_hours: u32, pub penalty_rate: f32, #[serde(default)] pub uptime_guarantee_percentage: f32, #[serde(default)] pub base_slice_price: Decimal, #[serde(default)] pub bandwidth_guarantee_mbps: f32, #[serde(default)] pub last_updated: DateTime, } impl Default for MarketplaceSLA { fn default() -> Self { Self { id: "sla-default".to_string(), name: "Standard Marketplace SLA".to_string(), uptime_guarantee: 99.8, response_time_hours: 24, resolution_time_hours: 48, penalty_rate: 0.01, uptime_guarantee_percentage: 99.8, base_slice_price: rust_decimal::Decimal::new(50, 2), // $0.50 bandwidth_guarantee_mbps: 1000.0, last_updated: chrono::Utc::now(), } } } /// Grid node data for external grid integration #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GridNodeData { pub node_id: u32, pub capacity: NodeCapacity, pub location: String, pub status: String, pub uptime: f32, #[serde(default)] pub total_resources: NodeCapacity, #[serde(default)] pub used_resources: NodeCapacity, #[serde(default)] pub country: String, #[serde(default)] pub city: String, #[serde(default)] pub farm_name: String, #[serde(default)] pub farm_id: u32, #[serde(default)] pub farming_policy_id: u32, #[serde(default)] pub certification_type: String, #[serde(default)] pub grid_node_id: u32, #[serde(default)] pub public_ips: Vec, #[serde(default)] pub last_updated: DateTime, } /// Additional missing user model types #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ResourceProviderRentalEarning { pub date: String, pub amount: Decimal, pub rental_id: String, #[serde(default)] pub id: String, #[serde(default)] pub node_id: String, #[serde(default)] pub renter_email: String, #[serde(default)] pub rental_type: NodeRentalType, #[serde(default)] pub payment_status: PaymentStatus, #[serde(default)] pub earning_date: DateTime, #[serde(default)] pub currency: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum NodeAvailabilityStatus { Available, Rented, Maintenance, Offline, PartiallyRented, FullyRented, } impl Default for NodeAvailabilityStatus { fn default() -> Self { Self::Available } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UsageStatistics { pub cpu_usage: f32, pub memory_usage: f32, pub storage_usage: f32, pub network_usage: f32, #[serde(default)] pub active_services: i32, #[serde(default)] pub total_spent: Decimal, #[serde(default)] pub favorite_categories: Vec, #[serde(default)] pub usage_trends: Vec, #[serde(default)] pub login_frequency: f32, #[serde(default)] pub total_deployments: i32, #[serde(default)] pub preferred_regions: Vec, #[serde(default)] pub account_age_days: i32, #[serde(default)] pub last_activity: DateTime, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeStakingOptions { pub enabled: bool, pub minimum_stake: Decimal, pub reward_rate: f32, #[serde(default)] pub staking_enabled: bool, #[serde(default)] pub staked_amount: Decimal, #[serde(default)] pub staking_start_date: Option>, #[serde(default)] pub staking_period_months: u32, #[serde(default)] pub early_withdrawal_allowed: bool, #[serde(default)] pub early_withdrawal_penalty_percent: f32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeRentalOptions { pub full_node_available: bool, pub slice_formats: Vec, pub pricing: FullNodePricing, #[serde(default)] pub slice_rental_enabled: bool, #[serde(default)] pub minimum_rental_days: u32, #[serde(default)] pub maximum_rental_days: Option, #[serde(default)] pub full_node_rental_enabled: bool, #[serde(default)] pub full_node_pricing: Option, #[serde(default)] pub auto_renewal_enabled: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct FullNodePricing { pub monthly_cost: Decimal, pub setup_fee: Option, pub deposit_required: Option, #[serde(default)] pub hourly: Decimal, #[serde(default)] pub daily: Decimal, #[serde(default)] pub monthly: Decimal, #[serde(default)] pub yearly: Decimal, #[serde(default)] pub daily_discount_percent: f32, #[serde(default)] pub monthly_discount_percent: f32, #[serde(default)] pub yearly_discount_percent: f32, #[serde(default)] pub auto_calculate: bool, } impl Default for FullNodePricing { fn default() -> Self { Self { monthly_cost: rust_decimal::Decimal::new(50, 0), setup_fee: Some(rust_decimal::Decimal::new(10, 0)), deposit_required: Some(rust_decimal::Decimal::new(100, 0)), hourly: rust_decimal::Decimal::new(2, 0), daily: rust_decimal::Decimal::new(45, 0), monthly: rust_decimal::Decimal::new(1200, 0), yearly: rust_decimal::Decimal::new(12000, 0), daily_discount_percent: 5.0, monthly_discount_percent: 15.0, yearly_discount_percent: 25.0, auto_calculate: true, } } } impl FullNodePricing { /// Calculate all pricing fields from hourly rate pub fn calculate_from_hourly(&mut self) { if self.auto_calculate { // Calculate daily pricing with discount self.daily = self.hourly * rust_decimal::Decimal::from(24); if self.daily_discount_percent > 0.0 { self.daily = self.daily * (rust_decimal::Decimal::from(100) - rust_decimal::Decimal::try_from(self.daily_discount_percent).unwrap_or_default()) / rust_decimal::Decimal::from(100); } // Calculate monthly pricing with discount self.monthly = self.hourly * rust_decimal::Decimal::from(24 * 30); if self.monthly_discount_percent > 0.0 { self.monthly = self.monthly * (rust_decimal::Decimal::from(100) - rust_decimal::Decimal::try_from(self.monthly_discount_percent).unwrap_or_default()) / rust_decimal::Decimal::from(100); } // Calculate yearly pricing with discount self.yearly = self.hourly * rust_decimal::Decimal::from(24 * 365); if self.yearly_discount_percent > 0.0 { self.yearly = self.yearly * (rust_decimal::Decimal::from(100) - rust_decimal::Decimal::try_from(self.yearly_discount_percent).unwrap_or_default()) / rust_decimal::Decimal::from(100); } // Set monthly_cost to monthly pricing self.monthly_cost = self.monthly; } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ResourceOptimization { pub cpu_optimization: f32, pub memory_optimization: f32, pub storage_optimization: f32, pub network_optimization: f32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NodeGroupConfig { pub group_name: String, pub max_nodes: u32, pub allocation_strategy: String, pub auto_scaling: bool, #[serde(default)] pub preferred_slice_formats: Vec, #[serde(default)] pub default_pricing: Option, #[serde(default)] pub resource_optimization: ResourceOptimization, } impl Default for NodeGroupConfig { fn default() -> Self { Self { group_name: "Default Group".to_string(), max_nodes: 10, allocation_strategy: "balanced".to_string(), auto_scaling: true, preferred_slice_formats: vec!["1x1".to_string(), "2x2".to_string()], default_pricing: None, resource_optimization: ResourceOptimization::default(), } } } impl Default for ResourceOptimization { fn default() -> Self { Self { cpu_optimization: 0.5, memory_optimization: 0.5, storage_optimization: 0.5, network_optimization: 0.5, } } } impl ResourceOptimization { /// Balanced optimization configuration pub fn balanced() -> Self { Self { cpu_optimization: 0.5, memory_optimization: 0.5, storage_optimization: 0.5, network_optimization: 0.5, } } /// Storage-optimized configuration pub fn storage() -> Self { Self { cpu_optimization: 0.3, memory_optimization: 0.3, storage_optimization: 0.8, network_optimization: 0.6, } } /// Compute-optimized configuration pub fn compute() -> Self { Self { cpu_optimization: 0.8, memory_optimization: 0.7, storage_optimization: 0.4, network_optimization: 0.5, } } // Provide enum-style access for backward compatibility pub const Balanced: Self = Self { cpu_optimization: 0.5, memory_optimization: 0.5, storage_optimization: 0.5, network_optimization: 0.5, }; pub const Storage: Self = Self { cpu_optimization: 0.3, memory_optimization: 0.3, storage_optimization: 0.8, network_optimization: 0.6, }; pub const Compute: Self = Self { cpu_optimization: 0.8, memory_optimization: 0.7, storage_optimization: 0.4, network_optimization: 0.5, }; }