From 3a292a44f1ebd08827ed9ff741aeb22b27b056d4 Mon Sep 17 00:00:00 2001 From: openhands Date: Mon, 24 Aug 2026 18:35:00 +0200 Subject: [PATCH] feat: make catalog-pages dedup a choosable step in Fix alles The maintenance "Fix alles" now has a checkbox to include or skip the duplicate catalog_pages merge, so admins can choose whether to run it. removeDuplicates takes an includePages flag and fixEverything threads it through to the action. --- src/actions/furni-maintenance.ts | 8 ++--- .../catalog/catalog-maintenance-panel.tsx | 34 +++++++++++++++++-- src/lib/services/furni-maintenance.ts | 14 +++++--- 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/actions/furni-maintenance.ts b/src/actions/furni-maintenance.ts index 26b34079..2cbea7ac 100644 --- a/src/actions/furni-maintenance.ts +++ b/src/actions/furni-maintenance.ts @@ -99,12 +99,12 @@ export async function applyAlignIdsAction(): Promise< } } -export async function fixEverythingAction(): Promise< - ActionResult -> { +export async function fixEverythingAction(input?: { + dedupePages?: boolean; +}): Promise> { try { await guard(); - return actionOk(await maintenance.fixEverything()); + return actionOk(await maintenance.fixEverything(input ?? {})); } catch (e) { return handleActionError(e); } diff --git a/src/components/admin/catalog/catalog-maintenance-panel.tsx b/src/components/admin/catalog/catalog-maintenance-panel.tsx index 34dacbd5..73b0d0c6 100644 --- a/src/components/admin/catalog/catalog-maintenance-panel.tsx +++ b/src/components/admin/catalog/catalog-maintenance-panel.tsx @@ -22,6 +22,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; +import { Checkbox } from "@/components/ui/checkbox"; interface Health { itemsBaseTotal: number; @@ -38,6 +39,7 @@ export function CatalogMaintenancePanel() { const [health, setHealth] = useState(null); const [loading, setLoading] = useState(true); const [busy, setBusy] = useState(null); + const [dedupePages, setDedupePages] = useState(true); const [alignPreview, setAlignPreview] = useState<{ moves: number; inserted: number; @@ -286,12 +288,38 @@ export function CatalogMaintenancePanel() { +
+ setDedupePages(v === true)} + /> + +
diff --git a/src/lib/services/furni-maintenance.ts b/src/lib/services/furni-maintenance.ts index c876d969..0538eabf 100644 --- a/src/lib/services/furni-maintenance.ts +++ b/src/lib/services/furni-maintenance.ts @@ -388,9 +388,13 @@ async function dedupCatalogTable(table: string): Promise { * product on the same page). The page merge runs before the row dedup so items * moved onto the survivor are still de-duplicated within the page afterwards. */ -export async function removeDuplicates(): Promise { +export async function removeDuplicates( + includePages = true, +): Promise { const ib = await removeDuplicateItemsBase(); - const pageDedup = await dedupeCatalogPages(); + const pageDedup = includePages + ? await dedupeCatalogPages() + : { groups: 0, removed: 0, remapped: 0 }; const catalogRemoved = await dedupCatalogTable("catalog_items"); const catalogBcRemoved = await dedupCatalogTable("catalog_items_bc"); return { @@ -630,12 +634,14 @@ export interface FixAllResult { } /** Run every repair in a sensible order, then return before/after health. */ -export async function fixEverything(): Promise { +export async function fixEverything( + opts: { dedupePages?: boolean } = {}, +): Promise { const healthBefore = await getFurniHealth(); const sprite = await fixSpriteIds(); const offers = await fixCatalogOffers(); const reconcile = await reconcileIds(); - const dedup = await removeDuplicates(); + const dedup = await removeDuplicates(opts.dedupePages ?? true); const align = await forceItemsBaseIdsToFurnidata(true); const healthAfter = await getFurniHealth(); return { healthBefore, sprite, offers, reconcile, dedup, align, healthAfter };