fix(sync): hydrate all origin product details
This commit is contained in:
@@ -402,7 +402,11 @@ export class SyncService {
|
||||
});
|
||||
}
|
||||
|
||||
async syncProductDetails(): Promise<{ synced: number; failed: number }> {
|
||||
async syncProductDetails(): Promise<{
|
||||
total: number;
|
||||
synced: number;
|
||||
failed: number;
|
||||
}> {
|
||||
if (this.running.details) {
|
||||
throw new Error('Product detail sync already in progress');
|
||||
}
|
||||
@@ -411,13 +415,20 @@ export class SyncService {
|
||||
data: { type: 'PRODUCT_DETAILS', status: 'RUNNING' },
|
||||
});
|
||||
try {
|
||||
const result = await this.syncConfiguredProductDetails();
|
||||
const result = await this.syncAllProductDetails(async (progress) => {
|
||||
await this.prisma.syncLog.update({
|
||||
where: { id: log.id },
|
||||
data: {
|
||||
message: `processed=${progress.processed}/${progress.total} synced=${progress.synced} failed=${progress.failed}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
await this.prisma.syncLog.update({
|
||||
where: { id: log.id },
|
||||
data: {
|
||||
status: 'SUCCESS',
|
||||
finishedAt: new Date(),
|
||||
message: `synced=${result.synced} failed=${result.failed}`,
|
||||
message: `total=${result.total} synced=${result.synced} failed=${result.failed}`,
|
||||
},
|
||||
});
|
||||
return result;
|
||||
@@ -463,25 +474,71 @@ export class SyncService {
|
||||
}
|
||||
|
||||
async syncConfiguredProductDetails(): Promise<{ synced: number; failed: number }> {
|
||||
const configured = await this.prisma.originGood.findMany({
|
||||
where: { delisted: false, goods: { some: {} } },
|
||||
const result = await this.syncMatchingProductDetails({
|
||||
delisted: false,
|
||||
goods: { some: {} },
|
||||
});
|
||||
return { synced: result.synced, failed: result.failed };
|
||||
}
|
||||
|
||||
async syncAllProductDetails(
|
||||
onProgress?: (progress: {
|
||||
processed: number;
|
||||
total: number;
|
||||
synced: number;
|
||||
failed: number;
|
||||
}) => Promise<void>,
|
||||
): Promise<{ total: number; synced: number; failed: number }> {
|
||||
return this.syncMatchingProductDetails(
|
||||
{ delisted: false },
|
||||
onProgress,
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
private async syncMatchingProductDetails(
|
||||
where: Prisma.OriginGoodWhereInput,
|
||||
onProgress?: (progress: {
|
||||
processed: number;
|
||||
total: number;
|
||||
synced: number;
|
||||
failed: number;
|
||||
}) => Promise<void>,
|
||||
attempts = 1,
|
||||
): Promise<{ total: number; synced: number; failed: number }> {
|
||||
const originGoods = await this.prisma.originGood.findMany({
|
||||
where,
|
||||
select: { id: true, sdsGoodId: true },
|
||||
orderBy: { id: 'asc' },
|
||||
});
|
||||
let synced = 0;
|
||||
let failed = 0;
|
||||
for (const originGood of configured) {
|
||||
try {
|
||||
const upstream = await this.sds.fetchProductDetail(originGood.sdsGoodId);
|
||||
await this.persistProductDetail(originGood.id, upstream);
|
||||
synced++;
|
||||
} catch (error) {
|
||||
let processed = 0;
|
||||
for (const originGood of originGoods) {
|
||||
let lastError: unknown;
|
||||
let succeeded = false;
|
||||
for (let attempt = 1; attempt <= attempts; attempt++) {
|
||||
try {
|
||||
const upstream = await this.sds.fetchProductDetail(originGood.sdsGoodId);
|
||||
await this.persistProductDetail(originGood.id, upstream);
|
||||
synced++;
|
||||
succeeded = true;
|
||||
break;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
}
|
||||
if (!succeeded) {
|
||||
failed++;
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
const message = lastError instanceof Error ? lastError.message : String(lastError);
|
||||
this.logger.warn(`Failed to sync SDS detail ${originGood.sdsGoodId}: ${message}`);
|
||||
}
|
||||
processed++;
|
||||
if (onProgress && (processed % 10 === 0 || processed === originGoods.length)) {
|
||||
await onProgress({ processed, total: originGoods.length, synced, failed });
|
||||
}
|
||||
}
|
||||
return { synced, failed };
|
||||
return { total: originGoods.length, synced, failed };
|
||||
}
|
||||
|
||||
async importProductDetail(upstream: SdsProductDetail): Promise<{
|
||||
|
||||
Reference in New Issue
Block a user