import { CosmosClient, Database, Container } from '@azure/cosmos'; import { SecretClient } from '@azure/keyvault-secrets'; import { DefaultAzureCredential } from '@azure/identity'; export interface ServiceContainer { cosmosClient: CosmosClient; database: Database; donationsContainer: Container; volunteersContainer: Container; programsContainer: Container; secretClient: SecretClient; } class DIContainer { private static instance: DIContainer; private services: ServiceContainer | null = null; private constructor() {} public static getInstance(): DIContainer { if (!DIContainer.instance) { DIContainer.instance = new DIContainer(); } return DIContainer.instance; } public async initializeServices(): Promise { if (this.services) { return this.services; } try { // Initialize Cosmos DB const cosmosConnectionString = process.env.COSMOS_CONNECTION_STRING; if (!cosmosConnectionString) { throw new Error('COSMOS_CONNECTION_STRING is not configured'); } const cosmosClient = new CosmosClient(cosmosConnectionString); const databaseName = process.env.COSMOS_DATABASE_NAME || 'MiraclesInMotion'; const database = cosmosClient.database(databaseName); // Get containers const donationsContainer = database.container('donations'); const volunteersContainer = database.container('volunteers'); const programsContainer = database.container('programs'); // Initialize Key Vault const keyVaultUrl = process.env.KEY_VAULT_URL; if (!keyVaultUrl) { throw new Error('KEY_VAULT_URL is not configured'); } const credential = new DefaultAzureCredential(); const secretClient = new SecretClient(keyVaultUrl, credential); this.services = { cosmosClient, database, donationsContainer, volunteersContainer, programsContainer, secretClient }; console.log('✅ Services initialized successfully'); return this.services; } catch (error) { console.error('❌ Failed to initialize services:', error); throw error; } } public getServices(): ServiceContainer { if (!this.services) { throw new Error('Services not initialized. Call initializeServices() first.'); } return this.services; } } export default DIContainer;