Files
esg/src/providers/factory/provider.factory.ts

80 lines
2.6 KiB
TypeScript

import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InquiryType } from '../../common/enums/inquiry-type.enum';
import { ProviderName } from '../../common/enums/provider-name.enum';
import { InquiryProvider } from '../../common/interfaces/inquiry-provider.interface';
import { InquiryRoutingConfig } from '../../config/configuration';
import { HamtaProvider } from '../implementations/hamta.provider';
import { MoallemProvider } from '../implementations/moallem.provider';
import { ParsianProvider } from '../implementations/parsian.provider';
import { TejaratNouProvider } from '../implementations/tejaratnou.provider';
/**
* Factory + registry for provider instances.
* Resolves providers by name and builds ordered execution chains (default + fallbacks).
* Note: AMITIS is not a provider, it's an authentication service used by other providers.
*/
@Injectable()
export class ProviderFactory {
private readonly logger = new Logger(ProviderFactory.name);
private readonly registry: Map<ProviderName, InquiryProvider>;
constructor(
private readonly configService: ConfigService,
hamta: HamtaProvider,
moallem: MoallemProvider,
parsian: ParsianProvider,
tejaratnou: TejaratNouProvider,
) {
this.registry = new Map<ProviderName, InquiryProvider>([
[ProviderName.HAMTA, hamta],
[ProviderName.MOALLEM, moallem],
[ProviderName.PARSIAN, parsian],
[ProviderName.TEJARATNOU, tejaratnou],
]);
}
getProvider(name: ProviderName): InquiryProvider | undefined {
const provider = this.registry.get(name);
if (!provider?.isEnabled()) {
this.logger.warn(`Provider ${name} is disabled or not configured`);
return undefined;
}
return provider;
}
/**
* Returns providers in execution order: default first, then fallbacks.
*/
getProvidersForInquiry(inquiryType: InquiryType): InquiryProvider[] {
const routing = this.configService.get<InquiryRoutingConfig>(
`inquiryRouting.${inquiryType}`,
);
if (!routing) {
this.logger.error(`No routing config for inquiry type ${inquiryType}`);
return [];
}
const orderedNames = [
routing.defaultProvider,
...(routing.fallbackEnabled ? routing.fallbackProviders : []),
];
const seen = new Set<ProviderName>();
const providers: InquiryProvider[] = [];
for (const name of orderedNames) {
if (seen.has(name)) continue;
seen.add(name);
const provider = this.getProvider(name);
if (provider?.supportedInquiryTypes.includes(inquiryType)) {
providers.push(provider);
}
}
return providers;
}
}