2025-11-12 08:17:28 -08:00
|
|
|
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<ServiceContainer> {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-05 14:33:52 -07:00
|
|
|
export default DIContainer;
|