Skip to main content

safeapp_notifier/
event_keys.rs

1use serde::{
2    Deserialize, Deserializer, Serialize, Serializer,
3    de::{self, Visitor},
4};
5use std::fmt;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum EventKey {
9    Account(AccountEventKey),
10    Sync(SyncEventKey),
11}
12
13impl EventKey {
14    pub fn as_str(&self) -> &'static str {
15        match self {
16            EventKey::Account(key) => key.as_str(),
17            EventKey::Sync(key) => key.as_str(),
18        }
19    }
20
21//    pub fn to_subject(&self) -> String {
22//         match self {
23//             EventKey::Account(account_key) => match account_key {
24//                 // account.*
25//                 AccountEventKey::Welcome => "Welcome to Safe — your AI guard against chargebacks".to_string(),
26//                 AccountEventKey::TierUpgrade => "You’ve been upgraded".to_string(),
27//                 AccountEventKey::ExistingChargebacks => "You have open chargebacks".to_string(),
28//                 AccountEventKey::HighChargebackRatioWarning => "Warning: chargeback rate rising".to_string(),
29//                 AccountEventKey::ProviderDisconnected => "Action needed: connection disconnected".to_string(),
30
31//                 // billing.* (modeled under Account)
32//                 AccountEventKey::BillingPaymentFailed => "Payment failed".to_string(),
33//                 AccountEventKey::BillingInvoiceReady => "Invoice ready".to_string(),
34//             },
35
36//             EventKey::Sync(sync_key) => match sync_key {
37//                 // sync.connection.*
38//                 SyncEventKey::Connection(connection_key) => match connection_key {
39//                     ConnectionEventKey::Finished => "Sync complete — Safe is watching for disputes".to_string(),
40//                     ConnectionEventKey::Added => "Connection successful — monitoring enabled".to_string(),
41//                 },
42
43//                 // sync.disputer.*
44//                 SyncEventKey::Disputer(disputer_key) => match disputer_key {
45//                     DisputerEventKey::PendingCharges(pending_key) => match pending_key {
46//                         PendingChargeEventKey::Payment => "Pending charges payment processed".to_string(),
47//                         PendingChargeEventKey::LimitReached => "Pending charges limit reached".to_string(),
48//                         PendingChargeEventKey::Added => "New pending charge added".to_string(),
49//                     },
50//                     DisputerEventKey::Disputes(dispute_key) => match dispute_key {
51//                         DisputeEventKey::Created => "New dispute detected".to_string(),
52//                         DisputeEventKey::Won => "🎉 You won a chargeback".to_string(),
53//                         DisputeEventKey::Lost => "Outcome: dispute lost".to_string(),
54//                     },
55//                     DisputerEventKey::Evidences(evidence_key) => match evidence_key {
56//                         EvidencesEventKey::Submitted => "Dispute response submitted".to_string(),
57//                     },
58//                 },
59
60//                 // sync.connection.not_created.nudge_day_*
61//                 SyncEventKey::ConnectionNudge(nudge_key) => match nudge_key {
62//                     ConnectionNudgeKey::Day1  => "Connect your account to start protection".to_string(),
63//                     ConnectionNudgeKey::Day2  => "Prevent disputes before they start".to_string(),
64//                     ConnectionNudgeKey::Day4  => "Win disputes automatically with Disputer".to_string(),
65//                     ConnectionNudgeKey::Day7  => "You’re close — finish connecting".to_string(),
66//                     ConnectionNudgeKey::Day30 => "Still here when you’re ready".to_string(),
67//                 },
68
69//                 // sync.chargeback.*
70//                 SyncEventKey::Chargeback(cb_key) => match cb_key {
71//                     ChargebackEventKey::Detected => "New chargeback detected".to_string(),
72//                 },
73
74//                 // sync.response.*
75//                 SyncEventKey::Response(resp_key) => match resp_key {
76//                     ResponseEventKey::DeadlineApproaching => "Urgent: response deadline approaching".to_string(),
77//                 },
78
79//                 // sync.stopper.*
80//                 SyncEventKey::Stopper(stopper_key) => match stopper_key {
81//                     StopperEventKey::PreChargebackAlert => "At-risk transaction detected".to_string(),
82//                     StopperEventKey::AutoRefundExecuted => "Auto-refund executed".to_string(),
83//                 },
84
85//                 // sync.rules.*
86//                 SyncEventKey::Rules(rules_key) => match rules_key {
87//                     RulesEventKey::Created => "Rule created".to_string(),
88//                     RulesEventKey::TriggeredAutoRefund => "Rule triggered: Auto-refund".to_string(),
89//                 },
90//             },
91//         }
92//     }
93}
94
95// Custom serialization (unchanged)
96impl Serialize for EventKey {
97    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
98    where
99        S: Serializer,
100    {
101        serializer.serialize_str(self.as_str())
102    }
103}
104
105// Custom deserialization with fallback for unknown keys
106impl<'de> Deserialize<'de> for EventKey {
107    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
108    where
109        D: Deserializer<'de>,
110    {
111        struct EventKeyVisitor;
112
113        impl<'de> Visitor<'de> for EventKeyVisitor {
114            type Value = EventKey;
115
116            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
117                formatter.write_str("a valid event key string")
118            }
119
120            fn visit_str<E>(self, value: &str) -> Result<EventKey, E>
121            where
122                E: de::Error,
123            {
124                match value {
125                    "account.welcome" => Ok(keys::ACCOUNT_WELCOME),
126                    "account.tier_upgrade" => Ok(keys::ACCOUNT_TIER_UPGRADE),
127                    "sync.connection.finished" => Ok(keys::SYNC_CONNECTION_FINISHED),
128                    "sync.connection.added" => Ok(keys::SYNC_CONNECTION_ADDED),
129                    "sync.disputer.pending_charges.payment" => Ok(keys::SYNC_DISPUTER_PENDING_CHARGES_PAYMENT),
130                    "sync.disputer.pending_charges.limit_reached" => {
131                        Ok(keys::SYNC_DISPUTER_PENDING_CHARGES_LIMIT_REACHED)
132                    }
133                    "sync.disputer.pending_charges.added" => Ok(keys::SYNC_DISPUTER_PENDING_CHARGES_ADDED),
134                    "sync.disputer.disputes.created" => Ok(keys::SYNC_DISPUTER_DISPUTES_CREATED),
135                    "sync.disputer.disputes.won" => Ok(keys::SYNC_DISPUTER_DISPUTES_WON),
136                    "sync.disputer.disputes.lost" => Ok(keys::SYNC_DISPUTER_DISPUTES_LOST),
137                    "sync.disputer.disputes.warning_closed" => Ok(keys::SYNC_DISPUTER_DISPUTES_WARNING_CLOSED),
138                    "sync.disputer.disputes.missing_evidence_reminder" => Ok(keys::SYNC_DISPUTER_DISPUTES_MISSING_EVIDENCE_REMINDER),
139                    "sync.disputer.evidences.submitted" => Ok(keys::SYNC_DISPUTER_EVIDENCES_SUBMITTED),
140                    "sync.disputer.evidences.received" => Ok(keys::SYNC_DISPUTER_EVIDENCES_RECEIVED),
141                    "sync.connection.not_created.nudge_day_1" => Ok(keys::SYNC_CONNECTION_NUDGE_DAY1),
142                    // connection nudges
143                    "sync.connection.not_created.nudge_day_2"  => Ok(keys::SYNC_CONNECTION_NUDGE_DAY2),
144                    "sync.connection.not_created.nudge_day_4"  => Ok(keys::SYNC_CONNECTION_NUDGE_DAY4),
145                    "sync.connection.not_created.nudge_day_7"  => Ok(keys::SYNC_CONNECTION_NUDGE_DAY7),
146                    "sync.connection.not_created.nudge_day_30" => Ok(keys::SYNC_CONNECTION_NUDGE_DAY30),
147
148                    // chargeback + response
149                    // "sync.chargeback.detected"             => Ok(keys::SYNC_CHARGEBACK_DETECTED),
150                    "sync.response.deadline.approaching"   => Ok(keys::SYNC_RESPONSE_DEADLINE_APPROACHING),
151
152                    // stopper
153                    // "sync.stopper.pre_chargeback_alert"    => Ok(keys::SYNC_STOPPER_PRE_CHARGEBACK_ALERT),
154                    // "sync.stopper.auto_refund_executed"    => Ok(keys::SYNC_STOPPER_AUTO_REFUND_EXECUTED),
155
156                    // rules
157                    // "sync.rules.created"                   => Ok(keys::SYNC_RULES_CREATED),
158                    // "sync.rules.triggered.auto_refund"     => Ok(keys::SYNC_RULES_TRIGGERED_AUTO_REFUND),
159
160                    // account extras
161                    "account.existing_chargebacks"         => Ok(keys::ACCOUNT_EXISTING_CHARGEBACKS),
162                    "account.high_chargeback_ratio_warning"=> Ok(keys::ACCOUNT_HIGH_CHARGEBACK_RATIO_WARNING),
163                    "account.provider_disconnected"        => Ok(keys::ACCOUNT_PROVIDER_DISCONNECTED),
164
165                    // billing (mapped under Account variant)
166                    "billing.payment_failed"               => Ok(keys::BILLING_PAYMENT_FAILED),
167                    "billing.invoice_ready"                => Ok(keys::BILLING_INVOICE_READY),
168
169                    // NEW billing email template keys
170                    "welcome"                              => Ok(keys::BILLING_WELCOME),
171                    "payment_succeeded"                    => Ok(keys::BILLING_PAYMENT_SUCCEEDED),
172                    "payment_failed"                       => Ok(keys::BILLING_PAYMENT_FAILED_2),
173                    "payment-failed"                       => Ok(keys::BILLING_PAYMENT_FAILED_3),
174                    "overage_invoice_created"              => Ok(keys::BILLING_OVERAGE_INVOICE_CREATED),
175                    "upcoming_invoice"                     => Ok(keys::BILLING_UPCOMING_INVOICE),
176                    "trial_expired"                        => Ok(keys::BILLING_TRIAL_EXPIRED),
177                    "trial_ending"                         => Ok(keys::BILLING_TRIAL_ENDING),
178                    "trial_started"                        => Ok(keys::BILLING_TRIAL_STARTED),
179                    "plan_downgraded"                      => Ok(keys::BILLING_PLAN_DOWNGRADED),
180                    "plan_upgraded"                        => Ok(keys::BILLING_PLAN_UPGRADED),
181                    "plan_renewed"                         => Ok(keys::BILLING_PLAN_RENEWED),
182                    "plan_cancelled"                       => Ok(keys::BILLING_PLAN_CANCELLED),
183                    "plan-cancelled"                       => Ok(keys::BILLING_PLAN_CANCELLED_2),
184                    "plan_purchased"                       => Ok(keys::BILLING_PLAN_PURCHASED),
185                    "success-fee-added"                    => Ok(keys::BILLING_SUCCESS_FEE_ADDED),
186
187                    unknown => {
188                        // Optionally log unknown keys for debugging
189                        eprintln!("Unknown event key '{}', expected a known key", unknown);
190                        Err(de::Error::custom(format!("Unknown event key: {}", unknown)))
191                    }
192                }
193            }
194        }
195
196        deserializer.deserialize_str(EventKeyVisitor)
197    }
198}
199
200#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
201pub enum AccountEventKey {
202    Welcome,
203    TierUpgrade,
204
205    // NEW account.* keys
206    ExistingChargebacks,
207    HighChargebackRatioWarning,
208    ProviderDisconnected,
209
210    // NEW billing.* (mapped under Account)
211    BillingPaymentFailed,
212    BillingInvoiceReady,
213
214    // NEW billing email template keys
215    BillingWelcome,
216    BillingPaymentSucceeded,
217    BillingPaymentFailed2,
218    BillingPaymentFailed3,
219    BillingOverageInvoiceCreated,
220    BillingUpcomingInvoice,
221    BillingTrialExpired,
222    BillingTrialEnding,
223    BillingTrialStarted,
224    BillingPlanDowngraded,
225    BillingPlanUpgraded,
226    BillingPlanRenewed,
227    BillingPlanCancelled,
228    BillingPlanCancelled2,
229    BillingPlanPurchased,
230    BillingSuccessFeeAdded,
231}
232
233impl AccountEventKey {
234    pub fn as_str(&self) -> &'static str {
235        match self {
236            AccountEventKey::Welcome                     => "account.welcome",
237            AccountEventKey::TierUpgrade                 => "account.tier_upgrade",
238            AccountEventKey::ExistingChargebacks         => "account.existing_chargebacks",
239            AccountEventKey::HighChargebackRatioWarning  => "account.high_chargeback_ratio_warning",
240            AccountEventKey::ProviderDisconnected        => "account.provider_disconnected",
241            AccountEventKey::BillingPaymentFailed        => "billing.payment_failed",
242            AccountEventKey::BillingInvoiceReady         => "billing.invoice_ready",
243            AccountEventKey::BillingWelcome              => "welcome",
244            AccountEventKey::BillingPaymentSucceeded     => "payment_succeeded",
245            AccountEventKey::BillingPaymentFailed2       => "payment_failed",
246            AccountEventKey::BillingPaymentFailed3       => "payment-failed",
247            AccountEventKey::BillingOverageInvoiceCreated => "overage_invoice_created",
248            AccountEventKey::BillingUpcomingInvoice      => "upcoming_invoice",
249            AccountEventKey::BillingTrialExpired         => "trial_expired",
250            AccountEventKey::BillingTrialEnding          => "trial_ending",
251            AccountEventKey::BillingTrialStarted         => "trial_started",
252            AccountEventKey::BillingPlanDowngraded       => "plan_downgraded",
253            AccountEventKey::BillingPlanUpgraded         => "plan_upgraded",
254            AccountEventKey::BillingPlanRenewed          => "plan_renewed",
255            AccountEventKey::BillingPlanCancelled        => "plan_cancelled",
256            AccountEventKey::BillingPlanCancelled2       => "plan-cancelled",
257            AccountEventKey::BillingPlanPurchased        => "plan_purchased",
258            AccountEventKey::BillingSuccessFeeAdded      => "success-fee-added",
259        }
260    }
261}
262
263#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
264pub enum SyncEventKey {
265    Connection(ConnectionEventKey),
266    Disputer(DisputerEventKey),
267
268    // already there:
269    ConnectionNudge(ConnectionNudgeKey),
270
271    // NEW:
272    // Chargeback(ChargebackEventKey),
273    Response(ResponseEventKey),
274    // Stopper(StopperEventKey),
275    // Rules(RulesEventKey),
276}
277
278impl SyncEventKey {
279    pub fn as_str(&self) -> &'static str {
280        match self {
281            SyncEventKey::Connection(key)      => key.as_str(),
282            SyncEventKey::Disputer(key)        => key.as_str(),
283            SyncEventKey::ConnectionNudge(key) => key.as_str(),
284            // SyncEventKey::Chargeback(key)      => key.as_str(),
285            SyncEventKey::Response(key)        => key.as_str(),
286            // SyncEventKey::Stopper(key)         => key.as_str(),
287            // SyncEventKey::Rules(key)           => key.as_str(),
288        }
289    }
290}
291
292#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
293pub enum ConnectionEventKey {
294    Finished,
295    Added,
296}
297
298impl ConnectionEventKey {
299    pub fn as_str(&self) -> &'static str {
300        match self {
301            ConnectionEventKey::Finished => "sync.connection.finished",
302            ConnectionEventKey::Added => "sync.connection.added",
303        }
304    }
305}
306
307#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
308pub enum DisputerEventKey {
309    PendingCharges(PendingChargeEventKey),
310    Disputes(DisputeEventKey),
311    Evidences(EvidencesEventKey),
312}
313
314impl DisputerEventKey {
315    pub fn as_str(&self) -> &'static str {
316        match self {
317            DisputerEventKey::PendingCharges(key) => key.as_str(),
318            DisputerEventKey::Disputes(key) => key.as_str(),
319            DisputerEventKey::Evidences(key) => key.as_str(),
320        }
321    }
322}
323
324#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
325pub enum DisputeEventKey {
326    Created,
327    Won,
328    Lost,
329    WarningClosed,
330    MissingEvidenceReminder
331}
332
333impl DisputeEventKey {
334    pub fn as_str(&self) -> &'static str {
335        match self {
336            DisputeEventKey::Created => "sync.disputer.disputes.created",
337            DisputeEventKey::Won => "sync.disputer.disputes.won",
338            DisputeEventKey::Lost => "sync.disputer.disputes.lost",
339            DisputeEventKey::WarningClosed => "sync.disputer.disputes.warning_closed",
340            DisputeEventKey::MissingEvidenceReminder => "sync.disputer.disputes.missing_evidence_reminder",
341        }
342    }
343}
344
345#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
346pub enum PendingChargeEventKey {
347    Payment,
348    LimitReached,
349    Added,
350}
351
352impl PendingChargeEventKey {
353    pub fn as_str(&self) -> &'static str {
354        match self {
355            PendingChargeEventKey::Payment => "sync.disputer.pending_charges.payment",
356            PendingChargeEventKey::LimitReached => "sync.disputer.pending_charges.limit_reached",
357            PendingChargeEventKey::Added => "sync.disputer.pending_charges.added",
358        }
359    }
360}
361
362#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
363pub enum EvidencesEventKey {
364    Submitted,
365    Received,
366}
367
368impl EvidencesEventKey {
369    pub fn as_str(&self) -> &'static str {
370        match self {
371            EvidencesEventKey::Submitted => "sync.disputer.evidences.submitted",
372            EvidencesEventKey::Received => "sync.disputer.evidences.received",
373        }
374    }
375}
376
377// --- Connection Nudges (extend what you already have) ---
378#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
379pub enum ConnectionNudgeKey {
380    Day1,
381    Day2,
382    Day4,
383    Day7,
384    Day30,
385}
386
387impl ConnectionNudgeKey {
388    pub fn as_str(&self) -> &'static str {
389        match self {
390            ConnectionNudgeKey::Day1  => "sync.connection.not_created.nudge_day_1",
391            ConnectionNudgeKey::Day2  => "sync.connection.not_created.nudge_day_2",
392            ConnectionNudgeKey::Day4  => "sync.connection.not_created.nudge_day_4",
393            ConnectionNudgeKey::Day7  => "sync.connection.not_created.nudge_day_7",
394            ConnectionNudgeKey::Day30 => "sync.connection.not_created.nudge_day_30",
395        }
396    }
397}
398
399// // --- Chargeback ---
400// #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
401// pub enum ChargebackEventKey {
402//     Detected,
403// }
404// impl ChargebackEventKey {
405//     pub fn as_str(&self) -> &'static str {
406//         match self {
407//             ChargebackEventKey::Detected => "sync.chargeback.detected",
408//         }
409//     }
410// }
411
412// --- Response (deadlines etc) ---
413#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
414pub enum ResponseEventKey {
415    DeadlineApproaching,
416}
417impl ResponseEventKey {
418    pub fn as_str(&self) -> &'static str {
419        match self {
420            ResponseEventKey::DeadlineApproaching => "sync.response.deadline.approaching",
421        }
422    }
423}
424
425// --- Stopper (pre-chargeback / actions) ---
426// #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
427// pub enum StopperEventKey {
428//     PreChargebackAlert,
429//     AutoRefundExecuted,
430// }
431// impl StopperEventKey {
432//     pub fn as_str(&self) -> &'static str {
433//         match self {
434//             StopperEventKey::PreChargebackAlert => "sync.stopper.pre_chargeback_alert",
435//             StopperEventKey::AutoRefundExecuted => "sync.stopper.auto_refund_executed",
436//         }
437//     }
438// }
439
440// // --- Rules (created / triggered) ---
441// #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
442// pub enum RulesEventKey {
443//     Created,
444//     TriggeredAutoRefund,
445// }
446// impl RulesEventKey {
447//     pub fn as_str(&self) -> &'static str {
448//         match self {
449//             RulesEventKey::Created => "sync.rules.created",
450//             RulesEventKey::TriggeredAutoRefund => "sync.rules.triggered.auto_refund",
451//         }
452//     }
453// }
454
455pub mod keys {
456    use super::*;
457
458    pub const ACCOUNT_WELCOME: EventKey = EventKey::Account(AccountEventKey::Welcome);
459    pub const ACCOUNT_TIER_UPGRADE: EventKey = EventKey::Account(AccountEventKey::TierUpgrade);
460
461    pub const SYNC_CONNECTION_FINISHED: EventKey =
462        EventKey::Sync(SyncEventKey::Connection(ConnectionEventKey::Finished));
463        
464    pub const SYNC_CONNECTION_ADDED: EventKey = EventKey::Sync(SyncEventKey::Connection(ConnectionEventKey::Added));
465
466    pub const SYNC_DISPUTER_PENDING_CHARGES_PAYMENT: EventKey = EventKey::Sync(SyncEventKey::Disputer(
467        DisputerEventKey::PendingCharges(PendingChargeEventKey::Payment),
468    ));
469    pub const SYNC_DISPUTER_PENDING_CHARGES_LIMIT_REACHED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
470        DisputerEventKey::PendingCharges(PendingChargeEventKey::LimitReached),
471    ));
472    pub const SYNC_DISPUTER_PENDING_CHARGES_ADDED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
473        DisputerEventKey::PendingCharges(PendingChargeEventKey::Added),
474    ));
475    pub const SYNC_DISPUTER_DISPUTES_CREATED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
476        DisputerEventKey::Disputes(DisputeEventKey::Created),
477    ));
478    pub const SYNC_DISPUTER_DISPUTES_WON: EventKey =
479        EventKey::Sync(SyncEventKey::Disputer(DisputerEventKey::Disputes(DisputeEventKey::Won)));
480    pub const SYNC_DISPUTER_DISPUTES_LOST: EventKey = EventKey::Sync(SyncEventKey::Disputer(
481        DisputerEventKey::Disputes(DisputeEventKey::Lost),
482    ));
483    pub const SYNC_DISPUTER_DISPUTES_WARNING_CLOSED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
484        DisputerEventKey::Disputes(DisputeEventKey::WarningClosed),
485    ));
486    pub const SYNC_DISPUTER_DISPUTES_MISSING_EVIDENCE_REMINDER: EventKey = EventKey::Sync(SyncEventKey::Disputer(
487        DisputerEventKey::Disputes(DisputeEventKey::MissingEvidenceReminder),
488    ));
489    pub const SYNC_DISPUTER_EVIDENCES_SUBMITTED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
490        DisputerEventKey::Evidences(EvidencesEventKey::Submitted),
491    ));
492    pub const SYNC_DISPUTER_EVIDENCES_RECEIVED: EventKey = EventKey::Sync(SyncEventKey::Disputer(
493        DisputerEventKey::Evidences(EvidencesEventKey::Received),
494    ));
495    
496    pub const SYNC_CONNECTION_NUDGE_DAY1: EventKey = EventKey::Sync(SyncEventKey::ConnectionNudge(ConnectionNudgeKey::Day1));
497
498    pub const SYNC_CONNECTION_NUDGE_DAY2: EventKey =
499        EventKey::Sync(SyncEventKey::ConnectionNudge(ConnectionNudgeKey::Day2));
500    pub const SYNC_CONNECTION_NUDGE_DAY4: EventKey =
501        EventKey::Sync(SyncEventKey::ConnectionNudge(ConnectionNudgeKey::Day4));
502    pub const SYNC_CONNECTION_NUDGE_DAY7: EventKey =
503        EventKey::Sync(SyncEventKey::ConnectionNudge(ConnectionNudgeKey::Day7));
504    pub const SYNC_CONNECTION_NUDGE_DAY30: EventKey =
505        EventKey::Sync(SyncEventKey::ConnectionNudge(ConnectionNudgeKey::Day30));
506
507    // pub const SYNC_CHARGEBACK_DETECTED: EventKey =
508    //     EventKey::Sync(SyncEventKey::Chargeback(ChargebackEventKey::Detected));
509
510    pub const SYNC_RESPONSE_DEADLINE_APPROACHING: EventKey =
511        EventKey::Sync(SyncEventKey::Response(ResponseEventKey::DeadlineApproaching));
512
513    // pub const SYNC_STOPPER_PRE_CHARGEBACK_ALERT: EventKey =
514    //     EventKey::Sync(SyncEventKey::Stopper(StopperEventKey::PreChargebackAlert));
515    // pub const SYNC_STOPPER_AUTO_REFUND_EXECUTED: EventKey =
516    //     EventKey::Sync(SyncEventKey::Stopper(StopperEventKey::AutoRefundExecuted));
517
518    // pub const SYNC_RULES_CREATED: EventKey =
519    //     EventKey::Sync(SyncEventKey::Rules(RulesEventKey::Created));
520    // pub const SYNC_RULES_TRIGGERED_AUTO_REFUND: EventKey =
521    //     EventKey::Sync(SyncEventKey::Rules(RulesEventKey::TriggeredAutoRefund));
522
523    // Account-side new keys
524    pub const ACCOUNT_EXISTING_CHARGEBACKS: EventKey =
525        EventKey::Account(AccountEventKey::ExistingChargebacks);
526    pub const ACCOUNT_HIGH_CHARGEBACK_RATIO_WARNING: EventKey =
527        EventKey::Account(AccountEventKey::HighChargebackRatioWarning);
528    pub const ACCOUNT_PROVIDER_DISCONNECTED: EventKey =
529        EventKey::Account(AccountEventKey::ProviderDisconnected);
530
531    // Billing (kept under Account to avoid new top-level variant)
532    pub const BILLING_PAYMENT_FAILED: EventKey =
533        EventKey::Account(AccountEventKey::BillingPaymentFailed);
534    pub const BILLING_INVOICE_READY: EventKey =
535        EventKey::Account(AccountEventKey::BillingInvoiceReady);
536
537    // NEW billing email template keys
538    pub const BILLING_WELCOME: EventKey =
539        EventKey::Account(AccountEventKey::BillingWelcome);
540    pub const BILLING_PAYMENT_SUCCEEDED: EventKey =
541        EventKey::Account(AccountEventKey::BillingPaymentSucceeded);
542    pub const BILLING_PAYMENT_FAILED_2: EventKey =
543        EventKey::Account(AccountEventKey::BillingPaymentFailed2);
544    pub const BILLING_PAYMENT_FAILED_3: EventKey =
545        EventKey::Account(AccountEventKey::BillingPaymentFailed3);
546    pub const BILLING_OVERAGE_INVOICE_CREATED: EventKey =
547        EventKey::Account(AccountEventKey::BillingOverageInvoiceCreated);
548    pub const BILLING_UPCOMING_INVOICE: EventKey =
549        EventKey::Account(AccountEventKey::BillingUpcomingInvoice);
550    pub const BILLING_TRIAL_EXPIRED: EventKey =
551        EventKey::Account(AccountEventKey::BillingTrialExpired);
552    pub const BILLING_TRIAL_ENDING: EventKey =
553        EventKey::Account(AccountEventKey::BillingTrialEnding);
554    pub const BILLING_TRIAL_STARTED: EventKey =
555        EventKey::Account(AccountEventKey::BillingTrialStarted);
556    pub const BILLING_PLAN_DOWNGRADED: EventKey =
557        EventKey::Account(AccountEventKey::BillingPlanDowngraded);
558    pub const BILLING_PLAN_UPGRADED: EventKey =
559        EventKey::Account(AccountEventKey::BillingPlanUpgraded);
560    pub const BILLING_PLAN_RENEWED: EventKey =
561        EventKey::Account(AccountEventKey::BillingPlanRenewed);
562    pub const BILLING_PLAN_CANCELLED: EventKey =
563        EventKey::Account(AccountEventKey::BillingPlanCancelled);
564    pub const BILLING_PLAN_CANCELLED_2: EventKey =
565        EventKey::Account(AccountEventKey::BillingPlanCancelled2);
566    pub const BILLING_PLAN_PURCHASED: EventKey =
567        EventKey::Account(AccountEventKey::BillingPlanPurchased);
568    pub const BILLING_SUCCESS_FEE_ADDED: EventKey =
569        EventKey::Account(AccountEventKey::BillingSuccessFeeAdded);
570
571}