1use crate::auth::Plan;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct PlanLimits {
9 pub max_schedules: usize,
10 pub max_models: usize,
11 pub max_workflows: usize,
12 pub max_skills: usize,
13 pub audit_retention_days: u32,
14 pub cloud_execution: bool,
15 pub team_sharing: bool,
16 pub autocomplete: bool,
17 pub live_streaming: bool,
18 pub auto_fix: bool,
19 pub nl_workflow: bool,
20}
21
22impl PlanLimits {
23 pub fn for_plan(plan: &Plan) -> Self {
25 match plan {
26 Plan::Free => Self {
27 max_schedules: 3,
28 max_models: 2,
29 max_workflows: 10,
30 max_skills: 5,
31 audit_retention_days: 7,
32 cloud_execution: false,
33 team_sharing: false,
34 autocomplete: false,
35 live_streaming: true,
36 auto_fix: false,
37 nl_workflow: false,
38 },
39 Plan::Pro => Self {
40 max_schedules: 50,
41 max_models: 5,
42 max_workflows: 100,
43 max_skills: 50,
44 audit_retention_days: 90,
45 cloud_execution: true,
46 team_sharing: false,
47 autocomplete: false,
48 live_streaming: true,
49 auto_fix: true,
50 nl_workflow: true,
51 },
52 Plan::Team => Self {
53 max_schedules: 500,
54 max_models: 5,
55 max_workflows: 1000,
56 max_skills: 500,
57 audit_retention_days: 365,
58 cloud_execution: true,
59 team_sharing: true,
60 autocomplete: true,
61 live_streaming: true,
62 auto_fix: true,
63 nl_workflow: true,
64 },
65 }
66 }
67
68 pub fn check_schedule_limit(&self, current: usize) -> bool {
70 current < self.max_schedules
71 }
72
73 pub fn check_workflow_limit(&self, current: usize) -> bool {
74 current < self.max_workflows
75 }
76
77 pub fn check_skill_limit(&self, current: usize) -> bool {
78 current < self.max_skills
79 }
80}
81
82pub fn plan_comparison() -> String {
84 r#"
85┌─────────────────┬──────────┬──────────┬──────────┐
86│ Feature │ Free │ Pro $9/m │ Team $49 │
87├─────────────────┼──────────┼──────────┼──────────┤
88│ Workflows │ 10 │ 100 │ 1000 │
89│ Schedules │ 3 │ 50 │ 500 │
90│ Models │ 2 │ 5 │ 5 │
91│ Audit Retention │ 7 days │ 90 days │ 365 days │
92│ Cloud Execution │ ✗ │ ✓ │ ✓ │
93│ Auto-fix │ ✗ │ ✓ │ ✓ │
94│ NL → Workflow │ ✗ │ ✓ │ ✓ │
95│ Team Sharing │ ✗ │ ✗ │ ✓ │
96│ Autocomplete │ ✗ │ ✗ │ ✓ │
97└─────────────────┴──────────┴──────────┴──────────┘
98"#
99 .to_string()
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn test_free_limits() {
108 let limits = PlanLimits::for_plan(&Plan::Free);
109 assert_eq!(limits.max_schedules, 3);
110 assert!(!limits.cloud_execution);
111 assert!(!limits.auto_fix);
112 }
113
114 #[test]
115 fn test_pro_limits() {
116 let limits = PlanLimits::for_plan(&Plan::Pro);
117 assert_eq!(limits.max_schedules, 50);
118 assert!(limits.cloud_execution);
119 assert!(limits.auto_fix);
120 assert!(!limits.team_sharing);
121 }
122
123 #[test]
124 fn test_team_limits() {
125 let limits = PlanLimits::for_plan(&Plan::Team);
126 assert!(limits.team_sharing);
127 assert!(limits.autocomplete);
128 assert_eq!(limits.audit_retention_days, 365);
129 }
130
131 #[test]
132 fn test_schedule_limit_check() {
133 let limits = PlanLimits::for_plan(&Plan::Free);
134 assert!(limits.check_schedule_limit(2));
135 assert!(!limits.check_schedule_limit(3));
136 }
137}