# Architecture Rules - Frontend Rules
# Combined rules for JavaScript, Templates, Components, and Styling

# ============================================================================
# JAVASCRIPT ARCHITECTURE RULES
# ============================================================================

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('✅"
      auto_exclude_files:
        - "init-*.js"

  - 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;
        }

  - id: "JS-008"
    name: "Use apiClient for API calls, not raw fetch()"
    severity: "error"
    description: |
      All API calls must use the apiClient helper instead of raw fetch().
      The apiClient automatically:
      - Adds Authorization header with JWT token from cookies
      - Sets Content-Type headers
      - Handles error responses consistently
      - Provides logging integration

      WRONG (raw fetch):
        const response = await fetch('/api/v1/admin/products/123');

      RIGHT (apiClient):
        const response = await apiClient.get('/admin/products/123');
        const result = await apiClient.post('/admin/products', data);
        await apiClient.delete('/admin/products/123');
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "fetch\\('/api/"
        - 'fetch\\("/api/'
        - "fetch\\(`/api/"
      exceptions:
        - "init-api-client.js"

  - id: "JS-009"
    name: "Use Utils.showToast() for notifications, not alert() or window.showToast"
    severity: "error"
    description: |
      All user notifications must use Utils.showToast() from static/shared/js/utils.js.
      Never use browser alert() dialogs or undefined window.showToast.

      Utils.showToast() provides:
      - Consistent styling (Tailwind-based toast in bottom-right corner)
      - Automatic fade-out after duration
      - Color-coded types (success=green, error=red, warning=yellow, info=blue)

      WRONG (browser dialog):
        alert('Product saved successfully');

      RIGHT (Utils helper):
        Utils.showToast('Product saved successfully', 'success');
        Utils.showToast('Failed to save product', 'error');
    pattern:
      file_pattern: "static/**/js/**/*.js"
      anti_patterns:
        - "alert\\("
        - "window\\.showToast"
      exceptions:
        - "utils.js"

# ============================================================================
# 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.

      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"

  - 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.

      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"
        - "components.html"
        - "shared/macros/"

  - 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.
    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.
    pattern:
      file_pattern: "app/templates/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/forms.html' import"

  - id: "FE-008"
    name: "Use number_stepper macro for quantity inputs"
    severity: "warning"
    description: |
      Use the shared number_stepper macro instead of raw <input type="number">.
      This ensures consistent styling, proper dark mode support, and hides
      native browser spinners that render inconsistently.

      RIGHT (use macro):
        {% from 'shared/macros/inputs.html' import number_stepper %}
        {{ number_stepper(model='quantity', min=1, max=99) }}

      Suppress with:
        - {# noqa: FE-008 #} on the line or at file level
    pattern:
      file_pattern: "app/templates/**/*.html"
      anti_patterns:
        - 'type="number"'
        - "type='number'"
      exceptions:
        - "shared/macros/inputs.html"
        - "components.html"

  - id: "FE-009"
    name: "Use product_card macro for product displays"
    severity: "info"
    description: |
      Use the shared product_card macro for consistent product presentation.
      Import from shared/macros/shop/product-card.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/product-card.html' import"

  - id: "FE-010"
    name: "Use product_grid macro for product listings"
    severity: "info"
    description: |
      Use the shared product_grid macro for responsive product grids.
      Import from shared/macros/shop/product-grid.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/product-grid.html' import"

  - id: "FE-011"
    name: "Use add_to_cart macros for cart interactions"
    severity: "info"
    description: |
      Use the shared add-to-cart macros for consistent cart functionality.
      Import from shared/macros/shop/add-to-cart.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/add-to-cart.html' import"

  - id: "FE-012"
    name: "Use mini_cart macro for cart dropdown"
    severity: "info"
    description: |
      Use the shared mini_cart macros for header cart functionality.
      Import from shared/macros/shop/mini-cart.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/mini-cart.html' import"

  - id: "FE-013"
    name: "Use product_gallery macro for image galleries"
    severity: "info"
    description: |
      Use the shared product_gallery macros for product image displays.
      Import from shared/macros/shop/product-gallery.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/product-gallery.html' import"

  - id: "FE-014"
    name: "Use variant_selector macros for product options"
    severity: "info"
    description: |
      Use the shared variant_selector macros for product variant selection.
      Import from shared/macros/shop/variant-selector.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/variant-selector.html' import"

  - id: "FE-015"
    name: "Use product_info macros for product details"
    severity: "info"
    description: |
      Use the shared product_info macros for product detail sections.
      Import from shared/macros/shop/product-info.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/product-info.html' import"

  - id: "FE-016"
    name: "Use product_tabs macro for product content tabs"
    severity: "info"
    description: |
      Use the shared product_tabs macros for tabbed product information.
      Import from shared/macros/shop/product-tabs.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/product-tabs.html' import"

  - id: "FE-017"
    name: "Use category_nav macros for category navigation"
    severity: "info"
    description: |
      Use the shared category_nav macros for category navigation sidebars and menus.
      Import from shared/macros/shop/category-nav.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/category-nav.html' import"

  - id: "FE-018"
    name: "Use breadcrumbs macros for breadcrumb navigation"
    severity: "info"
    description: |
      Use the shared breadcrumbs macros for navigation trails.
      Import from shared/macros/shop/breadcrumbs.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/breadcrumbs.html' import"

  - id: "FE-019"
    name: "Use search_bar macros for product search"
    severity: "info"
    description: |
      Use the shared search_bar macros for product search functionality.
      Import from shared/macros/shop/search-bar.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/search-bar.html' import"

  - id: "FE-020"
    name: "Use filter_sidebar macros for product filtering"
    severity: "info"
    description: |
      Use the shared filter_sidebar macros for product filtering panels.
      Import from shared/macros/shop/filter-sidebar.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/filter-sidebar.html' import"

  - id: "FE-021"
    name: "Use star_rating macros for rating displays"
    severity: "info"
    description: |
      Use the shared star_rating macros for all rating displays and inputs.
      Import from shared/macros/shop/star-rating.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/star-rating.html' import"

  - id: "FE-022"
    name: "Use review macros for review displays"
    severity: "info"
    description: |
      Use the shared review macros for product reviews.
      Import from shared/macros/shop/reviews.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/reviews.html' import"

  - id: "FE-023"
    name: "Use trust_badges macros for trust signals"
    severity: "info"
    description: |
      Use the shared trust_badges macros for security and trust indicators.
      Import from shared/macros/shop/trust-badges.html.
    pattern:
      file_pattern: "app/templates/shop/**/*.html"
      encouraged_patterns:
        - "{% from 'shared/macros/shop/trust-badges.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"'
