File size: 6,851 Bytes
d0fdbcd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Runtime simulator to validate that generated configs can actually execute.
Simulates app initialization and operation to detect execution errors early.
"""

from typing import Any, Dict, List, Optional
import json


class RuntimeSimulator:
    """Simulates execution of generated application configuration."""
    
    def __init__(self, config: Dict[str, Any]):
        self.config = config
        self.errors = []
        self.warnings = []
        self.simulation_log = []
    
    def validate_executability(self) -> bool:
        """Check if config can be executed without errors."""
        checks = [
            self._check_database_schema,
            self._check_api_endpoints,
            self._check_ui_pages,
            self._check_authentication,
            self._check_business_logic,
            self._simulate_user_flow,
        ]
        
        for check in checks:
            try:
                check()
            except Exception as e:
                self.errors.append(f"{check.__name__}: {str(e)}")
        
        return len(self.errors) == 0
    
    def _check_database_schema(self):
        """Simulate database initialization."""
        db_schema = self.config.get("database_schema", [])
        
        if not db_schema:
            self.warnings.append("No database schema defined")
            return
        
        for table in db_schema:
            # Check table can be created
            if not self._can_create_table(table):
                raise ValueError(f"Cannot create table '{table.get('name')}'")
            
            self.simulation_log.append(f"βœ“ Database table '{table['name']}' initialized")
    
    def _can_create_table(self, table: Dict[str, Any]) -> bool:
        """Check if a table can be created."""
        required = ["name", "fields", "primary_key"]
        if not all(k in table for k in required):
            return False
        
        if not isinstance(table["fields"], list):
            return False
        
        primary_key = table["primary_key"]
        field_names = [f.get("name") if isinstance(f, dict) else f for f in table["fields"]]
        
        if primary_key not in field_names:
            raise ValueError(f"Primary key '{primary_key}' not found in fields")
        
        return True
    
    def _check_api_endpoints(self):
        """Simulate API initialization."""
        api_schema = self.config.get("api_schema", [])
        
        if not api_schema:
            self.warnings.append("No API endpoints defined")
            return
        
        valid_methods = ["GET", "POST", "PUT", "DELETE", "PATCH"]
        
        for endpoint in api_schema:
            if not isinstance(endpoint, dict):
                raise ValueError("API endpoint is not a dict")
            
            if "path" not in endpoint or "method" not in endpoint:
                raise ValueError(f"API endpoint missing path or method: {endpoint}")
            
            if endpoint["method"] not in valid_methods:
                raise ValueError(f"Invalid HTTP method: {endpoint['method']}")
            
            self.simulation_log.append(f"βœ“ API endpoint '{endpoint['method']} {endpoint['path']}' registered")
    
    def _check_ui_pages(self):
        """Simulate UI initialization."""
        ui_schema = self.config.get("ui_schema", [])
        
        if not ui_schema:
            self.warnings.append("No UI pages defined")
            return
        
        for page in ui_schema:
            if not isinstance(page, dict):
                raise ValueError("UI page is not a dict")
            
            if "path" not in page or "title" not in page:
                raise ValueError(f"UI page missing path or title: {page}")
            
            if "components" not in page or not isinstance(page["components"], list):
                raise ValueError(f"UI page '{page['path']}' has no components")
            
            self.simulation_log.append(f"βœ“ UI page '{page['path']}' ({page['title']}) registered")
    
    def _check_authentication(self):
        """Simulate authentication system initialization."""
        auth_config = self.config.get("auth_config", {})
        roles = self.config.get("roles", [])
        
        if not auth_config:
            self.warnings.append("No auth config defined")
            return
        
        if "type" not in auth_config:
            raise ValueError("Auth config missing 'type'")
        
        if not roles:
            raise ValueError("No roles defined for authorization")
        
        role_names = set()
        for role in roles:
            if not isinstance(role, dict) or "name" not in role:
                raise ValueError(f"Invalid role definition: {role}")
            role_names.add(role["name"])
        
        self.simulation_log.append(f"βœ“ Authentication system initialized with {len(roles)} roles")
    
    def _check_business_logic(self):
        """Validate business logic consistency."""
        business_logic = self.config.get("business_logic", {})
        
        if isinstance(business_logic, dict):
            for key, value in business_logic.items():
                if value is None:
                    self.warnings.append(f"Business logic '{key}' is None")
            
            self.simulation_log.append(f"βœ“ Business logic validated ({len(business_logic)} rules)")
    
    def _simulate_user_flow(self):
        """Simulate a typical user flow."""
        # Typical flow: login β†’ access dashboard β†’ perform action
        
        # Check login page exists
        ui_pages = self.config.get("ui_schema", [])
        login_page = next((p for p in ui_pages if "login" in p.get("path", "").lower()), None)
        
        if not login_page:
            self.warnings.append("No login page found")
        
        # Check for dashboard
        dashboard = next((p for p in ui_pages if "dashboard" in p.get("path", "").lower()), None)
        
        if dashboard:
            self.simulation_log.append("βœ“ User flow validated: Login β†’ Dashboard")
        else:
            self.warnings.append("No dashboard page found in user flow")
    
    def get_report(self) -> Dict[str, Any]:
        """Generate execution report."""
        return {
            "is_executable": len(self.errors) == 0,
            "errors": self.errors,
            "warnings": self.warnings,
            "simulation_log": self.simulation_log,
            "total_checks": len(self.simulation_log) + len(self.errors) + len(self.warnings),
        }


def validate_config_executable(config: Dict[str, Any]) -> tuple[bool, Dict[str, Any]]:
    """Quick check if config is executable."""
    simulator = RuntimeSimulator(config)
    is_executable = simulator.validate_executability()
    return is_executable, simulator.get_report()