1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct DomainEndUserClaims {
9 pub sub: String,
11
12 pub domain_id: String,
14
15 pub domain: String,
17
18 pub roles: Vec<String>,
20
21 pub subscription: SubscriptionClaims,
23
24 pub exp: i64,
26
27 pub iat: i64,
29}
30
31#[derive(Debug, Clone, Default, Serialize, Deserialize)]
35pub struct SubscriptionClaims {
36 pub status: String,
38
39 pub plan_code: Option<String>,
41
42 pub plan_name: Option<String>,
44
45 pub current_period_end: Option<i64>,
47
48 pub cancel_at_period_end: Option<bool>,
50
51 pub trial_ends_at: Option<i64>,
53
54 pub subscription_id: Option<String>,
56}
57
58impl SubscriptionClaims {
59 pub fn none() -> Self {
61 Self {
62 status: "none".to_string(),
63 ..Default::default()
64 }
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_subscription_claims_none() {
74 let sub = SubscriptionClaims::none();
75 assert_eq!(sub.status, "none");
76 assert!(sub.plan_code.is_none());
77 assert!(sub.plan_name.is_none());
78 }
79
80 #[test]
81 fn test_domain_end_user_claims_serde() {
82 let claims = DomainEndUserClaims {
83 sub: "user123".to_string(),
84 domain_id: "00000000-0000-0000-0000-000000000001".to_string(),
85 domain: "example.com".to_string(),
86 roles: vec!["user".to_string()],
87 subscription: SubscriptionClaims {
88 status: "active".to_string(),
89 plan_code: Some("pro".to_string()),
90 plan_name: Some("Pro Plan".to_string()),
91 current_period_end: Some(1735689600),
92 cancel_at_period_end: Some(false),
93 trial_ends_at: None,
94 subscription_id: Some("sub_123".to_string()),
95 },
96 exp: 1735689600,
97 iat: 1735603200,
98 };
99
100 let json = serde_json::to_string(&claims).unwrap();
101 let parsed: DomainEndUserClaims = serde_json::from_str(&json).unwrap();
102
103 assert_eq!(parsed.sub, "user123");
104 assert_eq!(parsed.domain, "example.com");
105 assert_eq!(parsed.subscription.status, "active");
106 }
107}