diff --git a/src/app/admin/import/audit/audit-client.tsx b/src/app/admin/import/audit/audit-client.tsx index 9d896fb1..d2bf0b17 100644 --- a/src/app/admin/import/audit/audit-client.tsx +++ b/src/app/admin/import/audit/audit-client.tsx @@ -48,6 +48,11 @@ interface AuditSummary { catalogSqlApplied: number; furniDataAdded: number; furniDataDuplicatesRemoved: number; + orphanedRemoved: number; + orphanedCleaned: number; + duplicatesMerged: number; + duplicateRowsRemoved: number; + remappedReferences: number; } interface RepairStats { @@ -73,6 +78,13 @@ interface AuditEvent { applied?: number; sqlFailed?: number; furniData?: { added: number; removedDuplicates: number }; + structure?: { + orphanedRemoved: number; + orphanedCleaned: number; + duplicatesMerged: number; + duplicateRowsRemoved: number; + remappedReferences: number; + }; } const TYPE_LABELS: Record = { @@ -131,6 +143,7 @@ export function AuditClient() { const [generateSql, setGenerateSql] = useState(false); const [applySql, setApplySql] = useState(false); const [repairFurniData, setRepairFurniData] = useState(false); + const [repairStructure, setRepairStructure] = useState(false); const [issues, setIssues] = useState([]); const [missingFromSources, setMissingFromSources] = useState< @@ -150,6 +163,13 @@ export function AuditClient() { added: number; removedDuplicates: number; } | null>(null); + const [structureResult, setStructureResult] = useState<{ + orphanedRemoved: number; + orphanedCleaned: number; + duplicatesMerged: number; + duplicateRowsRemoved: number; + remappedReferences: number; + } | null>(null); const [checkProgress, setCheckProgress] = useState<{ section: string; @@ -170,6 +190,7 @@ export function AuditClient() { setSqlText(null); setSqlApplied(null); setFurniDataResult(null); + setStructureResult(null); setCheckProgress(null); setActiveTab("issues"); @@ -187,6 +208,7 @@ export function AuditClient() { sql: generateSql || applySql, applySql, repairFurniData, + repairStructure, }), }); @@ -267,6 +289,10 @@ export function AuditClient() { if (evt.furniData) setFurniDataResult(evt.furniData); } + if (evt.type === "structure_repair_complete") { + if (evt.structure) setStructureResult(evt.structure); + } + if (evt.type === "batch_complete") { setIssues(evt.issues ?? []); setMissingFromSources(evt.missingFromSources ?? []); @@ -309,7 +335,14 @@ export function AuditClient() { setLoading(false); abortRef.current = null; } - }, [repairEnabled, repairNitros, generateSql, applySql, repairFurniData]); + }, [ + repairEnabled, + repairNitros, + generateSql, + applySql, + repairFurniData, + repairStructure, + ]); const errors = issues.filter((i) => i.severity === "error"); const warnings = issues.filter((i) => i.severity === "warning"); @@ -372,6 +405,13 @@ export function AuditClient() { > Repair FurnitureData.json (add missing + dedupe) + + Repair structural issues (orphaned refs + duplicates) + {loading && (