diff --git a/frontend/src/admin/DraftQueue.tsx b/frontend/src/admin/DraftQueue.tsx index 96f729e..07d65c5 100644 --- a/frontend/src/admin/DraftQueue.tsx +++ b/frontend/src/admin/DraftQueue.tsx @@ -42,6 +42,16 @@ function priceLabel(source: PriceSource): string { * * The label is the state. `original_image_path` is the only thing consulted, * so there is no second flag that could disagree with what the button does. + * + * `enabled` is computed by the caller as `backgroundRemoval || cutOut`, not as + * `backgroundRemoval` alone. The two branches this button offers need opposite + * things: removing calls the sidecar and has nothing to do without one, but + * restoring is a pure database swap that needs no sidecar at all. Gating both + * on `backgroundRemoval` hides Restore the moment REMBG_URL is unset — which + * happens for real when the sidecar is decommissioned after photos were + * already cut out — leaving a cut-out photo with no control and no way back to + * the original short of hand-editing the database. That breaks the invariant + * this whole feature rests on: the original is always restorable. */ function DraftPhoto({ image, @@ -148,7 +158,7 @@ function DraftCard({ key={image.id} image={image} itemId={draft.item_id} - enabled={backgroundRemoval} + enabled={backgroundRemoval || image.original_image_path !== null} onChanged={onChanged} /> ))} diff --git a/frontend/src/admin/draftsApi.ts b/frontend/src/admin/draftsApi.ts index aaa3555..b5a5eaa 100644 --- a/frontend/src/admin/draftsApi.ts +++ b/frontend/src/admin/draftsApi.ts @@ -41,8 +41,11 @@ export interface DraftQueueResponse { drafts: Draft[]; /** * Whether a background-removal sidecar is configured. False hides the - * control rather than showing one that would answer 502 — an environment - * without a sidecar is a working environment. + * remove-background control rather than showing one that would answer 502 + * — an environment without a sidecar is a working environment. It does + * *not* hide Restore original: that endpoint is a pure database swap and + * needs no sidecar, so DraftQueue shows it whenever a photo has an + * original to restore, regardless of this flag. */ backgroundRemoval: boolean; }