WIP jordan
This commit is contained in:
176
app/composables/useAlertConfig.ts
Normal file
176
app/composables/useAlertConfig.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user