File size: 10,380 Bytes
383cb38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#!/usr/bin/env python3
"""
Production Setup Script
Environment configuration cleanup and production preparation
"""

from datetime import datetime
import json
import os
import subprocess
import sys
from typing import Any, Dict, List


class ProductionSetup:
    """Production environment setup and configuration"""

    def __init__(self):
        self.project_root = os.path.dirname(os.path.abspath(__file__))
        self.results = {
            "timestamp": datetime.now().isoformat(),
            "setup_steps": {},
            "summary": {"total": 0, "completed": 0, "failed": 0},
        }

    def log_step(self, step_name: str, success: bool, details: str = ""):
        """Log setup step result"""
        self.results["summary"]["total"] += 1
        if success:
            self.results["summary"]["completed"] += 1
            status = "✅ COMPLETED"
        else:
            self.results["summary"]["failed"] += 1
            status = "❌ FAILED"

        self.results["setup_steps"][step_name] = {
            "status": "completed" if success else "failed",
            "timestamp": datetime.now().isoformat(),
            "details": details,
        }

        print(f"{status} {step_name}")
        if details:
            print(f"   {details}")

    def check_environment_file(self):
        """Check and validate .env file"""
        env_file = os.path.join(self.project_root, ".env")
        
        try:
            if os.path.exists(env_file):
                with open(env_file, 'r') as f:
                    lines = f.readlines()
                
                # Check for common issues
                issues = []
                for i, line in enumerate(lines, 1):
                    line = line.strip()
                    if not line or line.startswith('#'):
                        continue
                    if ':' in line and '=' not in line:
                        issues.append(f"Line {i}: Using ':' instead of '='")
                    if 'export ' in line:
                        issues.append(f"Line {i}: Contains 'export' keyword")
                
                if issues:
                    self.log_step("Environment File Check", False, f"Issues found: {'; '.join(issues)}")
                else:
                    self.log_step("Environment File Check", True, f"Valid format ({len(lines)} lines)")
            else:
                self.log_step("Environment File Check", False, "File not found")
        except Exception as e:
            self.log_step("Environment File Check", False, str(e))

    def check_required_packages(self):
        """Check if required packages are installed"""
        required_packages = [
            "flask", "requests", "python-dotenv", "loguru"
        ]
        
        missing_packages = []
        for package in required_packages:
            try:
                __import__(package)
            except ImportError:
                missing_packages.append(package)
        
        if missing_packages:
            self.log_step("Required Packages Check", False, f"Missing: {', '.join(missing_packages)}")
        else:
            self.log_step("Required Packages Check", True, "All required packages installed")

    def check_service_endpoints(self):
        """Check if service endpoints are accessible"""
        endpoints = [
            "http://localhost:5058/health",
            "http://localhost:5058/api/integrations/google/health",
            "http://localhost:5058/api/integrations/asana/health",
            "http://localhost:5058/api/integrations/slack/health",
            "http://localhost:5058/api/integrations/notion/health",
            "http://localhost:5058/api/integrations/teams/health"
        ]
        
        accessible_endpoints = []
        failed_endpoints = []
        
        try:
            import requests
            for endpoint in endpoints:
                try:
                    response = requests.get(endpoint, timeout=5)
                    if response.status_code == 200:
                        accessible_endpoints.append(endpoint)
                    else:
                        failed_endpoints.append(f"{endpoint} (status: {response.status_code})")
                except Exception:
                    failed_endpoints.append(f"{endpoint} (connection failed)")
            
            if len(accessible_endpoints) == len(endpoints):
                self.log_step("Service Endpoints Check", True, f"All {len(endpoints)} endpoints accessible")
            else:
                self.log_step("Service Endpoints Check", False, f"{len(accessible_endpoints)}/{len(endpoints)} accessible")
                for failed in failed_endpoints:
                    print(f"   ❌ {failed}")
        except ImportError:
            self.log_step("Service Endpoints Check", False, "requests package not available")

    def check_database_connections(self):
        """Check database connectivity"""
        db_files = [
            "backend/python-api-service/atom.db",
            "backend/python-api-service/integrations.db"
        ]
        
        available_dbs = []
        for db_file in db_files:
            full_path = os.path.join(self.project_root, db_file)
            if os.path.exists(full_path):
                available_dbs.append(db_file)
        
        if available_dbs:
            self.log_step("Database Connections Check", True, f"Available: {', '.join(available_dbs)}")
        else:
            self.log_step("Database Connections Check", False, "No database files found")

    def check_security_configuration(self):
        """Check security configurations"""
        security_issues = []
        
        # Check for hardcoded secrets
        env_file = os.path.join(self.project_root, ".env")
        if os.path.exists(env_file):
            with open(env_file, 'r') as f:
                content = f.read()
                if "test_key" in content.lower() or "demo_key" in content.lower():
                    security_issues.append("Demo/test keys found in .env")
        
        # Check for exposed endpoints
        try:
            import requests
            response = requests.get("http://localhost:5058/api/auth/debug", timeout=5)
            if response.status_code == 200:
                security_issues.append("Debug endpoint exposed")
        except:
            pass  # Debug endpoint not accessible
        
        if security_issues:
            self.log_step("Security Configuration Check", False, f"Issues: {'; '.join(security_issues)}")
        else:
            self.log_step("Security Configuration Check", True, "No obvious security issues")

    def check_frontend_configuration(self):
        """Check frontend configuration"""
        frontend_dirs = [
            "frontend-nextjs/pages",
            "frontend-nextjs/src",
            "frontend-nextjs/public"
        ]
        
        available_dirs = []
        for frontend_dir in frontend_dirs:
            full_path = os.path.join(self.project_root, frontend_dir)
            if os.path.exists(full_path):
                available_dirs.append(frontend_dir)
        
        # Check package.json
        package_json = os.path.join(self.project_root, "frontend-nextjs/package.json")
        package_exists = os.path.exists(package_json)
        
        if available_dirs and package_exists:
            self.log_step("Frontend Configuration Check", True, f"Available dirs: {len(available_dirs)}, package.json exists")
        else:
            self.log_step("Frontend Configuration Check", False, f"Missing directories or package.json")

    def generate_production_config(self):
        """Generate production configuration recommendations"""
        recommendations = [
            "Set production environment variables",
            "Configure HTTPS/SSL certificates",
            "Enable API rate limiting",
            "Set up monitoring and logging",
            "Configure database backups",
            "Enable security headers",
            "Set up error reporting",
            "Configure load balancing"
        ]
        
        self.log_step("Production Config Generation", True, f"Generated {len(recommendations)} recommendations")
        
        # Save recommendations to file
        config_file = os.path.join(self.project_root, "PRODUCTION_RECOMMENDATIONS.md")
        with open(config_file, 'w') as f:
            f.write("# Production Deployment Recommendations\n\n")
            f.write(f"Generated: {datetime.now().isoformat()}\n\n")
            for i, rec in enumerate(recommendations, 1):
                f.write(f"{i}. {rec}\n")
        
        print(f"   💾 Saved to: PRODUCTION_RECOMMENDATIONS.md")

    def run_setup(self):
        """Run complete production setup"""
        print("🚀 Starting Production Setup")
        print("=" * 50)
        
        self.check_environment_file()
        self.check_required_packages()
        self.check_service_endpoints()
        self.check_database_connections()
        self.check_security_configuration()
        self.check_frontend_configuration()
        self.generate_production_config()
        
        # Print summary
        print("\n" + "=" * 50)
        print("📊 Setup Summary")
        total = self.results["summary"]["total"]
        completed = self.results["summary"]["completed"]
        failed = self.results["summary"]["failed"]
        
        print(f"Total Steps: {total}")
        print(f"Completed: {completed}")
        print(f"Failed: {failed}")
        print(f"Success Rate: {(completed/total*100):.1f}%")
        
        # Save results
        results_file = os.path.join(self.project_root, "production_setup_results.json")
        with open(results_file, 'w') as f:
            json.dump(self.results, f, indent=2)
        print(f"\n📄 Results saved to: production_setup_results.json")
        
        return self.results


def main():
    """Main execution function"""
    setup = ProductionSetup()
    results = setup.run_setup()
    
    if results["summary"]["failed"] == 0:
        print("\n🎉 Production Setup: EXCELLENT - Ready for deployment!")
    elif results["summary"]["failed"] <= 2:
        print("\n✅ Production Setup: GOOD - Minor issues to address")
    else:
        print("\n⚠️  Production Setup: NEEDS ATTENTION - Multiple issues to fix")


if __name__ == "__main__":
    main()