Files
inq-roi-simulador-web/src/features/report/TransparencySection.tsx

92 lines
3.9 KiB
TypeScript

import { AlertTriangle } from 'lucide-react'
import { formatPercent } from '@/lib/format'
import type { Activity } from '@/domain/types'
import type { RoiResult } from '@/domain/roi'
// Umbral de ROI a partir del cual se dispara la advertencia de verosimilitud.
// Un ROI > 1000% anual es matemáticamente posible pero comercialmente inverosímil:
// indica casi siempre un input incorrecto (frecuencia sobreestimada, costo auto subestimado
// o inversión subestimada). Documentado en METHODOLOGY_AUTOMATED_COST.md.
const ROI_HIGH_THRESHOLD = 1000
interface TransparencySectionProps {
activities: Activity[]
investment: number
roi?: RoiResult
}
export function TransparencySection({ activities, investment, roi }: TransparencySectionProps) {
const zeroCostAutomatable = activities.filter(
(a) => a.automatable && a.automatedCostFixed === 0 && a.automatedTimeMinutes === 0
)
const investmentIsZero = investment === 0
// Caso 4: ROI > 1000% finito (Infinity no aplica — ya lo cubre el caso de investment=0)
const roiIsUnusuallyHigh =
roi !== undefined &&
Number.isFinite(roi.roiAnnualPercent) &&
roi.roiAnnualPercent > ROI_HIGH_THRESHOLD
if (zeroCostAutomatable.length === 0 && !investmentIsZero && !roiIsUnusuallyHigh) return null
return (
<div className="rounded-xl border border-amber-200 bg-amber-50 p-5 space-y-3">
<div className="flex items-center gap-2">
<AlertTriangle className="h-4 w-4 text-amber-600 shrink-0" />
<h3 className="text-sm font-semibold text-amber-800">Transparencia metodológica</h3>
</div>
{zeroCostAutomatable.length > 0 && (
<div className="text-xs text-amber-700 leading-relaxed space-y-1.5">
<p className="font-medium">
{zeroCostAutomatable.length === 1
? '1 actividad automatizable sin costo configurado:'
: `${zeroCostAutomatable.length} actividades automatizables sin costo configurado:`}
</p>
<ul className="list-disc list-inside space-y-0.5 ml-1">
{zeroCostAutomatable.map((a) => (
<li key={a.id} className="font-mono">
{a.name || a.bpmnElementId}
</li>
))}
</ul>
<p className="text-amber-600">
Estas actividades se incluyen en el escenario automatizado con costo cero, lo que puede
inflar artificialmente el ahorro calculado. Configurá sus costos en el workspace para
un análisis realista.
</p>
</div>
)}
{investmentIsZero && (
<p className="text-xs text-amber-700 leading-relaxed">
<span className="font-medium">Inversión en automatización no configurada.</span>{' '}
El payback aparece como inmediato y el ROI como infinito porque no hay inversión inicial.
Configurá la inversión total en la tab &quot;Global&quot; del workspace para un análisis
financiero completo.
</p>
)}
{roiIsUnusuallyHigh && roi && (
<div className="text-xs text-amber-700 leading-relaxed space-y-1.5">
<p>
<span className="font-medium">
ROI inusualmente alto detectado: {formatPercent(roi.roiAnnualPercent)}.
</span>{' '}
Un ROI superior al {formatPercent(ROI_HIGH_THRESHOLD, 0)} anual suele indicar uno de estos casos:
</p>
<ul className="list-disc list-inside space-y-0.5 ml-1">
<li>Frecuencia anual del proceso sobreestimada</li>
<li>Costo automatizado por ejecución subestimado</li>
<li>Inversión en automatización subestimada</li>
</ul>
<p className="text-amber-600">
Revisá estos inputs antes de presentar el reporte al cliente.
Ver <span className="font-mono">METHODOLOGY_AUTOMATED_COST.md</span> para guía de estimación.
</p>
</div>
)}
</div>
)
}