- 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>
12 KiB
Modular Architecture Analysis & Infrastructure Abstractions
Project: Ario Web Application
Date: September 5, 2025
Scope: Analysis of modular plugin architecture for centralization opportunities
Executive Summary
The Ario web application demonstrates a well-architected modular system using Vue 3, TypeScript, and dependency injection. After comprehensive analysis of all modules, we've identified significant opportunities for code consolidation that could reduce duplication by 30-40% while improving maintainability, type safety, and development velocity.
Key Findings:
- 16+ duplicate patterns across modules requiring abstraction
- Common async operation pattern found in 12+ files
- Service dependency injection pattern duplicated in 7+ services
- Payment processing logic duplicated between market and events modules
- User-scoped storage pattern repeated across multiple stores
Recent Progress (September 6, 2025):
- ✅ Legacy relay infrastructure cleanup completed
- ✅ Removed redundant NostrclientHub service
- ✅ Removed legacy NostrStore Pinia store
- ✅ Standardized on RelayHub service for all Nostr operations
- ✅ Updated dependency injection to remove unused tokens
Current Module Structure
Base Module (src/modules/base/)
- Purpose: Core infrastructure (Nostr, Auth, PWA)
- Key Services: Authentication, Relay Hub, Payment Service, Visibility Service
- Status: Well-established foundation with recent cleanup of legacy relay infrastructure
Chat Module (src/modules/chat/)
- Purpose: Encrypted Nostr chat functionality
- Key Features: NIP-04 encryption, DM handling, peer management
- Dependencies: Base module services
Events Module (src/modules/events/)
- Purpose: Event ticketing with Lightning payments
- Key Features: Ticket purchase, Lightning integration, QR codes
- Dependencies: Base module, payment processing
Market Module (src/modules/market/)
- Purpose: Nostr marketplace with order management
- Key Features: Product catalog, order processing, payment handling
- Dependencies: Base module, payment processing, storage
Nostr Feed Module (src/modules/nostr-feed/)
- Purpose: Social feed functionality
- Key Features: Note filtering, admin posts, real-time updates
- Dependencies: Base module services
Identified Duplicate Patterns
1. Async Operation Pattern ⭐ HIGH PRIORITY
Occurrences: Found in 12+ files across all modules
Current Implementation:
// Repeated in every composable/component
const isLoading = ref(false)
const error = ref<string | null>(null)
const data = ref<T | null>(null)
try {
isLoading.value = true
// operation
} catch (err) {
error.value = err.message
} finally {
isLoading.value = false
}
Impact:
- 200+ lines of duplicate code
- Inconsistent error handling
- Manual loading state management
2. Service Dependency Injection ⭐ HIGH PRIORITY
Occurrences: Found in 7+ service files
Current Implementation:
// Repeated in every service
const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB) as any
const authService = injectService(SERVICE_TOKENS.AUTH_SERVICE) as any
if (!relayHub) {
throw new Error('RelayHub not available')
}
Impact:
- Type safety issues (
as anycasting) - Duplicate dependency checking
- Inconsistent error messages
3. Payment Processing Logic ⭐ HIGH PRIORITY
Occurrences: Duplicated between market and events modules
Current Implementation:
// Similar logic in both modules
const payInvoiceWithWallet = async (bolt11: string) => {
// Lightning payment logic
// QR code generation
// Success/error handling
// Toast notifications
}
Impact:
- 150+ lines of duplicate payment logic
- Inconsistent payment UX
- Duplicate error handling
4. User-Scoped Storage Pattern
Occurrences: Found in market store, chat service
Current Implementation:
// Pattern repeated across modules
const getUserStorageKey = (baseKey: string) => {
const userPubkey = auth.currentUser?.value?.pubkey
return userPubkey ? `${baseKey}_${userPubkey}` : baseKey
}
Impact:
- Duplicate storage key logic
- Potential data consistency issues
5. Module Registration Pattern
Occurrences: Every module (index.ts files)
Current Implementation:
// Identical structure in every module
export const modulePlugin: ModulePlugin = {
name: 'module-name',
install(app: App, options) {
// Service registration
// Component registration
// Route registration
// Event setup
},
uninstall() {
// Cleanup logic
}
}
Impact:
- Boilerplate code in every module
- Inconsistent registration patterns
6. Toast Notification Pattern
Occurrences: Found in 4+ files
Current Implementation:
// Inconsistent usage across modules
toast.success('Operation successful!')
toast.error('Operation failed')
Impact:
- Inconsistent notification styling
- Duplicate notification logic
Recommended Abstractions
1. Core Infrastructure Abstractions
A. useAsyncOperation Composable
Location: src/core/composables/useAsyncOperation.ts
export function useAsyncOperation<T>() {
const isLoading = ref(false)
const error = ref<string | null>(null)
const data = ref<T | null>(null)
const execute = async (operation: () => Promise<T>, options?: {
successMessage?: string
errorMessage?: string
showToast?: boolean
}) => {
// Standardized loading/error/success handling
}
return { isLoading, error, data, execute, reset }
}
Benefits:
- ✅ Eliminates 200+ lines of duplicate code
- ✅ Consistent error handling across all modules
- ✅ Standardized loading states
- ✅ Optional toast notification integration
B. BaseService Abstract Class
Location: src/core/base/BaseService.ts
export abstract class BaseService {
protected relayHub: any
protected authService: any
constructor() {
// Proper dependency injection with type safety
}
protected async initialize(): Promise<void> {
await this.waitForDependencies()
await this.onInitialize()
}
protected requireAuth() {
// Centralized auth requirement checking
}
protected handleError(error: Error, context: string) {
// Standardized error handling and reporting
}
}
Benefits:
- ✅ Eliminates
as anytype casting - ✅ Consistent dependency management
- ✅ Standardized service lifecycle
- ✅ Better error handling and debugging
C. PaymentService Centralization
Location: src/core/services/PaymentService.ts
export class PaymentService extends BaseService {
async processLightningPayment(bolt11: string, orderId?: string): Promise<PaymentResult>
async generateQRCode(paymentRequest: string): Promise<string>
async monitorPaymentStatus(paymentHash: string): Promise<void>
}
Benefits:
- ✅ Eliminates 150+ lines of duplicate payment logic
- ✅ Consistent payment UX across market and events
- ✅ Centralized payment monitoring and error handling
- ✅ Single source of truth for Lightning integration
D. StorageService Abstraction
Location: src/core/services/StorageService.ts
export class StorageService {
setUserData<T>(key: string, data: T): void
getUserData<T>(key: string, defaultValue?: T): T | undefined
clearUserData(key: string): void
}
Benefits:
- ✅ User-scoped storage abstraction
- ✅ Type-safe storage operations
- ✅ Consistent data isolation between users
2. UI/UX Standardization
A. Notification Service
Location: src/core/services/NotificationService.ts
export class NotificationService {
success(message: string, options?: NotificationOptions): void
error(message: string, options?: NotificationOptions): void
info(message: string, options?: NotificationOptions): void
}
B. Module Registration Utilities
Location: src/core/utils/moduleRegistration.ts
export function createModulePlugin(config: ModuleConfig): ModulePlugin {
// Standardized module registration with error handling
}
Implementation Roadmap
Phase 1: High-Impact Core Abstractions (Week 1-2)
-
Create
useAsyncOperationcomposable- Implement core functionality
- Replace usage in 12+ files
- Expected Impact: 40% reduction in loading/error code
-
Create
BaseServiceabstract class- Implement dependency injection abstraction
- Migrate 7+ services to inherit from BaseService
- Expected Impact: Eliminate
as anycasting, improve type safety
Phase 2: Service Consolidation (Week 3-4)
-
Create
PaymentServicecentralization- Consolidate market and events payment logic
- Implement centralized QR code generation
- Expected Impact: 30% reduction in payment-related code
-
Create
StorageServiceabstraction- Implement user-scoped storage
- Migrate existing storage patterns
- Expected Impact: Consistent data isolation
Phase 3: UX Standardization (Week 5-6)
-
Create
NotificationService- Standardize toast notifications
- Implement consistent messaging
- Expected Impact: Unified notification experience
-
Create module registration utilities
- Simplify module creation process
- Standardize registration patterns
- Expected Impact: Faster module development
Expected Benefits
Development Velocity
- 40% faster module development with reusable patterns
- Reduced onboarding time for new developers
- Consistent development patterns across team
Code Quality
- 30-40% reduction in duplicate code
- Improved type safety with proper service injection
- Standardized error handling across all modules
- Better test coverage of centralized functionality
User Experience
- Consistent loading states across all features
- Unified error messaging and handling
- Standardized payment flows between market and events
- Better performance through optimized common operations
Maintainability
- Single source of truth for common patterns
- Easier debugging with centralized error handling
- Propagated improvements - enhancements benefit all modules
- Reduced technical debt through consolidation
Risk Assessment
Low Risk
- Backward compatibility: New abstractions won't break existing functionality
- Incremental adoption: Can be implemented module by module
- Fallback options: Existing patterns remain functional during transition
Medium Risk
- TypeScript complexity: Need careful typing for generic abstractions
- Testing coverage: Must ensure centralized code is thoroughly tested
Mitigation Strategies
- Comprehensive testing of all abstracted functionality
- Gradual migration one module at a time
- Maintain existing APIs during transition period
Success Metrics
Quantitative Metrics
- Lines of Code: Target 30-40% reduction in common patterns
- Type Safety: Eliminate all
as anycasting in services - Test Coverage: Achieve 90%+ coverage of centralized functionality
- Build Performance: Maintain sub-6s production build times
Qualitative Metrics
- Developer Experience: Faster module development and onboarding
- Code Consistency: Uniform patterns across all modules
- Error Handling: Consistent error reporting and recovery
- User Experience: Uniform loading states and notifications
Conclusion
The modular architecture analysis reveals a mature, well-structured codebase with significant opportunities for optimization. The identified abstractions will:
- Reduce code duplication by 30-40% in common patterns
- Improve type safety and eliminate
as anycasting - Standardize user experience across all modules
- Accelerate future development through reusable patterns
Recommendation: Proceed with Phase 1 implementation starting with useAsyncOperation and BaseService abstractions, which will deliver immediate benefits with minimal risk.
The proposed changes align with the existing architectural principles while providing substantial improvements in maintainability, developer experience, and code quality.
This analysis was conducted on September 5, 2025, based on the current state of the Ario web application modular architecture.