/** * DiffView — shows field-level diff between current rule and suggested_fix. * Only fields that differ are shown. * Red block = current value. Green block = suggested value. */ import React from 'react' const SKIP_FIELDS = ['conflict_with', 'suggested_fix', 'review_status'] function renderValue(val) { if (val === null || val === undefined) return 'null' if (typeof val === 'object') return JSON.stringify(val, null, 2) return String(val) } function getDiffedFields(current, suggested) { const allKeys = new Set([ ...Object.keys(current || {}), ...Object.keys(suggested || {}), ]) const diffs = [] for (const key of allKeys) { if (SKIP_FIELDS.includes(key)) continue const a = renderValue(current?.[key]) const b = renderValue(suggested?.[key]) if (a !== b) { diffs.push({ key, current: a, suggested: b }) } } return diffs } export default function DiffView({ currentRule, suggestedFix, explanation }) { if (!suggestedFix) return null const diffs = getDiffedFields(currentRule, suggestedFix) if (diffs.length === 0) { return (
Suggested fix has no field-level differences from the current rule.
) } return (
{/* Explanation */} {explanation && (
⚠ Conflict detected: {explanation}
)} {/* Field diffs */} {diffs.map(({ key, current, suggested }) => (

{key}

{/* Current (remove) */}
{current}
{/* Suggested (add) */}
+
{suggested}
))}
) }