1789 lines
50 KiB
Rust
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,
|
|
};
|
|
}
|