Team Ai
Apppublic

2008robocode-crypto/code-generation-system

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
validator.py272 linesDownload Raw Back to src
1"""2Validation engine for detecting and reporting issues in generated schemas.3Checks for: invalid JSON, missing keys, type mismatches, cross-layer inconsistencies.4"""5 6import json7from typing import Any, Dict, List, Optional, Tuple8from schemas import ValidationResult, GeneratedConfig, DBTable, APIEndpoint, UIPage, Role, FieldType9 10 11class Validator:12    """Comprehensive validation for generated configurations."""13    14    def __init__(self):15        self.result = ValidationResult()16    17    def validate_json(self, json_str: str) -> Tuple[bool, Optional[Dict[str, Any]]]:18        """Validate if string is valid JSON."""19        try:20            data = json.loads(json_str)21            return True, data22        except json.JSONDecodeError as e:23            self.result.add_error(f"Invalid JSON: {str(e)}")24            return False, None25    26    def validate_required_fields(self, data: Dict[str, Any], required_fields: List[str]) -> bool:27        """Check if all required fields are present."""28        missing = [f for f in required_fields if f not in data or data[f] is None]29        if missing:30            self.result.add_error(f"Missing required fields: {', '.join(missing)}")31            return False32        return True33    34    def validate_generated_config_structure(self, config_dict: Dict[str, Any]) -> bool:35        """Validate top-level structure of GeneratedConfig."""36        required_fields = [37            "app_name", "app_description", "database_schema", 38            "api_schema", "ui_schema", "auth_config", "roles", "business_logic"39        ]40        return self.validate_required_fields(config_dict, required_fields)41    42    def validate_database_schema(self, db_schema: List[Dict[str, Any]]) -> bool:43        """Validate database schema integrity."""44        if not isinstance(db_schema, list):45            self.result.add_error("database_schema must be a list")46            return False47        48        table_names = set()49        is_valid = True50        51        for i, table in enumerate(db_schema):52            if not isinstance(table, dict):53                self.result.add_error(f"Table {i} is not a dict")54                is_valid = False55                continue56            57            # Check required fields58            if "name" not in table or "fields" not in table or "primary_key" not in table:59                self.result.add_error(f"Table {i}: missing name, fields, or primary_key")60                is_valid = False61                continue62            63            table_names.add(table["name"])64            65            # Validate fields66            if not isinstance(table["fields"], list):67                self.result.add_error(f"Table '{table['name']}': fields must be a list")68                is_valid = False69                continue70            71            # Validate field types72            for field in table["fields"]:73                if not self._validate_field(field, table["name"]):74                    is_valid = False75        76        # Validate foreign key relations77        for table in db_schema:78            if "relations" in table and table["relations"]:79                for field, related_table in table["relations"].items():80                    if related_table not in table_names:81                        self.result.add_warning(82                            f"Foreign key in {table['name']}.{field} references non-existent table: {related_table}"83                        )84        85        return is_valid86    87    def _validate_field(self, field: Dict[str, Any], table_name: str) -> bool:88        """Validate a single field."""89        if not isinstance(field, dict):90            self.result.add_error(f"Field in {table_name} is not a dict")91            return False92        93        required = ["name", "type"]94        if not all(k in field for k in required):95            self.result.add_error(f"Field in {table_name}: missing name or type")96            return False97        98        field_type = field["type"]99        valid_types = [t.value for t in FieldType]100        if field_type not in valid_types:101            self.result.add_error(102                f"Field '{field['name']}' in {table_name}: invalid type '{field_type}'"103            )104            return False105        106        return True107    108    def validate_api_schema(self, api_schema: List[Dict[str, Any]]) -> bool:109        """Validate API schema structure."""110        if not isinstance(api_schema, list):111            self.result.add_error("api_schema must be a list")112            return False113        114        valid_methods = ["GET", "POST", "PUT", "DELETE", "PATCH"]115        is_valid = True116        117        for i, endpoint in enumerate(api_schema):118            if not isinstance(endpoint, dict):119                self.result.add_error(f"Endpoint {i} is not a dict")120                is_valid = False121                continue122            123            # Check required fields124            if "path" not in endpoint or "method" not in endpoint:125                self.result.add_error(f"Endpoint {i}: missing path or method")126                is_valid = False127                continue128            129            # Validate method130            if endpoint["method"] not in valid_methods:131                self.result.add_error(132                    f"Endpoint {endpoint['path']}: invalid method '{endpoint['method']}'"133                )134                is_valid = False135        136        return is_valid137    138    def validate_ui_schema(self, ui_schema: List[Dict[str, Any]]) -> bool:139        """Validate UI schema structure."""140        if not isinstance(ui_schema, list):141            self.result.add_error("ui_schema must be a list")142            return False143        144        is_valid = True145        146        for i, page in enumerate(ui_schema):147            if not isinstance(page, dict):148                self.result.add_error(f"Page {i} is not a dict")149                is_valid = False150                continue151            152            required = ["path", "title", "components"]153            if not all(k in page for k in required):154                self.result.add_error(f"Page {i}: missing path, title, or components")155                is_valid = False156                continue157            158            if not isinstance(page["components"], list):159                self.result.add_error(f"Page {i}: components must be a list")160                is_valid = False161        162        return is_valid163    164    def validate_cross_layer_consistency(self, config_dict: Dict[str, Any]) -> bool:165        """Validate consistency between API, DB, and UI layers."""166        is_valid = True167        168        # Extract API fields169        api_fields = set()170        for endpoint in config_dict.get("api_schema", []):171            if endpoint.get("request_body"):172                api_fields.update(endpoint["request_body"].keys())173            if endpoint.get("response_body"):174                api_fields.update(endpoint["response_body"].keys())175        176        # Extract DB fields177        db_fields = set()178        for table in config_dict.get("database_schema", []):179            for field in table.get("fields", []):180                if isinstance(field, dict):181                    db_fields.add(field.get("name"))182                elif hasattr(field, "name"):183                    db_fields.add(field.name)184        185        # Extract UI fields186        ui_fields = set()187        for page in config_dict.get("ui_schema", []):188            for component in page.get("components", []):189                if isinstance(component, dict):190                    ui_fields.update(component.get("fields", {}).keys() if isinstance(component.get("fields"), dict) else [])191        192        # Check consistency193        if api_fields and db_fields:194            # API fields should reference DB fields (not strict - API can have computed fields)195            missing_db_fields = api_fields - db_fields196            if missing_db_fields and len(missing_db_fields) > 3:  # Allow some computed fields197                self.result.add_warning(198                    f"API references fields not in DB: {missing_db_fields}"199                )200        201        return is_valid202    203    def validate_roles_and_permissions(self, roles: List[Dict[str, Any]], 204                                       api_schema: List[Dict[str, Any]]) -> bool:205        """Validate roles match API requirements."""206        is_valid = True207        208        if not isinstance(roles, list):209            self.result.add_error("roles must be a list")210            return False211        212        role_names = set()213        for role in roles:214            if not isinstance(role, dict) or "name" not in role:215                self.result.add_error("Each role must be a dict with 'name'")216                is_valid = False217                continue218            role_names.add(role["name"])219        220        # Check if API endpoints reference existing roles221        for endpoint in api_schema:222            required_role = endpoint.get("required_role")223            if required_role and required_role not in role_names:224                self.result.add_warning(225                    f"API endpoint {endpoint.get('path')} requires role '{required_role}' which doesn't exist"226                )227        228        return is_valid229    230    def validate_no_hallucinations(self, config_dict: Dict[str, Any]) -> bool:231        """Detect hallucinated or nonsensical fields."""232        is_valid = True233        234        # Check for common hallucination patterns235        for key, value in config_dict.items():236            if isinstance(value, str):237                # Check for placeholder text238                if any(p in value.lower() for p in ["todo", "placeholder", "tbd", "fix me"]):239                    self.result.add_warning(f"Potential placeholder in {key}: {value}")240            241            # Check for values that don't match their keys semantically242            if key == "business_logic" and not isinstance(value, dict):243                self.result.add_error(f"{key} should be a dict, got {type(value)}")244                is_valid = False245        246        return is_valid247    248    def validate_complete(self, config_dict: Dict[str, Any]) -> ValidationResult:249        """Run complete validation suite."""250        self.result = ValidationResult()251        252        # Structure validation253        if not self.validate_generated_config_structure(config_dict):254            return self.result255        256        # Layer-specific validation257        self.validate_database_schema(config_dict.get("database_schema", []))258        self.validate_api_schema(config_dict.get("api_schema", []))259        self.validate_ui_schema(config_dict.get("ui_schema", []))260        261        # Cross-layer validation262        self.validate_cross_layer_consistency(config_dict)263        self.validate_roles_and_permissions(264            config_dict.get("roles", []),265            config_dict.get("api_schema", [])266        )267        268        # Hallucination detection269        self.validate_no_hallucinations(config_dict)270        271        return self.result272