1use crate::persona_lifecycle::{LifecycleState, PersonaLifecycle};
8use serde_json::Value;
9
10pub fn apply_billing_lifecycle_effects(response: &mut Value, lifecycle: &PersonaLifecycle) {
16 if let Some(obj) = response.as_object_mut() {
17 match lifecycle.current_state {
18 LifecycleState::NewSignup => {
19 obj.insert("payment_method".to_string(), Value::String("none".to_string()));
21 obj.insert("billing_status".to_string(), Value::String("pending".to_string()));
22 obj.insert("subscription_status".to_string(), Value::String("trial".to_string()));
23 }
24 LifecycleState::Active => {
25 obj.insert("billing_status".to_string(), Value::String("active".to_string()));
27 obj.insert("subscription_status".to_string(), Value::String("active".to_string()));
28 obj.insert("payment_method".to_string(), Value::String("credit_card".to_string()));
29 }
30 LifecycleState::PowerUser => {
31 obj.insert("billing_status".to_string(), Value::String("active".to_string()));
33 obj.insert("subscription_status".to_string(), Value::String("premium".to_string()));
34 obj.insert("payment_method".to_string(), Value::String("credit_card".to_string()));
35 }
36 LifecycleState::ChurnRisk => {
37 obj.insert("billing_status".to_string(), Value::String("warning".to_string()));
39 obj.insert("subscription_status".to_string(), Value::String("at_risk".to_string()));
40 obj.insert("payment_method".to_string(), Value::String("credit_card".to_string()));
41 obj.insert("last_payment_failed".to_string(), Value::Bool(true));
42 }
43 LifecycleState::Churned => {
44 obj.insert("billing_status".to_string(), Value::String("cancelled".to_string()));
46 obj.insert(
47 "subscription_status".to_string(),
48 Value::String("cancelled".to_string()),
49 );
50 obj.insert("payment_method".to_string(), Value::String("none".to_string()));
51 }
52 LifecycleState::UpgradePending => {
53 obj.insert(
55 "billing_status".to_string(),
56 Value::String("pending_upgrade".to_string()),
57 );
58 obj.insert(
59 "subscription_status".to_string(),
60 Value::String("upgrading".to_string()),
61 );
62 }
63 LifecycleState::PaymentFailed => {
64 obj.insert("billing_status".to_string(), Value::String("failed".to_string()));
66 obj.insert(
67 "subscription_status".to_string(),
68 Value::String("suspended".to_string()),
69 );
70 obj.insert("payment_method".to_string(), Value::String("credit_card".to_string()));
71 obj.insert("last_payment_failed".to_string(), Value::Bool(true));
72 obj.insert(
73 "failed_payment_count".to_string(),
74 Value::Number(
75 lifecycle
76 .get_metadata("payment_failed_count")
77 .and_then(|v| v.as_u64())
78 .unwrap_or(1)
79 .into(),
80 ),
81 );
82 }
83 }
84 }
85}
86
87pub fn apply_support_lifecycle_effects(response: &mut Value, lifecycle: &PersonaLifecycle) {
93 if let Some(obj) = response.as_object_mut() {
94 match lifecycle.current_state {
95 LifecycleState::NewSignup => {
96 obj.insert("support_tier".to_string(), Value::String("onboarding".to_string()));
98 obj.insert("open_tickets".to_string(), Value::Number(0.into()));
99 obj.insert("priority".to_string(), Value::String("normal".to_string()));
100 }
101 LifecycleState::Active => {
102 obj.insert("support_tier".to_string(), Value::String("standard".to_string()));
104 obj.insert("open_tickets".to_string(), Value::Number(0.into()));
105 obj.insert("priority".to_string(), Value::String("normal".to_string()));
106 }
107 LifecycleState::PowerUser => {
108 obj.insert("support_tier".to_string(), Value::String("premium".to_string()));
110 obj.insert("open_tickets".to_string(), Value::Number(0.into()));
111 obj.insert("priority".to_string(), Value::String("high".to_string()));
112 }
113 LifecycleState::ChurnRisk => {
114 obj.insert("support_tier".to_string(), Value::String("retention".to_string()));
116 obj.insert("open_tickets".to_string(), Value::Number(1.into()));
117 obj.insert("priority".to_string(), Value::String("high".to_string()));
118 obj.insert("last_contact_days_ago".to_string(), Value::Number(30.into()));
119 }
120 LifecycleState::Churned => {
121 obj.insert("support_tier".to_string(), Value::String("none".to_string()));
123 obj.insert("open_tickets".to_string(), Value::Number(0.into()));
124 obj.insert("priority".to_string(), Value::String("low".to_string()));
125 }
126 LifecycleState::UpgradePending => {
127 obj.insert("support_tier".to_string(), Value::String("sales".to_string()));
129 obj.insert("open_tickets".to_string(), Value::Number(1.into()));
130 obj.insert("priority".to_string(), Value::String("high".to_string()));
131 }
132 LifecycleState::PaymentFailed => {
133 obj.insert("support_tier".to_string(), Value::String("billing".to_string()));
135 obj.insert("open_tickets".to_string(), Value::Number(1.into()));
136 obj.insert("priority".to_string(), Value::String("urgent".to_string()));
137 obj.insert("ticket_type".to_string(), Value::String("payment_issue".to_string()));
138 }
139 }
140 }
141}
142
143pub fn apply_user_engagement_lifecycle_effects(response: &mut Value, lifecycle: &PersonaLifecycle) {
151 if let Some(obj) = response.as_object_mut() {
152 match lifecycle.current_state {
153 LifecycleState::NewSignup => {
154 obj.insert("status".to_string(), Value::String("new".to_string()));
156 obj.insert("engagement_level".to_string(), Value::String("low".to_string()));
157 obj.insert("last_active".to_string(), Value::String("recent".to_string()));
158 obj.insert("engagement_score".to_string(), Value::Number(10.into()));
159 obj.insert("recent_activity".to_string(), Value::Array(vec![]));
160 obj.insert(
161 "notification_preferences".to_string(),
162 Value::Object(serde_json::Map::new()),
163 );
164 obj.insert("engagement_alerts".to_string(), Value::Bool(false));
165 }
166 LifecycleState::Active => {
167 obj.insert("status".to_string(), Value::String("active".to_string()));
169 obj.insert("engagement_level".to_string(), Value::String("medium".to_string()));
170 obj.insert("last_active".to_string(), Value::String("recent".to_string()));
171 obj.insert("engagement_score".to_string(), Value::Number(75.into()));
172 obj.insert(
173 "recent_activity".to_string(),
174 Value::Array(vec![
175 serde_json::json!({"type": "login", "timestamp": "recent"}),
176 serde_json::json!({"type": "action", "timestamp": "recent"}),
177 ]),
178 );
179 obj.insert(
180 "notification_preferences".to_string(),
181 Value::Object({
182 let mut prefs = serde_json::Map::new();
183 prefs.insert("email".to_string(), Value::Bool(true));
184 prefs.insert("push".to_string(), Value::Bool(true));
185 prefs
186 }),
187 );
188 obj.insert("engagement_alerts".to_string(), Value::Bool(false));
189 }
190 LifecycleState::ChurnRisk => {
191 obj.insert("status".to_string(), Value::String("at_risk".to_string()));
193 obj.insert("engagement_level".to_string(), Value::String("low".to_string()));
194 obj.insert("last_active".to_string(), Value::String("30_days_ago".to_string()));
195 obj.insert("engagement_score".to_string(), Value::Number(25.into()));
196 obj.insert("recent_activity".to_string(), Value::Array(vec![]));
197 obj.insert(
198 "notification_preferences".to_string(),
199 Value::Object({
200 let mut prefs = serde_json::Map::new();
201 prefs.insert("email".to_string(), Value::Bool(true));
202 prefs.insert("push".to_string(), Value::Bool(false));
203 prefs
204 }),
205 );
206 obj.insert("engagement_alerts".to_string(), Value::Bool(true));
207 obj.insert(
208 "churn_risk_reason".to_string(),
209 Value::String("inactivity".to_string()),
210 );
211 }
212 LifecycleState::Churned => {
213 obj.insert("status".to_string(), Value::String("churned".to_string()));
215 obj.insert("engagement_level".to_string(), Value::String("none".to_string()));
216 obj.insert("last_active".to_string(), Value::String("90_days_ago".to_string()));
217 obj.insert("engagement_score".to_string(), Value::Number(0.into()));
218 obj.insert("recent_activity".to_string(), Value::Array(vec![]));
219 obj.insert(
220 "notification_preferences".to_string(),
221 Value::Object(serde_json::Map::new()),
222 );
223 obj.insert("engagement_alerts".to_string(), Value::Bool(false));
224 obj.insert("churned_at".to_string(), Value::String("recent".to_string()));
225 }
226 _ => {
227 obj.insert("status".to_string(), Value::String("active".to_string()));
229 obj.insert("engagement_level".to_string(), Value::String("medium".to_string()));
230 }
231 }
232 }
233}
234
235pub fn apply_order_fulfillment_lifecycle_effects(
245 response: &mut Value,
246 lifecycle: &PersonaLifecycle,
247) {
248 if let Some(obj) = response.as_object_mut() {
249 match lifecycle.current_state {
250 LifecycleState::NewSignup => {
251 obj.insert("status".to_string(), Value::String("pending".to_string()));
252 obj.insert("estimated_delivery".to_string(), Value::Null);
253 }
254 LifecycleState::Active => {
255 obj.insert("status".to_string(), Value::String("processing".to_string()));
256 obj.insert("estimated_delivery".to_string(), Value::Null);
257 }
258 LifecycleState::PowerUser => {
259 obj.insert("status".to_string(), Value::String("shipped".to_string()));
260 obj.insert("tracking_number".to_string(), Value::String("TRACK123456".to_string()));
261 obj.insert(
262 "shipped_at".to_string(),
263 Value::String(chrono::Utc::now().to_rfc3339()),
264 );
265 }
266 LifecycleState::UpgradePending => {
267 obj.insert("status".to_string(), Value::String("delivered".to_string()));
268 obj.insert(
269 "delivered_at".to_string(),
270 Value::String(chrono::Utc::now().to_rfc3339()),
271 );
272 }
273 LifecycleState::Churned => {
274 obj.insert("status".to_string(), Value::String("completed".to_string()));
275 obj.insert(
276 "completed_at".to_string(),
277 Value::String(chrono::Utc::now().to_rfc3339()),
278 );
279 }
280 _ => {
281 obj.insert("status".to_string(), Value::String("processing".to_string()));
283 }
284 }
285 }
286}
287
288pub fn apply_loan_lifecycle_effects(response: &mut Value, lifecycle: &PersonaLifecycle) {
297 if let Some(obj) = response.as_object_mut() {
298 match lifecycle.current_state {
299 LifecycleState::NewSignup => {
300 obj.insert("status".to_string(), Value::String("application".to_string()));
301 obj.insert("approved".to_string(), Value::Bool(false));
302 }
303 LifecycleState::Active => {
304 obj.insert("status".to_string(), Value::String("active".to_string()));
305 obj.insert("approved".to_string(), Value::Bool(true));
306 obj.insert(
307 "approved_at".to_string(),
308 Value::String(chrono::Utc::now().to_rfc3339()),
309 );
310 }
311 LifecycleState::PaymentFailed => {
312 obj.insert("status".to_string(), Value::String("past_due".to_string()));
313 obj.insert(
314 "days_past_due".to_string(),
315 Value::Number(
316 lifecycle
317 .get_metadata("payment_failed_count")
318 .and_then(|v| v.as_u64())
319 .unwrap_or(1)
320 .into(),
321 ),
322 );
323 }
324 LifecycleState::Churned => {
325 obj.insert("status".to_string(), Value::String("defaulted".to_string()));
326 obj.insert(
327 "defaulted_at".to_string(),
328 Value::String(chrono::Utc::now().to_rfc3339()),
329 );
330 }
331 _ => {
332 obj.insert("status".to_string(), Value::String("application".to_string()));
334 }
335 }
336 }
337}
338
339pub fn apply_lifecycle_effects(
344 response: &mut Value,
345 lifecycle: &PersonaLifecycle,
346 endpoint_type: &str,
347) {
348 match endpoint_type {
349 "billing" | "billing_status" | "payment" | "subscription" => {
350 apply_billing_lifecycle_effects(response, lifecycle);
351 }
352 "support" | "support_tickets" | "tickets" | "help" => {
353 apply_support_lifecycle_effects(response, lifecycle);
354 }
355 "order" | "orders" | "fulfillment" | "shipment" | "delivery" => {
356 apply_order_fulfillment_lifecycle_effects(response, lifecycle);
357 }
358 "loan" | "loans" | "credit" | "application" => {
359 apply_loan_lifecycle_effects(response, lifecycle);
360 }
361 "profile" | "user" | "users" | "activity" | "engagement" | "notifications"
362 | "notification" => {
363 apply_user_engagement_lifecycle_effects(response, lifecycle);
364 }
365 _ => {
366 if let Some(obj) = response.as_object_mut() {
368 let effects = lifecycle.apply_lifecycle_effects();
369 for (key, value) in effects {
370 obj.insert(key, Value::String(value));
371 }
372 }
373 }
374 }
375}
376
377#[cfg(test)]
378mod tests {
379 use super::*;
380 use crate::persona_lifecycle::PersonaLifecycle;
381 use serde_json::json;
382
383 #[test]
384 fn test_apply_billing_lifecycle_effects_new_signup() {
385 let lifecycle = PersonaLifecycle::new("user123".to_string(), LifecycleState::NewSignup);
386 let mut response = json!({});
387 apply_billing_lifecycle_effects(&mut response, &lifecycle);
388
389 assert_eq!(response["billing_status"], "pending");
390 assert_eq!(response["subscription_status"], "trial");
391 }
392
393 #[test]
394 fn test_apply_billing_lifecycle_effects_payment_failed() {
395 let lifecycle = PersonaLifecycle::new("user123".to_string(), LifecycleState::PaymentFailed);
396 let mut response = json!({});
397 apply_billing_lifecycle_effects(&mut response, &lifecycle);
398
399 assert_eq!(response["billing_status"], "failed");
400 assert_eq!(response["subscription_status"], "suspended");
401 assert_eq!(response["last_payment_failed"], true);
402 }
403
404 #[test]
405 fn test_apply_support_lifecycle_effects_churn_risk() {
406 let lifecycle = PersonaLifecycle::new("user123".to_string(), LifecycleState::ChurnRisk);
407 let mut response = json!({});
408 apply_support_lifecycle_effects(&mut response, &lifecycle);
409
410 assert_eq!(response["support_tier"], "retention");
411 assert_eq!(response["open_tickets"], 1);
412 assert_eq!(response["priority"], "high");
413 }
414
415 #[test]
416 fn test_apply_lifecycle_effects_routing() {
417 let lifecycle = PersonaLifecycle::new("user123".to_string(), LifecycleState::Active);
418 let mut billing_response = json!({});
419 apply_lifecycle_effects(&mut billing_response, &lifecycle, "billing");
420 assert_eq!(billing_response["billing_status"], "active");
421
422 let mut support_response = json!({});
423 apply_lifecycle_effects(&mut support_response, &lifecycle, "support");
424 assert_eq!(support_response["support_tier"], "standard");
425 }
426}