From c60a3bb226d06ecbf72cb009e667937d6230524b Mon Sep 17 00:00:00 2001 From: 134 Date: Tue, 7 Jul 2026 20:08:40 +0800 Subject: [PATCH] fix: stabilize product lock scale adjust uploads --- app/api/canvas/local-edit/route.ts | 68 ++++++++++++++++++++++++++++-- lib/storage/service.ts | 2 +- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/app/api/canvas/local-edit/route.ts b/app/api/canvas/local-edit/route.ts index a10e040e1..8b3a3ed73 100644 --- a/app/api/canvas/local-edit/route.ts +++ b/app/api/canvas/local-edit/route.ts @@ -3848,6 +3848,7 @@ async function buildScaleAdjustVisualLayoutGuideBuffer(params: { async function createScaleAdjustPatchReference(params: { fullFrameReferenceOnly?: boolean; + minimalProductLockMaskEditReferences?: boolean; regions: NormalizedLocalEditRegion[]; scalePercent?: ScaleAdjustPercent | null; sourceBuffer: Buffer; @@ -3886,6 +3887,58 @@ async function createScaleAdjustPatchReference(params: { const targetDraftBuffer = targetDraftReference.buffer; const suffix = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; if (params.fullFrameReferenceOnly && structureLockAppliedRef.value) { + if ( + params.minimalProductLockMaskEditReferences && + targetDraftReference.productLockOverlayBuffer && + targetDraftReference.productLockEditMaskBuffer + ) { + const sourceFullBuffer = await sharp(sourceBuffer, { failOn: "none" }) + .png({ compressionLevel: 6 }) + .toBuffer(); + const sourceFullUpload = await uploadFile( + `canvas-scale-adjust-source-full-${suffix}.png`, + toArrayBuffer(sourceFullBuffer) + ); + const productLockOverlayUpload = await uploadFile( + `canvas-scale-adjust-product-lock-overlay-${suffix}.png`, + toArrayBuffer(targetDraftReference.productLockOverlayBuffer) + ); + const productLockProtectMaskUpload = targetDraftReference.productLockProtectMaskBuffer + ? await uploadFile( + `canvas-scale-adjust-product-lock-protect-mask-${suffix}.png`, + toArrayBuffer(targetDraftReference.productLockProtectMaskBuffer) + ) + : null; + const productLockEditMaskUpload = await uploadFile( + `canvas-scale-adjust-product-lock-edit-mask-${suffix}.png`, + toArrayBuffer(targetDraftReference.productLockEditMaskBuffer) + ); + const productLockFalEditMaskUpload = targetDraftReference.productLockFalEditMaskBuffer + ? await uploadFile( + `canvas-scale-adjust-product-lock-fal-edit-mask-${suffix}.png`, + toArrayBuffer(targetDraftReference.productLockFalEditMaskBuffer) + ) + : null; + + return { + backgroundPlateFullUrl: null, + compositeClipMaskUrl: null, + productLockBackgroundRepairMaskUrl: null, + productLockMethod: "rmbg-cutout", + productLockEditMaskUrl: productLockEditMaskUpload.url, + productLockFalEditMaskUrl: productLockFalEditMaskUpload?.url || null, + productLockOverlayUrl: productLockOverlayUpload.url, + productLockProtectMaskUrl: productLockProtectMaskUpload?.url || null, + sourceCropUrl: sourceImageUrl || sourceFullUpload.url, + sourceFullUrl: sourceFullUpload.url, + structureLockedDraft: structureLockAppliedRef.value, + targetDraftFullUrl: sourceImageUrl || sourceFullUpload.url, + targetDraftUrl: sourceImageUrl || sourceFullUpload.url, + workspacePixelRect, + workspaceRect, + }; + } + const [ sourceFullUpload, targetDraftFullUpload, @@ -5415,6 +5468,12 @@ export async function POST(request: NextRequest) { regions.some((region) => isScaleAdjustFurnitureProductLikePrompt(region.prompt) ), + minimalProductLockMaskEditReferences: + useScaleAdjustStructureLockedPatchWorkflow && + isScaleAdjustMaskCapableModel(resolvedScaleAdjustModelEntry) && + regions.some((region) => + isScaleAdjustFurnitureProductLikePrompt(region.prompt) + ), userId: session.user.id, }); } catch (error) { @@ -5461,14 +5520,17 @@ export async function POST(request: NextRequest) { regions.some((region) => isScaleAdjustFurnitureProductLikePrompt(region.prompt) ); - const useScaleAdjustProductLockComposite = + const useScaleAdjustProductLockBase = useScaleAdjustFullFrameStructurePatch && - Boolean(scaleAdjustPatchReference?.backgroundPlateFullUrl) && Boolean(scaleAdjustPatchReference?.productLockOverlayUrl); const useScaleAdjustProductLockMaskEdit = - useScaleAdjustProductLockComposite && + useScaleAdjustProductLockBase && isScaleAdjustMaskCapableModel(resolvedScaleAdjustModelEntry) && Boolean(scaleAdjustPatchReference?.productLockEditMaskUrl); + const useScaleAdjustProductLockComposite = + useScaleAdjustProductLockBase && + (Boolean(scaleAdjustPatchReference?.backgroundPlateFullUrl) || + useScaleAdjustProductLockMaskEdit); const useScaleAdjustProductLockGuidedFinal = useScaleAdjustProductLockComposite && !useScaleAdjustProductLockMaskEdit && diff --git a/lib/storage/service.ts b/lib/storage/service.ts index 6e3b130c9..5f5a32152 100644 --- a/lib/storage/service.ts +++ b/lib/storage/service.ts @@ -45,7 +45,7 @@ export type StorageUploadFunction = ( let lastKnownGoodDbS3Config: S3UploadConfig | null = null; const STORAGE_FAILOVER_CONFIG_KEY = "storage_failover_config"; -const DEFAULT_S3_REQUEST_TIMEOUT_MS = 30_000; +const DEFAULT_S3_REQUEST_TIMEOUT_MS = 90_000; function getStorageTimeoutMs(name: string, fallback: number, min: number, max: number) { const parsed = Number(process.env[name]);