# Architecture Validation Scripts

This directory contains scripts for validating and enforcing architectural patterns across the codebase.

## Architecture Validator

### Overview

`validate_architecture.py` is an automated tool that checks the codebase against architectural rules defined in `.architecture-rules.yaml`.

### Key Features

- **API Endpoint Validation**: Ensures proper separation of concerns, Pydantic usage, exception handling
- **Service Layer Validation**: Enforces domain exceptions, database session patterns
- **Model Validation**: Checks proper separation of SQLAlchemy and Pydantic models
- **Exception Handling**: Validates proper exception patterns
- **JavaScript Patterns**: Enforces coding standards for frontend code
- **Template Validation**: Ensures templates follow required patterns

### Usage

```bash
# Validate entire codebase
python scripts/validate/validate_architecture.py

# Validate specific directory
python scripts/validate/validate_architecture.py app/api/

# Verbose output with code context
python scripts/validate/validate_architecture.py --verbose

# Show only errors (suppress warnings)
python scripts/validate/validate_architecture.py --errors-only

# Use custom config file
python scripts/validate/validate_architecture.py --config custom-rules.yaml
```

### Exit Codes

- `0`: Validation passed (warnings allowed)
- `1`: Validation failed (errors found)

### Integration with Pre-commit

Install pre-commit hooks to run validation automatically:

```bash
# Install pre-commit
pip install pre-commit

# Setup hooks
pre-commit install

# Run manually on all files
pre-commit run --all-files

# Run on staged files only
pre-commit run
```

### Configuration

The validation rules are defined in `.architecture-rules.yaml` at the project root. This file contains:

- **Core Principles**: Separation of concerns, type safety, exception handling
- **API Endpoint Rules**: (API-001 through API-004)
- **Service Layer Rules**: (SVC-001 through SVC-004)
- **Model Rules**: (MDL-001 through MDL-002)
- **Exception Rules**: (EXC-001 through EXC-002)
- **JavaScript Rules**: (JS-001 through JS-003)
- **Template Rules**: (TPL-001)

### Rule Categories

#### API Endpoint Rules

- **API-001**: Use Pydantic models for request/response
- **API-002**: No business logic in endpoints
- **API-003**: Proper exception handling (catch and convert to HTTPException)
- **API-004**: Authentication on protected endpoints

#### Service Layer Rules

- **SVC-001**: No HTTPException in services (use domain exceptions)
- **SVC-002**: Create custom exception classes (avoid generic Exception)
- **SVC-003**: Database session as parameter (not created internally)
- **SVC-004**: Use Pydantic for input validation

#### Model Rules

- **MDL-001**: Use SQLAlchemy Base for database models
- **MDL-002**: Separate Pydantic from SQLAlchemy models

#### Exception Rules

- **EXC-001**: Define custom exceptions in exceptions module
- **EXC-002**: Never use bare except

#### JavaScript Rules

- **JS-001**: Use apiClient directly (not window.apiClient)
- **JS-002**: Use centralized logger (not console)
- **JS-003**: Alpine components must spread ...data()

### Example Output

```
🔍 Starting architecture validation...

📡 Validating API endpoints...
🔧 Validating service layer...
📦 Validating models...
⚠️  Validating exception handling...
🟨 Validating JavaScript...
📄 Validating templates...

================================================================================
📊 ARCHITECTURE VALIDATION REPORT
================================================================================

Files checked: 145
Total violations: 3

❌ ERRORS (2):
--------------------------------------------------------------------------------

  [API-002] Endpoint must NOT contain business logic
  File: app/api/v1/admin/stores.py:45
  Issue: Database operations should be in service layer
  💡 Suggestion: Move database operations to service layer

  [SVC-001] Service must NOT raise HTTPException
  File: app/services/store_service.py:78
  Issue: Service raises HTTPException - use domain exceptions instead
  💡 Suggestion: Create custom exception class (e.g., StoreNotFoundError) and raise that

⚠️  WARNINGS (1):
--------------------------------------------------------------------------------

  [JS-001] Use apiClient directly
  File: static/admin/js/stores.js:23
  Issue: Use apiClient directly instead of window.apiClient
  💡 Suggestion: Replace window.apiClient with apiClient

================================================================================
❌ VALIDATION FAILED - Fix errors before committing
================================================================================
```

### CI/CD Integration

Add to your CI pipeline (GitHub Actions example):

```yaml
# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  validate-architecture:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'

      - name: Install dependencies
        run: |
          pip install pyyaml

      - name: Validate Architecture
        run: |
          python scripts/validate/validate_architecture.py
```

### Documentation

For detailed architectural patterns and examples, see:

- [Architecture Patterns Documentation](../docs/architecture/architecture-patterns.md)
- [Architecture Rules Config](../.architecture-rules.yaml)

### Extending the Validator

To add new rules:

1. Add rule definition to `.architecture-rules.yaml`
2. Implement validation logic in `validate_architecture.py`
3. Add examples to `docs/architecture/architecture-patterns.md`
4. Test with `python scripts/validate/validate_architecture.py --verbose`

### Troubleshooting

**Issue**: Validator reports false positives

**Solution**: Add exception patterns to `.architecture-rules.yaml` under `ignore` section

**Issue**: Validator doesn't catch a specific violation

**Solution**: The rule might not be implemented yet. Check `.architecture-rules.yaml` and `validate_architecture.py` to add the rule.

**Issue**: Pre-commit hook fails but manual run passes

**Solution**: Ensure pre-commit is using the same Python environment:
```bash
pre-commit clean
pre-commit install
```

### Contributing

When adding new architectural patterns:

1. Document the pattern in `docs/architecture/architecture-patterns.md`
2. Add validation rule to `.architecture-rules.yaml`
3. Implement validation in `validate_architecture.py`
4. Test thoroughly with existing codebase
5. Update this README with the new rule

---

**Questions?** See the [Architecture Patterns Documentation](../docs/architecture/architecture-patterns.md)
