# Architecture Rules Configuration
# This file defines the key architectural decisions and patterns that must be followed
# across the application. The validator script uses these rules to check compliance.

version: "2.0"
project: "letzshop-product-import"
description: "Comprehensive architectural rules for multi-tenant e-commerce platform"

# ============================================================================
# CORE ARCHITECTURAL PRINCIPLES
# ============================================================================

principles:
  - name: "Separation of Concerns"
    description: "API endpoints should only handle HTTP concerns. Business logic belongs in services."

  - name: "Layered Architecture"
    description: "Routes → Services → Models. Each layer has specific responsibilities."

  - name: "Type Safety"
    description: "Use Pydantic models for request/response validation. Use SQLAlchemy models for database."

  - name: "Proper Exception Handling"
    description: "Services throw domain exceptions. Global handler converts to HTTP responses. Endpoints do NOT catch or raise HTTPException."

  - name: "Multi-Tenancy"
    description: "All queries must be scoped to vendor_id. No cross-vendor data access."

  - name: "Consistent Naming"
    description: "API files: plural, Services: singular+service, Models: singular"

# ============================================================================
# API ENDPOINT RULES (app/api/v1/**/*.py)
# ============================================================================

api_endpoint_rules:

  - id: "API-001"
    name: "Endpoint must use Pydantic models for request/response"
    severity: "error"
    description: |
      All API endpoints must use Pydantic models (BaseModel) for request bodies
      and response models. Never use raw dicts or SQLAlchemy models directly.
    pattern:
      file_pattern: "app/api/v1/**/*.py"
      anti_patterns:
        - "return dict"
        - "-> dict"
        - "return db_object"
    example_good: |
      @router.post("/vendors", response_model=VendorResponse)
      async def create_vendor(vendor: VendorCreate):
          return vendor_service.create_vendor(db, vendor)

  - id: "API-002"
    name: "Endpoint must NOT contain business logic"
    severity: "error"
    description: |
      API endpoints should only handle HTTP concerns (validation, auth, response formatting).
      All business logic must be delegated to service layer.

      Transaction control (db.commit) IS allowed at endpoint level - this is the recommended
      pattern for request-scoped transactions. One request = one transaction.

      What's NOT allowed:
      - db.add() - creating entities is business logic
      - db.query() - complex queries are business logic
      - db.delete() - deleting entities is business logic
    pattern:
      file_pattern: "app/api/v1/**/*.py"
      anti_patterns:
        - "db.add("
        - "db.delete("
        - "db.query("
      # NOTE: db.commit() is intentionally NOT listed - it's allowed for transaction control

  - id: "API-003"
    name: "Endpoint must NOT raise ANY exceptions directly"
    severity: "error"
    description: |
      API endpoints should NOT raise exceptions directly. Endpoints are a thin
      orchestration layer that:
      1. Accepts request parameters (validated by Pydantic)
      2. Calls dependencies for authentication/authorization (deps.py raises exceptions)
      3. Calls services for business logic (services raise domain exceptions)
      4. Returns response (formatted by Pydantic)

      Exception raising belongs in:
      - Dependencies (app/api/deps.py) - authentication/authorization validation
      - Services (app/services/) - business logic validation

      The global exception handler catches all WizamartException subclasses and
      converts them to appropriate HTTP responses.

      WRONG (endpoint raises exception):
        @router.get("/orders")
        def get_orders(current_user: User = Depends(get_current_vendor_api)):
            if not hasattr(current_user, "token_vendor_id"):  # ❌ Redundant check
                raise InvalidTokenException("...")            # ❌ Don't raise here
            return order_service.get_orders(db, current_user.token_vendor_id)

      RIGHT (dependency guarantees, endpoint trusts):
        @router.get("/orders")
        def get_orders(current_user: User = Depends(get_current_vendor_api)):
            # Dependency guarantees token_vendor_id is present
            return order_service.get_orders(db, current_user.token_vendor_id)
    pattern:
      file_pattern: "app/api/v1/**/*.py"
      anti_patterns:
        - "raise HTTPException"
        - "raise InvalidTokenException"
        - "raise InsufficientPermissionsException"
        - "if not hasattr\\(current_user.*token_vendor"
      exceptions:
        - "app/exceptions/handler.py"  # Handler is allowed to use HTTPException

  - id: "API-004"
    name: "Endpoint must have proper authentication/authorization"
    severity: "warning"
    description: |
      Protected endpoints must use Depends() for authentication.
      Use get_current_user, get_current_admin, etc.

      Auto-excluded files:
      - */auth.py - Authentication endpoints (login, logout, register) are intentionally public

      Public endpoint markers (place on line before or after decorator):
      - # public - Descriptive marker for intentionally unauthenticated endpoints
      - # noqa: API-004 - Standard noqa style to suppress warning

      Example:
        # public - Stripe webhook receives external callbacks
        @router.post("/webhook/stripe")
        def stripe_webhook(request: Request):
            ...
    pattern:
      file_pattern: "app/api/v1/**/*.py"
      required_if_not_public:
        - "Depends(get_current_"
      auto_exclude_files:
        - "*/auth.py"
      public_markers:
        - "# public"
        - "# noqa: api-004"

  - id: "API-005"
    name: "Multi-tenant endpoints must scope queries to vendor_id"
    severity: "error"
    description: |
      All queries in vendor/shop contexts must filter by vendor_id.
      Use request.state.vendor_id from middleware.
    pattern:
      file_pattern: "app/api/v1/vendor/**/*.py"
      file_pattern: "app/api/v1/shop/**/*.py"
      discouraged_patterns:
        - "db.query(.*).all()"  # Without vendor filter

# ============================================================================
# SERVICE LAYER RULES (app/services/**/*.py)
# ============================================================================

service_layer_rules:

  - id: "SVC-001"
    name: "Service must NOT raise HTTPException"
    severity: "error"
    description: |
      Services are business logic layer - they should NOT know about HTTP.
      Raise domain-specific exceptions instead (ValueError, custom exceptions).
    pattern:
      file_pattern: "app/services/**/*.py"
      anti_patterns:
        - "raise HTTPException"
        - "from fastapi import HTTPException"

  - id: "SVC-002"
    name: "Service must use proper exception handling"
    severity: "error"
    description: |
      Services should raise meaningful domain exceptions, not generic Exception.
      Create custom exception classes for business rule violations.
    pattern:
      file_pattern: "app/services/**/*.py"
      discouraged_patterns:
        - "raise Exception\\("

  - id: "SVC-003"
    name: "Service methods must accept db session as parameter"
    severity: "error"
    description: |
      Service methods should receive database session as a parameter for testability
      and transaction control. Never create session inside service.
    pattern:
      file_pattern: "app/services/**/*.py"
      required_in_method_signature:
        - "db: Session"
      anti_patterns:
        - "SessionLocal()"
        - "get_db()"

  - id: "SVC-004"
    name: "Service must use Pydantic models for input validation"
    severity: "warning"
    description: |
      Service methods should accept Pydantic models for complex inputs
      to ensure type safety and validation.
    pattern:
      file_pattern: "app/services/**/*.py"
      encouraged_patterns:
        - "BaseModel"

  - id: "SVC-005"
    name: "Service must scope queries to vendor_id in multi-tenant contexts"
    severity: "error"
    description: |
      All database queries must be scoped to vendor_id to prevent cross-tenant data access.
    pattern:
      file_pattern: "app/services/**/*.py"
      check: "vendor_scoping"

  - id: "SVC-006"
    name: "Service must NOT call db.commit()"
    severity: "warning"
    description: |
      Services should NOT commit transactions. Transaction control belongs at the
      API endpoint level where one request = one transaction.

      This allows:
      - Composing multiple service calls in a single transaction
      - Clean rollback on any failure
      - Easier testing of services in isolation

      The endpoint should call db.commit() after all service operations succeed.
    pattern:
      file_pattern: "app/services/**/*.py"
      anti_patterns:
        - "db.commit()"
      exceptions:
        - "log_service.py"  # Audit logs may need immediate commits

# ============================================================================
# MODEL RULES (models/database/*.py, models/schema/*.py)
# ============================================================================

model_rules:

  - id: "MDL-001"
    name: "Database models must use SQLAlchemy Base"
    severity: "error"
    description: |
      All database models must inherit from SQLAlchemy Base and use proper
      column definitions with types and constraints.
    pattern:
      file_pattern: "models/database/**/*.py"
      required_patterns:
        - "class.*\\(Base\\):"

  - id: "MDL-002"
    name: "Use Pydantic models separately from SQLAlchemy models"
    severity: "error"
    description: |
      Never mix SQLAlchemy and Pydantic in the same model.
      SQLAlchemy = database schema, Pydantic = API validation/serialization.
    pattern:
      file_pattern: "models/**/*.py"
      anti_patterns:
        - "class.*\\(Base, BaseModel\\):"

  - id: "MDL-003"
    name: "Pydantic models must use from_attributes for ORM mode"
    severity: "error"
    description: |
      Pydantic response models must enable from_attributes to work with SQLAlchemy models.
    pattern:
      file_pattern: "models/schema/**/*.py"
      required_in_response_models:
        - "from_attributes = True"

  - id: "MDL-004"
    name: "Database models use singular table names"
    severity: "warning"
    description: |
      Database table names should be singular lowercase (e.g., 'vendor' not 'vendors').
    pattern:
      file_pattern: "models/database/**/*.py"
      check: "table_naming"

# ============================================================================
# EXCEPTION HANDLING RULES
# ============================================================================

exception_rules:

  - id: "EXC-001"
    name: "Define custom exceptions in exceptions module"
    severity: "warning"
    description: |
      Create domain-specific exceptions in app/exceptions/ for better
      error handling and clarity.
    pattern:
      file_pattern: "app/exceptions/**/*.py"
      encouraged_structure: |
        class VendorError(Exception):
            """Base exception for vendor-related errors"""
            pass

  - id: "EXC-002"
    name: "Never use bare except"
    severity: "error"
    description: |
      Always specify exception types. Bare except catches everything including
      KeyboardInterrupt and SystemExit.
    pattern:
      file_pattern: "**/*.py"
      anti_patterns:
        - "except:"
        - "except\\s*:"

  - id: "EXC-003"
    name: "Log all exceptions with context"
    severity: "warning"
    description: |
      When catching exceptions, log them with context and stack trace.
    pattern:
      file_pattern: "app/services/**/*.py"
      encouraged_patterns:
        - "logger.error"
        - "exc_info=True"

  - id: "EXC-004"
    name: "Domain exceptions must inherit from WizamartException"
    severity: "error"
    description: |
      All custom domain exceptions must inherit from WizamartException (or its
      subclasses like ResourceNotFoundException, ValidationException, etc.).
      This ensures the global exception handler catches and converts them properly.
    pattern:
      file_pattern: "app/exceptions/**/*.py"
      required_base_class: "WizamartException"
      example_good: |
        class VendorNotFoundException(ResourceNotFoundException):
            def __init__(self, vendor_code: str):
                super().__init__(resource_type="Vendor", identifier=vendor_code)

  - id: "EXC-005"
    name: "Exception handler must be registered"
    severity: "error"
    description: |
      The global exception handler must be set up in app initialization to
      catch WizamartException and convert to HTTP responses.
    pattern:
      file_pattern: "app/main.py"
      required_patterns:
        - "setup_exception_handlers"

# ============================================================================
# NAMING CONVENTION RULES
# ============================================================================

naming_rules:

  - id: "NAM-001"
    name: "API files use PLURAL names"
    severity: "error"
    description: |
      API endpoint files should use plural names (vendors.py, products.py)
    pattern:
      file_pattern: "app/api/v1/**/*.py"
      check: "plural_naming"
      exceptions:
        - "__init__.py"
        - "auth.py"
        - "health.py"

  - id: "NAM-002"
    name: "Service files use SINGULAR + 'service' suffix"
    severity: "error"
    description: |
      Service files should use singular name + _service (vendor_service.py)
    pattern:
      file_pattern: "app/services/**/*.py"
      check: "service_naming"

  - id: "NAM-003"
    name: "Model files use SINGULAR names"
    severity: "error"
    description: |
      Both database and schema model files use singular names (product.py)
    pattern:
      file_pattern: "models/**/*.py"
      check: "singular_naming"

  - id: "NAM-004"
    name: "Use consistent terminology: vendor not shop"
    severity: "warning"
    description: |
      Use 'vendor' consistently, not 'shop' (except for shop frontend)
    pattern:
      file_pattern: "app/**/*.py"
      discouraged_terms:
        - "shop_id"  # Use vendor_id
        - "shop_service"  # Use vendor_service

  - id: "NAM-005"
    name: "Use consistent terminology: inventory not stock"
    severity: "warning"
    description: |
      Use 'inventory' consistently, not 'stock'
    pattern:
      file_pattern: "app/**/*.py"
      discouraged_terms:
        - "stock_service"  # Use inventory_service

# ============================================================================
# JAVASCRIPT ARCHITECTURE RULES (Frontend)
# ============================================================================

javascript_rules:

  - id: "JS-001"
    name: "Use centralized logger, not console"
    severity: "error"
    description: |
      Use window.LogConfig.createLogger() for consistent logging.
      Never use console.log, console.error, console.warn directly.
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "console\\.log"
        - "console\\.error"
        - "console\\.warn"
      exceptions:
        - "// eslint-disable"
        - "console.log('✅"  # Bootstrap messages allowed
      auto_exclude_files:
        - "init-*.js"  # Init files run before logger is available

  - id: "JS-002"
    name: "Use lowercase apiClient for API calls"
    severity: "error"
    description: |
      Use lowercase 'apiClient' consistently, not 'ApiClient' or 'API_CLIENT'
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "ApiClient\\."
        - "API_CLIENT\\."
      required_pattern: "apiClient\\."

  - id: "JS-003"
    name: "Alpine components must spread ...data()"
    severity: "error"
    description: |
      All Alpine.js components must inherit base layout data using spread operator
    pattern:
      file_pattern: "static/**/js/**/*.js"
      required_in_alpine_components:
        - "\\.\\.\\.data\\(\\)"

  - id: "JS-004"
    name: "Alpine components must set currentPage"
    severity: "error"
    description: |
      All Alpine.js page components must set a currentPage identifier
    pattern:
      file_pattern: "static/**/js/**/*.js"
      required_in_alpine_components:
        - "currentPage:"

  - id: "JS-005"
    name: "Initialization methods must include guard"
    severity: "error"
    description: |
      Init methods should prevent duplicate initialization with guard
    pattern:
      file_pattern: "static/**/js/**/*.js"
      recommended_pattern: |
        if (window._pageInitialized) return;
        window._pageInitialized = true;

  - id: "JS-006"
    name: "All async operations must have try/catch with error logging"
    severity: "error"
    description: |
      All API calls and async operations must have error handling
    pattern:
      file_pattern: "static/**/js/**/*.js"
      check: "async_error_handling"

  - id: "JS-007"
    name: "Set loading state before async operations"
    severity: "warning"
    description: |
      Loading state should be set before and cleared after async operations
    pattern:
      file_pattern: "static/**/js/**/*.js"
      recommended_pattern: |
        loading = true;
        try {
          // operation
        } finally {
          loading = false;
        }

# ============================================================================
# TEMPLATE RULES (Jinja2)
# ============================================================================

template_rules:

  - id: "TPL-001"
    name: "Admin templates must extend admin/base.html"
    severity: "error"
    description: |
      All admin templates must extend the base template for consistency.

      Auto-excluded files:
      - login.html - Standalone login page (no sidebar/navigation)
      - errors/*.html - Error pages extend errors/base.html instead
      - test-*.html - Test/development templates

      Standalone template markers (place in first 5 lines):
      - {# standalone #} - Mark template as intentionally standalone
      - {# noqa: TPL-001 #} - Standard noqa style to suppress error
      - <!-- standalone --> - HTML comment style
    pattern:
      file_pattern: "app/templates/admin/**/*.html"
      required_patterns:
        - "{% extends ['\"]admin/base\\.html['\"] %}"
      auto_exclude_files:
        - "login.html"
        - "errors/"
        - "test-"
      standalone_markers:
        - "{# standalone #}"
        - "{# noqa: tpl-001 #}"
        - "<!-- standalone -->"
      exceptions:
        - "base.html"
        - "partials/"

  - id: "TPL-002"
    name: "Vendor templates must extend vendor/base.html"
    severity: "error"
    description: "All vendor templates must extend the base template"
    pattern:
      file_pattern: "app/templates/vendor/**/*.html"
      required_patterns:
        - "{% extends ['\"]vendor/base\\.html['\"] %}"
      exceptions:
        - "base.html"
        - "partials/"

  - id: "TPL-003"
    name: "Shop templates must extend shop/base.html"
    severity: "error"
    description: "All shop templates must extend the base template"
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      required_patterns:
        - "{% extends ['\"]shop/base\\.html['\"] %}"
      exceptions:
        - "base.html"
        - "partials/"

  - id: "TPL-004"
    name: "Use x-text for dynamic text content (prevents XSS)"
    severity: "warning"
    description: |
      Use x-text directive for dynamic content to prevent XSS vulnerabilities
    pattern:
      file_pattern: "app/templates/**/*.html"
      recommended_pattern: '<p x-text="item.name"></p>'

  - id: "TPL-005"
    name: "Use x-html ONLY for safe content"
    severity: "error"
    description: |
      Use x-html only for trusted content like icons, never for user-generated content
    pattern:
      file_pattern: "app/templates/**/*.html"
      safe_usage:
        - 'x-html="\\$icon\\('

  - id: "TPL-006"
    name: "Implement loading state for data loads"
    severity: "warning"
    description: |
      All templates that load data should show loading state
    pattern:
      file_pattern: "app/templates/**/*.html"
      recommended_pattern: '<div x-show="loading">Loading...</div>'

  - id: "TPL-007"
    name: "Implement empty state when no data"
    severity: "warning"
    description: |
      Show empty state when lists have no items
    pattern:
      file_pattern: "app/templates/**/*.html"
      recommended_pattern: '<template x-if="items.length === 0">No items</template>'

# ============================================================================
# FRONTEND COMPONENT RULES
# ============================================================================

frontend_component_rules:

  - id: "FE-001"
    name: "Use pagination macro instead of inline HTML"
    severity: "warning"
    description: |
      Use the shared pagination macro instead of duplicating pagination HTML.
      Import from shared/macros/pagination.html.

      WRONG (inline pagination):
        <div class="grid px-4 py-3 text-xs font-semibold...">
            <span class="flex items-center col-span-3">
                Showing ...
            </span>
            <nav aria-label="Table navigation">...

      RIGHT (use macro):
        {% from 'shared/macros/pagination.html' import pagination %}
        {{ pagination() }}
    pattern:
      file_pattern: "app/templates/**/*.html"
      anti_patterns:
        - 'aria-label="Table navigation"'
        - "previousPage\\(\\).*nextPage\\(\\)"
      exceptions:
        - "shared/macros/pagination.html"
        - "components.html"  # Showcase page

  - id: "FE-002"
    name: "Use $icon() helper instead of inline SVGs"
    severity: "warning"
    description: |
      Use the Alpine.js $icon() helper for consistent iconography.
      Do not use inline <svg> elements.

      WRONG (inline SVG):
        <svg class="w-4 h-4" viewBox="0 0 20 20">...</svg>

      RIGHT (icon helper):
        <span x-html="$icon('arrow-left', 'w-4 h-4')"></span>
    pattern:
      file_pattern: "app/templates/**/*.html"
      anti_patterns:
        - "<svg.*viewBox.*>.*</svg>"
      exceptions:
        - "base.html"  # Base templates may define SVG sprites
        - "components.html"  # Showcase page
        - "shared/macros/"  # Macros may contain SVGs for compatibility

  - id: "FE-003"
    name: "Use table macros for consistent table styling"
    severity: "info"
    description: |
      Use the shared table macros for consistent table styling.
      Import from shared/macros/tables.html.

      Recommended macros:
      - table_wrapper() - Wraps table with overflow and shadow
      - table_header(['Column1', 'Column2']) - Consistent header styling
      - table_empty_state(colspan, 'icon', 'Title', 'Message') - Empty states
    pattern:
      file_pattern: "app/templates/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/tables.html' import"

  - id: "FE-004"
    name: "Use form macros for consistent form styling"
    severity: "info"
    description: |
      Use the shared form macros for consistent input styling and validation.
      Import from shared/macros/forms.html.

      Recommended macros:
      - form_input(label, name, x_model, ...) - Text inputs with validation
      - form_select(label, x_model, options) - Select dropdowns
      - form_textarea(label, x_model, rows) - Textareas
      - form_checkbox(label, x_model) - Checkboxes
    pattern:
      file_pattern: "app/templates/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/forms.html' import"

# ============================================================================
# FRONTEND STYLING RULES
# ============================================================================

styling_rules:

  - id: "CSS-001"
    name: "Use Tailwind utility classes"
    severity: "warning"
    description: |
      Prefer Tailwind utility classes over custom CSS
    pattern:
      file_pattern: "app/templates/**/*.html"
      encouraged: true

  - id: "CSS-002"
    name: "Support dark mode with dark: prefix"
    severity: "warning"
    description: |
      All color classes should include dark mode variants
    pattern:
      file_pattern: "app/templates/**/*.html"
      recommended_pattern: 'class="bg-white dark:bg-gray-800"'

  - id: "CSS-003"
    name: "Shop templates use vendor theme CSS variables"
    severity: "error"
    description: |
      Shop templates must use CSS variables for vendor-specific theming
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      required_pattern: 'var\\(--color-primary\\)'

  - id: "CSS-004"
    name: "Mobile-first responsive design"
    severity: "warning"
    description: |
      Use mobile-first responsive classes
    pattern:
      file_pattern: "app/templates/**/*.html"
      recommended_pattern: 'class="grid-cols-1 md:grid-cols-2 lg:grid-cols-4"'

# ============================================================================
# MIDDLEWARE RULES
# ============================================================================

middleware_rules:

  - id: "MDW-001"
    name: "Middleware files use simple nouns without _middleware suffix"
    severity: "warning"
    description: |
      Middleware files should be named with simple nouns (auth.py, not auth_middleware.py)
    pattern:
      file_pattern: "middleware/**/*.py"
      check: "middleware_naming"

  - id: "MDW-002"
    name: "Vendor context must be injected for vendor/shop routes"
    severity: "error"
    description: |
      Vendor context middleware must set request.state.vendor_id and request.state.vendor
    pattern:
      file_pattern: "middleware/vendor_context.py"
      required: true

# ============================================================================
# MULTI-TENANCY RULES
# ============================================================================

multi_tenancy_rules:

  - id: "MT-001"
    name: "All queries must be scoped to vendor_id"
    severity: "error"
    description: |
      In vendor/shop contexts, all database queries must filter by vendor_id
    pattern:
      file_pattern: "app/services/**/*.py"
      context: "vendor_shop"
      required_pattern: ".filter\\(.*vendor_id.*\\)"

  - id: "MT-002"
    name: "No cross-vendor data access"
    severity: "error"
    description: |
      Queries must never access data from other vendors
    pattern:
      file_pattern: "app/services/**/*.py"
      enforcement: "database_query_level"

# ============================================================================
# AUTHENTICATION & AUTHORIZATION RULES
# ============================================================================

auth_rules:

  - id: "AUTH-001"
    name: "Use JWT tokens in Authorization header"
    severity: "error"
    description: |
      Authentication must use JWT tokens in Authorization: Bearer header
    pattern:
      file_pattern: "app/api/**/*.py"
      enforcement: "middleware"

  - id: "AUTH-002"
    name: "Role-based access control with Depends"
    severity: "error"
    description: |
      Use Depends(get_current_admin/vendor/customer) for role checks
    pattern:
      file_pattern: "app/api/v1/**/*.py"
      required: "Depends\\(get_current_"

  - id: "AUTH-003"
    name: "Never store plain passwords"
    severity: "error"
    description: |
      Always hash passwords with bcrypt before storing
    pattern:
      file_pattern: "app/services/auth_service.py"
      required: "bcrypt"

  - id: "AUTH-004"
    name: "Vendor context pattern - use appropriate dependency for endpoint type"
    severity: "error"
    description: |
      Two vendor context patterns exist - use the appropriate one:

      1. SHOP ENDPOINTS (public, no authentication required):
         - Use: vendor: Vendor = Depends(require_vendor_context())
         - Vendor is detected from URL/subdomain/domain
         - File pattern: app/api/v1/shop/**/*.py
         - Mark as public with: # public

      2. VENDOR API ENDPOINTS (authenticated):
         - Use: current_user.token_vendor_id from JWT token
         - Or use permission dependencies: require_vendor_permission(), require_vendor_owner
         - These dependencies get vendor from token and set request.state.vendor
         - File pattern: app/api/v1/vendor/**/*.py

      DEPRECATED for vendor APIs:
         - require_vendor_context() - only for shop endpoints
         - getattr(request.state, "vendor", None) without permission dependency

      See: docs/backend/vendor-in-token-architecture.md
    pattern:
      file_pattern: "app/api/v1/vendor/**/*.py"
      anti_patterns:
        - "require_vendor_context\\(\\)"
      file_pattern: "app/api/v1/shop/**/*.py"
      required_patterns:
        - "require_vendor_context\\(\\)|# public"

# ============================================================================
# CODE QUALITY RULES
# ============================================================================

code_quality_rules:

  - id: "QUAL-001"
    name: "All code must be formatted with Ruff"
    severity: "error"
    description: |
      Run 'make format' before committing
    enforcement: "pre_commit"

  - id: "QUAL-002"
    name: "All code must pass Ruff linting"
    severity: "error"
    description: |
      Run 'make lint' before committing
    enforcement: "pre_commit"

  - id: "QUAL-003"
    name: "Type hints recommended for functions"
    severity: "warning"
    description: |
      Add type hints to function parameters and return types
    pattern:
      file_pattern: "app/**/*.py"
      encouraged: true

# ============================================================================
# VALIDATION SEVERITY LEVELS
# ============================================================================

severity_levels:
  error:
    description: "Critical architectural violation - must be fixed"
    exit_code: 1

  warning:
    description: "Pattern deviation - should be fixed"
    exit_code: 0

  info:
    description: "Suggestion for improvement"
    exit_code: 0

# ============================================================================
# IGNORED PATTERNS
# ============================================================================

ignore:
  files:
    - "**/*_test.py"
    - "**/test_*.py"
    - "**/__pycache__/**"
    - "**/migrations/**"
    - "**/alembic/versions/**"
    - "**/node_modules/**"
    - "**/.venv/**"
    - "**/venv/**"
    - ".venv/**"
    - "venv/**"
    - "**/build/**"
    - "**/dist/**"

  patterns:
    # Allow HTTPException in specific files
    - file: "app/core/exceptions.py"
      pattern: "HTTPException"
      reason: "Exception handling utilities"

    - file: "app/exceptions/handler.py"
      pattern: "HTTPException"
      reason: "Exception handler converts to HTTP"

# ============================================================================
# DOCUMENTATION
# ============================================================================

documentation:
  architecture: "docs/architecture/overview.md"
  backend: "docs/backend/overview.md"
  frontend: "docs/frontend/overview.md"
  contributing: "docs/development/contributing.md"
  code_quality: "docs/development/code-quality.md"
