diff --git a/docs/.obsidian/workspace.json b/docs/.obsidian/workspace.json index 74aab89..506705b 100644 --- a/docs/.obsidian/workspace.json +++ b/docs/.obsidian/workspace.json @@ -13,12 +13,12 @@ "state": { "type": "markdown", "state": { - "file": "01-architecture/index.md", + "file": "04-migrations/dependency-injection-migration.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "index" + "title": "dependency-injection-migration" } } ] @@ -170,6 +170,7 @@ }, "active": "fe085d296b05d361", "lastOpenFiles": [ + "01-architecture/index.md", "00-overview/index.md" ] } \ No newline at end of file diff --git a/src/core/base/BaseService.ts b/src/core/base/BaseService.ts index f08ac44..812a462 100644 --- a/src/core/base/BaseService.ts +++ b/src/core/base/BaseService.ts @@ -47,6 +47,7 @@ export abstract class BaseService { protected visibilityService: any = null protected storageService: any = null protected toastService: any = null + protected invoiceService: any = null // Service state public readonly isInitialized: Ref = ref(false) @@ -138,6 +139,7 @@ export abstract class BaseService { this.visibilityService = tryInjectService(SERVICE_TOKENS.VISIBILITY_SERVICE) this.storageService = tryInjectService(SERVICE_TOKENS.STORAGE_SERVICE) this.toastService = tryInjectService(SERVICE_TOKENS.TOAST_SERVICE) + this.invoiceService = tryInjectService(SERVICE_TOKENS.INVOICE_SERVICE) // Check if all required dependencies are available const missingDeps = this.getMissingDependencies() diff --git a/src/modules/market/index.ts b/src/modules/market/index.ts index adcfb95..e18c26a 100644 --- a/src/modules/market/index.ts +++ b/src/modules/market/index.ts @@ -19,6 +19,7 @@ import { useMarketPreloader } from './composables/useMarketPreloader' // Import services import { NostrmarketService } from './services/nostrmarketService' +import { PaymentMonitorService } from './services/paymentMonitor' export interface MarketModuleConfig { defaultCurrency: string @@ -44,11 +45,14 @@ export const marketModule: ModulePlugin = { throw new Error('Market module requires configuration') } - // Create and register NostrmarketService instance + // Create and register service instances const nostrmarketService = new NostrmarketService() container.provide(SERVICE_TOKENS.NOSTRMARKET_SERVICE, nostrmarketService) - // Initialize the service (will handle dependency injection) + const paymentMonitorService = new PaymentMonitorService() + container.provide(SERVICE_TOKENS.PAYMENT_MONITOR, paymentMonitorService) + + // Initialize services (will handle dependency injection) await nostrmarketService.initialize({ waitForDependencies: true, maxRetries: 3 @@ -56,6 +60,14 @@ export const marketModule: ModulePlugin = { console.warn('🛒 NostrmarketService initialization deferred:', error) // Service will auto-initialize when dependencies are available }) + + await paymentMonitorService.initialize({ + waitForDependencies: true, + maxRetries: 3 + }).catch(error => { + console.warn('🛒 PaymentMonitorService initialization deferred:', error) + // Service will auto-initialize when dependencies are available + }) // Register global components app.component('MarketSettings', MarketSettings) @@ -75,6 +87,7 @@ export const marketModule: ModulePlugin = { // Clean up services container.remove(SERVICE_TOKENS.NOSTRMARKET_SERVICE) + container.remove(SERVICE_TOKENS.PAYMENT_MONITOR) console.log('✅ Market module uninstalled') }, diff --git a/src/modules/market/services/paymentMonitor.ts b/src/modules/market/services/paymentMonitor.ts index 4880f55..4357679 100644 --- a/src/modules/market/services/paymentMonitor.ts +++ b/src/modules/market/services/paymentMonitor.ts @@ -1,4 +1,5 @@ import { ref } from 'vue' +import { BaseService } from '@/core/base/BaseService' import type { PaymentStatus, LightningInvoice } from '@/core/services/invoiceService' import type { Order } from '@/stores/market' @@ -18,7 +19,14 @@ export interface PaymentUpdate { paidAt?: number } -class PaymentMonitorService { +export class PaymentMonitorService extends BaseService { + // Service metadata + protected readonly metadata = { + name: 'PaymentMonitorService', + version: '1.0.0', + dependencies: ['InvoiceService'] // Only depends on InvoiceService for payment status checking + } + private state = ref({ isMonitoring: false, activeInvoices: new Map(), @@ -30,6 +38,14 @@ class PaymentMonitorService { private monitoringInterval: number | null = null private updateCallbacks: Map void> = new Map() + /** + * Service-specific initialization (called by BaseService) + */ + protected async onInitialize(): Promise { + this.debug('PaymentMonitorService initialized') + // No special initialization needed + } + // Computed properties get isMonitoring() { return this.state.value.isMonitoring } get activeInvoices() { return this.state.value.activeInvoices } @@ -156,22 +172,29 @@ class PaymentMonitorService { */ private async getPaymentStatus(paymentHash: string): Promise { try { - // For now, we'll simulate payment status checking since we don't have wallet context here - // In production, this would integrate with LNBits webhooks or polling - // TODO: Pass wallet information from the order context - console.log('Payment status check requested for:', paymentHash) + // Use injected InvoiceService for payment status checking + if (!this.invoiceService) { + console.warn('InvoiceService not available, returning default pending status') + return { + paid: false, + amount_paid: 0, + payment_hash: paymentHash + } + } - // Return default pending status for now + console.log('Checking payment status for:', paymentHash) + + // TODO: Need to pass adminKey from order context - for now return pending + // In a complete implementation, we'd store wallet context with each order + // const status = await this.invoiceService.checkPaymentStatus(paymentHash, adminKey) + // return status + + // Return default pending status until wallet context is available return { paid: false, amount_paid: 0, payment_hash: paymentHash } - - // TODO: Implement when wallet context is available and PaymentMonitorService is migrated to DI: - // const invoiceService = injectService(SERVICE_TOKENS.INVOICE_SERVICE) as InvoiceService - // const status = await invoiceService.checkPaymentStatus(paymentHash, adminKey) - // return status } catch (error) { console.error('Failed to get payment status:', error) // Return default pending status @@ -271,6 +294,5 @@ class PaymentMonitorService { } } -// Export singleton instance -export const paymentMonitor = new PaymentMonitorService() +// Service is now registered in the DI container diff --git a/src/modules/market/stores/market.ts b/src/modules/market/stores/market.ts index 9b8e167..81007e9 100644 --- a/src/modules/market/stores/market.ts +++ b/src/modules/market/stores/market.ts @@ -1,6 +1,6 @@ import { defineStore } from 'pinia' import { ref, computed, readonly, watch } from 'vue' -import { paymentMonitor } from '../services/paymentMonitor' +import type { PaymentMonitorService } from '../services/paymentMonitor' import { useAuth } from '@/composables/useAuthService' import { injectService, SERVICE_TOKENS } from '@/core/di-container' import type { LightningInvoice, InvoiceService } from '@/core/services/invoiceService' @@ -19,6 +19,7 @@ export const useMarketStore = defineStore('market', () => { const storageService = injectService(SERVICE_TOKENS.STORAGE_SERVICE) as any const invoiceService = injectService(SERVICE_TOKENS.INVOICE_SERVICE) as InvoiceService const nostrmarketService = injectService(SERVICE_TOKENS.NOSTRMARKET_SERVICE) as NostrmarketService + const paymentMonitorService = injectService(SERVICE_TOKENS.PAYMENT_MONITOR) as PaymentMonitorService // Core market state const markets = ref([]) const stalls = ref([]) @@ -545,10 +546,10 @@ export const useMarketStore = defineStore('market', () => { saveOrdersToStorage() // Start monitoring payment - await paymentMonitor.startMonitoring(order, invoice) + await paymentMonitorService.startMonitoring(order, invoice) // Set up payment update callback - paymentMonitor.onPaymentUpdate(orderId, (update) => { + paymentMonitorService.onPaymentUpdate(orderId, (update) => { handlePaymentUpdate(orderId, update) })