48 lines
2.2 KiB
TypeScript
48 lines
2.2 KiB
TypeScript
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.`,
|
|
);
|
|
}
|
|
}
|