Files
orion/docs/frontend/shop/architecture.md

27 KiB

╔══════════════════════════════════════════════════════════════════╗ ║ SHOP FRONTEND ARCHITECTURE OVERVIEW ║ ║ Alpine.js + Jinja2 + Tailwind CSS + Multi-Theme ║ ╚══════════════════════════════════════════════════════════════════╝

📦 WHAT IS THIS? ═════════════════════════════════════════════════════════════════

Customer-facing shop frontend provides visitors with a branded e-commerce experience unique to each vendor. Built with: Jinja2 Templates (server-side rendering) Alpine.js (client-side reactivity) Tailwind CSS (utility-first styling) Multi-Theme System (vendor branding) FastAPI (backend routes)

🎯 KEY PRINCIPLES ═════════════════════════════════════════════════════════════════

  1. Theme-First Design • Each vendor has unique colors, fonts, logos • CSS variables for dynamic theming • Custom CSS support per vendor • Dark mode with vendor colors

  2. Progressive Enhancement • Works without JavaScript (basic HTML) • JavaScript adds cart, search, filters • Graceful degradation for older browsers

  3. API-First Data Loading • All products from REST APIs • Client-side cart management • Real-time stock updates • Search and filtering

  4. Responsive & Mobile-First • Mobile-first Tailwind approach • Touch-friendly interactions • Optimized images • Fast page loads

📁 FILE STRUCTURE ═════════════════════════════════════════════════════════════════

app/ ├── templates/shop/ │ ├── base.html ← Base template (layout) │ ├── home.html ← Homepage / product grid │ ├── product-detail.html ← Single product page │ ├── cart.html ← Shopping cart │ ├── checkout.html ← Checkout flow │ ├── search.html ← Search results │ ├── category.html ← Category browse │ ├── about.html ← About the shop │ ├── contact.html ← Contact form │ └── partials/ ← Reusable components │ ├── product-card.html ← Product display card │ ├── cart-item.html ← Cart item row │ ├── search-modal.html ← Search overlay │ └── filters.html ← Product filters │ ├── static/shop/ │ ├── css/ │ │ ├── shop.css ← Shop-specific styles │ │ └── themes/ ← Optional theme stylesheets │ │ ├── modern.css │ │ ├── minimal.css │ │ └── elegant.css │ ├── js/ │ │ ├── shop-layout.js ← Base shop functionality │ │ ├── home.js ← Homepage logic │ │ ├── product-detail.js ← Product page logic │ │ ├── cart.js ← Cart management │ │ ├── checkout.js ← Checkout flow │ │ ├── search.js ← Search functionality │ │ └── filters.js ← Product filtering │ └── img/ │ ├── placeholder-product.png │ └── empty-cart.svg │ ├── static/shared/ ← Shared across all areas │ ├── js/ │ │ ├── log-config.js ← Logging setup │ │ ├── icons.js ← Icon registry │ │ ├── utils.js ← Utility functions │ │ └── api-client.js ← API wrapper │ └── css/ │ └── base.css ← Global styles │ └── api/v1/shop/ └── pages.py ← Route handlers

🏗️ ARCHITECTURE LAYERS ═════════════════════════════════════════════════════════════════

Layer 1: Routes (FastAPI) ↓ Layer 2: Middleware (Vendor + Theme Detection) ↓ Layer 3: Templates (Jinja2) ↓ Layer 4: JavaScript (Alpine.js) ↓ Layer 5: API (REST endpoints) ↓ Layer 6: Database

Layer 1: ROUTES (FastAPI) ────────────────────────────────────────────────────────────────── Purpose: Vendor Detection + Template Rendering Location: app/api/v1/shop/pages.py

Example: @router.get("/") async def shop_home( request: Request, db: Session = Depends(get_db) ): vendor = request.state.vendor # From middleware theme = request.state.theme # From middleware

  return templates.TemplateResponse(
      "shop/home.html",
      {
          "request": request,
          "vendor": vendor,
          "theme": theme,
      }
  )

Responsibilities: Access vendor from middleware Access theme from middleware Render template NO database queries (data loaded client-side) NO business logic

Layer 2: MIDDLEWARE ────────────────────────────────────────────────────────────────── Purpose: Vendor & Theme Identification

Two middleware components work together:

  1. Vendor Context Middleware • Detects vendor from domain/subdomain • Sets request.state.vendor • Returns 404 if vendor not found

  2. Theme Context Middleware • Loads theme for detected vendor • Sets request.state.theme • Falls back to default theme

Order matters: vendor_context_middleware → theme_context_middleware

Layer 3: TEMPLATES (Jinja2) ────────────────────────────────────────────────────────────────── Purpose: HTML Structure + Vendor Branding Location: app/templates/shop/

Template Hierarchy: base.html (layout + theme injection) ↓ home.html (product grid) ↓ partials/product-card.html (components)

Example: {% extends "shop/base.html" %} {% block title %}{{ vendor.name }}{% endblock %} {% block alpine_data %}shopHome(){% endblock %} {% block content %}

Loading products...
{% endblock %}

Key Features: Theme CSS variables injection Vendor logo (light/dark mode) Custom CSS from theme Social links from theme Dynamic favicon

Layer 4: JAVASCRIPT (Alpine.js) ────────────────────────────────────────────────────────────────── Purpose: Client-Side Interactivity + Cart + Search Location: app/static/shop/js/

Example (shop-layout.js): function shopLayoutData() { return { dark: false, cartCount: 0, cart: [],

      init() {
          this.loadCart();
          this.loadThemePreference();
      },
      
      addToCart(product, quantity) {
          // Add to cart logic
          this.cart.push({ ...product, quantity });
          this.saveCart();
      },
      
      toggleTheme() {
          this.dark = !this.dark;
          localStorage.setItem('shop-theme', 
              this.dark ? 'dark' : 'light');
      }
  };

}

Responsibilities: Load products from API Manage cart in localStorage Handle search and filters Update DOM reactively Theme toggling

Layer 5: API (REST) ────────────────────────────────────────────────────────────────── Purpose: Product Data + Cart + Orders Location: app/api/v1/shop/*.py (not pages.py)

Example Endpoints: GET /api/v1/shop/{vendor_code}/products GET /api/v1/shop/{vendor_code}/products/{id} GET /api/v1/shop/{vendor_code}/categories POST /api/v1/shop/{vendor_code}/search POST /api/v1/shop/{vendor_code}/cart/checkout

🔄 DATA FLOW ═════════════════════════════════════════════════════════════════

Page Load Flow: ──────────────────────────────────────────────────────────────────

  1. Customer → visits acme-shop.com
  2. Vendor Middleware → Identifies "ACME" vendor
  3. Theme Middleware → Loads ACME's theme config
  4. FastAPI → Renders shop/home.html
  5. Browser → Receives HTML with theme CSS variables
  6. Alpine.js → init() executes
  7. JavaScript → GET /api/v1/shop/ACME/products
  8. API → Returns product list JSON
  9. Alpine.js → Updates products array
  10. Browser → DOM updates with product cards

Add to Cart Flow: ──────────────────────────────────────────────────────────────────

  1. Customer → Clicks "Add to Cart"
  2. Alpine.js → addToCart(product, quantity)
  3. Alpine.js → Updates cart array
  4. Alpine.js → Saves to localStorage
  5. Alpine.js → Updates cartCount badge
  6. Alpine.js → Shows toast notification
  7. Browser → Cart icon updates automatically

Checkout Flow: ──────────────────────────────────────────────────────────────────

  1. Customer → Goes to /cart
  2. Page → Loads cart from localStorage
  3. Customer → Fills checkout form
  4. Alpine.js → POST /api/v1/shop/ACME/cart/checkout
  5. API → Creates order + payment intent
  6. Alpine.js → Redirects to payment
  7. Payment → Completes
  8. Redirect → /order/{order_id}/confirmation

🎨 MULTI-THEME SYSTEM ═════════════════════════════════════════════════════════════════

How Themes Work:

  1. Database Storage • Each vendor has a theme record • Stores colors, fonts, logos, layout prefs • Custom CSS per vendor

  2. CSS Variables Injection • base.html injects variables in <style> tag • Variables available throughout page • Example: :root { --color-primary: #6366f1; --color-secondary: #8b5cf6; --color-accent: #ec4899; --color-background: #ffffff; --color-text: #1f2937; --font-heading: Inter, sans-serif; --font-body: Inter, sans-serif; }

  3. Usage in Templates Buy Now

  4. Dark Mode • Vendor colors adjust for dark mode • Saved in localStorage • Applied via :class="{ 'dark': dark }" • Uses dark: variants in Tailwind

Theme Configuration Example: ────────────────────────────────────────────────────────────────── { "theme_name": "modern", "colors": { "primary": "#6366f1", "secondary": "#8b5cf6", "accent": "#ec4899", "background": "#ffffff", "text": "#1f2937" }, "fonts": { "heading": "Inter, sans-serif", "body": "Inter, sans-serif" }, "branding": { "logo": "/media/vendors/acme/logo.png", "logo_dark": "/media/vendors/acme/logo-dark.png", "favicon": "/media/vendors/acme/favicon.ico" }, "layout": { "header": "fixed", "style": "grid" }, "social_links": { "facebook": "https://facebook.com/acme", "instagram": "https://instagram.com/acme" }, "custom_css": ".product-card { border-radius: 12px; }" }

🛒 CART SYSTEM ═════════════════════════════════════════════════════════════════

Client-Side Cart Management:

Storage: localStorage Format: JSON array of cart items

Cart Item Structure: { "id": "product-123", "name": "Product Name", "price": 29.99, "quantity": 2, "image": "/media/products/image.jpg", "vendor_code": "ACME" }

Key Functions: • loadCart(): Load from localStorage • saveCart(): Persist to localStorage • addToCart(product, quantity): Add item • updateCartItem(id, quantity): Update quantity • removeFromCart(id): Remove item • clearCart(): Empty cart • cartTotal: Computed total price

Cart Persistence: • Survives page refresh • Shared across shop pages • Cleared on checkout completion • Synced across tabs (optional)

🔍 SEARCH & FILTERS ═════════════════════════════════════════════════════════════════

Search System:

  1. Search Modal • Overlay with input • Live search as you type • Keyboard shortcuts (Cmd+K)

  2. Search API POST /api/v1/shop/{vendor_code}/search { "query": "laptop", "category": "electronics", "min_price": 100, "max_price": 1000, "sort": "price:asc" }

  3. Client-Side Filtering • Filter products array • No API call needed for basic filters • Use for in-memory datasets

Filter Components: • Category dropdown • Price range slider • Sort options • Availability toggle • Brand checkboxes

📱 RESPONSIVE DESIGN ═════════════════════════════════════════════════════════════════

Breakpoints (Tailwind): • sm: 640px (mobile landscape) • md: 768px (tablet) • lg: 1024px (desktop) • xl: 1280px (large desktop)

Product Grid Responsive: • Mobile: 1 column • Tablet: 2 columns • Desktop: 4 columns

Example:

Touch Optimization: • Larger touch targets (min 44x44px) • Swipeable carousels • Touch-friendly buttons • Tap to zoom images

🌙 DARK MODE ═════════════════════════════════════════════════════════════════

Implementation:

  1. Alpine.js state: dark: boolean
  2. HTML class binding: :class="{ 'dark': dark }"
  3. Tailwind variants: dark:bg-gray-800
  4. LocalStorage persistence
  5. Vendor colors adapt to dark mode

Toggle Button: <button @click="toggleTheme()">

Dark Mode Colors: • Background: dark:bg-gray-900 • Text: dark:text-gray-100 • Borders: dark:border-gray-700 • Cards: dark:bg-gray-800

Vendor Colors: • Primary color adjusts brightness • Maintains brand identity • Readable in both modes

🔐 CUSTOMER AUTHENTICATION ═════════════════════════════════════════════════════════════════

Optional Auth System:

Guest Checkout: No account required Email for order updates Quick checkout

Account Features: Order history Saved addresses Wishlist Profile management

Auth Flow:

  1. Login/Register → POST /api/v1/shop/auth/login
  2. API → Return JWT token
  3. JavaScript → Store in localStorage
  4. API Client → Add to authenticated requests
  5. Optional → Use account features

📡 API CLIENT ═════════════════════════════════════════════════════════════════

Location: app/static/shared/js/api-client.js

Usage: const products = await apiClient.get( /api/v1/shop/${vendorCode}/products );

const order = await apiClient.post( /api/v1/shop/${vendorCode}/checkout, orderData );

Features: Automatic error handling JSON parsing Loading states Auth token injection (if logged in)

🐛 LOGGING ═════════════════════════════════════════════════════════════════

Location: app/static/shared/js/log-config.js

Shop-Specific Logging: shopLog.info('Product added to cart', product); shopLog.error('Checkout failed', error); shopLog.debug('Search query', { query, results });

Levels: • INFO: User actions • ERROR: Failures and exceptions • DEBUG: Development debugging • WARN: Warnings

🎭 ICONS ═════════════════════════════════════════════════════════════════

Location: app/static/shared/js/icons.js

Usage:

Shop Icons: • shopping-cart, shopping-bag • heart (wishlist) • search, filter • eye (view) • star (rating) • truck (shipping) • check (success) • x (close) • chevron-left, chevron-right • spinner (loading)

🚀 PERFORMANCE ═════════════════════════════════════════════════════════════════

Optimization Techniques:

  1. Image Optimization • WebP format • Lazy loading • Responsive images (srcset) • CDN delivery

  2. Code Splitting • Base layout loads first • Page-specific JS loads after • Deferred non-critical CSS

  3. Caching • Browser cache for assets • LocalStorage for cart • Service worker (optional)

  4. Lazy Loading • Products load as you scroll • Images load when visible • Infinite scroll for large catalogs

  5. CDN Assets • Tailwind from CDN • Alpine.js from CDN • Vendor assets from CDN

📊 PAGE-BY-PAGE BREAKDOWN ═════════════════════════════════════════════════════════════════

/ (Homepage) ────────────────────────────────────────────────────────────────── Purpose: Display featured products, hero section Components: • Hero banner with CTA • Featured products grid • Category cards • About vendor section Data Sources: • GET /api/v1/shop/{code}/products?featured=true • GET /api/v1/shop/{code}/categories

/products ────────────────────────────────────────────────────────────────── Purpose: Browse all products with filters Components: • Product grid • Filter sidebar • Sort dropdown • Pagination Data Sources: • GET /api/v1/shop/{code}/products • Filters applied client-side or server-side

/products/{product_id} ────────────────────────────────────────────────────────────────── Purpose: Single product detail page Components: • Image gallery • Product info • Add to cart form • Related products • Reviews (optional) Data Sources: • GET /api/v1/shop/{code}/products/{id} • GET /api/v1/shop/{code}/products/{id}/related

/cart ────────────────────────────────────────────────────────────────── Purpose: Review cart contents before checkout Components: • Cart items list • Quantity adjusters • Remove buttons • Cart total • Checkout button Data Sources: • LocalStorage cart • No API call needed

/checkout ────────────────────────────────────────────────────────────────── Purpose: Complete purchase Components: • Shipping form • Payment form • Order summary • Submit button Data Sources: • POST /api/v1/shop/{code}/checkout • Stripe/PayPal integration

/search ────────────────────────────────────────────────────────────────── Purpose: Search results page Components: • Search input • Results grid • Filter options • Sort options Data Sources: • POST /api/v1/shop/{code}/search

/category/{category_slug} ────────────────────────────────────────────────────────────────── Purpose: Browse products by category Components: • Breadcrumbs • Product grid • Subcategories • Filters Data Sources: • GET /api/v1/shop/{code}/categories/{slug}/products

/about ────────────────────────────────────────────────────────────────── Purpose: About the vendor Components: • Vendor story • Team photos • Values/mission • Contact info Data Sources: • Vendor info from middleware • Static content

/contact ────────────────────────────────────────────────────────────────── Purpose: Contact form Components: • Contact form • Map (optional) • Business hours • Social links Data Sources: • POST /api/v1/shop/{code}/contact

🎓 LEARNING PATH ═════════════════════════════════════════════════════════════════

For New Developers:

  1. Understand Architecture (1 hour) → Read this document → Review file structure → Examine base template → Understand theme system

  2. Study Existing Page (2 hours) → Open home.html → Open shop-layout.js → Trace product loading flow → Examine cart management

  3. Create Simple Page (4 hours) → Copy templates → Modify for new feature → Test with different vendor themes → Verify responsive design

  4. Add Complex Feature (1 day) → Product filters → Cart operations → API integration → Search functionality

  5. Master Patterns (1 week) → All common patterns → Theme customization → Performance optimization → Mobile responsiveness

🔄 DEPLOYMENT CHECKLIST ═════════════════════════════════════════════════════════════════

Before Deploying: □ Build Tailwind CSS □ Minify JavaScript □ Test all routes □ Test with multiple vendor themes □ Verify cart persistence □ Check mobile responsive □ Test dark mode □ Validate product display □ Test checkout flow □ Check image optimization □ Test search functionality □ Verify social links □ Test across browsers □ Check console for errors □ Test in production mode

🔒 SECURITY ═════════════════════════════════════════════════════════════════

Best Practices:

  1. Input Validation Validate all form inputs Sanitize user content XSS prevention

  2. Cart Security Validate cart on server Check stock availability Verify prices server-side Never trust client cart

  3. Payment Security Use trusted payment providers Never store card details HTTPS only PCI compliance

  4. Rate Limiting Search endpoint throttling Contact form limits Checkout attempt limits

📚 REFERENCE LINKS ═════════════════════════════════════════════════════════════════

Documentation: • Alpine.js: https://alpinejs.dev/ • Tailwind CSS: https://tailwindcss.com/ • Jinja2: https://jinja.palletsprojects.com/ • FastAPI: https://fastapi.tiangolo.com/

Internal Docs: • Page Template Guide: FRONTEND_SHOP_ALPINE_PAGE_TEMPLATE.md • Multi-Theme Guide: MULTI_THEME_SHOP_GUIDE.md • API Documentation: API_REFERENCE.md • Database Schema: DATABASE_SCHEMA.md

══════════════════════════════════════════════════════════════════ SHOP FRONTEND ARCHITECTURE Theme-Driven, Customer-Focused, Brand-Consistent ══════════════════════════════════════════════════════════════════