feat: auto-repair sprite_id drift after every import
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 54s

The emulator sends items_base.sprite_id to the client and Nitro resolves
the furniture by looking up that id in FurnitureData.json. Legacy rows
where sprite_id drifted from the id made the client render a completely
different item (e.g. a wired or custom asset instead of the purchased
furniture).

Add verifyAndFixSpriteIds() which repairs any row whose sprite_id no
longer matches its id while the local furnidata carries the item under
that id, and run it after every import path (single, batch, batch-regen,
clone) next to the offer_id rebuild.
This commit is contained in:
openhands committed 2026-08-21 14:02:42 +02:00
1 parent 92b0ba3b18
commit 984b5bf793
5 files changed
+84

No files matched your search

+14
View File
@@ -12,6 +12,7 @@ import { getFurniAssetDirs } from "@/lib/services/furni-asset-dirs";
import {
rebuildCatalogOfferIds,
reconcileFurniDataWithItemsBase,
verifyAndFixSpriteIds,
} from "@/lib/services/furni-data";
import {
autoPriceFurni,
@@ -175,6 +176,7 @@ export const GET = withAdmin(
if (action === "live-reconcile") {
const furniReconcile = await reconcileFurniDataWithItemsBase();
const offerRebuild = await rebuildCatalogOfferIds();
const spriteVerify = await verifyAndFixSpriteIds();
return apiOk({
furniDataFixedIds: furniReconcile.fixedIds,
furniDataFixedOfferIds: furniReconcile.fixedOfferIds,
@@ -182,6 +184,8 @@ export const GET = withAdmin(
furniDataConflicts: furniReconcile.conflicts,
offerRebuildChecked: offerRebuild.checked,
offerRebuildFixed: offerRebuild.fixed,
spriteChecked: spriteVerify.checked,
spriteFixed: spriteVerify.fixed,
});
}
@@ -461,6 +465,9 @@ export const POST = withAdmin(
// Rebuild every catalog offer_id from the furnidata
const offerRebuild = await rebuildCatalogOfferIds();
// Repair any sprite_id drift so the client renders the right item
const spriteVerify = await verifyAndFixSpriteIds();
// Verify + fix interaction_modes_count once for the whole batch
const verification = await verifyAndFixInteractionModesCount();
@@ -482,6 +489,8 @@ export const POST = withAdmin(
furniDataConflicts: furniReconcile.conflicts,
offerRebuildChecked: offerRebuild.checked,
offerRebuildFixed: offerRebuild.fixed,
spriteChecked: spriteVerify.checked,
spriteFixed: spriteVerify.fixed,
interactionFixed: verification.fixed,
});
}
@@ -547,6 +556,9 @@ export const POST = withAdmin(
// Rebuild every catalog offer_id from the furnidata
const offerRebuild = await rebuildCatalogOfferIds();
// Repair any sprite_id drift so the client renders the right item
const spriteVerify = await verifyAndFixSpriteIds();
// Verify + fix interaction_modes_count (single consolidated pass)
const verification = await verifyAndFixInteractionModesCount();
@@ -580,6 +592,8 @@ export const POST = withAdmin(
furniDataConflicts: furniReconcile.conflicts,
offerRebuildChecked: offerRebuild.checked,
offerRebuildFixed: offerRebuild.fixed,
spriteChecked: spriteVerify.checked,
spriteFixed: spriteVerify.fixed,
interactionFixed: verification.fixed,
spriteCount: result.spriteCount,
warnings: result.warnings,