web-app/docs/archive/ARCHITECTURE_ANALYSIS_PRINT.md
padreug cdf099e45f Create comprehensive Obsidian-style documentation structure
- Reorganize all markdown documentation into structured docs/ folder
- Create 7 main documentation categories (00-overview through 06-deployment)
- Add comprehensive index files for each category with cross-linking
- Implement Obsidian-compatible [[link]] syntax throughout
- Move legacy/deprecated documentation to archive folder
- Establish documentation standards and maintenance guidelines
- Provide complete coverage of modular architecture, services, and deployment
- Enable better navigation and discoverability for developers and contributors

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-06 14:31:27 +02:00

11 KiB

Web App Architecture Analysis & Modularity Assessment

⚠️ OUTDATED DOCUMENT
Updated Version: /docs/modular-architecture-analysis.md
Status: Print version of outdated September 4, 2025 analysis

Date: September 4, 2025
Project: Ario Web App (Vue 3 + Nostr + LNbits)
Objective: Evaluate current architecture for modular plugin-based development


Executive Summary

The current web application demonstrates solid foundational architecture with excellent Nostr infrastructure (RelayHub/NostrclientHub) but lacks true modularity for plugin-based development.

Overall Modularity Rating: 6.5/10

The app successfully implements core Nostr functionality and component organization but requires significant architectural refactoring to achieve the stated objective of independent, pluggable feature modules.


Current Architecture Assessment

Strengths (What's Working Well)

1. Strong Base Infrastructure (8/10)

  • RelayHub & NostrclientHub: Excellent centralized Nostr infrastructure with robust connection management, event handling, and browser compatibility
  • Pinia Stores: Clean state management separation (nostr.ts, market.ts) with reactive patterns
  • Composables Pattern: Good reactive logic encapsulation (useRelayHub, useNostrChat, useMarket)
  • UI Component Library: Well-structured Shadcn/ui components with consistent design system

2. Component Organization (7/10)

  • Components grouped by domain (/market, /nostr, /events, /auth)
  • Page-level routing with lazy loading implementation
  • Composables provide reusable business logic across components
  • Clean separation of concerns between UI and business logic

3. Service Layer (6/10)

  • Clean service abstractions (nostrmarketService, paymentMonitor)
  • API layer separation (/lib/api)
  • Type-safe interfaces and proper error handling

Critical Issues (What's Missing)

1. No Plugin Architecture (3/10)

  • Hard-coded routes: All features baked into main router configuration
  • Tight coupling: Components directly import across modules without abstraction
  • No feature isolation: Cannot develop/deploy components independently
  • No plugin registration system: Missing infrastructure for dynamic feature loading

2. Cross-Module Dependencies (4/10)

Examples of problematic tight coupling:

// Payment monitor importing market types directly
src/lib/services/paymentMonitor.ts: import type { Order } from '@/stores/market'

// Navbar importing chat composable directly  
src/components/layout/Navbar.vue: import { nostrChat } from '@/composables/useNostrChat'

// Services importing market store directly
src/lib/services/nostrmarketService.ts: import type { Stall, Product, Order } from '@/stores/market'

3. Missing Module Boundaries (5/10)

  • No clear module interfaces/contracts
  • Shared types scattered across modules without centralized definition
  • No dependency injection system for service management
  • Missing module lifecycle management

Required Changes for Modular Architecture

Phase 1: Core Infrastructure Refactor

1. Create Module System

// /src/modules/base/types.ts
interface ModuleConfig {
  name: string
  routes: RouteConfig[]
  components: ComponentConfig[]
  services: ServiceConfig[]
  dependencies?: string[]
}

interface ModulePlugin {
  install(app: App, options?: any): void
  uninstall(): void
}

2. Plugin Registration System

// /src/core/plugin-manager.ts
class PluginManager {
  private plugins = new Map<string, ModulePlugin>()
  
  register(module: ModulePlugin): void
  unregister(name: string): void
  getModule(name: string): ModulePlugin
  getDependencies(name: string): string[]
}

Phase 2: Module Extraction

1. Base Module Structure

/src/modules/base/
  nostr/
    relayHub.ts          # Centralized relay management
    nostrclientHub.ts    # Client connection handling
    types.ts             # Nostr-specific types
  auth/
    lnbits.ts           # LNbits authentication
    composables/
  pwa/
    install-prompt.ts
    notifications.ts
  ui/                    # Shadcn components

2. Feature Modules

/src/modules/
  nostr-feed/
    components/
      NostrFeed.vue
    composables/
      useFeed.ts
    services/
      feedService.ts
    index.ts             # Module export
  market/
    components/
    composables/
    stores/
    services/
    index.ts
  chat/
  events/

3. Module Interface Standards

// Each module exports standardized interface
export interface NostrFeedModule extends ModulePlugin {
  name: 'nostr-feed'
  components: {
    NostrFeed: Component
  }
  routes: RouteConfig[]
  dependencies: ['base']
  config?: NostrFeedConfig
}

Phase 3: Event-Driven Communication

Replace Direct Imports with Event Bus

// /src/core/event-bus.ts
interface ModuleEventBus {
  emit(event: string, data: any): void
  on(event: string, handler: Function): void
  off(event: string, handler: Function): void
}

// Example usage:
// Market module: eventBus.emit('order:created', order)
// Chat module: eventBus.on('order:created', handleNewOrder)

Dependency Injection Container

// /src/core/di-container.ts
class DIContainer {
  provide<T>(token: string, instance: T): void
  inject<T>(token: string): T
  
  // Module-scoped injection
  provideForModule(module: string, token: string, instance: any): void
}

If rebuilding from scratch, implement these architectural patterns:

1. Module-First Architecture

src/
  core/                    # Base app infrastructure
    plugin-manager.ts    # Plugin registration & lifecycle
    di-container.ts      # Dependency injection
    event-bus.ts         # Inter-module communication
    module-registry.ts   # Module discovery & loading
    base-services/       # Core services
  modules/
    base/               # Core functionality (required)
      nostr/           # RelayHub, NostrclientHub
      auth/            # LNbits authentication
      pwa/             # Progressive Web App features
      ui/              # Shadcn component library
    nostr-feed/        # Announcements & social feed
    market/            # Marketplace functionality  
    chat/              # Nostr chat implementation
    events/            # Event ticketing system
  app.ts               # Application composition & startup

2. Configuration-Driven Setup

// /src/app.config.ts
export const appConfig = {
  modules: {
    base: { 
      required: true,
      nostr: {
        relays: process.env.VITE_NOSTR_RELAYS
      }
    },
    'nostr-feed': { 
      enabled: true,
      config: {
        refreshInterval: 30000,
        maxPosts: 100
      }
    },
    market: { 
      enabled: true, 
      config: {
        defaultCurrency: 'sats',
        paymentTimeout: 300000
      }
    },
    chat: { 
      enabled: false  // Can be toggled via config
    },
    events: { 
      enabled: true,
      config: {
        ticketValidationEndpoint: '/api/tickets/validate'
      }
    }
  },
  features: {
    pwa: true,
    pushNotifications: true,
    electronApp: true
  }
}

3. Dynamic Module Loading

// /src/core/module-loader.ts
class ModuleLoader {
  async loadModule(name: string): Promise<ModulePlugin> {
    const module = await import(`@/modules/${name}/index.ts`)
    await this.resolveDependencies(module.dependencies || [])
    return module.default
  }
  
  async unloadModule(name: string): Promise<void> {
    const module = this.getModule(name)
    if (module) {
      await module.uninstall()
      this.cleanupRoutes(name)
      this.cleanupServices(name)
    }
  }

  private async resolveDependencies(deps: string[]): Promise<void> {
    for (const dep of deps) {
      if (!this.isModuleLoaded(dep)) {
        await this.loadModule(dep)
      }
    }
  }
}

4. Module Development Workflow

# Develop single module in isolation
npm run dev:module market

# Test module independently  
npm run test:module market

# Build specific modules only
npm run build:modules market,chat

# Hot reload module during development
npm run dev:hot-module nostr-feed

Key Architectural Improvements

1. Dependency Inversion

  • Modules depend on interfaces, not concrete implementations
  • Services injected via DI container rather than direct imports
  • Clear separation between module contracts and implementations

2. Event-Driven Communication

  • Replace direct imports with event-based messaging
  • Loose coupling between modules via standardized events
  • Centralized event routing and handling

3. Module Lifecycle Management

  • Proper setup and teardown hooks for each module
  • Resource cleanup when modules are disabled/unloaded
  • Dependency resolution during module loading

4. Configuration Over Code

  • Enable/disable features via configuration files
  • Runtime module toggling without code changes
  • Environment-specific module configurations

5. Hot Module Replacement

  • Develop modules independently without full app restart
  • Live reloading of individual modules during development
  • Isolated testing environments for each module

Implementation Roadmap

High Priority (Immediate)

  1. Extract RelayHub/NostrclientHub to base module (mostly complete)
  2. Create plugin registration system - Core infrastructure for module loading
  3. Convert nostr-feed to plugin pattern - Proof of concept implementation

Medium Priority (Phase 2)

  1. Implement event bus communication - Replace direct imports between modules
  2. Add module lifecycle management - Proper setup/teardown hooks
  3. Create development tooling - Scripts for isolated module development

Low Priority (Phase 3)

  1. Add module versioning support - Handle different module versions
  2. Implement hot module replacement - Live development workflow
  3. Add module marketplace - Plugin discovery and installation

Conclusion

The current web application has excellent technical foundations, particularly the Nostr infrastructure (RelayHub/NostrclientHub), but requires significant architectural refactoring to achieve true modularity.

Key Strengths to Preserve:

  • Robust Nostr client implementation
  • Clean component organization
  • Solid TypeScript foundations
  • PWA capabilities

Critical Areas for Improvement:

  • Plugin architecture implementation
  • Module boundary enforcement
  • Event-driven communication
  • Development workflow optimization

Estimated Effort:

  • Phase 1 (Core Infrastructure): 2-3 weeks
  • Phase 2 (Module Extraction): 3-4 weeks
  • Phase 3 (Advanced Features): 2-3 weeks

The investment in modular architecture will enable independent development of features, easier testing, better code maintainability, and the ability to dynamically enable/disable functionality based on deployment requirements.


Generated by: Claude Code Architecture Analysis
Last Updated: September 4, 2025