web-app/docs/02-modules/index.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

12 KiB

📦 Module System Overview

Modular architecture enabling feature-based development with plugin-based modules, dependency injection, and clean separation of concerns.

Table of Contents

Module Architecture

Plugin-Based Design

Ario uses a plugin-based architecture where each feature is implemented as a self-contained module:

  • Independent Development - Modules can be developed, tested, and deployed separately
  • Optional Features - Modules can be enabled or disabled via configuration
  • Clear Boundaries - Each module owns its domain logic and UI components
  • Extensible - New modules can be added without modifying existing code

Module Structure

Each module follows a consistent directory structure:

src/modules/[module-name]/
├── index.ts                 # Module plugin definition
├── components/              # Module-specific UI components
├── composables/             # Module composables and hooks
├── services/               # Business logic and API services
├── stores/                 # Module-specific Pinia stores
├── types/                  # TypeScript type definitions
└── views/                  # Page components and routes

Module Plugin Interface

All modules implement the ModulePlugin interface:

interface ModulePlugin {
  name: string              // Unique module identifier
  version: string           // Semantic version
  dependencies: string[]    // Required module dependencies
  
  // Installation lifecycle
  install(app: App, options?: ModuleConfig): Promise<void>
  
  // Optional exports
  routes?: RouteRecordRaw[]           // Vue Router routes
  components?: Record<string, any>    // Global components  
  composables?: Record<string, any>   // Exported composables
}

Available Modules

Base Module 🏗️

Purpose: Core infrastructure and shared services
Location: src/modules/base/
Dependencies: None (foundation module)

Provides:

  • Authentication Service - User identity management and Nostr key handling
  • Relay Hub - Centralized Nostr relay connection management
  • Storage Service - User-scoped localStorage operations
  • Toast Service - Application-wide notifications and feedback
  • PWA Features - Service worker and offline capabilities

Key Components:

  • Identity management UI (key generation, import/export)
  • Connection status indicators
  • Theme and language switching
  • Authentication guards and utilities

See: base-module/index

Nostr Feed Module 📰

Purpose: Social feed and content discovery
Location: src/modules/nostr-feed/
Dependencies: ['base']

Features:

  • Social Feed - Timeline of Nostr events (kind 1 notes)
  • Admin Announcements - Highlighted posts from configured admin pubkeys
  • Content Filtering - Filter by author, content type, or keywords
  • Real-time Updates - Live feed updates via Nostr subscriptions
  • Engagement - Like, repost, and reply to posts

Key Components:

  • FeedComponent with infinite scroll
  • NoteCard for individual posts
  • AdminBadge for announcement highlighting
  • Content filtering and search

See: nostr-feed-module/index

Chat Module 💬

Purpose: Encrypted direct messaging
Location: src/modules/chat/
Dependencies: ['base']

Features:

  • Encrypted Messages - NIP-04 encrypted direct messages
  • Contact Management - Add and manage chat contacts
  • Real-time Chat - Live message delivery via Nostr relays
  • Message History - Persistent chat history with local storage
  • Typing Indicators - Real-time typing status (when supported)

Key Components:

  • ChatComponent with message bubbles
  • ContactList for chat participants
  • MessageInput with encryption handling
  • Chat history management

See: chat-module/index

Events Module 🎟️

Purpose: Event ticketing and management
Location: src/modules/events/
Dependencies: ['base']

Features:

  • Event Creation - Create and publish events to Nostr
  • Lightning Tickets - Paid event tickets using Lightning invoices
  • Event Discovery - Browse and search upcoming events
  • Ticket Management - Purchase, transfer, and validate tickets
  • Event Check-in - QR code-based event entry system

Key Components:

  • EventCard for event display
  • TicketPurchase with Lightning payment flow
  • EventCreation form with rich editing
  • QR code generation and scanning

See: events-module/index

Market Module 🛒

Purpose: Nostr marketplace functionality
Location: src/modules/market/
Dependencies: ['base']

Features:

  • Product Listings - Create and browse marketplace items
  • Lightning Payments - Bitcoin payments for products
  • Vendor Profiles - Seller reputation and product history
  • Order Management - Track purchases and sales
  • Product Search - Filter and search marketplace items

Key Components:

  • ProductCard for item display
  • ProductListing creation form
  • OrderHistory and transaction tracking
  • Vendor dashboard and analytics

See: market-module/index

Module Development

Creating a New Module

1. Module Structure Setup

mkdir src/modules/my-module
cd src/modules/my-module

# Create module directories
mkdir components composables services stores types views
touch index.ts

2. Module Plugin Definition

// src/modules/my-module/index.ts
import type { App } from 'vue'
import type { ModulePlugin } from '@/core/types'

export const myModule: ModulePlugin = {
  name: 'my-module',
  version: '1.0.0',
  dependencies: ['base'], // Always depend on base for core services
  
  async install(app: App, options?: MyModuleConfig) {
    // Register module components
    // Initialize module services  
    // Set up module routes
  },
  
  routes: [
    {
      path: '/my-feature',
      component: () => import('./views/MyFeatureView.vue')
    }
  ]
}

3. Service Implementation

// src/modules/my-module/services/my-service.ts
import { BaseService } from '@/core/base/BaseService'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'

export class MyService extends BaseService {
  constructor(
    private relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
  ) {
    super()
  }
  
  async initialize(): Promise<void> {
    // Service initialization logic
    this.isInitialized.value = true
  }
  
  async dispose(): Promise<void> {
    // Cleanup logic
    this.isDisposed.value = true
  }
}

4. Module Registration

// src/app.config.ts
export const moduleConfigs = {
  // ... existing modules
  'my-module': {
    enabled: true,
    customOption: 'value'
  }
}

Module Development Best Practices

Dependency Management

  • Always declare module dependencies explicitly
  • Use dependency injection for cross-module service access
  • Avoid direct imports between modules

Service Architecture

  • Extend BaseService for consistent lifecycle management
  • Register services in the DI container during module installation
  • Use reactive properties for state that affects UI

Component Patterns

  • Export reusable components for other modules
  • Use module-specific component naming (e.g., ChatMessage, EventCard)
  • Follow the existing UI component patterns with Shadcn/ui

Module Configuration

Configuration Schema

Modules can be configured via src/app.config.ts:

interface ModuleConfig {
  enabled: boolean          // Enable/disable module
  [key: string]: any       // Module-specific configuration
}

export const moduleConfigs: Record<string, ModuleConfig> = {
  'base': { enabled: true },
  'chat': { 
    enabled: true,
    maxMessageLength: 1000,
    enableTypingIndicators: true
  },
  'events': {
    enabled: true,
    defaultCurrency: 'sat',
    allowedEventTypes: ['meetup', 'conference', 'workshop']
  }
}

Runtime Configuration

Configuration is passed to modules during installation:

async install(app: App, options?: ChatModuleConfig) {
  const config = options || defaultConfig
  
  // Use configuration to customize module behavior
  this.messageService.setMaxLength(config.maxMessageLength)
}

Inter-Module Communication

Service Dependencies

For required functionality between modules:

// ✅ Correct: Use dependency injection
const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)

// ❌ Wrong: Direct import breaks modularity
import { relayHub } from '../base/services/relay-hub'

Event Bus Communication

For optional cross-module notifications:

// Publishing events
eventBus.emit('user:authenticated', { userId: user.pubkey })
eventBus.emit('payment:received', { amount: 1000, invoiceId: 'abc123' })

// Subscribing to events
eventBus.on('chat:message-received', (message) => {
  // Handle message in events module
})

Shared Components

Modules can export components for use by other modules:

// In module plugin definition
export const chatModule: ModulePlugin = {
  // ...
  components: {
    'ChatAvatar': () => import('./components/ChatAvatar.vue'),
    'MessageBubble': () => import('./components/MessageBubble.vue')
  }
}

// Usage in other modules
<ChatAvatar :pubkey="user.pubkey" :size="32" />

Module Lifecycle

Initialization Order

  1. Dependency Resolution - PluginManager sorts modules by dependencies
  2. Service Registration - Modules register services in DI container
  3. Component Registration - Global components made available
  4. Route Registration - Module routes added to Vue Router
  5. Service Initialization - Services initialize in dependency order

Module Installation Process

async install(app: App, options?: ModuleConfig) {
  // 1. Register services
  container.provide(SERVICE_TOKENS.MY_SERVICE, new MyService())
  
  // 2. Register global components
  app.component('MyGlobalComponent', MyGlobalComponent)
  
  // 3. Initialize module-specific logic
  await this.initializeModule(options)
}

Service Lifecycle Management

// Service initialization (called automatically)
async initialize(): Promise<void> {
  await this.setupEventListeners()
  await this.loadUserData()
  this.isInitialized.value = true
}

// Service disposal (called on app unmount)
async dispose(): Promise<void> {
  this.removeEventListeners()
  await this.saveUserData()
  this.isDisposed.value = true
}

See Also

Module Documentation

Architecture References


Tags: #modules #architecture #plugin-system #development
Last Updated: 2025-09-06
Author: Development Team