Files
projectmycelium/src/models/user.rs

1789 lines
50 KiB
Rust

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<i32>,
/// 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<String>,
/// User's timezone
pub timezone: Option<String>,
/// When the user was created
pub created_at: Option<DateTime<Utc>>,
/// When the user was last updated
pub updated_at: Option<DateTime<Utc>>,
}
/// 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<Decimal, Box<dyn std::error::Error>> {
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<Vec<crate::models::product::Product>, Box<dyn std::error::Error>> {
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<DateTime<Utc>>,
#[serde(default)]
pub updated_at: Option<DateTime<Utc>>,
}
/// 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<DateTime<Utc>>,
#[serde(default)]
pub end_date: Option<DateTime<Utc>>,
}
/// 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<i32>,
pub resource_reservations: Vec<i32>,
}
#[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<RegionDeployments>,
}
#[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<Utc>,
pub last_updated: DateTime<Utc>,
pub utilization_7_day_avg: f32,
pub slice_formats_supported: Vec<String>,
pub slice_last_calculated: Option<DateTime<Utc>>,
#[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<String>,
pub slack_webhook: Option<String>,
pub max_slice_commitment_months: Option<u32>,
pub emergency_contact: Option<String>,
pub automated_updates: Option<bool>,
pub performance_notifications: Option<bool>,
pub maintenance_reminders: Option<bool>,
#[serde(default)]
pub auto_accept_deployments: bool,
#[serde(default)]
pub default_slice_customizations: Option<serde_json::Value>,
#[serde(default)]
pub minimum_deployment_duration: u32,
#[serde(default)]
pub notification_preferences: Option<serde_json::Value>,
#[serde(default)]
pub preferred_regions: Vec<String>,
}
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<chrono::Utc>,
}
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<chrono::Utc>,
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<rust_decimal::Decimal>,
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<rust_decimal::Decimal>,
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<DateTime<Utc>>,
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<Utc>,
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<NodeAssignment>,
pub start_date: DateTime<Utc>,
pub end_date: DateTime<Utc>,
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<Utc>,
pub end_date: DateTime<Utc>,
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<Utc>,
pub end_date: DateTime<Utc>,
pub auto_renewal: bool,
pub payment_status: PaymentStatus,
pub sla_id: Option<String>,
pub custom_configuration: Option<serde_json::Value>,
pub metadata: std::collections::HashMap<String, serde_json::Value>,
#[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<serde_json::Value>,
pub timestamp: DateTime<Utc>,
pub ip_address: Option<String>,
pub user_agent: Option<String>,
pub session_id: Option<String>,
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<Utc>,
pub expires_at: DateTime<Utc>,
pub ip_address: String,
pub user_agent: String,
pub is_active: bool,
pub last_activity: DateTime<Utc>,
}
fn default_subscription_multiplier() -> f32 {
1.0
}
fn default_last_activity() -> DateTime<Utc> {
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<PublishedApp>,
pub deployment_stats: Vec<DeploymentStat>,
pub revenue_history: Vec<RevenueRecord>,
#[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<Service>,
pub client_requests: Vec<ServiceRequest>,
pub availability: Option<bool>,
pub hourly_rate_range: Option<String>,
pub last_payment_method: Option<String>,
#[serde(default)]
pub revenue_history: Vec<RevenueRecord>,
}
/// 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<NotificationSettings>,
#[serde(default)]
pub privacy_settings: Option<PrivacySettings>,
#[serde(default)]
pub dashboard_layout: String,
#[serde(default)]
pub last_payment_method: Option<String>,
}
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<Utc>,
#[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<NodeInfo>,
pub revenue_history: Vec<RevenueRecord>,
#[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<EarningsRecord>,
#[serde(default)]
pub active_slices: i32,
#[serde(default)]
pub slice_templates: Vec<serde_json::Value>,
}
/// 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<ServiceBooking>,
pub spending_history: Vec<SpendingRecord>,
pub pending_transactions: i32,
#[serde(default)]
pub total_spent: Decimal,
#[serde(default)]
pub monthly_spending: Decimal,
#[serde(default)]
pub favorite_providers: Vec<String>,
#[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<String>,
pub discord_webhook: Option<String>,
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<String>,
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<Utc>,
pub updated_at: DateTime<Utc>,
pub auto_scaling: Option<bool>,
pub auto_healing: Option<bool>,
pub revenue_history: Vec<RevenueRecord>,
#[serde(default)]
pub deployments: i32,
#[serde(default)]
pub monthly_revenue_usd: Decimal,
#[serde(default)]
pub last_updated: DateTime<Utc>,
}
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<f32>,
pub uptime_percentage: Option<f32>,
pub status: String,
#[serde(default)]
pub instances: i32,
#[serde(default)]
pub resource_usage: Option<String>,
#[serde(default)]
pub customer_name: Option<String>,
#[serde(default)]
pub deployed_date: Option<DateTime<Utc>>,
#[serde(default)]
pub deployment_id: Option<String>,
pub last_deployment: Option<DateTime<Utc>>,
pub auto_healing: Option<bool>,
}
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<rust_decimal::Decimal>,
pub availability: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[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<i32>,
}
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<String>,
pub status: String,
pub estimated_hours: Option<i32>,
pub hourly_rate_usd: Option<rust_decimal::Decimal>,
pub total_cost_usd: Option<rust_decimal::Decimal>,
pub progress_percentage: Option<f32>,
pub created_date: Option<String>,
pub completed_date: Option<String>,
#[serde(default)]
pub progress: Option<f32>,
#[serde(default)]
pub priority: String,
#[serde(default)]
pub hours_worked: Option<i32>,
#[serde(default)]
pub notes: Option<String>,
#[serde(default)]
pub service_name: String,
#[serde(default)]
pub budget: Decimal,
#[serde(default)]
pub requested_date: String,
#[serde(default)]
pub client_phone: Option<String>,
#[serde(default)]
pub client_name: Option<String>,
#[serde(default)]
pub client_email: Option<String>,
}
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<String>,
pub status: String,
pub estimated_hours: Option<i32>,
pub hourly_rate_usd: Option<rust_decimal::Decimal>,
pub total_cost_usd: Option<rust_decimal::Decimal>,
pub progress_percentage: Option<f32>,
pub created_date: Option<String>,
pub completed_date: Option<String>,
#[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<f32>,
#[serde(default)]
pub client_phone: Option<String>,
#[serde(default)]
pub booking_date: Option<DateTime<Utc>>,
}
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<String>,
pub exchange_rate_usd: Option<rust_decimal::Decimal>,
pub amount_usd: Option<rust_decimal::Decimal>,
pub description: Option<String>,
pub reference_id: Option<String>,
pub metadata: Option<std::collections::HashMap<String, serde_json::Value>>,
pub timestamp: DateTime<Utc>,
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<String> },
CreditsTransfer { to_user: String, note: Option<String> },
// 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<u32> },
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<DateTime<Utc>, 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<String>,
pub node_ids: Vec<String>,
pub group_type: NodeGroupType,
#[serde(default)]
pub updated_at: DateTime<Utc>,
#[serde(default)]
pub created_at: DateTime<Utc>,
#[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<Utc>,
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<i32>,
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<Utc>,
pub last_updated: DateTime<Utc>,
pub utilization_7_day_avg: f32,
pub slice_formats_supported: Vec<String>,
pub rental_options: Option<serde_json::Value>,
#[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<String>,
#[serde(default)]
pub available_combinations: Vec<serde_json::Value>,
#[serde(default)]
pub slice_allocations: Vec<serde_json::Value>,
#[serde(default)]
pub slice_last_calculated: Option<DateTime<Utc>>,
#[serde(default)]
pub marketplace_sla: Option<MarketplaceSLA>,
#[serde(default)]
pub slice_pricing: Option<serde_json::Value>,
#[serde(default)]
pub grid_data: Option<serde_json::Value>,
#[serde(default)]
pub slice_formats: Option<Vec<String>>,
#[serde(default)]
pub name: String,
#[serde(default)]
pub region: String,
#[serde(default)]
pub node_type: String,
#[serde(default)]
pub staking_options: Option<serde_json::Value>,
#[serde(default)]
pub availability_status: NodeAvailabilityStatus,
#[serde(default)]
pub node_group_id: Option<String>,
#[serde(default)]
pub group_assignment_date: Option<DateTime<Utc>>,
#[serde(default)]
pub group_slice_format: Option<String>,
#[serde(default)]
pub group_slice_price: Option<Decimal>,
#[serde(default)]
pub last_seen: Option<DateTime<Utc>>,
#[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<Utc>,
}
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<String>,
#[serde(default)]
pub last_updated: DateTime<Utc>,
}
/// 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<Utc>,
#[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<String>,
#[serde(default)]
pub usage_trends: Vec<serde_json::Value>,
#[serde(default)]
pub login_frequency: f32,
#[serde(default)]
pub total_deployments: i32,
#[serde(default)]
pub preferred_regions: Vec<String>,
#[serde(default)]
pub account_age_days: i32,
#[serde(default)]
pub last_activity: DateTime<Utc>,
}
#[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<DateTime<Utc>>,
#[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<String>,
pub pricing: FullNodePricing,
#[serde(default)]
pub slice_rental_enabled: bool,
#[serde(default)]
pub minimum_rental_days: u32,
#[serde(default)]
pub maximum_rental_days: Option<u32>,
#[serde(default)]
pub full_node_rental_enabled: bool,
#[serde(default)]
pub full_node_pricing: Option<FullNodePricing>,
#[serde(default)]
pub auto_renewal_enabled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FullNodePricing {
pub monthly_cost: Decimal,
pub setup_fee: Option<Decimal>,
pub deposit_required: Option<Decimal>,
#[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<String>,
#[serde(default)]
pub default_pricing: Option<serde_json::Value>,
#[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,
};
}