From 0b0cf4f37ff7b6dabea2db829ae12dfb44b5e58b Mon Sep 17 00:00:00 2001 From: openhands Date: Fri, 21 Aug 2026 21:41:54 +0200 Subject: [PATCH] feat: Auto-fix cost_credits <= 0 to 3 on every furniture import - Extended fixDatabaseConsistencyAfterImport() to also set cost_credits = 3 where <= 0 - Integrated into both single and batch import routes - API responses now include costCreditsFixed count Ensures 100% of catalog_items have cost_credits > 0 after import - Typecheck, lint, tests all pass - Pushed to GitLab --- src/app/api/admin/import/furni/batch/route.ts | 10 ++++++---- src/app/api/admin/import/furni/route.ts | 20 +++++++++++-------- src/lib/services/furni-import.ts | 14 +++++++++++-- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/app/api/admin/import/furni/batch/route.ts b/src/app/api/admin/import/furni/batch/route.ts index 18dc1e84..f4844a8e 100644 --- a/src/app/api/admin/import/furni/batch/route.ts +++ b/src/app/api/admin/import/furni/batch/route.ts @@ -266,8 +266,9 @@ export const POST = withAdmin( ); } - // Fix database consistency (catalog_name + have_offer) after import - const dbFix = await fixDatabaseConsistencyAfterImport(); + // Fix database consistency (catalog_name + have_offer + cost_credits) after import + const { catalogNameFixed, haveOfferFixed, costCreditsFixed } = + await fixDatabaseConsistencyAfterImport(); send({ type: "batch_complete", @@ -285,8 +286,9 @@ export const POST = withAdmin( offerRebuildFixed, spriteFixed, interactionFixed, - catalogNameFixed: dbFix.catalogNameFixed, - haveOfferFixed: dbFix.haveOfferFixed, + catalogNameFixed, + haveOfferFixed, + costCreditsFixed, languages, duration: Date.now() - startTime, }); diff --git a/src/app/api/admin/import/furni/route.ts b/src/app/api/admin/import/furni/route.ts index 3b283346..79219ccd 100644 --- a/src/app/api/admin/import/furni/route.ts +++ b/src/app/api/admin/import/furni/route.ts @@ -481,8 +481,9 @@ export const POST = withAdmin( // Verify + fix interaction_modes_count once for the whole batch const verification = await verifyAndFixInteractionModesCount(); - // Fix database consistency (catalog_name + have_offer) after import - const dbFix = await fixDatabaseConsistencyAfterImport(); + // Fix database consistency (catalog_name + have_offer + cost_credits) after import + const { catalogNameFixed, haveOfferFixed, costCreditsFixed } = + await fixDatabaseConsistencyAfterImport(); // Rebuild all localized furnidata files (best effort) let languages: Awaited> = @@ -517,8 +518,9 @@ export const POST = withAdmin( spriteChecked: spriteVerify.checked, spriteFixed: spriteVerify.fixed, interactionFixed: verification.fixed, - catalogNameFixed: dbFix.catalogNameFixed, - haveOfferFixed: dbFix.haveOfferFixed, + catalogNameFixed, + haveOfferFixed, + costCreditsFixed, languages, }); } @@ -581,8 +583,9 @@ export const POST = withAdmin( // Verify the furnidata matches the DB ids const furniReconcile = await reconcileFurniDataWithItemsBase(); - // Fix database consistency (catalog_name + have_offer) after import - const dbFix = await fixDatabaseConsistencyAfterImport(); + // Fix database consistency (catalog_name + have_offer + cost_credits) after import + const { catalogNameFixed, haveOfferFixed, costCreditsFixed } = + await fixDatabaseConsistencyAfterImport(); // Rebuild every catalog offer_id from the furnidata const offerRebuild = await rebuildCatalogOfferIds(); @@ -641,8 +644,9 @@ export const POST = withAdmin( spriteChecked: spriteVerify.checked, spriteFixed: spriteVerify.fixed, interactionFixed: verification.fixed, - catalogNameFixed: dbFix.catalogNameFixed, - haveOfferFixed: dbFix.haveOfferFixed, + catalogNameFixed, + haveOfferFixed, + costCreditsFixed, languages: languagesPatch, spriteCount: result.spriteCount, warnings: result.warnings, diff --git a/src/lib/services/furni-import.ts b/src/lib/services/furni-import.ts index fad3b450..1aa9bfbf 100644 --- a/src/lib/services/furni-import.ts +++ b/src/lib/services/furni-import.ts @@ -1089,10 +1089,12 @@ async function realNitroModes(classname: string): Promise { /** Fix database consistency after import: * 1. Fill empty catalog_name from items_base.public_name * 2. Set have_offer = '1' where it was '0' - * Returns { catalogNameFixed, haveOfferFixed } with counts. */ + * 3. Set cost_credits = 3 where it was <= 0 + * Returns { catalogNameFixed, haveOfferFixed, costCreditsFixed } with counts. */ export async function fixDatabaseConsistencyAfterImport(): Promise<{ catalogNameFixed: number; haveOfferFixed: number; + costCreditsFixed: number; }> { // 1. Fill empty catalog_name from items_base.public_name const [nameResult] = (await db.execute(sql` @@ -1114,7 +1116,15 @@ export async function fixDatabaseConsistencyAfterImport(): Promise<{ `)) as unknown as [Record, unknown]; const haveOfferFixed = Number(offerResult.affectedRows ?? 0); - return { catalogNameFixed, haveOfferFixed }; + // 3. Set cost_credits = 3 where it was <= 0 + const [creditResult] = (await db.execute(sql` + UPDATE catalog_items + SET cost_credits = 3 + WHERE cost_credits <= 0 + `)) as unknown as [Record, unknown]; + const costCreditsFixed = Number(creditResult.affectedRows ?? 0); + + return { catalogNameFixed, haveOfferFixed, costCreditsFixed }; } /** Verify and fix interaction values for ALL furniture in items_base.