Files
policy-ui/app/data/mock-renewals.ts
Jordan Weingarten 67482f6629 WIP jordan
2026-04-16 11:11:44 -05:00

661 lines
38 KiB
TypeScript

// ═══════════════════════════════════════════════════════════════════════════════
// RENEWALS — Data Layer
// ═══════════════════════════════════════════════════════════════════════════════
// --- Carrier Status ---
export type CarrierRenewalStatus =
| 'pending'
| 'terms_received'
| 'remarketing'
| 'bound'
| 'declined'
| 'lapsed'
// --- Broker Workflow Status ---
export type BrokerRenewalStatus =
| 'unreviewed'
| 'under_review'
| 'proposal_sent'
| 'awaiting_client_response'
| 'awaiting_payment'
| 'closed_renewed'
| 'closed_remarketed'
| 'closed_cancelled'
| 'not_renewing'
export type RenewalPriority = 'critical' | 'high' | 'medium' | 'low'
export type RetentionRisk = 'high' | 'medium' | 'low'
export type CancellationReason =
| 'price'
| 'service'
| 'competitor'
| 'coverage_gap'
| 'business_closed'
| 'non_payment'
| 'carrier_declined'
| 'other'
export interface CancellationData {
reason: CancellationReason
reasonDetail: string | null
competitor: string | null
competitorPremium: number | null
recoverable: boolean
exitDate: string
}
export interface RenewalTask {
id: string
title: string
type: 'review' | 'send_proposal' | 'follow_up' | 'collect_payment' | 'escalation'
status: 'open' | 'in_progress' | 'overdue' | 'done'
assignee: string
dueDate: string
aiGenerated: boolean
slaPercent: number
}
export interface RenewalCommunication {
id: string
type: 'email' | 'call' | 'note' | 'system'
direction: 'inbound' | 'outbound' | 'internal'
from: string
to: string | null
subject: string | null
body: string
aiDigest: string | null
templateUsed: string | null
timestamp: string
partyRole: string
}
export interface RenewalDocument {
id: string
name: string
category: 'current_policy' | 'renewal_terms' | 'proposal_sent' |
'client_confirmation' | 'payment_receipt' | 'loss_runs' |
'correspondence' | 'cancellation'
uploadedBy: string
uploadedAt: string
required: boolean
fulfilled: boolean
}
export interface RenewalParty {
id: string
role: 'insured' | 'carrier_rep' | 'producer' | 'handler' | 'ai_agent'
name: string
company: string | null
phone: string | null
email: string | null
hasUnread: boolean
}
export interface RenewalQuote {
id: string
carrier: string
premium: number
currency: 'USD' | 'CRC'
coverageAmount: number
deductible: number
receivedAt: string
recommended: boolean
notes: string | null
}
export interface CoverageLine {
name: string
currentAmount: number | string
renewalAmount: number | string | null
delta: string | null
flag: 'increase' | 'decrease' | 'same' | 'new' | 'removed' | null
}
export interface PolicyComparison {
currentPremium: number
renewalPremium: number | null
premiumDelta: number | null
currentDeductible: number
renewalDeductible: number | null
deductibleDelta: number | null
coverageLines: CoverageLine[]
aiAnalysis: string | null
}
export interface EmailTemplate {
id: string
name: string
subject: string
body: string
stage: BrokerRenewalStatus
lob: string | 'all'
isDefault: boolean
}
export interface RenewalHistoryEntry {
year: number
carrier: string
premium: number
outcome: 'renewed' | 'remarketed' | 'cancelled' | 'new'
}
// --- List item ---
export interface Renewal {
id: string
policyId: string
policyNumber: string
customerId: string
customerName: string
customerType: 'individual' | 'corporate'
carrier: string
lob: string
currentPremium: number
renewalPremium: number | null
premiumDelta: number | null
currency: 'USD' | 'CRC'
expiryDate: string
daysUntilExpiry: number
carrierStatus: CarrierRenewalStatus
brokerStatus: BrokerRenewalStatus
priority: RenewalPriority
retentionRisk: RetentionRisk
lossRatio: number
yearsAsClient: number
openClaims: number
assignedTo: string
lastContactDate: string | null
slaPercent: number
outstandingBalance: number
paymentStatus: 'current' | 'overdue' | 'grace_period'
}
// --- Detail ---
export interface RenewalDetail extends Renewal {
claimIds: string[]
parties: RenewalParty[]
tasks: RenewalTask[]
communications: RenewalCommunication[]
documents: RenewalDocument[]
comparison: PolicyComparison | null
quotes: RenewalQuote[]
renewalHistory: RenewalHistoryEntry[]
cancellationData: CancellationData | null
commissionRate: number
commissionAmount: number
aiRenewalBrief: string | null
aiTalkTrack: string[] | null
aiRetentionFactors: string[] | null
}
// ═══════════════════════════════════════════════════════════════════════════════
// Label Maps
// ═══════════════════════════════════════════════════════════════════════════════
export const carrierStatusLabels: Record<CarrierRenewalStatus, string> = {
pending: 'Pendiente',
terms_received: 'Términos Recibidos',
remarketing: 'En Remarketing',
bound: 'Vinculada',
declined: 'Declinada',
lapsed: 'Vencida',
}
export const brokerStatusLabels: Record<BrokerRenewalStatus, string> = {
unreviewed: 'Sin Revisar',
under_review: 'En Revisión',
proposal_sent: 'Propuesta Enviada',
awaiting_client_response: 'Esperando Cliente',
awaiting_payment: 'Esperando Pago',
closed_renewed: 'Renovada',
closed_remarketed: 'Remarketing Exitoso',
closed_cancelled: 'Cancelada',
not_renewing: 'No Renueva',
}
export const priorityLabels: Record<RenewalPriority, string> = {
critical: 'Crítica',
high: 'Alta',
medium: 'Media',
low: 'Baja',
}
export const retentionRiskLabels: Record<RetentionRisk, string> = {
high: 'Alto',
medium: 'Medio',
low: 'Bajo',
}
export const cancellationReasonLabels: Record<CancellationReason, string> = {
price: 'Precio',
service: 'Servicio',
competitor: 'Competencia',
coverage_gap: 'Cobertura insuficiente',
business_closed: 'Cierre de negocio',
non_payment: 'Falta de pago',
carrier_declined: 'Aseguradora declinó',
other: 'Otro',
}
export const expiryBuckets = {
expired: { label: 'Vencidas', min: -Infinity, max: -1 },
this_week: { label: 'Esta semana', min: 0, max: 7 },
thirty_days: { label: '30 días', min: 8, max: 30 },
sixty_days: { label: '60 días', min: 31, max: 60 },
ninety_days: { label: '90 días', min: 61, max: 90 },
future: { label: '90+ días', min: 91, max: Infinity },
}
export const templateMergeFields = [
'{{customer_name}}', '{{policy_number}}', '{{lob}}', '{{carrier}}',
'{{current_premium}}', '{{renewal_premium}}', '{{premium_delta}}',
'{{expiry_date}}', '{{coverage_amount}}', '{{deductible}}',
'{{producer_name}}', '{{producer_phone}}', '{{producer_email}}',
'{{company_name}}', '{{loss_ratio}}', '{{years_as_client}}',
]
// ═══════════════════════════════════════════════════════════════════════════════
// Helpers
// ═══════════════════════════════════════════════════════════════════════════════
export function slaColor(percent: number): 'green' | 'amber' | 'red' {
if (percent >= 100) return 'red'
if (percent >= 75) return 'amber'
return 'green'
}
export function expiryBucket(days: number): string {
for (const [key, b] of Object.entries(expiryBuckets)) {
if (days >= b.min && days <= b.max) return key
}
return 'future'
}
// ═══════════════════════════════════════════════════════════════════════════════
// Mock Email Templates
// ═══════════════════════════════════════════════════════════════════════════════
export const MOCK_EMAIL_TEMPLATES: EmailTemplate[] = [
{
id: 'tpl-1', name: 'Aviso de Renovación', stage: 'under_review', lob: 'all', isDefault: true,
subject: 'Su póliza {{policy_number}} próxima a vencer',
body: 'Estimado/a {{customer_name}},\n\nLe informamos que su póliza {{policy_number}} de {{lob}} con {{carrier}} vence el {{expiry_date}}.\n\nPrima actual: {{current_premium}}\n\nNos pondremos en contacto próximamente con los términos de renovación.\n\nSaludos cordiales,\n{{producer_name}}',
},
{
id: 'tpl-2', name: 'Propuesta de Renovación', stage: 'proposal_sent', lob: 'all', isDefault: true,
subject: 'Términos de renovación — {{policy_number}}',
body: 'Estimado/a {{customer_name}},\n\nAdjunto los términos de renovación para su póliza {{policy_number}}:\n\n• Prima actual: {{current_premium}}\n• Prima renovación: {{renewal_premium}} ({{premium_delta}})\n• Cobertura: {{coverage_amount}}\n• Deducible: {{deductible}}\n\nPor favor confirme si desea proceder con la renovación.\n\nQuedamos atentos,\n{{producer_name}}\n{{producer_phone}}',
},
{
id: 'tpl-3', name: 'Seguimiento #1', stage: 'awaiting_client_response', lob: 'all', isDefault: true,
subject: 'Recordatorio: renovación de póliza {{policy_number}}',
body: 'Estimado/a {{customer_name}},\n\nLe recordamos que estamos a la espera de su confirmación para renovar la póliza {{policy_number}} que vence el {{expiry_date}}.\n\nPor favor responda a este correo o comuníquese al {{producer_phone}} para evitar cualquier lapso en su cobertura.\n\nSaludos,\n{{producer_name}}',
},
{
id: 'tpl-4', name: 'Seguimiento #2', stage: 'awaiting_client_response', lob: 'all', isDefault: true,
subject: 'Segundo aviso: su póliza {{policy_number}} vence el {{expiry_date}}',
body: 'Estimado/a {{customer_name}},\n\nEste es un segundo aviso sobre la renovación de su póliza {{policy_number}}. La fecha de vencimiento es {{expiry_date}} y necesitamos su confirmación a la brevedad posible.\n\nSin su confirmación, la póliza podría vencer sin renovación, dejándole sin cobertura.\n\nPor favor contáctenos de inmediato.\n\n{{producer_name}}\n{{producer_email}} | {{producer_phone}}',
},
{
id: 'tpl-5', name: 'Confirmación de Pago', stage: 'awaiting_payment', lob: 'all', isDefault: true,
subject: 'Pago pendiente — renovación {{policy_number}}',
body: 'Estimado/a {{customer_name}},\n\nGracias por confirmar la renovación de su póliza {{policy_number}}.\n\nPara completar el proceso, le solicitamos realizar el pago de {{renewal_premium}} a la brevedad.\n\nUna vez recibido el pago, procederemos con la emisión de su nueva póliza.\n\nSaludos,\n{{producer_name}}',
},
{
id: 'tpl-6', name: 'Renovación Completada', stage: 'closed_renewed', lob: 'all', isDefault: true,
subject: 'Confirmación de renovación — {{policy_number}}',
body: 'Estimado/a {{customer_name}},\n\nNos complace confirmar que su póliza {{policy_number}} ha sido renovada exitosamente con {{carrier}}.\n\nNueva vigencia: {{expiry_date}}\nPrima: {{renewal_premium}}\n\nAdjunto encontrará su nueva póliza. No dude en contactarnos para cualquier consulta.\n\nGracias por su confianza,\n{{producer_name}}\n{{company_name}}',
},
]
// ═══════════════════════════════════════════════════════════════════════════════
// Mock Renewals (Pipeline List)
// ═══════════════════════════════════════════════════════════════════════════════
export const MOCK_RENEWALS: Renewal[] = [
{
id: 'REN-001', policyId: 'POL-0955', policyNumber: 'PROP-2024-HP-001',
customerId: 'CUS-001', customerName: 'Hotel Pacífico Resort', customerType: 'corporate',
carrier: 'ASSA', lob: 'Auto', currentPremium: 18500, renewalPremium: 22570,
premiumDelta: 22, currency: 'USD', expiryDate: '2026-04-11', daysUntilExpiry: 3,
carrierStatus: 'terms_received', brokerStatus: 'awaiting_client_response',
priority: 'critical', retentionRisk: 'high', lossRatio: 0.42, yearsAsClient: 5,
openClaims: 1, assignedTo: 'Marco V.', lastContactDate: '2026-04-03',
slaPercent: 95, outstandingBalance: 0, paymentStatus: 'current',
},
{
id: 'REN-002', policyId: 'POL-1034', policyNumber: 'GR-2024-CM-001',
customerId: 'CUS-002', customerName: 'Constructora Montes', customerType: 'corporate',
carrier: 'Mapfre', lob: 'General Risk', currentPremium: 32000, renewalPremium: null,
premiumDelta: null, currency: 'USD', expiryDate: '2026-04-22', daysUntilExpiry: 14,
carrierStatus: 'pending', brokerStatus: 'under_review',
priority: 'high', retentionRisk: 'medium', lossRatio: 0.15, yearsAsClient: 3,
openClaims: 0, assignedTo: 'Ana R.', lastContactDate: '2026-04-01',
slaPercent: 55, outstandingBalance: 0, paymentStatus: 'current',
},
{
id: 'REN-003', policyId: 'POL-1077', policyNumber: 'LIFE-2024-CR-001',
customerId: 'CUS-003', customerName: 'Carmen Ruiz', customerType: 'individual',
carrier: 'Pan-American Life', lob: 'Life', currentPremium: 2800, renewalPremium: 2940,
premiumDelta: 5, currency: 'USD', expiryDate: '2026-04-15', daysUntilExpiry: 7,
carrierStatus: 'terms_received', brokerStatus: 'awaiting_payment',
priority: 'medium', retentionRisk: 'low', lossRatio: 0, yearsAsClient: 8,
openClaims: 0, assignedTo: 'Ana R.', lastContactDate: '2026-04-06',
slaPercent: 30, outstandingBalance: 0, paymentStatus: 'current',
},
{
id: 'REN-004', policyId: 'POL-1110', policyNumber: 'AUTO-2024-ABC-001',
customerId: 'CUS-004', customerName: 'Empresa ABC S.A.', customerType: 'corporate',
carrier: 'Qualitas', lob: 'Auto', currentPremium: 22400, renewalPremium: null,
premiumDelta: null, currency: 'USD', expiryDate: '2026-05-08', daysUntilExpiry: 30,
carrierStatus: 'pending', brokerStatus: 'unreviewed',
priority: 'low', retentionRisk: 'low', lossRatio: 0.08, yearsAsClient: 2,
openClaims: 0, assignedTo: 'Unassigned', lastContactDate: null,
slaPercent: 10, outstandingBalance: 0, paymentStatus: 'current',
},
{
id: 'REN-005', policyId: 'POL-0888', policyNumber: 'HEALTH-2024-CSJ-001',
customerId: 'CUS-005', customerName: 'Clínica San José', customerType: 'corporate',
carrier: 'ASSA', lob: 'Health', currentPremium: 45000, renewalPremium: null,
premiumDelta: null, currency: 'USD', expiryDate: '2026-04-01', daysUntilExpiry: -7,
carrierStatus: 'lapsed', brokerStatus: 'closed_cancelled',
priority: 'high', retentionRisk: 'high', lossRatio: 0.65, yearsAsClient: 4,
openClaims: 0, assignedTo: 'Marco V.', lastContactDate: '2026-03-28',
slaPercent: 100, outstandingBalance: 8500, paymentStatus: 'overdue',
},
{
id: 'REN-006', policyId: 'POL-1200', policyNumber: 'GR-2024-TN-001',
customerId: 'CUS-006', customerName: 'Transportes del Norte', customerType: 'corporate',
carrier: 'ASSA', lob: 'General Risk', currentPremium: 38000, renewalPremium: null,
premiumDelta: null, currency: 'USD', expiryDate: '2026-06-07', daysUntilExpiry: 60,
carrierStatus: 'pending', brokerStatus: 'unreviewed',
priority: 'high', retentionRisk: 'high', lossRatio: 0.55, yearsAsClient: 6,
openClaims: 1, assignedTo: 'Unassigned', lastContactDate: null,
slaPercent: 15, outstandingBalance: 21000, paymentStatus: 'overdue',
},
]
// ═══════════════════════════════════════════════════════════════════════════════
// Mock Renewal Details
// ═══════════════════════════════════════════════════════════════════════════════
const ren001Detail: RenewalDetail = {
...MOCK_RENEWALS[0],
claimIds: ['CLM-0048'],
parties: [
{ id: 'rp-1', role: 'insured', name: 'Carlos Montero', company: 'Hotel Pacífico Resort', phone: '+507 6700-1234', email: 'cmontero@hotelpacífico.com', hasUnread: true },
{ id: 'rp-2', role: 'carrier_rep', name: 'Lucía Vargas', company: 'ASSA', phone: '+507 6600-9876', email: 'lvargas@assa.com', hasUnread: false },
{ id: 'rp-3', role: 'handler', name: 'Marco V.', company: null, phone: null, email: 'marco@segur-os.com', hasUnread: false },
],
tasks: [
{ id: 'rt-1', title: 'Follow up with client — no response in 5 days', type: 'follow_up', status: 'overdue', assignee: 'Marco V.', dueDate: '2026-04-06', aiGenerated: true, slaPercent: 110 },
{ id: 'rt-2', title: 'Prepare counter-proposal (premium increase justification)', type: 'send_proposal', status: 'open', assignee: 'Marco V.', dueDate: '2026-04-09', aiGenerated: false, slaPercent: 80 },
{ id: 'rt-3', title: 'Review loss runs before presenting to client', type: 'review', status: 'done', assignee: 'Marco V.', dueDate: '2026-04-02', aiGenerated: false, slaPercent: 20 },
],
communications: [
{ id: 'rc-1', type: 'email', direction: 'outbound', from: 'Marco V.', to: 'Carlos Montero', subject: 'Términos de renovación — PROP-2024-HP-001', body: 'Estimado Carlos, adjunto los términos de renovación de su póliza de auto. La prima pasa de $18,500 a $22,570 (+22%) debido al reclamo abierto y al ajuste de mercado. Quedo atento a su respuesta.', aiDigest: null, templateUsed: 'tpl-2', timestamp: '2026-04-03T10:30:00', partyRole: 'insured' },
{ id: 'rc-2', type: 'email', direction: 'inbound', from: 'Lucía Vargas', to: 'Marco V.', subject: 'RE: Renewal terms HP-001', body: 'Marco, adjunto los términos definitivos para Hotel Pacífico. El aumento refleja el siniestro abierto CLM-0048 y el ajuste de tarifa general para flota comercial.', aiDigest: 'ASSA confirma aumento de 22% justificado por siniestro abierto y ajuste de tarifa.', templateUsed: null, timestamp: '2026-04-02T15:45:00', partyRole: 'carrier_rep' },
{ id: 'rc-3', type: 'note', direction: 'internal', from: 'Marco V.', to: null, subject: null, body: 'Client not responding to emails. Called twice, went to voicemail. Need to escalate if no response by Apr 8.', aiDigest: null, templateUsed: null, timestamp: '2026-04-06T09:00:00', partyRole: 'handler' },
{ id: 'rc-4', type: 'system', direction: 'internal', from: 'System', to: null, subject: null, body: 'AI escalation: Client non-response exceeds 5 days. Recommended action: send Seguimiento #1 template.', aiDigest: null, templateUsed: null, timestamp: '2026-04-08T08:00:00', partyRole: 'ai_agent' },
],
documents: [
{ id: 'rd-1', name: 'Póliza actual — PROP-2024-HP-001.pdf', category: 'current_policy', uploadedBy: 'System', uploadedAt: '2026-03-01', required: true, fulfilled: true },
{ id: 'rd-2', name: 'Términos renovación ASSA 2026.pdf', category: 'renewal_terms', uploadedBy: 'Lucía Vargas', uploadedAt: '2026-04-02', required: true, fulfilled: true },
{ id: 'rd-3', name: 'Propuesta enviada a cliente.pdf', category: 'proposal_sent', uploadedBy: 'Marco V.', uploadedAt: '2026-04-03', required: true, fulfilled: true },
{ id: 'rd-4', name: 'Loss runs 2023-2025.pdf', category: 'loss_runs', uploadedBy: 'ASSA', uploadedAt: '2026-04-01', required: true, fulfilled: true },
{ id: 'rd-5', name: 'Client confirmation', category: 'client_confirmation', uploadedBy: '', uploadedAt: '', required: true, fulfilled: false },
{ id: 'rd-6', name: 'Payment receipt', category: 'payment_receipt', uploadedBy: '', uploadedAt: '', required: true, fulfilled: false },
],
comparison: {
currentPremium: 18500, renewalPremium: 22570, premiumDelta: 22,
currentDeductible: 500, renewalDeductible: 750, deductibleDelta: 50,
coverageLines: [
{ name: 'Responsabilidad Civil', currentAmount: 100000, renewalAmount: 100000, delta: '=', flag: 'same' },
{ name: 'Daños Propios', currentAmount: 45000, renewalAmount: 45000, delta: '=', flag: 'same' },
{ name: 'Robo Total', currentAmount: 45000, renewalAmount: 40000, delta: '-11%', flag: 'decrease' },
{ name: 'Asistencia Vial', currentAmount: 'Incluida', renewalAmount: 'Incluida', delta: '=', flag: 'same' },
{ name: 'Vidrios', currentAmount: 2000, renewalAmount: 2500, delta: '+25%', flag: 'increase' },
],
aiAnalysis: 'El aumento de 22% se justifica por el siniestro abierto CLM-0048 ($128K reservado) y el ajuste de tarifa general de ASSA para flotas comerciales (+8% promedio). El deducible subió 50%. La cobertura de Robo Total baja 11% — recomendar al cliente mantener nivel actual. Se detecta oportunidad de negociar Vidrios si se acepta deducible mayor.',
},
quotes: [],
renewalHistory: [
{ year: 2025, carrier: 'ASSA', premium: 18500, outcome: 'renewed' },
{ year: 2024, carrier: 'ASSA', premium: 16200, outcome: 'renewed' },
{ year: 2023, carrier: 'Qualitas', premium: 15800, outcome: 'remarketed' },
{ year: 2022, carrier: 'Qualitas', premium: 14500, outcome: 'renewed' },
],
cancellationData: null,
commissionRate: 15, commissionAmount: 3385.50,
aiRenewalBrief: 'Hotel Pacífico es un cliente corporativo de 5 años con prima actual de $18,500 en Auto. ASSA ofrece renovación a $22,570 (+22%), justificado por siniestro abierto CLM-0048 con $128K reservados y ajuste de tarifa de flota. El cliente no ha respondido en 5 días. El deducible sube de $500 a $750. Loss ratio de 42% está por encima del promedio para esta línea. Comisión proyectada: $3,385. Riesgo de retención ALTO.',
aiTalkTrack: [
'Abrir con empatía: reconocer que un aumento de 22% es significativo y que entendemos su preocupación.',
'Explicar el contexto: el siniestro abierto impacta directamente la tarificación. ASSA subió tarifas de flota 8% en general.',
'Destacar valor: 5 años como cliente, historial mayormente limpio. Hemos negociado mantener la cobertura de RC en $100K sin cambio.',
'Proponer alternativa: si acepta deducible de $1,000 en vez de $750, podemos negociar bajar prima a ~$21,500.',
'Urgencia: la póliza vence el 11 de abril. Sin confirmación antes del 9, hay riesgo de lapso.',
],
aiRetentionFactors: [
'5 años como cliente — relación establecida',
'Siniestro abierto CLM-0048 dificulta remarketing',
'Flota comercial con cobertura especializada — pocas opciones en mercado local',
'Balance al día, historial de pago puntual',
'Riesgo: aumento de 22% puede motivar búsqueda de alternativas',
],
}
const ren005Detail: RenewalDetail = {
...MOCK_RENEWALS[4],
claimIds: [],
parties: [
{ id: 'rp-10', role: 'insured', name: 'Dr. Alejandro Solís', company: 'Clínica San José', phone: '+507 6500-3456', email: 'asolis@clinicasanjose.com', hasUnread: false },
{ id: 'rp-11', role: 'handler', name: 'Marco V.', company: null, phone: null, email: 'marco@segur-os.com', hasUnread: false },
],
tasks: [
{ id: 'rt-10', title: 'Document cancellation reason', type: 'review', status: 'done', assignee: 'Marco V.', dueDate: '2026-04-02', aiGenerated: false, slaPercent: 100 },
{ id: 'rt-11', title: 'Win-back outreach — 30 day follow-up', type: 'follow_up', status: 'open', assignee: 'Marco V.', dueDate: '2026-05-01', aiGenerated: true, slaPercent: 20 },
],
communications: [
{ id: 'rc-10', type: 'email', direction: 'inbound', from: 'Dr. Alejandro Solís', to: 'Marco V.', subject: 'Decisión sobre renovación', body: 'Marco, lamentablemente hemos decidido no renovar con ASSA. Recibimos una oferta más competitiva de Mapfre a $38,500 con mejores términos de copago. Agradecemos el servicio durante estos 4 años.', aiDigest: 'Cliente cancela por oferta competidora de Mapfre a $38,500 (vs $45,000 actual). Menciona mejores copagos.', templateUsed: null, timestamp: '2026-03-28T11:00:00', partyRole: 'insured' },
{ id: 'rc-11', type: 'note', direction: 'internal', from: 'Marco V.', to: null, subject: null, body: 'Lost to Mapfre. Client says their copay terms are better. ASSA was unable to match. Client open to reconsidering in 12 months if terms change. Marked as recoverable.', aiDigest: null, templateUsed: null, timestamp: '2026-03-29T09:00:00', partyRole: 'handler' },
],
documents: [
{ id: 'rd-10', name: 'Póliza actual — HEALTH-2024-CSJ-001.pdf', category: 'current_policy', uploadedBy: 'System', uploadedAt: '2026-02-15', required: true, fulfilled: true },
{ id: 'rd-11', name: 'Cancellation email from client.pdf', category: 'cancellation', uploadedBy: 'Marco V.', uploadedAt: '2026-03-28', required: false, fulfilled: true },
],
comparison: null,
quotes: [],
renewalHistory: [
{ year: 2025, carrier: 'ASSA', premium: 45000, outcome: 'cancelled' },
{ year: 2024, carrier: 'ASSA', premium: 42000, outcome: 'renewed' },
{ year: 2023, carrier: 'ASSA', premium: 38000, outcome: 'renewed' },
{ year: 2022, carrier: 'ASSA', premium: 35000, outcome: 'new' },
],
cancellationData: {
reason: 'competitor',
reasonDetail: 'Mapfre offered better copay terms and lower premium',
competitor: 'Mapfre',
competitorPremium: 38500,
recoverable: true,
exitDate: '2026-04-01',
},
commissionRate: 12, commissionAmount: 0,
aiRenewalBrief: 'Clínica San José — cliente corporativo de 4 años, póliza de Salud Grupal con ASSA por $45,000. Cancelada por competencia: Mapfre ofreció $38,500 con mejores copagos. Loss ratio 65% (alto). El cliente expresó apertura a reconsiderar en 12 meses. Marcado como recuperable para win-back.',
aiTalkTrack: null,
aiRetentionFactors: [
'Loss ratio de 65% — difícil competir en precio',
'Mapfre ofreció $6,500 menos con mejores copagos',
'Cliente indica apertura a reconsiderar en 12 meses',
'Balance pendiente de $8,500 complica relación',
],
}
const ren002Detail: RenewalDetail = {
...MOCK_RENEWALS[1],
claimIds: [],
parties: [
{ id: 'rp-20', role: 'insured', name: 'Ing. Ricardo Montes', company: 'Constructora Montes', phone: '+507 6800-2222', email: 'rmontes@constructoramontes.com', hasUnread: false },
{ id: 'rp-21', role: 'carrier_rep', name: 'Fernando Gil', company: 'Mapfre', phone: '+507 6600-3333', email: 'fgil@mapfre.com', hasUnread: false },
{ id: 'rp-22', role: 'handler', name: 'Ana R.', company: null, phone: null, email: 'ana@segur-os.com', hasUnread: false },
],
tasks: [
{ id: 'rt-20', title: 'Request renewal terms from Mapfre', type: 'review', status: 'in_progress', assignee: 'Ana R.', dueDate: '2026-04-10', aiGenerated: false, slaPercent: 55 },
{ id: 'rt-21', title: 'Review last year loss runs', type: 'review', status: 'open', assignee: 'Ana R.', dueDate: '2026-04-12', aiGenerated: false, slaPercent: 40 },
],
communications: [
{ id: 'rc-20', type: 'email', direction: 'outbound', from: 'Ana R.', to: 'Fernando Gil', subject: 'Solicitud de términos — GR-2024-CM-001', body: 'Fernando, buen día. Solicitamos los términos de renovación para la póliza GR-2024-CM-001 de Constructora Montes, vigente hasta el 22 de abril. Agradecemos envío a la brevedad.', aiDigest: null, templateUsed: null, timestamp: '2026-04-01T14:00:00', partyRole: 'carrier_rep' },
],
documents: [
{ id: 'rd-20', name: 'Póliza actual — GR-2024-CM-001.pdf', category: 'current_policy', uploadedBy: 'System', uploadedAt: '2026-03-15', required: true, fulfilled: true },
{ id: 'rd-21', name: 'Loss runs 2024-2025.pdf', category: 'loss_runs', uploadedBy: 'Mapfre', uploadedAt: '2026-03-20', required: true, fulfilled: true },
{ id: 'rd-22', name: 'Renewal terms', category: 'renewal_terms', uploadedBy: '', uploadedAt: '', required: true, fulfilled: false },
],
comparison: null,
quotes: [],
renewalHistory: [
{ year: 2025, carrier: 'Mapfre', premium: 32000, outcome: 'renewed' },
{ year: 2024, carrier: 'Mapfre', premium: 29000, outcome: 'renewed' },
{ year: 2023, carrier: 'ASSA', premium: 27500, outcome: 'remarketed' },
],
cancellationData: null,
commissionRate: 12, commissionAmount: 3840,
aiRenewalBrief: 'Constructora Montes — cliente corporativo de 3 años, General Risk con Mapfre por $32,000. Términos de renovación aún no recibidos. Loss ratio bajo (15%). Sin reclamos abiertos. Buena relación con carrier. Se espera renovación sin complicaciones pero se necesitan los términos antes del 15 de abril para cumplir SLA.',
aiTalkTrack: null,
aiRetentionFactors: [
'Loss ratio de 15% — excelente para la línea',
'Sin reclamos abiertos',
'3 años como cliente, relación estable',
'Riesgo moderado: constructora puede buscar cotizaciones competitivas',
],
}
const ren003Detail: RenewalDetail = {
...MOCK_RENEWALS[2],
claimIds: [],
parties: [
{ id: 'rp-30', role: 'insured', name: 'Carmen Ruiz', company: null, phone: '+507 6400-5555', email: 'carmen.ruiz@gmail.com', hasUnread: false },
{ id: 'rp-31', role: 'handler', name: 'Ana R.', company: null, phone: null, email: 'ana@segur-os.com', hasUnread: false },
],
tasks: [
{ id: 'rt-30', title: 'Collect payment — client confirmed renewal', type: 'collect_payment', status: 'open', assignee: 'Ana R.', dueDate: '2026-04-12', aiGenerated: false, slaPercent: 30 },
],
communications: [
{ id: 'rc-30', type: 'email', direction: 'outbound', from: 'Ana R.', to: 'Carmen Ruiz', subject: 'Confirmación de pago — LIFE-2024-CR-001', body: 'Estimada Carmen, gracias por confirmar la renovación de su póliza de vida. La prima para el nuevo período es de $2,940. Por favor realice la transferencia para completar el proceso.', aiDigest: null, templateUsed: 'tpl-5', timestamp: '2026-04-06T10:00:00', partyRole: 'insured' },
{ id: 'rc-31', type: 'email', direction: 'inbound', from: 'Carmen Ruiz', to: 'Ana R.', subject: 'RE: Renovación vida', body: 'Ana, confirmo que deseo renovar. Haré la transferencia esta semana.', aiDigest: 'Cliente confirma renovación, promete pago esta semana.', templateUsed: null, timestamp: '2026-04-05T16:30:00', partyRole: 'insured' },
],
documents: [
{ id: 'rd-30', name: 'Póliza actual — LIFE-2024-CR-001.pdf', category: 'current_policy', uploadedBy: 'System', uploadedAt: '2026-03-01', required: true, fulfilled: true },
{ id: 'rd-31', name: 'Términos Pan-American Life 2026.pdf', category: 'renewal_terms', uploadedBy: 'Pan-American Life', uploadedAt: '2026-03-25', required: true, fulfilled: true },
{ id: 'rd-32', name: 'Propuesta enviada.pdf', category: 'proposal_sent', uploadedBy: 'Ana R.', uploadedAt: '2026-03-28', required: true, fulfilled: true },
{ id: 'rd-33', name: 'Client confirmation email.pdf', category: 'client_confirmation', uploadedBy: 'Ana R.', uploadedAt: '2026-04-05', required: true, fulfilled: true },
{ id: 'rd-34', name: 'Payment receipt', category: 'payment_receipt', uploadedBy: '', uploadedAt: '', required: true, fulfilled: false },
],
comparison: {
currentPremium: 2800, renewalPremium: 2940, premiumDelta: 5,
currentDeductible: 0, renewalDeductible: 0, deductibleDelta: 0,
coverageLines: [
{ name: 'Vida Individual', currentAmount: 100000, renewalAmount: 100000, delta: '=', flag: 'same' },
{ name: 'Muerte Accidental', currentAmount: 50000, renewalAmount: 50000, delta: '=', flag: 'same' },
{ name: 'Incapacidad Total', currentAmount: 100000, renewalAmount: 100000, delta: '=', flag: 'same' },
],
aiAnalysis: 'Aumento de 5% es estándar para ajuste de edad en seguro de vida. Coberturas sin cambio. Renovación rutinaria sin complicaciones.',
},
quotes: [],
renewalHistory: [
{ year: 2025, carrier: 'Pan-American Life', premium: 2800, outcome: 'renewed' },
{ year: 2024, carrier: 'Pan-American Life', premium: 2650, outcome: 'renewed' },
{ year: 2023, carrier: 'Pan-American Life', premium: 2500, outcome: 'renewed' },
{ year: 2022, carrier: 'Pan-American Life', premium: 2350, outcome: 'renewed' },
{ year: 2021, carrier: 'Pan-American Life', premium: 2200, outcome: 'renewed' },
{ year: 2020, carrier: 'Pan-American Life', premium: 2050, outcome: 'renewed' },
{ year: 2019, carrier: 'Pan-American Life', premium: 1900, outcome: 'renewed' },
{ year: 2018, carrier: 'Pan-American Life', premium: 1750, outcome: 'new' },
],
cancellationData: null,
commissionRate: 20, commissionAmount: 588,
aiRenewalBrief: 'Carmen Ruiz — cliente individual de 8 años, póliza de Vida con Pan-American Life. Aumento de 5% por ajuste de edad, estándar. Cliente confirmó renovación, pendiente cobro de $2,940. Excelente historial de retención. Sin reclamos.',
aiTalkTrack: null,
aiRetentionFactors: ['8 años como cliente — altamente leal', 'Sin reclamos, loss ratio 0%', 'Aumento de 5% es mínimo y esperado'],
}
const ren004Detail: RenewalDetail = {
...MOCK_RENEWALS[3],
claimIds: [],
parties: [
{ id: 'rp-40', role: 'insured', name: 'Lic. Patricia Vega', company: 'Empresa ABC S.A.', phone: '+507 6300-7777', email: 'pvega@empresaabc.com', hasUnread: false },
],
tasks: [
{ id: 'rt-40', title: 'Assign handler and begin review', type: 'review', status: 'open', assignee: 'Unassigned', dueDate: '2026-04-15', aiGenerated: true, slaPercent: 10 },
],
communications: [],
documents: [
{ id: 'rd-40', name: 'Póliza actual — AUTO-2024-ABC-001.pdf', category: 'current_policy', uploadedBy: 'System', uploadedAt: '2026-04-01', required: true, fulfilled: true },
],
comparison: null,
quotes: [],
renewalHistory: [
{ year: 2025, carrier: 'Qualitas', premium: 22400, outcome: 'renewed' },
{ year: 2024, carrier: 'Qualitas', premium: 21000, outcome: 'new' },
],
cancellationData: null,
commissionRate: 15, commissionAmount: 3360,
aiRenewalBrief: 'Empresa ABC S.A. — flota Auto con Qualitas por $22,400. Renovación sin asignar, 30 días hasta vencimiento. Sin reclamos, loss ratio 8%. Necesita asignación inmediata para cumplir SLA.',
aiTalkTrack: null,
aiRetentionFactors: ['Loss ratio bajo (8%)', '2 años como cliente', 'Sin complicaciones previas'],
}
const ren006Detail: RenewalDetail = {
...MOCK_RENEWALS[5],
claimIds: ['CLM-0043'],
parties: [
{ id: 'rp-60', role: 'insured', name: 'Gerardo Núñez', company: 'Transportes del Norte', phone: '+507 6200-8888', email: 'gnunez@transportesnorte.com', hasUnread: true },
],
tasks: [
{ id: 'rt-60', title: 'Assign handler — high-risk renewal', type: 'review', status: 'open', assignee: 'Unassigned', dueDate: '2026-04-20', aiGenerated: true, slaPercent: 15 },
{ id: 'rt-61', title: 'Address $21K outstanding balance before renewal', type: 'escalation', status: 'open', assignee: 'Unassigned', dueDate: '2026-04-18', aiGenerated: true, slaPercent: 20 },
],
communications: [
{ id: 'rc-60', type: 'system', direction: 'internal', from: 'System', to: null, subject: null, body: 'AI alert: Transportes del Norte has $21,000 outstanding balance and an open claim (CLM-0043). This renewal requires early attention due to high retention risk.', aiDigest: null, templateUsed: null, timestamp: '2026-04-08T08:00:00', partyRole: 'ai_agent' },
],
documents: [
{ id: 'rd-60', name: 'Póliza actual — GR-2024-TN-001.pdf', category: 'current_policy', uploadedBy: 'System', uploadedAt: '2026-03-15', required: true, fulfilled: true },
],
comparison: null,
quotes: [],
renewalHistory: [
{ year: 2025, carrier: 'ASSA', premium: 38000, outcome: 'renewed' },
{ year: 2024, carrier: 'ASSA', premium: 35000, outcome: 'renewed' },
{ year: 2023, carrier: 'ASSA', premium: 32000, outcome: 'renewed' },
{ year: 2022, carrier: 'ASSA', premium: 28000, outcome: 'renewed' },
{ year: 2021, carrier: 'ASSA', premium: 25000, outcome: 'renewed' },
{ year: 2020, carrier: 'ASSA', premium: 22000, outcome: 'new' },
],
cancellationData: null,
commissionRate: 12, commissionAmount: 4560,
aiRenewalBrief: 'Transportes del Norte — cliente corporativo de 6 años, General Risk con ASSA por $38,000. ALERTA: balance pendiente de $21,000 y reclamo abierto CLM-0043 ($45K reservado). Loss ratio de 55% dificulta la negociación. Necesita atención temprana a pesar de tener 60 días hasta vencimiento. Comisión en riesgo: $4,560.',
aiTalkTrack: [
'Primero resolver el tema del balance pendiente de $21K antes de hablar de renovación.',
'Reconocer que es un cliente de 6 años con historial generalmente positivo.',
'El reclamo abierto CLM-0043 impactará los términos — preparar al cliente para posible aumento.',
'Proponer plan de pago para el balance pendiente como condición para negociar mejores términos de renovación.',
'Si ASSA sube prima significativamente, tener plan B de remarketing con Mapfre.',
],
aiRetentionFactors: [
'6 años como cliente — relación de largo plazo',
'Balance pendiente de $21K — señal de alerta',
'Reclamo abierto CLM-0043 por $45K reservado',
'Loss ratio 55% — por encima del promedio',
'Comisión de $4,560 en riesgo',
'Flota de transporte — pocas opciones en mercado local',
],
}
export const MOCK_RENEWAL_DETAILS: Record<string, RenewalDetail> = {
'REN-001': ren001Detail,
'REN-002': ren002Detail,
'REN-003': ren003Detail,
'REN-004': ren004Detail,
'REN-005': ren005Detail,
'REN-006': ren006Detail,
}