feat: rename Application Solutions to Agentic Apps in docs, UI, and codebase
This commit is contained in:
		@@ -18,8 +18,8 @@ This document outlines the comprehensive redesign of the Project Mycelium market
 | 
				
			|||||||
  - [ ] Update navigation and menus
 | 
					  - [ ] Update navigation and menus
 | 
				
			||||||
  - [ ] Update backend user management
 | 
					  - [ ] Update backend user management
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [ ] **Application Solutions → Agentic Apps**
 | 
					- [x] **Application Solutions → Agentic Apps**
 | 
				
			||||||
  - [ ] Update product categories
 | 
					  - [x] Update product categories
 | 
				
			||||||
  - [ ] Update marketplace listings
 | 
					  - [ ] Update marketplace listings
 | 
				
			||||||
  - [ ] Update search and filtering
 | 
					  - [ ] Update search and filtering
 | 
				
			||||||
  - [ ] Update backend product models
 | 
					  - [ ] Update backend product models
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ The marketplace is organized into categories that align with the exchange mechan
 | 
				
			|||||||
| **[Bandwidth Providers](./bandwidth_providers.md)** | Bandwidth supply for TF-run Mycelium Gateways | Bandwidth providers | TF-run Mycelium Gateways | TFP paid based on TB of bandwidth delivered |
 | 
					| **[Bandwidth Providers](./bandwidth_providers.md)** | Bandwidth supply for TF-run Mycelium Gateways | Bandwidth providers | TF-run Mycelium Gateways | TFP paid based on TB of bandwidth delivered |
 | 
				
			||||||
| **Mycelium Names** | Global fair name system | TF COOP (name provider) | Users registering names | TFP paid based on name length (shorter names cost more) |
 | 
					| **Mycelium Names** | Global fair name system | TF COOP (name provider) | Users registering names | TFP paid based on name length (shorter names cost more) |
 | 
				
			||||||
| **Human Energy Services** | Professional technical services | Service providers (designers, admins, developers) | Users needing expertise | TFP transferred based on agreed rates |
 | 
					| **Human Energy Services** | Professional technical services | Service providers (designers, admins, developers) | Users needing expertise | TFP transferred based on agreed rates |
 | 
				
			||||||
| **Application Solutions** | Pre-configured, self-healing applications | Solution providers | End users | Users provide slices to solution providers while maintaining sovereignty |
 | 
					| **Agentic Apps** | Pre-configured, self-healing applications | Solution providers | End users | Users provide slices to solution providers while maintaining sovereignty |
 | 
				
			||||||
| **TFP Exchange** (phase 2)| Trading platform for TFP | TFP sellers | TFP buyers | Direct exchange of TFP for currencies (TFT, USD, etc.) |
 | 
					| **TFP Exchange** (phase 2)| Trading platform for TFP | TFP sellers | TFP buyers | Direct exchange of TFP for currencies (TFT, USD, etc.) |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Marketplace Features
 | 
					## Marketplace Features
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,7 +86,7 @@ The TF Marketplace offers various products and services that facilitate the mutu
 | 
				
			|||||||
  - Support for various domain types and structures
 | 
					  - Support for various domain types and structures
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [Application Solutions](apps.md)
 | 
					## [Agentic Apps](apps.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **Definition**: Pre-configured, self-healing applications deployed on the platform
 | 
					- **Definition**: Pre-configured, self-healing applications deployed on the platform
 | 
				
			||||||
- **Suppliers**: Solution providers who develop and maintain applications
 | 
					- **Suppliers**: Solution providers who develop and maintain applications
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,8 +79,8 @@ impl DashboardController {
 | 
				
			|||||||
        Some(user)
 | 
					        Some(user)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Helper function to count deployments across all users for a specific app provider
 | 
					    /// Helper function to count deployments across all users for a specific application provider
 | 
				
			||||||
    fn count_cross_user_deployments(app_provider_email: &str) -> std::collections::HashMap<String, i32> {
 | 
					    fn count_cross_user_deployments(application_provider_email: &str) -> std::collections::HashMap<String, i32> {
 | 
				
			||||||
        use std::collections::HashMap;
 | 
					        use std::collections::HashMap;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        let mut deployment_counts: HashMap<String, i32> = HashMap::new();
 | 
					        let mut deployment_counts: HashMap<String, i32> = HashMap::new();
 | 
				
			||||||
@@ -108,8 +108,8 @@ impl DashboardController {
 | 
				
			|||||||
                                // Count deployments for this app provider's apps
 | 
					                                // Count deployments for this app provider's apps
 | 
				
			||||||
                                for deployment in &user_data.application_deployments {
 | 
					                                for deployment in &user_data.application_deployments {
 | 
				
			||||||
                                    // Check if this deployment belongs to an app from our app provider
 | 
					                                    // Check if this deployment belongs to an app from our app provider
 | 
				
			||||||
                                    // We need to get the app provider's apps to match
 | 
					                                    // We need to get the application provider's apps to match
 | 
				
			||||||
                                    let provider_apps = UserPersistence::get_user_apps(app_provider_email);
 | 
					                                    let provider_apps = UserPersistence::get_user_apps(application_provider_email);
 | 
				
			||||||
                                    
 | 
					                                    
 | 
				
			||||||
                                    for provider_app in &provider_apps {
 | 
					                                    for provider_app in &provider_apps {
 | 
				
			||||||
                                        if deployment.app_id == provider_app.id && deployment.status == "Active" {
 | 
					                                        if deployment.app_id == provider_app.id && deployment.status == "Active" {
 | 
				
			||||||
@@ -517,7 +517,7 @@ impl DashboardController {
 | 
				
			|||||||
        let mut ctx = crate::models::builders::ContextBuilder::new()
 | 
					        let mut ctx = crate::models::builders::ContextBuilder::new()
 | 
				
			||||||
            .active_page("dashboard")
 | 
					            .active_page("dashboard")
 | 
				
			||||||
            .build();
 | 
					            .build();
 | 
				
			||||||
        ctx.insert("active_section", "app_provider");
 | 
					        ctx.insert("active_section", "application_provider");
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        let config = get_app_config();
 | 
					        let config = get_app_config();
 | 
				
			||||||
        ctx.insert("gitea_enabled", &config.is_gitea_enabled());
 | 
					        ctx.insert("gitea_enabled", &config.is_gitea_enabled());
 | 
				
			||||||
@@ -607,7 +607,7 @@ impl DashboardController {
 | 
				
			|||||||
                })
 | 
					                })
 | 
				
			||||||
                .collect();
 | 
					                .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let app_provider_data = crate::models::user::AppProviderData {
 | 
					            let application_provider_data = crate::models::user::AppProviderData {
 | 
				
			||||||
                published_apps: fresh_apps.len() as i32,
 | 
					                published_apps: fresh_apps.len() as i32,
 | 
				
			||||||
                total_deployments: fresh_apps.iter().map(|a| a.deployments).sum::<i32>(),
 | 
					                total_deployments: fresh_apps.iter().map(|a| a.deployments).sum::<i32>(),
 | 
				
			||||||
                active_deployments,
 | 
					                active_deployments,
 | 
				
			||||||
@@ -618,7 +618,7 @@ impl DashboardController {
 | 
				
			|||||||
                revenue_history: Vec::new(),
 | 
					                revenue_history: Vec::new(),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ctx.insert("app_provider_data", &app_provider_data);
 | 
					            ctx.insert("application_provider_data", &application_provider_data);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // Ensure template always has a defined structure even without a logged-in user
 | 
					            // Ensure template always has a defined structure even without a logged-in user
 | 
				
			||||||
            let empty: crate::models::user::AppProviderData = crate::models::user::AppProviderData {
 | 
					            let empty: crate::models::user::AppProviderData = crate::models::user::AppProviderData {
 | 
				
			||||||
@@ -631,10 +631,10 @@ impl DashboardController {
 | 
				
			|||||||
                deployment_stats: Vec::new(),
 | 
					                deployment_stats: Vec::new(),
 | 
				
			||||||
                revenue_history: Vec::new(),
 | 
					                revenue_history: Vec::new(),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            ctx.insert("app_provider_data", &empty);
 | 
					            ctx.insert("application_provider_data", &empty);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        render_template(&tmpl, "dashboard/app_provider.html", &ctx)
 | 
					        render_template(&tmpl, "dashboard/application_provider.html", &ctx)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Renders the service provider section of the dashboard
 | 
					    /// Renders the service provider section of the dashboard
 | 
				
			||||||
@@ -2936,7 +2936,7 @@ impl DashboardController {
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }).collect();
 | 
					                }).collect();
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            let app_provider_data = crate::models::user::AppProviderData {
 | 
					            let application_provider_data = crate::models::user::AppProviderData {
 | 
				
			||||||
                apps: fresh_apps.clone(),
 | 
					                apps: fresh_apps.clone(),
 | 
				
			||||||
                published_apps: fresh_apps.len() as i32,
 | 
					                published_apps: fresh_apps.len() as i32,
 | 
				
			||||||
                total_deployments,
 | 
					                total_deployments,
 | 
				
			||||||
@@ -2947,7 +2947,7 @@ impl DashboardController {
 | 
				
			|||||||
                revenue_history: Vec::new(),
 | 
					                revenue_history: Vec::new(),
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            return Ok(ResponseBuilder::ok().json(app_provider_data).build());
 | 
					            return Ok(ResponseBuilder::ok().json(application_provider_data).build());
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -405,11 +405,11 @@ impl Default for ServiceLevelAgreement {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/// Application deployment configuration
 | 
					/// Application deployment configuration
 | 
				
			||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
					#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
				
			||||||
pub struct AppDeployment {
 | 
					pub struct ApplicationDeployment {
 | 
				
			||||||
    pub id: String,
 | 
					    pub id: String,
 | 
				
			||||||
    pub app_id: String,
 | 
					    pub app_id: String,
 | 
				
			||||||
    pub customer_email: String,
 | 
					    pub customer_email: String,
 | 
				
			||||||
    pub deployment_status: AppDeploymentStatus,
 | 
					    pub deployment_status: ApplicationDeploymentStatus,
 | 
				
			||||||
    pub resource_allocation: ResourceUtilization,
 | 
					    pub resource_allocation: ResourceUtilization,
 | 
				
			||||||
    pub monthly_cost: rust_decimal::Decimal,
 | 
					    pub monthly_cost: rust_decimal::Decimal,
 | 
				
			||||||
    pub deployed_at: Option<DateTime<Utc>>,
 | 
					    pub deployed_at: Option<DateTime<Utc>>,
 | 
				
			||||||
@@ -418,9 +418,9 @@ pub struct AppDeployment {
 | 
				
			|||||||
    pub monitoring_enabled: bool,
 | 
					    pub monitoring_enabled: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// App deployment status
 | 
					/// Application deployment status
 | 
				
			||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
					#[derive(Debug, Clone, Serialize, Deserialize)]
 | 
				
			||||||
pub enum AppDeploymentStatus {
 | 
					pub enum ApplicationDeploymentStatus {
 | 
				
			||||||
    Pending,
 | 
					    Pending,
 | 
				
			||||||
    Deploying,
 | 
					    Deploying,
 | 
				
			||||||
    Running,
 | 
					    Running,
 | 
				
			||||||
@@ -429,7 +429,7 @@ pub enum AppDeploymentStatus {
 | 
				
			|||||||
    Maintenance,
 | 
					    Maintenance,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for AppDeploymentStatus {
 | 
					impl Default for ApplicationDeploymentStatus {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self::Pending
 | 
					        Self::Pending
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -804,8 +804,8 @@ impl OrderService {
 | 
				
			|||||||
            // Only create deployments for application products
 | 
					            // Only create deployments for application products
 | 
				
			||||||
            if item.product_category == "application" {
 | 
					            if item.product_category == "application" {
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // Find the app provider by looking up who published this app
 | 
					                // Find the application provider by looking up who published this app
 | 
				
			||||||
                if let Some(app_provider_email) = self.find_app_provider(&item.product_id) {
 | 
					                if let Some(application_provider_email) = self.find_application_provider(&item.product_id) {
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    // Create deployment for each quantity ordered
 | 
					                    // Create deployment for each quantity ordered
 | 
				
			||||||
                    for _i in 0..item.quantity {
 | 
					                    for _i in 0..item.quantity {
 | 
				
			||||||
@@ -838,7 +838,7 @@ impl OrderService {
 | 
				
			|||||||
                            .unwrap();
 | 
					                            .unwrap();
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
                        // Add deployment to application provider's data
 | 
					                        // Add deployment to application provider's data
 | 
				
			||||||
                        if let Err(e) = UserPersistence::add_user_application_deployment(&app_provider_email, deployment.clone()) {
 | 
					                        if let Err(e) = UserPersistence::add_user_application_deployment(&application_provider_email, deployment.clone()) {
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
@@ -857,8 +857,8 @@ impl OrderService {
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /// Find the app provider (user who published the app) by product ID
 | 
					    /// Find the application provider (user who published the app) by product ID
 | 
				
			||||||
    fn find_app_provider(&self, product_id: &str) -> Option<String> {
 | 
					    fn find_application_provider(&self, product_id: &str) -> Option<String> {
 | 
				
			||||||
        // Get all user data files and search for the app
 | 
					        // Get all user data files and search for the app
 | 
				
			||||||
        let user_data_dir = std::path::Path::new("user_data");
 | 
					        let user_data_dir = std::path::Path::new("user_data");
 | 
				
			||||||
        if !user_data_dir.exists() {
 | 
					        if !user_data_dir.exists() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,7 @@ class UserDatabase {
 | 
				
			|||||||
                    display_name: 'Alex Thompson',
 | 
					                    display_name: 'Alex Thompson',
 | 
				
			||||||
                    email: 'user2@example.com',
 | 
					                    email: 'user2@example.com',
 | 
				
			||||||
                    password: 'password',
 | 
					                    password: 'password',
 | 
				
			||||||
                    role: 'app_provider',
 | 
					                    role: 'application_provider',
 | 
				
			||||||
                    location: 'Berlin, Germany',
 | 
					                    location: 'Berlin, Germany',
 | 
				
			||||||
                    joined_date: '2024-02-20',
 | 
					                    joined_date: '2024-02-20',
 | 
				
			||||||
                    reputation: 4.9,
 | 
					                    reputation: 4.9,
 | 
				
			||||||
@@ -84,7 +84,7 @@ class UserDatabase {
 | 
				
			|||||||
                    display_name: 'Jordan Mitchell',
 | 
					                    display_name: 'Jordan Mitchell',
 | 
				
			||||||
                    email: 'user5@example.com',
 | 
					                    email: 'user5@example.com',
 | 
				
			||||||
                    password: 'password',
 | 
					                    password: 'password',
 | 
				
			||||||
                    role: 'multi', // Can be resource_provider, app_provider, service_provider, user
 | 
					                    role: 'multi', // Can be resource_provider, application_provider, service_provider, user
 | 
				
			||||||
                    location: 'Toronto, Canada',
 | 
					                    location: 'Toronto, Canada',
 | 
				
			||||||
                    joined_date: new Date().toISOString().split('T')[0],
 | 
					                    joined_date: new Date().toISOString().split('T')[0],
 | 
				
			||||||
                    reputation: 5.0,
 | 
					                    reputation: 5.0,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
            <div class="stats-card info">
 | 
					            <div class="stats-card info">
 | 
				
			||||||
                <h5 class="card-title">Published Apps</h5>
 | 
					                <h5 class="card-title">Published Apps</h5>
 | 
				
			||||||
                <div class="d-flex justify-content-between align-items-end">
 | 
					                <div class="d-flex justify-content-between align-items-end">
 | 
				
			||||||
                    <h2 class="mb-0">{% if app_provider_data is defined and app_provider_data.published_apps is defined %}{{ app_provider_data.published_apps }}{% else %}0{% endif %}</h2>
 | 
					                    <h2 class="mb-0">{% if application_provider_data is defined and application_provider_data.published_apps is defined %}{{ application_provider_data.published_apps }}{% else %}0{% endif %}</h2>
 | 
				
			||||||
                    <small class="text-muted">Active</small>
 | 
					                    <small class="text-muted">Active</small>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -22,7 +22,7 @@
 | 
				
			|||||||
            <div class="stats-card primary">
 | 
					            <div class="stats-card primary">
 | 
				
			||||||
                <h5 class="card-title">Active Deployments</h5>
 | 
					                <h5 class="card-title">Active Deployments</h5>
 | 
				
			||||||
                <div class="d-flex justify-content-between align-items-end">
 | 
					                <div class="d-flex justify-content-between align-items-end">
 | 
				
			||||||
                    <h2 class="mb-0">{% if app_provider_data is defined and app_provider_data.active_deployments is defined %}{{ app_provider_data.active_deployments }}{% else %}0{% endif %}</h2>
 | 
					                    <h2 class="mb-0">{% if application_provider_data is defined and application_provider_data.active_deployments is defined %}{{ application_provider_data.active_deployments }}{% else %}0{% endif %}</h2>
 | 
				
			||||||
                    <small class="text-muted">Instances</small>
 | 
					                    <small class="text-muted">Instances</small>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -31,7 +31,7 @@
 | 
				
			|||||||
            <div class="stats-card warning">
 | 
					            <div class="stats-card warning">
 | 
				
			||||||
                <h5 class="card-title">Customer Base</h5>
 | 
					                <h5 class="card-title">Customer Base</h5>
 | 
				
			||||||
                <div class="d-flex justify-content-between align-items-end">
 | 
					                <div class="d-flex justify-content-between align-items-end">
 | 
				
			||||||
                    <h2 class="mb-0">{% if app_provider_data is defined and app_provider_data.total_deployments is defined %}{{ app_provider_data.total_deployments }}{% else %}0{% endif %}</h2>
 | 
					                    <h2 class="mb-0">{% if application_provider_data is defined and application_provider_data.total_deployments is defined %}{{ application_provider_data.total_deployments }}{% else %}0{% endif %}</h2>
 | 
				
			||||||
                    <small class="text-muted">Total Deployments</small>
 | 
					                    <small class="text-muted">Total Deployments</small>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -40,7 +40,7 @@
 | 
				
			|||||||
            <div class="stats-card success">
 | 
					            <div class="stats-card success">
 | 
				
			||||||
                <h5 class="card-title">Monthly Earnings</h5>
 | 
					                <h5 class="card-title">Monthly Earnings</h5>
 | 
				
			||||||
                <div class="d-flex justify-content-between align-items-end">
 | 
					                <div class="d-flex justify-content-between align-items-end">
 | 
				
			||||||
                    <h2 class="mb-0">{% if app_provider_data is defined and app_provider_data.monthly_revenue_usd is defined %}{{ app_provider_data.monthly_revenue_usd }}{% else %}0{% endif %}</h2>
 | 
					                    <h2 class="mb-0">{% if application_provider_data is defined and application_provider_data.monthly_revenue_usd is defined %}{{ application_provider_data.monthly_revenue_usd }}{% else %}0{% endif %}</h2>
 | 
				
			||||||
                    <small class="text-muted">$/month</small>
 | 
					                    <small class="text-muted">$/month</small>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -232,8 +232,8 @@
 | 
				
			|||||||
{{ super() }}
 | 
					{{ super() }}
 | 
				
			||||||
<!-- Hydration JSON for initial app provider dashboard data (safe, non-executable) -->
 | 
					<!-- Hydration JSON for initial app provider dashboard data (safe, non-executable) -->
 | 
				
			||||||
<script id="ap-dashboard-hydration" type="application/json">
 | 
					<script id="ap-dashboard-hydration" type="application/json">
 | 
				
			||||||
{% if app_provider_data is defined %}
 | 
					{% if application_provider_data is defined %}
 | 
				
			||||||
{{ app_provider_data | json_encode() }}
 | 
					{{ application_provider_data | json_encode() }}
 | 
				
			||||||
{% else %}
 | 
					{% else %}
 | 
				
			||||||
null
 | 
					null
 | 
				
			||||||
{% endif %}
 | 
					{% endif %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,7 +92,7 @@
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        <div class="row align-items-center mb-4">
 | 
					        <div class="row align-items-center mb-4">
 | 
				
			||||||
            <div class="col-md-6">
 | 
					            <div class="col-md-6">
 | 
				
			||||||
                <img src="/static/images/docs/application-flow.svg" alt="Application Solution Flow Diagram" class="img-fluid rounded shadow">
 | 
					                <img src="/static/images/docs/application-flow.svg" alt="Agentic Apps Flow Diagram" class="img-fluid rounded shadow">
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="col-md-6">
 | 
					            <div class="col-md-6">
 | 
				
			||||||
                <ol class="list-group list-group-numbered mb-0">
 | 
					                <ol class="list-group list-group-numbered mb-0">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,7 @@
 | 
				
			|||||||
                        <td><a href="/docs/gateways" class="btn btn-sm btn-outline-primary">Learn More</a></td>
 | 
					                        <td><a href="/docs/gateways" class="btn btn-sm btn-outline-primary">Learn More</a></td>
 | 
				
			||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
                    <tr>
 | 
					                    <tr>
 | 
				
			||||||
                        <td><strong>Application Solutions</strong></td>
 | 
					                        <td><strong>Agentic Apps</strong></td>
 | 
				
			||||||
                        <td>Pre-configured, self-healing applications</td>
 | 
					                        <td>Pre-configured, self-healing applications</td>
 | 
				
			||||||
                        <td>Credits paid to application providers for application management while users maintain sovereignty</td>
 | 
					                        <td>Credits paid to application providers for application management while users maintain sovereignty</td>
 | 
				
			||||||
                        <td><a href="/docs/applications" class="btn btn-sm btn-outline-primary">Learn More</a></td>
 | 
					                        <td><a href="/docs/applications" class="btn btn-sm btn-outline-primary">Learn More</a></td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,7 +44,7 @@
 | 
				
			|||||||
                                <td>Credits paid based on bandwidth consumption</td>
 | 
					                                <td>Credits paid based on bandwidth consumption</td>
 | 
				
			||||||
                            </tr>
 | 
					                            </tr>
 | 
				
			||||||
                            <tr>
 | 
					                            <tr>
 | 
				
			||||||
                                <td><strong>Application Solutions</strong></td>
 | 
					                                <td><strong>Agentic Apps</strong></td>
 | 
				
			||||||
                                <td>Pre-configured, self-healing applications</td>
 | 
					                                <td>Pre-configured, self-healing applications</td>
 | 
				
			||||||
                                <td>Users provide slices to application providers while maintaining sovereignty</td>
 | 
					                                <td>Users provide slices to application providers while maintaining sovereignty</td>
 | 
				
			||||||
                            </tr>
 | 
					                            </tr>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,7 +70,7 @@
 | 
				
			|||||||
                <li>Mycelium Nodes</li>
 | 
					                <li>Mycelium Nodes</li>
 | 
				
			||||||
                <li>Mycelium Gateways</li>
 | 
					                <li>Mycelium Gateways</li>
 | 
				
			||||||
                <li>Bandwidth Providers</li>
 | 
					                <li>Bandwidth Providers</li>
 | 
				
			||||||
                <li>Application Solutions</li>
 | 
					                <li>Agentic Apps</li>
 | 
				
			||||||
                <li>Human Energy Services</li>
 | 
					                <li>Human Energy Services</li>
 | 
				
			||||||
            </ul>
 | 
					            </ul>
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,12 +42,12 @@ async fn test_complete_provider_dashboards_ux_workflow() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Test users for different provider types
 | 
					    // Test users for different provider types
 | 
				
			||||||
    let farmer_email = "farmer_dashboard_test@example.com";
 | 
					    let farmer_email = "farmer_dashboard_test@example.com";
 | 
				
			||||||
    let app_provider_email = "app_provider_test@example.com";
 | 
					    let application_provider_email = "application_provider_test@example.com";
 | 
				
			||||||
    let service_provider_email = "service_provider_test@example.com";
 | 
					    let service_provider_email = "service_provider_test@example.com";
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Clean up any existing test data
 | 
					    // Clean up any existing test data
 | 
				
			||||||
    cleanup_test_user_data(farmer_email);
 | 
					    cleanup_test_user_data(farmer_email);
 | 
				
			||||||
    cleanup_test_user_data(app_provider_email);
 | 
					    cleanup_test_user_data(application_provider_email);
 | 
				
			||||||
    cleanup_test_user_data(service_provider_email);
 | 
					    cleanup_test_user_data(service_provider_email);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Initialize services
 | 
					    // Initialize services
 | 
				
			||||||
@@ -133,8 +133,8 @@ async fn test_complete_provider_dashboards_ux_workflow() {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    println!("✅ Farmer Dashboard: WORKING - Node management, capacity planning, earnings tracking");
 | 
					    println!("✅ Farmer Dashboard: WORKING - Node management, capacity planning, earnings tracking");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Step 3: Test Application Provider Dashboard (/dashboard/app-provider)
 | 
					    // Step 3: Test Application Provider Dashboard (/dashboard/application-provider)
 | 
				
			||||||
    println!("\n🔧 Step 3: Test Application Provider Dashboard (/dashboard/app-provider)");
 | 
					    println!("\n🔧 Step 3: Test Application Provider Dashboard (/dashboard/application-provider)");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Create test app provider profile
 | 
					    // Create test app provider profile
 | 
				
			||||||
    let published_apps = vec![
 | 
					    let published_apps = vec![
 | 
				
			||||||
@@ -144,7 +144,7 @@ async fn test_complete_provider_dashboards_ux_workflow() {
 | 
				
			|||||||
        ("backup-solution", "Automated Backup Tool", 34, 4.1, "pending"),
 | 
					        ("backup-solution", "Automated Backup Tool", 34, 4.1, "pending"),
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    println!("    📱 Application Provider: {}", app_provider_email);
 | 
					    println!("    📱 Application Provider: {}", application_provider_email);
 | 
				
			||||||
    println!("    📊 Published Applications:");
 | 
					    println!("    📊 Published Applications:");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    let mut total_installs = 0;
 | 
					    let mut total_installs = 0;
 | 
				
			||||||
@@ -282,7 +282,7 @@ async fn test_complete_provider_dashboards_ux_workflow() {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    // Final cleanup
 | 
					    // Final cleanup
 | 
				
			||||||
    cleanup_test_user_data(farmer_email);
 | 
					    cleanup_test_user_data(farmer_email);
 | 
				
			||||||
    cleanup_test_user_data(app_provider_email);
 | 
					    cleanup_test_user_data(application_provider_email);
 | 
				
			||||||
    cleanup_test_user_data(service_provider_email);
 | 
					    cleanup_test_user_data(service_provider_email);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Final verification
 | 
					    // Final verification
 | 
				
			||||||
@@ -321,7 +321,7 @@ async fn test_provider_dashboards_performance() {
 | 
				
			|||||||
    let start_time = std::time::Instant::now();
 | 
					    let start_time = std::time::Instant::now();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Simulate dashboard data loading
 | 
					    // Simulate dashboard data loading
 | 
				
			||||||
    let provider_types = vec!["farmer", "app_provider", "service_provider"];
 | 
					    let provider_types = vec!["farmer", "application_provider", "service_provider"];
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for provider_type in provider_types {
 | 
					    for provider_type in provider_types {
 | 
				
			||||||
        // Simulate dashboard page load
 | 
					        // Simulate dashboard page load
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -165,7 +165,7 @@ impl TestDataManager {
 | 
				
			|||||||
    /// Create test marketplace data
 | 
					    /// Create test marketplace data
 | 
				
			||||||
    fn create_test_marketplace_data(personas: &HashMap<UserRole, TestPersona>) -> TestMarketplaceData {
 | 
					    fn create_test_marketplace_data(personas: &HashMap<UserRole, TestPersona>) -> TestMarketplaceData {
 | 
				
			||||||
        let farmer_email = personas.get(&UserRole::Farmer).unwrap().email.clone();
 | 
					        let farmer_email = personas.get(&UserRole::Farmer).unwrap().email.clone();
 | 
				
			||||||
        let app_provider_email = personas.get(&UserRole::AppProvider).unwrap().email.clone();
 | 
					        let application_provider_email = personas.get(&UserRole::AppProvider).unwrap().email.clone();
 | 
				
			||||||
        let service_provider_email = personas.get(&UserRole::ServiceProvider).unwrap().email.clone();
 | 
					        let service_provider_email = personas.get(&UserRole::ServiceProvider).unwrap().email.clone();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        TestMarketplaceData {
 | 
					        TestMarketplaceData {
 | 
				
			||||||
@@ -186,7 +186,7 @@ impl TestDataManager {
 | 
				
			|||||||
                    price: 25.0,
 | 
					                    price: 25.0,
 | 
				
			||||||
                    currency: "TFC".to_string(),
 | 
					                    currency: "TFC".to_string(),
 | 
				
			||||||
                    description: "Test application for UX testing".to_string(),
 | 
					                    description: "Test application for UX testing".to_string(),
 | 
				
			||||||
                    provider_email: app_provider_email.clone(),
 | 
					                    provider_email: application_provider_email.clone(),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            services: vec![
 | 
					            services: vec![
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user