import { Injectable, Logger } from '@nestjs/common'; import { CategoryHiboutikRepository } from '../../hiboutik/category.hiboutik.repository'; import { CategoryDatabaseRepository } from '../../database/category.database.repository'; import { CategoryConverter } from '../../models/converter/category.converter'; import { forEachSafely } from '../../utils/sync'; @Injectable() export class CategoryHiboutikService { private readonly logger = new Logger('CategoryHiboutikService'); constructor( private readonly categoryHiboutikRepository: CategoryHiboutikRepository, private readonly categoryDatabaseRepository: CategoryDatabaseRepository, private readonly categoryConverter: CategoryConverter, ) {} /** * Mirrors Hiboutik categories and their tree: upserts each of them, links them to their parent, * then deletes the categories missing from Hiboutik. */ async syncCategories() { const hiboutikCategories = await this.categoryHiboutikRepository.getCategories(); // Pass 1: categories themselves. One upsert per category: an invalid category must not prevent the others from being saved const nbFailed = await forEachSafely( this.categoryConverter.fromHiboutikList(hiboutikCategories), (category) => this.categoryDatabaseRepository.upsert(category), this.logger, (category) => `Hiboutik category ${category.hiboutikId}`, ); // Pass 2: parent links, once every category exists (a child can come before its parent in Hiboutik's list) const nbParentsFailed = await forEachSafely( hiboutikCategories, (dto) => this.categoryDatabaseRepository.setParent(dto.category_id, dto.category_id_parent || null), this.logger, (dto) => `parent of Hiboutik category ${dto.category_id}`, ); // 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.categoryDatabaseRepository.deleteMissing(hiboutikCategories.map((dto) => dto.category_id)); this.logger.log( `Categories sync ended: ${hiboutikCategories.length - nbFailed}/${hiboutikCategories.length} synced, ${nbFailed} failed, ` + `${nbParentsFailed} parent links failed, ${nbDeleted} deleted.`, ); } }