feat: rename Application Solutions to Agentic Apps in docs, UI, and codebase

This commit is contained in:
mik-tf
2025-09-08 11:43:53 -04:00
parent 2ddd538941
commit bfc24070d7
14 changed files with 46 additions and 46 deletions

View File

@@ -18,8 +18,8 @@ This document outlines the comprehensive redesign of the Project Mycelium market
- [ ] Update navigation and menus
- [ ] Update backend user management
- [ ] **Application Solutions → Agentic Apps**
- [ ] Update product categories
- [x] **Application Solutions → Agentic Apps**
- [x] Update product categories
- [ ] Update marketplace listings
- [ ] Update search and filtering
- [ ] Update backend product models

View File

@@ -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 |
| **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 |
| **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.) |
## Marketplace Features

View File

@@ -86,7 +86,7 @@ The TF Marketplace offers various products and services that facilitate the mutu
- 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
- **Suppliers**: Solution providers who develop and maintain applications

View File

@@ -79,8 +79,8 @@ impl DashboardController {
Some(user)
}
/// Helper function to count deployments across all users for a specific app provider
fn count_cross_user_deployments(app_provider_email: &str) -> std::collections::HashMap<String, i32> {
/// Helper function to count deployments across all users for a specific application provider
fn count_cross_user_deployments(application_provider_email: &str) -> std::collections::HashMap<String, i32> {
use std::collections::HashMap;
let mut deployment_counts: HashMap<String, i32> = HashMap::new();
@@ -108,8 +108,8 @@ impl DashboardController {
// Count deployments for this app provider's apps
for deployment in &user_data.application_deployments {
// Check if this deployment belongs to an app from our app provider
// We need to get the app provider's apps to match
let provider_apps = UserPersistence::get_user_apps(app_provider_email);
// We need to get the application provider's apps to match
let provider_apps = UserPersistence::get_user_apps(application_provider_email);
for provider_app in &provider_apps {
if deployment.app_id == provider_app.id && deployment.status == "Active" {
@@ -517,7 +517,7 @@ impl DashboardController {
let mut ctx = crate::models::builders::ContextBuilder::new()
.active_page("dashboard")
.build();
ctx.insert("active_section", "app_provider");
ctx.insert("active_section", "application_provider");
let config = get_app_config();
ctx.insert("gitea_enabled", &config.is_gitea_enabled());
@@ -607,7 +607,7 @@ impl DashboardController {
})
.collect();
let app_provider_data = crate::models::user::AppProviderData {
let application_provider_data = crate::models::user::AppProviderData {
published_apps: fresh_apps.len() as i32,
total_deployments: fresh_apps.iter().map(|a| a.deployments).sum::<i32>(),
active_deployments,
@@ -618,7 +618,7 @@ impl DashboardController {
revenue_history: Vec::new(),
};
ctx.insert("app_provider_data", &app_provider_data);
ctx.insert("application_provider_data", &application_provider_data);
} else {
// Ensure template always has a defined structure even without a logged-in user
let empty: crate::models::user::AppProviderData = crate::models::user::AppProviderData {
@@ -631,10 +631,10 @@ impl DashboardController {
deployment_stats: 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
@@ -2936,7 +2936,7 @@ impl DashboardController {
}
}).collect();
let app_provider_data = crate::models::user::AppProviderData {
let application_provider_data = crate::models::user::AppProviderData {
apps: fresh_apps.clone(),
published_apps: fresh_apps.len() as i32,
total_deployments,
@@ -2947,7 +2947,7 @@ impl DashboardController {
revenue_history: Vec::new(),
};
return Ok(ResponseBuilder::ok().json(app_provider_data).build());
return Ok(ResponseBuilder::ok().json(application_provider_data).build());
} else {
}

View File

@@ -405,11 +405,11 @@ impl Default for ServiceLevelAgreement {
/// Application deployment configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppDeployment {
pub struct ApplicationDeployment {
pub id: String,
pub app_id: String,
pub customer_email: String,
pub deployment_status: AppDeploymentStatus,
pub deployment_status: ApplicationDeploymentStatus,
pub resource_allocation: ResourceUtilization,
pub monthly_cost: rust_decimal::Decimal,
pub deployed_at: Option<DateTime<Utc>>,
@@ -418,9 +418,9 @@ pub struct AppDeployment {
pub monitoring_enabled: bool,
}
/// App deployment status
/// Application deployment status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AppDeploymentStatus {
pub enum ApplicationDeploymentStatus {
Pending,
Deploying,
Running,
@@ -429,7 +429,7 @@ pub enum AppDeploymentStatus {
Maintenance,
}
impl Default for AppDeploymentStatus {
impl Default for ApplicationDeploymentStatus {
fn default() -> Self {
Self::Pending
}

View File

@@ -804,8 +804,8 @@ impl OrderService {
// Only create deployments for application products
if item.product_category == "application" {
// Find the app provider by looking up who published this app
if let Some(app_provider_email) = self.find_app_provider(&item.product_id) {
// Find the application provider by looking up who published this app
if let Some(application_provider_email) = self.find_application_provider(&item.product_id) {
// Create deployment for each quantity ordered
for _i in 0..item.quantity {
@@ -838,7 +838,7 @@ impl OrderService {
.unwrap();
// 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 {
}
@@ -857,8 +857,8 @@ impl OrderService {
Ok(())
}
/// Find the app provider (user who published the app) by product ID
fn find_app_provider(&self, product_id: &str) -> Option<String> {
/// Find the application provider (user who published the app) by product ID
fn find_application_provider(&self, product_id: &str) -> Option<String> {
// Get all user data files and search for the app
let user_data_dir = std::path::Path::new("user_data");
if !user_data_dir.exists() {

View File

@@ -33,7 +33,7 @@ class UserDatabase {
display_name: 'Alex Thompson',
email: 'user2@example.com',
password: 'password',
role: 'app_provider',
role: 'application_provider',
location: 'Berlin, Germany',
joined_date: '2024-02-20',
reputation: 4.9,
@@ -84,7 +84,7 @@ class UserDatabase {
display_name: 'Jordan Mitchell',
email: 'user5@example.com',
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',
joined_date: new Date().toISOString().split('T')[0],
reputation: 5.0,

View File

@@ -13,7 +13,7 @@
<div class="stats-card info">
<h5 class="card-title">Published Apps</h5>
<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>
</div>
</div>
@@ -22,7 +22,7 @@
<div class="stats-card primary">
<h5 class="card-title">Active Deployments</h5>
<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>
</div>
</div>
@@ -31,7 +31,7 @@
<div class="stats-card warning">
<h5 class="card-title">Customer Base</h5>
<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>
</div>
</div>
@@ -40,7 +40,7 @@
<div class="stats-card success">
<h5 class="card-title">Monthly Earnings</h5>
<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>
</div>
</div>
@@ -232,8 +232,8 @@
{{ super() }}
<!-- Hydration JSON for initial app provider dashboard data (safe, non-executable) -->
<script id="ap-dashboard-hydration" type="application/json">
{% if app_provider_data is defined %}
{{ app_provider_data | json_encode() }}
{% if application_provider_data is defined %}
{{ application_provider_data | json_encode() }}
{% else %}
null
{% endif %}

View File

@@ -92,7 +92,7 @@
<div class="row align-items-center mb-4">
<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 class="col-md-6">
<ol class="list-group list-group-numbered mb-0">

View File

@@ -58,7 +58,7 @@
<td><a href="/docs/gateways" class="btn btn-sm btn-outline-primary">Learn More</a></td>
</tr>
<tr>
<td><strong>Application Solutions</strong></td>
<td><strong>Agentic Apps</strong></td>
<td>Pre-configured, self-healing applications</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>

View File

@@ -44,7 +44,7 @@
<td>Credits paid based on bandwidth consumption</td>
</tr>
<tr>
<td><strong>Application Solutions</strong></td>
<td><strong>Agentic Apps</strong></td>
<td>Pre-configured, self-healing applications</td>
<td>Users provide slices to application providers while maintaining sovereignty</td>
</tr>

View File

@@ -70,7 +70,7 @@
<li>Mycelium Nodes</li>
<li>Mycelium Gateways</li>
<li>Bandwidth Providers</li>
<li>Application Solutions</li>
<li>Agentic Apps</li>
<li>Human Energy Services</li>
</ul>

View File

@@ -42,12 +42,12 @@ async fn test_complete_provider_dashboards_ux_workflow() {
// Test users for different provider types
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";
// Clean up any existing test data
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);
// Initialize services
@@ -133,8 +133,8 @@ async fn test_complete_provider_dashboards_ux_workflow() {
println!("✅ Farmer Dashboard: WORKING - Node management, capacity planning, earnings tracking");
// Step 3: Test Application Provider Dashboard (/dashboard/app-provider)
println!("\n🔧 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/application-provider)");
// Create test app provider profile
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"),
];
println!(" 📱 Application Provider: {}", app_provider_email);
println!(" 📱 Application Provider: {}", application_provider_email);
println!(" 📊 Published Applications:");
let mut total_installs = 0;
@@ -282,7 +282,7 @@ async fn test_complete_provider_dashboards_ux_workflow() {
// Final cleanup
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);
// Final verification
@@ -321,7 +321,7 @@ async fn test_provider_dashboards_performance() {
let start_time = std::time::Instant::now();
// 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 {
// Simulate dashboard page load

View File

@@ -165,7 +165,7 @@ impl TestDataManager {
/// Create test marketplace data
fn create_test_marketplace_data(personas: &HashMap<UserRole, TestPersona>) -> TestMarketplaceData {
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();
TestMarketplaceData {
@@ -186,7 +186,7 @@ impl TestDataManager {
price: 25.0,
currency: "TFC".to_string(),
description: "Test application for UX testing".to_string(),
provider_email: app_provider_email.clone(),
provider_email: application_provider_email.clone(),
},
],
services: vec![