177 lines
4.6 KiB
TypeScript
177 lines
4.6 KiB
TypeScript
import { useLocalStorageRef } from '~/utils/useLocalStorageRef'
|
|
|
|
/* ── Types ── */
|
|
|
|
export type AlertRecipient = 'handler' | 'manager' | 'customer' | 'custom'
|
|
|
|
export interface EmailSenderConfig {
|
|
senderEmail: string
|
|
senderDisplayName: string
|
|
replyToEmail: string
|
|
}
|
|
|
|
export interface AlertThresholdEntry {
|
|
id: string
|
|
daysBefore: number
|
|
enabled: boolean
|
|
}
|
|
|
|
export interface EscalationTier {
|
|
id: string
|
|
daysOverdue: number
|
|
recipients: AlertRecipient[]
|
|
action: string
|
|
}
|
|
|
|
export interface RenewalAlertConfig {
|
|
enabled: boolean
|
|
thresholds: AlertThresholdEntry[]
|
|
}
|
|
|
|
export interface CancellationAlertConfig {
|
|
enabled: boolean
|
|
recipients: AlertRecipient[]
|
|
}
|
|
|
|
export interface LatePaymentAlertConfig {
|
|
enabled: boolean
|
|
tiers: EscalationTier[]
|
|
}
|
|
|
|
export interface CreditCardExpiryAlertConfig {
|
|
enabled: boolean
|
|
thresholds: AlertThresholdEntry[]
|
|
autoDebitOnly: boolean
|
|
}
|
|
|
|
export interface CustomAlertRule {
|
|
id: string
|
|
alertName: string
|
|
field: string
|
|
operator: 'gte' | 'lte' | 'eq' | 'gt' | 'lt' | 'contains'
|
|
value: string | number | boolean
|
|
recipients: AlertRecipient[]
|
|
enabled: boolean
|
|
}
|
|
|
|
export interface AlertConfig {
|
|
emailSender: EmailSenderConfig
|
|
renewals: RenewalAlertConfig
|
|
cancellations: CancellationAlertConfig
|
|
latePayments: LatePaymentAlertConfig
|
|
creditCardExpiry: CreditCardExpiryAlertConfig
|
|
customRules: CustomAlertRule[]
|
|
}
|
|
|
|
/* ── Defaults ── */
|
|
|
|
function defaultConfig(): AlertConfig {
|
|
return {
|
|
emailSender: {
|
|
senderEmail: 'alertas@miagencia.com',
|
|
senderDisplayName: 'Segur-OS Alertas',
|
|
replyToEmail: 'soporte@miagencia.com',
|
|
},
|
|
renewals: {
|
|
enabled: true,
|
|
thresholds: [
|
|
{ id: 'r90', daysBefore: 90, enabled: true },
|
|
{ id: 'r60', daysBefore: 60, enabled: true },
|
|
{ id: 'r30', daysBefore: 30, enabled: true },
|
|
{ id: 'r15', daysBefore: 15, enabled: true },
|
|
],
|
|
},
|
|
cancellations: {
|
|
enabled: true,
|
|
recipients: ['handler', 'manager'],
|
|
},
|
|
latePayments: {
|
|
enabled: true,
|
|
tiers: [
|
|
{ id: 'lp5', daysOverdue: 5, recipients: ['handler'], action: 'Notify assigned handler' },
|
|
{ id: 'lp15', daysOverdue: 15, recipients: ['handler', 'manager'], action: 'Notify handler + manager' },
|
|
{ id: 'lp30', daysOverdue: 30, recipients: ['handler', 'manager', 'customer'], action: 'Auto-escalate + notify customer' },
|
|
],
|
|
},
|
|
creditCardExpiry: {
|
|
enabled: true,
|
|
thresholds: [
|
|
{ id: 'cc60', daysBefore: 60, enabled: true },
|
|
{ id: 'cc30', daysBefore: 30, enabled: true },
|
|
{ id: 'cc15', daysBefore: 15, enabled: true },
|
|
],
|
|
autoDebitOnly: true,
|
|
},
|
|
customRules: [
|
|
{
|
|
id: 'cr1',
|
|
alertName: 'High-value policy renewal',
|
|
field: 'premium',
|
|
operator: 'gte',
|
|
value: 25000,
|
|
recipients: ['handler', 'manager'],
|
|
enabled: true,
|
|
},
|
|
],
|
|
}
|
|
}
|
|
|
|
/* ── Composable ── */
|
|
|
|
let _counter = 100
|
|
|
|
export function useAlertConfig() {
|
|
const config = useLocalStorageRef<AlertConfig>('policy-ui-alert-config-v1', defaultConfig)
|
|
|
|
/* ── Threshold CRUD ── */
|
|
|
|
function addThreshold(section: 'renewals' | 'creditCardExpiry', daysBefore: number) {
|
|
const id = `t${++_counter}`
|
|
config.value[section].thresholds.push({ id, daysBefore, enabled: true })
|
|
}
|
|
|
|
function removeThreshold(section: 'renewals' | 'creditCardExpiry', id: string) {
|
|
config.value[section].thresholds = config.value[section].thresholds.filter(t => t.id !== id)
|
|
}
|
|
|
|
/* ── Late payment tier CRUD ── */
|
|
|
|
function addPaymentTier(daysOverdue: number, action: string, recipients: AlertRecipient[]) {
|
|
const id = `lp${++_counter}`
|
|
config.value.latePayments.tiers.push({ id, daysOverdue, recipients, action })
|
|
}
|
|
|
|
function removePaymentTier(id: string) {
|
|
config.value.latePayments.tiers = config.value.latePayments.tiers.filter(t => t.id !== id)
|
|
}
|
|
|
|
/* ── Custom rule CRUD ── */
|
|
|
|
function addCustomRule(rule: Omit<CustomAlertRule, 'id'>) {
|
|
const id = `cr${++_counter}`
|
|
config.value.customRules.push({ ...rule, id })
|
|
}
|
|
|
|
function updateCustomRule(id: string, patch: Partial<CustomAlertRule>) {
|
|
const idx = config.value.customRules.findIndex(r => r.id === id)
|
|
if (idx !== -1) {
|
|
config.value.customRules[idx] = { ...config.value.customRules[idx], ...patch }
|
|
}
|
|
}
|
|
|
|
function removeCustomRule(id: string) {
|
|
config.value.customRules = config.value.customRules.filter(r => r.id !== id)
|
|
}
|
|
|
|
return {
|
|
config,
|
|
addThreshold,
|
|
removeThreshold,
|
|
addPaymentTier,
|
|
removePaymentTier,
|
|
addCustomRule,
|
|
updateCustomRule,
|
|
removeCustomRule,
|
|
}
|
|
}
|