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,
|
||||
IMPORTED_PAGE_CAPTION_SAVE,
|
||||
importSingleFurni,
|
||||
reconcileImportedOfferIds,
|
||||
resetCatalogPageCache,
|
||||
} from "@/lib/services/furni-import";
|
||||
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 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 ────────────────────────────────────────────────
|
||||
@@ -455,6 +465,9 @@ export const POST = withAdmin(
|
||||
result.warnings.push("RCON cache refresh failed");
|
||||
}
|
||||
|
||||
// Reconcile offer_id with the furnidata sprite id across the tree
|
||||
const reconciled = await reconcileImportedOfferIds();
|
||||
|
||||
logAudit({
|
||||
userId: ctx.session.user.id,
|
||||
action: "furni_import",
|
||||
@@ -475,9 +488,9 @@ export const POST = withAdmin(
|
||||
return apiOk({
|
||||
id: result.itemId,
|
||||
catalogItemId: result.catalogItemId,
|
||||
dimensions: result.dimensions,
|
||||
offerIdsFixed: reconciled.fixed,
|
||||
spriteCount: result.spriteCount,
|
||||
warnings: result.warnings.length > 0 ? result.warnings : undefined,
|
||||
warnings: result.warnings,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -284,6 +284,25 @@ export function resetCatalogPageCache(): void {
|
||||
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
|
||||
* process-level async mutex so concurrent imports in the same Node process
|
||||
|
||||
Reference in new issue
Block a user