# 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 - - 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 #}" - "" 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: '

' - 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: '
Loading...
' - 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: '' # ============================================================================ # 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 elements. RIGHT (icon helper): pattern: file_pattern: "app/templates/**/*.html" anti_patterns: - ".*" 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 . 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"'