Reconcile offer_id after every import
After each single or batch import, walk all catalog items under the Imported Furniture tree and set offer_id to the furnidata sprite id, repairing any stale values (e.g. legacy -1 rows). Reports how many rows were fixed in the API response.
This commit is contained in:
1 parent
305a0c42ff
commit
c95ad4a37f
2 files changed
+35
-3
No files matched your search
@@ -19,6 +19,7 @@ import {
|
|||||||
ensureDirectories,
|
ensureDirectories,
|
||||||
IMPORTED_PAGE_CAPTION_SAVE,
|
IMPORTED_PAGE_CAPTION_SAVE,
|
||||||
importSingleFurni,
|
importSingleFurni,
|
||||||
|
reconcileImportedOfferIds,
|
||||||
resetCatalogPageCache,
|
resetCatalogPageCache,
|
||||||
} from "@/lib/services/furni-import";
|
} from "@/lib/services/furni-import";
|
||||||
import { getOfficialHabboFurnidata } from "@/lib/services/habbo-furnidata-cache";
|
import { getOfficialHabboFurnidata } from "@/lib/services/habbo-furnidata-cache";
|
||||||
@@ -403,10 +404,19 @@ export const POST = withAdmin(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reconcile offer_id with the furnidata sprite id across the tree
|
||||||
|
const reconciled = await reconcileImportedOfferIds();
|
||||||
|
|
||||||
const succeeded = results.filter((r) => r.ok).length;
|
const succeeded = results.filter((r) => r.ok).length;
|
||||||
const failed = results.filter((r) => !r.ok).length;
|
const failed = results.filter((r) => !r.ok).length;
|
||||||
|
|
||||||
return apiOk({ batch: true, succeeded, failed, results });
|
return apiOk({
|
||||||
|
batch: true,
|
||||||
|
succeeded,
|
||||||
|
failed,
|
||||||
|
results,
|
||||||
|
offerIdsFixed: reconciled.fixed,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Single import ────────────────────────────────────────────────
|
// ── Single import ────────────────────────────────────────────────
|
||||||
@@ -455,6 +465,9 @@ export const POST = withAdmin(
|
|||||||
result.warnings.push("RCON cache refresh failed");
|
result.warnings.push("RCON cache refresh failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reconcile offer_id with the furnidata sprite id across the tree
|
||||||
|
const reconciled = await reconcileImportedOfferIds();
|
||||||
|
|
||||||
logAudit({
|
logAudit({
|
||||||
userId: ctx.session.user.id,
|
userId: ctx.session.user.id,
|
||||||
action: "furni_import",
|
action: "furni_import",
|
||||||
@@ -475,9 +488,9 @@ export const POST = withAdmin(
|
|||||||
return apiOk({
|
return apiOk({
|
||||||
id: result.itemId,
|
id: result.itemId,
|
||||||
catalogItemId: result.catalogItemId,
|
catalogItemId: result.catalogItemId,
|
||||||
dimensions: result.dimensions,
|
offerIdsFixed: reconciled.fixed,
|
||||||
spriteCount: result.spriteCount,
|
spriteCount: result.spriteCount,
|
||||||
warnings: result.warnings.length > 0 ? result.warnings : undefined,
|
warnings: result.warnings,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -284,6 +284,25 @@ export function resetCatalogPageCache(): void {
|
|||||||
categoryCacheTimestamp = 0;
|
categoryCacheTimestamp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walk every catalog item under the "Imported Furniture" tree and make its
|
||||||
|
* offer_id match the furnidata sprite id (item_ids). Fixes any stale values
|
||||||
|
* (e.g. legacy -1 rows) after an import.
|
||||||
|
*/
|
||||||
|
export async function reconcileImportedOfferIds(): Promise<{
|
||||||
|
fixed: number;
|
||||||
|
}> {
|
||||||
|
const parentId = await getOrCreateImportedParentPage();
|
||||||
|
const [result] = (await db.execute(sql`
|
||||||
|
UPDATE catalog_items ci
|
||||||
|
JOIN catalog_pages cp ON cp.id = ci.page_id
|
||||||
|
SET ci.offer_id = CAST(ci.item_ids AS UNSIGNED)
|
||||||
|
WHERE cp.parent_id = ${parentId}
|
||||||
|
AND ci.offer_id <> CAST(ci.item_ids AS UNSIGNED)
|
||||||
|
`)) as unknown as [Record<string, unknown>, unknown];
|
||||||
|
return { fixed: Number(result.affectedRows ?? 0) };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate the next `catalog_items.id` and run the INSERT through a
|
* Allocate the next `catalog_items.id` and run the INSERT through a
|
||||||
* process-level async mutex so concurrent imports in the same Node process
|
* process-level async mutex so concurrent imports in the same Node process
|
||||||
|
|||||||
Reference in new issue
Block a user