Files
orion/scripts/validate_all.py
Samir Boulahtit 82c07c165f feat: add customer profile, VAT alignment, and fix shop auth
Customer Profile:
- Add profile API (GET/PUT /api/v1/shop/profile)
- Add password change endpoint (PUT /api/v1/shop/profile/password)
- Implement full profile page with preferences and password sections
- Add CustomerPasswordChange schema

Shop Authentication Fixes:
- Add Authorization header to all shop account API calls
- Fix orders, order-detail, messages pages authentication
- Add proper redirect to login on 401 responses
- Fix toast message showing noqa comment in shop-layout.js

VAT Calculation:
- Add shared VAT utility (app/utils/vat.py)
- Add VAT fields to Order model (vat_regime, vat_rate, etc.)
- Align order VAT calculation with invoice settings
- Add migration for VAT fields on orders

Validation Framework:
- Fix base_validator.py with missing methods
- Add validate_file, output_results, get_exit_code methods
- Fix validate_all.py import issues

Documentation:
- Add launch-readiness.md tracking OMS status
- Update to 95% feature complete

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 20:31:48 +01:00

217 lines
7.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Unified Code Validator
======================
Runs all validation scripts (architecture, security, performance) in sequence.
This provides a single entry point for comprehensive code validation,
useful for CI/CD pipelines and pre-commit hooks.
Usage:
python scripts/validate_all.py # Run all validators
python scripts/validate_all.py --security # Run only security validator
python scripts/validate_all.py --performance # Run only performance validator
python scripts/validate_all.py --architecture # Run only architecture validator
python scripts/validate_all.py -v # Verbose output
python scripts/validate_all.py --fail-fast # Stop on first failure
python scripts/validate_all.py --json # JSON output
Options:
--architecture Run architecture validator
--security Run security validator
--performance Run performance validator
--fail-fast Stop on first validator failure
-v, --verbose Show detailed output
--errors-only Only show errors
--json Output results as JSON
"""
import argparse
import json
import sys
from pathlib import Path
# Add parent directory to path for imports
sys.path.insert(0, str(Path(__file__).parent))
def run_architecture_validator(verbose: bool = False) -> tuple[int, dict]:
"""Run the architecture validator"""
try:
# Import dynamically to avoid circular imports
sys.path.insert(0, str(Path(__file__).parent.parent))
from scripts.validate_architecture import ArchitectureValidator
config_path = Path.cwd() / ".architecture-rules.yaml"
validator = ArchitectureValidator(config_path=config_path, verbose=verbose)
result = validator.validate_all()
return (
1 if result.has_errors() else 0,
{
"name": "Architecture",
"files_checked": result.files_checked,
"errors": sum(1 for v in result.violations if v.severity.value == "error"),
"warnings": sum(1 for v in result.violations if v.severity.value == "warning"),
"info": sum(1 for v in result.violations if v.severity.value == "info"),
}
)
except ImportError as e:
print(f"⚠️ Architecture validator not available: {e}")
return 0, {"name": "Architecture", "skipped": True}
except Exception as e:
print(f"❌ Architecture validator failed: {e}")
return 1, {"name": "Architecture", "error": str(e)}
def run_security_validator(verbose: bool = False) -> tuple[int, dict]:
"""Run the security validator"""
try:
from validate_security import SecurityValidator
validator = SecurityValidator(verbose=verbose)
result = validator.validate_all()
return (
1 if result.has_errors() else 0,
{
"name": "Security",
"files_checked": result.files_checked,
"errors": result.error_count(),
"warnings": result.warning_count(),
"info": result.info_count(),
}
)
except ImportError as e:
print(f"⚠️ Security validator not available: {e}")
return 0, {"name": "Security", "skipped": True}
except Exception as e:
print(f"❌ Security validator failed: {e}")
return 1, {"name": "Security", "error": str(e)}
def run_performance_validator(verbose: bool = False) -> tuple[int, dict]:
"""Run the performance validator"""
try:
from validate_performance import PerformanceValidator
validator = PerformanceValidator(verbose=verbose)
result = validator.validate_all()
return (
1 if result.has_errors() else 0,
{
"name": "Performance",
"files_checked": result.files_checked,
"errors": result.error_count(),
"warnings": result.warning_count(),
"info": result.info_count(),
}
)
except ImportError as e:
print(f"⚠️ Performance validator not available: {e}")
return 0, {"name": "Performance", "skipped": True}
except Exception as e:
print(f"❌ Performance validator failed: {e}")
return 1, {"name": "Performance", "error": str(e)}
def print_summary(results: list[dict], json_output: bool = False):
"""Print validation summary"""
if json_output:
print(json.dumps({"validators": results}, indent=2))
return
print("\n" + "=" * 80)
print("📊 UNIFIED VALIDATION SUMMARY")
print("=" * 80)
total_errors = 0
total_warnings = 0
total_info = 0
for result in results:
if result.get("skipped"):
print(f"\n⏭️ {result['name']}: Skipped")
elif result.get("error"):
print(f"\n{result['name']}: Error - {result['error']}")
else:
errors = result.get("errors", 0)
warnings = result.get("warnings", 0)
info = result.get("info", 0)
total_errors += errors
total_warnings += warnings
total_info += info
status = "" if errors == 0 else ""
print(f"\n{status} {result['name']}:")
print(f" Files: {result.get('files_checked', 0)}")
print(f" Errors: {errors}, Warnings: {warnings}, Info: {info}")
print("\n" + "-" * 80)
print(f"TOTAL: {total_errors} errors, {total_warnings} warnings, {total_info} info")
print("=" * 80)
if total_errors > 0:
print("❌ VALIDATION FAILED")
elif total_warnings > 0:
print(f"⚠️ VALIDATION PASSED WITH {total_warnings} WARNING(S)")
else:
print("✅ VALIDATION PASSED")
print("=" * 80)
def main():
parser = argparse.ArgumentParser(
description="Unified code validator - runs architecture, security, and performance checks",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("--architecture", action="store_true", help="Run architecture validator")
parser.add_argument("--security", action="store_true", help="Run security validator")
parser.add_argument("--performance", action="store_true", help="Run performance validator")
parser.add_argument("--fail-fast", action="store_true", help="Stop on first failure")
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
parser.add_argument("--errors-only", action="store_true", help="Only show errors")
parser.add_argument("--json", action="store_true", help="JSON output")
args = parser.parse_args()
# If no specific validators selected, run all
run_all = not (args.architecture or args.security or args.performance)
print("\n🔍 UNIFIED CODE VALIDATION")
print("=" * 80)
validators = []
if run_all or args.architecture:
validators.append(("Architecture", run_architecture_validator))
if run_all or args.security:
validators.append(("Security", run_security_validator))
if run_all or args.performance:
validators.append(("Performance", run_performance_validator))
results = []
exit_code = 0
for name, validator_func in validators:
print(f"\n{'=' * 40}")
print(f"🔍 Running {name} Validator...")
print("=" * 40)
code, result = validator_func(verbose=args.verbose)
results.append(result)
if code != 0:
exit_code = 1
if args.fail_fast:
print(f"\n{name} validator failed. Stopping (--fail-fast)")
break
print_summary(results, json_output=args.json)
sys.exit(exit_code)
if __name__ == "__main__":
main()