У площадок разные форматы данных. Если писать импорт напрямую в бизнес-логику, система быстро станет неподдерживаемой.
Я разделил источники через адаптеры: каждый адаптер отвечает только за получение и преобразование внешних данных в единую модель тендера.
На первом этапе не стал делать универсальный конструктор парсеров. Явный адаптер под каждый источник был быстрее и надёжнее.
export interface TenderSourceAdapter {
readonly source: TenderSource;
fetch(params: ImportParams): Promise<RawTender[]>;
normalize(raw: RawTender): NormalizedTender;
}
@Injectable()
export class TenderImportService {
constructor(private readonly tenders: TenderRepository) {}
async importFrom(adapter: TenderSourceAdapter, params: ImportParams) {
const rawTenders = await adapter.fetch(params);
return Promise.all(
rawTenders.map((raw) => {
const tender = adapter.normalize(raw);
return this.tenders.upsertByExternalId({
externalId: tender.externalId,
source: adapter.source,
data: tender,
});
}),
);
}
}
