import { Injectable, Logger } from '@nestjs/common'; import { BrandHiboutikRepository } from '../../hiboutik/brand.hiboutik.repository'; import { BrandDatabaseRepository } from '../../database/brand.database.repository'; import { BrandConverter } from '../../models/converter/brand.converter'; import { forEachSafely } from '../../utils/sync'; @Injectable() export class BrandHiboutikService { private readonly logger = new Logger('BrandHiboutikService'); constructor( private readonly brandHiboutikRepository: BrandHiboutikRepository, private readonly brandDatabaseRepository: BrandDatabaseRepository, private readonly brandConverter: BrandConverter, ) {} /** Mirrors Hiboutik brands: upserts each of them, then deletes the brands missing from Hiboutik. */ async syncBrands() { const hiboutikBrands = await this.brandHiboutikRepository.getBrands(); // One upsert per brand: an invalid brand must not prevent the others from being saved const nbFailed = await forEachSafely( this.brandConverter.fromHiboutikList(hiboutikBrands), (brand) => this.brandDatabaseRepository.upsert(brand), this.logger, (brand) => `Hiboutik brand ${brand.hiboutikId}`, ); // Hiboutik is trusted: a successful (2xx) answer, even an empty list, is the truth. An HTTP error throws before this point. const nbDeleted = await this.brandDatabaseRepository.deleteMissing(hiboutikBrands.map((dto) => dto.brand_id)); this.logger.log( `Brands sync ended: ${hiboutikBrands.length - nbFailed}/${hiboutikBrands.length} synced, ${nbFailed} failed, ${nbDeleted} deleted.`, ); } }