1226 lines
59 KiB
Plaintext
1226 lines
59 KiB
Plaintext
╔══════════════════════════════════════════════════════════════════╗
|
||
║ LETZSHOP FRONTEND ARCHITECTURE ║
|
||
║ Complete Multi-Tenant E-Commerce Platform ║
|
||
║ Architecture Overview & Design Patterns ║
|
||
╚══════════════════════════════════════════════════════════════════╝
|
||
|
||
📦 WHAT IS THIS DOCUMENT?
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
This document provides a comprehensive overview of the LetzShop frontend
|
||
architecture, covering all three distinct frontend applications and the
|
||
shared design patterns that ensure consistency, maintainability, and
|
||
developer productivity across the entire platform.
|
||
|
||
This serves as the introduction to three detailed architecture documents:
|
||
1. Admin Frontend Architecture
|
||
2. Vendor Frontend Architecture
|
||
3. Shop Frontend Architecture
|
||
|
||
|
||
🎯 PLATFORM OVERVIEW
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
LetzShop is a multi-tenant e-commerce marketplace platform with three
|
||
distinct frontend applications, each serving different user groups:
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
|
||
│ │ ADMIN │ │ VENDOR │ │ SHOP │ │
|
||
│ │ FRONTEND │ │ FRONTEND │ │ FRONTEND │ │
|
||
│ └──────────────┘ └──────────────┘ └────────────┘ │
|
||
│ │ │ │ │
|
||
│ ├────────────────────────┴─────────────────────┤ │
|
||
│ │ │ │
|
||
│ │ SHARED ARCHITECTURE │ │
|
||
│ │ • Alpine.js │ │
|
||
│ │ • Jinja2 Templates │ │
|
||
│ │ • Tailwind CSS │ │
|
||
│ │ • FastAPI Backend │ │
|
||
│ │ • Design Patterns │ │
|
||
│ │ │ │
|
||
│ └──────────────────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
|
||
🏛️ THREE FRONTENDS EXPLAINED
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 1. ADMIN FRONTEND │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Purpose: Platform administration and control │
|
||
│ Users: Platform administrators │
|
||
│ Access: /admin/* │
|
||
│ Auth: Admin role required (is_admin=True) │
|
||
│ │
|
||
│ Key Features: │
|
||
│ • Vendor management (create, verify, suspend) │
|
||
│ • User management (roles, permissions) │
|
||
│ • Platform-wide analytics and monitoring │
|
||
│ • Theme customization for vendors │
|
||
│ • Import job monitoring │
|
||
│ • Audit log viewing │
|
||
│ • System settings and configuration │
|
||
│ │
|
||
│ UI Theme: Windmill Dashboard (professional admin UI) │
|
||
│ Colors: Purple (#7c3aed) primary │
|
||
│ │
|
||
│ Pages: │
|
||
│ ├── /admin/dashboard │
|
||
│ ├── /admin/vendors │
|
||
│ ├── /admin/vendors/{code}/edit │
|
||
│ ├── /admin/vendors/{code}/theme │
|
||
│ ├── /admin/users │
|
||
│ ├── /admin/products │
|
||
│ ├── /admin/orders │
|
||
│ ├── /admin/import-jobs │
|
||
│ ├── /admin/audit-logs │
|
||
│ └── /admin/settings │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 2. VENDOR FRONTEND │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Purpose: Vendor shop management and operations │
|
||
│ Users: Vendor owners and their team members │
|
||
│ Access: /vendor/{vendor_code}/* │
|
||
│ Auth: Vendor role required + vendor ownership │
|
||
│ │
|
||
│ Key Features: │
|
||
│ • Product catalog management │
|
||
│ • Inventory tracking │
|
||
│ • Order management │
|
||
│ • Customer management │
|
||
│ • Marketplace imports (Amazon, eBay, etc.) │
|
||
│ • Shop analytics and reports │
|
||
│ • Team member management │
|
||
│ • Shop settings │
|
||
│ │
|
||
│ UI Theme: Windmill Dashboard (professional admin UI) │
|
||
│ Colors: Purple (#7c3aed) primary │
|
||
│ │
|
||
│ Pages: │
|
||
│ ├── /vendor/{code}/dashboard │
|
||
│ ├── /vendor/{code}/products │
|
||
│ ├── /vendor/{code}/inventory │
|
||
│ ├── /vendor/{code}/orders │
|
||
│ ├── /vendor/{code}/customers │
|
||
│ ├── /vendor/{code}/marketplace │
|
||
│ ├── /vendor/{code}/analytics │
|
||
│ ├── /vendor/{code}/team │
|
||
│ └── /vendor/{code}/settings │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 3. SHOP FRONTEND │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Purpose: Customer-facing e-commerce storefront │
|
||
│ Users: Customers and visitors │
|
||
│ Access: Vendor-specific domains or subdomains │
|
||
│ Auth: Optional (guest checkout supported) │
|
||
│ │
|
||
│ Key Features: │
|
||
│ • Product browsing and search │
|
||
│ • Shopping cart management │
|
||
│ • Checkout and payment │
|
||
│ • Order tracking │
|
||
│ • Customer account (optional) │
|
||
│ • Wishlist (optional) │
|
||
│ • Product reviews (optional) │
|
||
│ • Multi-theme system (vendor branding) │
|
||
│ │
|
||
│ UI Theme: Custom per vendor (multi-theme system) │
|
||
│ Colors: Vendor-specific via CSS variables │
|
||
│ │
|
||
│ Special Features: │
|
||
│ • Vendor Context Middleware (domain → vendor detection) │
|
||
│ • Theme Context Middleware (loads vendor theme) │
|
||
│ • CSS Variables for dynamic theming │
|
||
│ • Client-side cart (localStorage) │
|
||
│ │
|
||
│ Pages: │
|
||
│ ├── / (homepage) │
|
||
│ ├── /products (catalog) │
|
||
│ ├── /products/{id} (product detail) │
|
||
│ ├── /category/{slug} (category browse) │
|
||
│ ├── /search (search results) │
|
||
│ ├── /cart (shopping cart) │
|
||
│ ├── /checkout (checkout flow) │
|
||
│ ├── /account (customer account) │
|
||
│ ├── /orders (order history) │
|
||
│ ├── /about (about vendor) │
|
||
│ └── /contact (contact form) │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
|
||
🏗️ SHARED TECHNOLOGY STACK
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
All three frontends share the same core technologies:
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ LAYER TECHNOLOGY PURPOSE │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Backend FastAPI REST API + routing │
|
||
│ Templates Jinja2 Server-side rendering │
|
||
│ Interactivity Alpine.js 3.x Client-side reactivity│
|
||
│ Styling Tailwind CSS 2.x Utility-first CSS │
|
||
│ Icons Heroicons SVG icon system │
|
||
│ HTTP Client Fetch API API requests │
|
||
│ State Management Alpine.js reactive No external state lib │
|
||
│ Logging Custom LogConfig Centralized logging │
|
||
│ Error Handling Custom exceptions Structured errors │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
Why This Stack?
|
||
|
||
✅ Minimal JavaScript complexity (no React/Vue build process)
|
||
✅ Server-side rendering for SEO
|
||
✅ Progressive enhancement (works without JS)
|
||
✅ Fast development iteration
|
||
✅ Small bundle sizes
|
||
✅ Easy to learn and maintain
|
||
✅ Python developers can contribute to frontend
|
||
|
||
|
||
🎨 ARCHITECTURE PHILOSOPHY
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
1. API-First Design
|
||
─────────────────────────────────────────────────────────────
|
||
• Routes only render templates (no business logic)
|
||
• ALL data loaded client-side via REST APIs
|
||
• Clear separation: pages.py (templates) vs other API files
|
||
• Enables future mobile apps or SPA migrations
|
||
|
||
2. Progressive Enhancement
|
||
─────────────────────────────────────────────────────────────
|
||
• HTML works without JavaScript (basic functionality)
|
||
• JavaScript enhances experience (filters, live updates)
|
||
• Graceful degradation for older browsers
|
||
• Accessible by default
|
||
|
||
3. Component-Based Templates
|
||
─────────────────────────────────────────────────────────────
|
||
• Base templates provide layout
|
||
• Pages extend base templates
|
||
• Partials for reusable components
|
||
• Block overrides for customization
|
||
|
||
4. Centralized Design Patterns
|
||
─────────────────────────────────────────────────────────────
|
||
• Shared utilities (logging, API client, utils)
|
||
• Consistent error handling across frontends
|
||
• Standardized state management patterns
|
||
• Common UI components and patterns
|
||
|
||
5. Developer Experience
|
||
─────────────────────────────────────────────────────────────
|
||
• Copy-paste templates for new pages
|
||
• Consistent patterns reduce cognitive load
|
||
• Comprehensive documentation
|
||
• Clear file organization
|
||
|
||
|
||
📁 FILE ORGANIZATION
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
The project follows a clear, frontend-specific organization:
|
||
|
||
app/
|
||
├── templates/
|
||
│ ├── admin/ ← Admin frontend templates
|
||
│ │ ├── base.html
|
||
│ │ ├── dashboard.html
|
||
│ │ └── partials/
|
||
│ ├── vendor/ ← Vendor frontend templates
|
||
│ │ ├── base.html
|
||
│ │ ├── dashboard.html
|
||
│ │ └── partials/
|
||
│ └── shop/ ← Shop frontend templates
|
||
│ ├── base.html
|
||
│ ├── home.html
|
||
│ └── partials/
|
||
│
|
||
├── static/
|
||
│ ├── admin/ ← Admin-specific assets
|
||
│ │ ├── css/
|
||
│ │ ├── js/
|
||
│ │ └── img/
|
||
│ ├── vendor/ ← Vendor-specific assets
|
||
│ │ ├── css/
|
||
│ │ ├── js/
|
||
│ │ └── img/
|
||
│ ├── shop/ ← Shop-specific assets
|
||
│ │ ├── css/
|
||
│ │ ├── js/
|
||
│ │ └── img/
|
||
│ └── shared/ ← Shared across all frontends
|
||
│ ├── js/
|
||
│ │ ├── log-config.js ← Centralized logging
|
||
│ │ ├── api-client.js ← HTTP client wrapper
|
||
│ │ ├── icons.js ← Icon registry
|
||
│ │ └── utils.js ← Utility functions
|
||
│ └── css/
|
||
│
|
||
├── api/v1/
|
||
│ ├── admin/ ← Admin API endpoints
|
||
│ │ ├── pages.py ← Routes (templates only)
|
||
│ │ ├── vendors.py ← Business logic
|
||
│ │ ├── users.py
|
||
│ │ └── ...
|
||
│ ├── vendor/ ← Vendor API endpoints
|
||
│ │ ├── pages.py
|
||
│ │ ├── products.py
|
||
│ │ └── ...
|
||
│ └── shop/ ← Shop API endpoints
|
||
│ ├── pages.py
|
||
│ ├── products.py
|
||
│ └── ...
|
||
│
|
||
└── exceptions/ ← Custom exception classes
|
||
├── base.py ← Base exception classes
|
||
├── admin.py ← Admin-specific exceptions
|
||
├── shop.py ← Shop-specific exceptions
|
||
├── product.py ← Product exceptions
|
||
└── handler.py ← Exception handler setup
|
||
|
||
|
||
🔄 REQUEST FLOW
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
Understanding the complete request flow:
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ PAGE LOAD FLOW │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
1. Browser Request
|
||
↓
|
||
2. FastAPI Route Handler (pages.py)
|
||
• Verify authentication
|
||
• Extract route parameters
|
||
• Render Jinja2 template
|
||
↓
|
||
3. Template Rendering
|
||
• Extend base template
|
||
• Include partials
|
||
• Inject server-side data (user, vendor, theme)
|
||
↓
|
||
4. Browser Receives HTML
|
||
• Load CSS (Tailwind)
|
||
• Load JavaScript (Alpine.js, page scripts)
|
||
↓
|
||
5. Alpine.js Initialization
|
||
• x-data component initialized
|
||
• ...data() spreads base state
|
||
• init() method runs
|
||
• Initialization guard checked
|
||
↓
|
||
6. Client-Side Data Loading
|
||
• JavaScript calls REST API
|
||
• apiClient handles request
|
||
• JSON response received
|
||
↓
|
||
7. Reactive Updates
|
||
• Alpine.js updates reactive state
|
||
• DOM automatically updates
|
||
• Page fully interactive
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ USER INTERACTION FLOW │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
1. User Action (click, input, etc.)
|
||
↓
|
||
2. Alpine.js Event Handler
|
||
• @click, @input, @change, etc.
|
||
• Calls component method
|
||
↓
|
||
3. Business Logic
|
||
• Validate input
|
||
• Update local state
|
||
• Call API if needed
|
||
↓
|
||
4. API Request (if needed)
|
||
• apiClient.post/put/delete
|
||
• Automatic error handling
|
||
• Logging
|
||
↓
|
||
5. Update State
|
||
• Modify reactive data
|
||
• Alpine.js watches changes
|
||
↓
|
||
6. DOM Updates
|
||
• Automatic reactive updates
|
||
• No manual DOM manipulation
|
||
↓
|
||
7. User Feedback
|
||
• Toast notification
|
||
• Loading indicator removed
|
||
• Success/error message
|
||
|
||
|
||
🎭 DESIGN PATTERNS
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
The platform uses consistent design patterns across all frontends:
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 1. BASE LAYOUT INHERITANCE PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Share common UI state across all pages
|
||
Location: static/{frontend}/js/init-alpine.js
|
||
|
||
Pattern:
|
||
────────────────────────────────────────────────────────────────
|
||
// init-alpine.js provides base state
|
||
function data() {
|
||
return {
|
||
// Theme
|
||
dark: localStorage.getItem('theme') === 'dark',
|
||
toggleTheme() { /* ... */ },
|
||
|
||
// Side menu
|
||
isSideMenuOpen: false,
|
||
toggleSideMenu() { /* ... */ },
|
||
|
||
// Profile menu
|
||
isProfileMenuOpen: false,
|
||
toggleProfileMenu() { /* ... */ },
|
||
|
||
// Page identifier
|
||
currentPage: ''
|
||
};
|
||
}
|
||
|
||
// Every page inherits this via spread operator
|
||
function adminDashboard() {
|
||
return {
|
||
...data(), // ← Inherits ALL base functionality
|
||
currentPage: 'dashboard', // ← Override identifier
|
||
|
||
// Page-specific state
|
||
stats: [],
|
||
loading: false
|
||
};
|
||
}
|
||
|
||
Benefits:
|
||
✅ Dark mode works automatically on all pages
|
||
✅ Menu states consistent across navigation
|
||
✅ No duplicate code
|
||
✅ Easy to add new base functionality
|
||
✅ Sidebar highlighting works automatically
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 2. INITIALIZATION GUARD PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Prevent duplicate initialization and API calls
|
||
Problem: Alpine.js can sometimes initialize components twice
|
||
|
||
Pattern:
|
||
────────────────────────────────────────────────────────────────
|
||
async init() {
|
||
// Check if already initialized
|
||
if (window._dashboardInitialized) {
|
||
log.warn('Already initialized, skipping...');
|
||
return; // Exit early
|
||
}
|
||
|
||
// Set flag BEFORE async operations
|
||
window._dashboardInitialized = true;
|
||
|
||
// Safe to proceed
|
||
await this.loadData();
|
||
}
|
||
|
||
Naming Convention:
|
||
• Dashboard: window._dashboardInitialized
|
||
• Vendors: window._vendorsInitialized
|
||
• Products: window._productsInitialized
|
||
|
||
Benefits:
|
||
✅ Prevents duplicate API calls
|
||
✅ Prevents duplicate event listeners
|
||
✅ Improves performance
|
||
✅ Avoids state conflicts
|
||
✅ Console warnings help debugging
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 3. CENTRALIZED LOGGING PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Consistent, configurable logging across all frontends
|
||
Location: static/shared/js/log-config.js
|
||
|
||
Old Way (❌ BAD):
|
||
────────────────────────────────────────────────────────────────
|
||
// Every file had 15+ lines of duplicate code
|
||
const DASHBOARD_LOG_LEVEL = 3;
|
||
const dashLog = {
|
||
error: (...args) => DASHBOARD_LOG_LEVEL >= 1 &&
|
||
console.error('❌ [DASHBOARD ERROR]', ...args),
|
||
warn: (...args) => DASHBOARD_LOG_LEVEL >= 2 &&
|
||
console.warn('⚠️ [DASHBOARD WARN]', ...args),
|
||
info: (...args) => DASHBOARD_LOG_LEVEL >= 3 &&
|
||
console.info('ℹ️ [DASHBOARD INFO]', ...args),
|
||
debug: (...args) => DASHBOARD_LOG_LEVEL >= 4 &&
|
||
console.log('🔍 [DASHBOARD DEBUG]', ...args)
|
||
};
|
||
|
||
New Way (✅ GOOD):
|
||
────────────────────────────────────────────────────────────────
|
||
// Just ONE line per file!
|
||
const dashLog = window.LogConfig.loggers.dashboard;
|
||
|
||
// Use it
|
||
dashLog.info('Dashboard loading...');
|
||
dashLog.error('Failed to load', error);
|
||
dashLog.debug('Stats data:', statsData);
|
||
|
||
Pre-configured Loggers:
|
||
────────────────────────────────────────────────────────────────
|
||
Admin Frontend:
|
||
window.LogConfig.loggers.dashboard
|
||
window.LogConfig.loggers.vendors
|
||
window.LogConfig.loggers.vendorTheme
|
||
window.LogConfig.loggers.users
|
||
window.LogConfig.loggers.products
|
||
window.LogConfig.loggers.orders
|
||
window.LogConfig.loggers.imports
|
||
window.LogConfig.loggers.audit
|
||
|
||
Vendor Frontend:
|
||
window.LogConfig.loggers.dashboard
|
||
window.LogConfig.loggers.products
|
||
window.LogConfig.loggers.inventory
|
||
window.LogConfig.loggers.orders
|
||
window.LogConfig.loggers.theme
|
||
window.LogConfig.loggers.settings
|
||
window.LogConfig.loggers.analytics
|
||
|
||
Shop Frontend:
|
||
window.LogConfig.loggers.catalog
|
||
window.LogConfig.loggers.product
|
||
window.LogConfig.loggers.search
|
||
window.LogConfig.loggers.cart
|
||
window.LogConfig.loggers.checkout
|
||
window.LogConfig.loggers.account
|
||
|
||
Advanced Features:
|
||
────────────────────────────────────────────────────────────────
|
||
// Grouped logging
|
||
log.group('Loading Theme Data');
|
||
log.info('Fetching vendor...');
|
||
log.info('Fetching theme...');
|
||
log.groupEnd();
|
||
|
||
// API call logging
|
||
window.LogConfig.logApiCall('GET', url, data, 'response');
|
||
|
||
// Performance logging
|
||
window.LogConfig.logPerformance('Load Stats', duration);
|
||
|
||
// Error logging with context
|
||
window.LogConfig.logError(error, 'Save Theme');
|
||
|
||
// Table logging
|
||
log.table([
|
||
{ id: 1, name: 'Vendor A', status: 'active' },
|
||
{ id: 2, name: 'Vendor B', status: 'inactive' }
|
||
]);
|
||
|
||
Environment-Aware:
|
||
────────────────────────────────────────────────────────────────
|
||
• Development: Full logging (level 4)
|
||
• Production: Errors only (level 1)
|
||
• Automatically detects environment
|
||
• Can override with localStorage
|
||
|
||
Benefits:
|
||
✅ 1 line instead of 15+ lines per file
|
||
✅ Consistent format across all frontends
|
||
✅ Environment-aware (dev vs prod)
|
||
✅ Frontend-aware (admin/vendor/shop)
|
||
✅ Advanced features (groups, perf, API)
|
||
✅ Easy to update globally
|
||
✅ Reduces code duplication by 90%
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 4. API CLIENT PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Consistent API communication with automatic error handling
|
||
Location: static/shared/js/api-client.js
|
||
|
||
CRITICAL: Always use lowercase 'apiClient'
|
||
|
||
Usage:
|
||
────────────────────────────────────────────────────────────────
|
||
// ✅ CORRECT
|
||
const data = await apiClient.get('/api/v1/admin/vendors');
|
||
|
||
await apiClient.post('/api/v1/admin/vendors', {
|
||
name: 'New Vendor',
|
||
code: 'NEWVENDOR'
|
||
});
|
||
|
||
await apiClient.put('/api/v1/admin/vendors/123', {
|
||
name: 'Updated Name'
|
||
});
|
||
|
||
await apiClient.delete('/api/v1/admin/vendors/123');
|
||
|
||
// ❌ WRONG - Capital letters
|
||
await ApiClient.get('/url');
|
||
await API_CLIENT.get('/url');
|
||
|
||
Features:
|
||
────────────────────────────────────────────────────────────────
|
||
✅ Automatic auth token injection (from localStorage)
|
||
✅ Automatic JSON parsing
|
||
✅ Automatic error handling
|
||
✅ Request/response logging integration
|
||
✅ Timeout handling
|
||
✅ Retry logic (optional)
|
||
|
||
Error Handling:
|
||
────────────────────────────────────────────────────────────────
|
||
try {
|
||
const data = await apiClient.get('/endpoint');
|
||
// Success
|
||
} catch (error) {
|
||
// Error is already logged by apiClient
|
||
// Error is formatted with:
|
||
// - error.message (user-friendly)
|
||
// - error.details (technical details)
|
||
// - error.status_code (HTTP status)
|
||
|
||
this.error = error.message;
|
||
Utils.showToast('Failed to load', 'error');
|
||
}
|
||
|
||
Benefits:
|
||
✅ Consistent error handling
|
||
✅ Automatic auth headers
|
||
✅ Integrated logging
|
||
✅ Reduced boilerplate
|
||
✅ Easy to mock for testing
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 5. EXCEPTION HANDLING PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Structured, consistent error handling across backend
|
||
Location: app/exceptions/
|
||
|
||
Exception Hierarchy:
|
||
────────────────────────────────────────────────────────────────
|
||
WizamartException (base)
|
||
├── ValidationException (422)
|
||
├── AuthenticationException (401)
|
||
├── AuthorizationException (403)
|
||
├── ResourceNotFoundException (404)
|
||
├── ConflictException (409)
|
||
├── BusinessLogicException (400)
|
||
├── ExternalServiceException (502)
|
||
├── RateLimitException (429)
|
||
└── ServiceUnavailableException (503)
|
||
|
||
Domain-Specific Exceptions:
|
||
────────────────────────────────────────────────────────────────
|
||
app/exceptions/
|
||
├── base.py ← Base exceptions
|
||
├── admin.py ← Admin operations
|
||
│ ├── UserNotFoundException
|
||
│ ├── UserStatusChangeException
|
||
│ ├── ShopVerificationException
|
||
│ ├── CannotModifyAdminException
|
||
│ └── InvalidAdminActionException
|
||
├── shop.py ← Shop operations
|
||
│ ├── ShopNotFoundException
|
||
│ ├── ShopNotActiveException
|
||
│ ├── UnauthorizedShopAccessException
|
||
│ └── MaxShopsReachedException
|
||
├── product.py ← Product operations
|
||
│ ├── ProductNotFoundException
|
||
│ ├── InvalidProductDataException
|
||
│ └── InvalidGTINException
|
||
├── stock.py ← Stock operations
|
||
│ ├── StockNotFoundException
|
||
│ ├── InsufficientStockException
|
||
│ └── NegativeStockException
|
||
└── marketplace.py ← Marketplace imports
|
||
├── ImportJobNotFoundException
|
||
├── InvalidImportDataException
|
||
└── MarketplaceConnectionException
|
||
|
||
Exception Structure:
|
||
────────────────────────────────────────────────────────────────
|
||
class ProductNotFoundException(ResourceNotFoundException):
|
||
def __init__(self, product_id: str):
|
||
super().__init__(
|
||
resource_type="Product",
|
||
identifier=product_id,
|
||
message=f"Product with ID '{product_id}' not found",
|
||
error_code="PRODUCT_NOT_FOUND",
|
||
)
|
||
|
||
# Automatic JSON response:
|
||
{
|
||
"error_code": "PRODUCT_NOT_FOUND",
|
||
"message": "Product with ID '123' not found",
|
||
"status_code": 404,
|
||
"details": {
|
||
"resource_type": "Product",
|
||
"identifier": "123"
|
||
}
|
||
}
|
||
|
||
Global Exception Handler:
|
||
────────────────────────────────────────────────────────────────
|
||
Location: app/exceptions/handler.py
|
||
|
||
Handles:
|
||
• WizamartException → Custom JSON response
|
||
• HTTPException → Formatted JSON response
|
||
• RequestValidationError → Cleaned validation errors
|
||
• Exception → Generic 500 error
|
||
|
||
Automatic Logging:
|
||
• All exceptions logged with context
|
||
• Structured logging data
|
||
• Exception type tracking
|
||
|
||
Benefits:
|
||
✅ Consistent error responses
|
||
✅ Automatic logging
|
||
✅ Client-friendly error messages
|
||
✅ Technical details preserved
|
||
✅ Type-safe error handling
|
||
✅ Easy to test
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 6. UTILITY FUNCTIONS PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Shared utility functions across all frontends
|
||
Location: static/shared/js/utils.js
|
||
|
||
Available Functions:
|
||
────────────────────────────────────────────────────────────────
|
||
// Toast notifications
|
||
Utils.showToast(message, type, duration)
|
||
// Types: 'success', 'error', 'warning', 'info'
|
||
|
||
// Date formatting
|
||
Utils.formatDate(dateString)
|
||
// Returns: "Jan 15, 2024"
|
||
|
||
Utils.formatDateTime(dateString)
|
||
// Returns: "Jan 15, 2024 3:45 PM"
|
||
|
||
Utils.formatRelativeTime(dateString)
|
||
// Returns: "2 hours ago", "3 days ago"
|
||
|
||
// String utilities
|
||
Utils.truncate(text, length)
|
||
Utils.capitalize(text)
|
||
Utils.slugify(text)
|
||
|
||
// Number formatting
|
||
Utils.formatCurrency(amount, currency)
|
||
Utils.formatNumber(number)
|
||
Utils.formatPercentage(value)
|
||
|
||
// Validation
|
||
Utils.isValidEmail(email)
|
||
Utils.isValidUrl(url)
|
||
|
||
// Debounce
|
||
Utils.debounce(func, wait)
|
||
|
||
Usage Example:
|
||
────────────────────────────────────────────────────────────────
|
||
// Show success toast
|
||
Utils.showToast('Saved successfully', 'success');
|
||
|
||
// Format date for display
|
||
const formattedDate = Utils.formatDate(item.created_at);
|
||
|
||
// Format currency
|
||
const price = Utils.formatCurrency(29.99, 'USD');
|
||
|
||
// Debounce search
|
||
const debouncedSearch = Utils.debounce(
|
||
() => this.performSearch(),
|
||
300
|
||
);
|
||
|
||
Benefits:
|
||
✅ No code duplication
|
||
✅ Consistent formatting
|
||
✅ Easy to extend
|
||
✅ Tested and reliable
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 7. ICON REGISTRY PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Centralized SVG icon management
|
||
Location: static/shared/js/icons.js
|
||
|
||
Usage:
|
||
────────────────────────────────────────────────────────────────
|
||
<!-- In templates -->
|
||
<span x-html="$icon('home', 'w-5 h-5')"></span>
|
||
<span x-html="$icon('user', 'w-4 h-4 text-blue-500')"></span>
|
||
|
||
<!-- Loading spinner -->
|
||
<span x-html="$icon('spinner', 'w-8 h-8 text-purple-600')"></span>
|
||
|
||
Available Icons:
|
||
────────────────────────────────────────────────────────────────
|
||
Navigation:
|
||
home, dashboard, settings, menu
|
||
|
||
Users:
|
||
user, users, user-group, user-circle
|
||
|
||
Commerce:
|
||
shopping-cart, shopping-bag, credit-card
|
||
|
||
Content:
|
||
document, folder, archive, download, upload
|
||
|
||
Actions:
|
||
plus, minus, x, check, trash, pencil, eye
|
||
|
||
Arrows:
|
||
chevron-left, chevron-right, chevron-up, chevron-down
|
||
arrow-left, arrow-right
|
||
|
||
Status:
|
||
exclamation, exclamation-circle, check-circle, x-circle
|
||
spinner (animated)
|
||
|
||
Other:
|
||
search, filter, bell, star, heart, cube
|
||
|
||
Benefits:
|
||
✅ Consistent icon style (Heroicons)
|
||
✅ Easy to use
|
||
✅ Customizable size and color
|
||
✅ No external dependencies
|
||
✅ Reduced duplication
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 8. DARK MODE PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Consistent dark mode across all frontends
|
||
Implementation: Tailwind CSS dark mode + Alpine.js state
|
||
|
||
Pattern:
|
||
────────────────────────────────────────────────────────────────
|
||
// Base layout provides dark mode state
|
||
function data() {
|
||
return {
|
||
dark: localStorage.getItem('theme') === 'dark',
|
||
|
||
toggleTheme() {
|
||
this.dark = !this.dark;
|
||
localStorage.setItem('theme',
|
||
this.dark ? 'dark' : 'light'
|
||
);
|
||
}
|
||
};
|
||
}
|
||
|
||
// HTML class binding
|
||
<html x-data="data()" :class="{ 'dark': dark }">
|
||
|
||
// Tailwind dark mode classes
|
||
<div class="bg-white dark:bg-gray-800">
|
||
<p class="text-gray-900 dark:text-white">Content</p>
|
||
</div>
|
||
|
||
// Toggle button
|
||
<button @click="toggleTheme()">
|
||
<svg x-show="!dark"><!-- Sun icon --></svg>
|
||
<svg x-show="dark"><!-- Moon icon --></svg>
|
||
</button>
|
||
|
||
Shop Frontend Special Case:
|
||
────────────────────────────────────────────────────────────────
|
||
• Vendor colors adapt to dark mode
|
||
• CSS variables for both modes
|
||
• Maintains brand identity in dark mode
|
||
|
||
Benefits:
|
||
✅ Automatic on all pages
|
||
✅ Persisted preference
|
||
✅ Smooth transitions
|
||
✅ Vendor branding preserved (shop)
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 9. MULTI-THEME PATTERN (Shop Frontend Only) ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Vendor-specific branding for shop frontend
|
||
Location: Shop frontend only
|
||
|
||
Components:
|
||
────────────────────────────────────────────────────────────────
|
||
1. Database: vendor_themes table
|
||
2. Model: VendorTheme (colors, fonts, logos, layout)
|
||
3. Middleware: theme_context_middleware
|
||
4. Template: CSS variables injection
|
||
5. JavaScript: Theme-aware utilities
|
||
|
||
Flow:
|
||
────────────────────────────────────────────────────────────────
|
||
1. Request → customdomain1.com
|
||
2. Vendor Middleware → Identifies Vendor 1
|
||
3. Theme Middleware → Loads Vendor 1's theme
|
||
4. Template → Injects CSS variables
|
||
5. Render → Vendor-branded shop
|
||
|
||
CSS Variables:
|
||
────────────────────────────────────────────────────────────────
|
||
:root {
|
||
--color-primary: #6366f1; /* Vendor's color */
|
||
--color-secondary: #8b5cf6;
|
||
--color-accent: #ec4899;
|
||
--font-heading: Inter, sans-serif;
|
||
--font-body: Inter, sans-serif;
|
||
}
|
||
|
||
Usage:
|
||
────────────────────────────────────────────────────────────────
|
||
<button style="background-color: var(--color-primary)">
|
||
Buy Now
|
||
</button>
|
||
|
||
<h1 style="font-family: var(--font-heading)">
|
||
Welcome
|
||
</h1>
|
||
|
||
Benefits:
|
||
✅ Each vendor has unique branding
|
||
✅ No code changes per vendor
|
||
✅ Database-driven configuration
|
||
✅ Custom CSS support
|
||
✅ Theme presets available
|
||
|
||
|
||
╔═══════════════════════════════════════════════════════════════╗
|
||
║ 10. PAGINATION PATTERN ║
|
||
╚═══════════════════════════════════════════════════════════════╝
|
||
|
||
Purpose: Consistent pagination across all list pages
|
||
|
||
State:
|
||
────────────────────────────────────────────────────────────────
|
||
pagination: {
|
||
currentPage: 1,
|
||
totalPages: 1,
|
||
perPage: 10,
|
||
total: 0,
|
||
from: 0,
|
||
to: 0
|
||
}
|
||
|
||
Methods:
|
||
────────────────────────────────────────────────────────────────
|
||
async goToPage(page) {
|
||
if (page < 1 || page > this.pagination.totalPages) return;
|
||
this.pagination.currentPage = page;
|
||
await this.loadData();
|
||
}
|
||
|
||
async previousPage() {
|
||
await this.goToPage(this.pagination.currentPage - 1);
|
||
}
|
||
|
||
async nextPage() {
|
||
await this.goToPage(this.pagination.currentPage + 1);
|
||
}
|
||
|
||
get paginationRange() {
|
||
const current = this.pagination.currentPage;
|
||
const total = this.pagination.totalPages;
|
||
const range = [];
|
||
|
||
let start = Math.max(1, current - 2);
|
||
let end = Math.min(total, start + 4);
|
||
|
||
if (end - start < 4) {
|
||
start = Math.max(1, end - 4);
|
||
}
|
||
|
||
for (let i = start; i <= end; i++) {
|
||
range.push(i);
|
||
}
|
||
|
||
return range;
|
||
}
|
||
|
||
Benefits:
|
||
✅ Consistent UX
|
||
✅ Smart page range calculation
|
||
✅ Easy to implement
|
||
|
||
|
||
🔐 SECURITY PATTERNS
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
Authentication & Authorization:
|
||
────────────────────────────────────────────────────────────────
|
||
1. JWT Tokens
|
||
• Stored in localStorage
|
||
• Automatically sent with API requests
|
||
• Expiration handling
|
||
|
||
2. Role-Based Access
|
||
• Admin: Full platform access
|
||
• Vendor: Limited to own shop
|
||
• Customer: Public + account access
|
||
|
||
3. Route Protection
|
||
• FastAPI dependencies verify auth
|
||
• Middleware for vendor context
|
||
• Automatic redirects to login
|
||
|
||
Input Validation:
|
||
────────────────────────────────────────────────────────────────
|
||
1. Client-Side (Alpine.js)
|
||
• Immediate feedback
|
||
• Better UX
|
||
• Reduces server load
|
||
|
||
2. Server-Side (Pydantic)
|
||
• Security boundary
|
||
• Type validation
|
||
• Cannot be bypassed
|
||
|
||
3. Both Required
|
||
• Client-side for UX
|
||
• Server-side for security
|
||
|
||
XSS Prevention:
|
||
────────────────────────────────────────────────────────────────
|
||
• Jinja2 auto-escapes by default
|
||
• Use | safe only when necessary
|
||
• Sanitize user content
|
||
|
||
CSRF Protection:
|
||
────────────────────────────────────────────────────────────────
|
||
• Token-based (if using forms)
|
||
• SameSite cookies
|
||
• API uses Bearer tokens (CSRF-safe)
|
||
|
||
|
||
📚 DETAILED ARCHITECTURE DOCUMENTS
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
This overview introduces the architecture. For complete details:
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 1. FRONTEND_ADMIN_ARCHITECTURE_OVERVIEW.txt │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Comprehensive guide to admin frontend: │
|
||
│ • Complete file structure │
|
||
│ • Layer-by-layer architecture │
|
||
│ • All admin pages detailed │
|
||
│ • Authentication and authorization │
|
||
│ • Performance optimization │
|
||
│ • Learning path for new developers │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 2. FRONTEND_ADMIN_ALPINE_PAGE_TEMPLATE.md │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Complete templates for creating admin pages: │
|
||
│ • Full Jinja2 template boilerplate │
|
||
│ • Complete Alpine.js component structure │
|
||
│ • 4 common page patterns │
|
||
│ • Best practices with examples │
|
||
│ • Testing checklist │
|
||
│ • Quick start guide │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 3. FRONTEND_VENDOR_ARCHITECTURE_OVERVIEW.txt │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Similar to admin but vendor-specific: │
|
||
│ • Vendor context and scoping │
|
||
│ • Shop management features │
|
||
│ • Marketplace integration │
|
||
│ • Team management │
|
||
│ • Vendor-specific pages │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 4. FRONTEND_VENDOR_ALPINE_PAGE_TEMPLATE.md │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Templates for vendor pages: │
|
||
│ • Similar to admin templates │
|
||
│ • Vendor context integration │
|
||
│ • Scoped data patterns │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 5. FRONTEND_SHOP_ARCHITECTURE_OVERVIEW.txt │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Customer-facing shop frontend: │
|
||
│ • Multi-theme system │
|
||
│ • Vendor branding │
|
||
│ • Cart management │
|
||
│ • Search and filters │
|
||
│ • E-commerce patterns │
|
||
│ • SEO optimization │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 6. FRONTEND_SHOP_ALPINE_PAGE_TEMPLATE.md │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ Templates for shop pages: │
|
||
│ • Theme-aware components │
|
||
│ • Cart integration patterns │
|
||
│ • Product display patterns │
|
||
│ • Checkout flow patterns │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
|
||
|
||
🎓 LEARNING PATH
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
For New Developers:
|
||
|
||
Week 1: Foundation
|
||
──────────────────────────────────────────────────────────────────
|
||
Day 1-2: Read this overview document
|
||
Day 3-4: Study one detailed architecture doc (start with admin)
|
||
Day 5: Review shared design patterns
|
||
|
||
Week 2: Hands-On
|
||
──────────────────────────────────────────────────────────────────
|
||
Day 1-2: Examine existing dashboard.js (best example)
|
||
Day 3-4: Copy template and create simple page
|
||
Day 5: Test and understand data flow
|
||
|
||
Week 3: Patterns
|
||
──────────────────────────────────────────────────────────────────
|
||
Day 1: Practice base layout inheritance
|
||
Day 2: Implement initialization guards
|
||
Day 3: Use centralized logging
|
||
Day 4: Work with API client
|
||
Day 5: Handle errors properly
|
||
|
||
Week 4: Advanced
|
||
──────────────────────────────────────────────────────────────────
|
||
Day 1-2: Create complex page with filters/pagination
|
||
Day 3: Implement modal forms
|
||
Day 4: Add dark mode support
|
||
Day 5: Review and refactor
|
||
|
||
After 1 Month:
|
||
──────────────────────────────────────────────────────────────────
|
||
✅ Understand all three frontends
|
||
✅ Can create new pages independently
|
||
✅ Follow all design patterns
|
||
✅ Debug issues effectively
|
||
✅ Contribute to architecture improvements
|
||
|
||
|
||
✅ DEVELOPMENT CHECKLIST
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
Before Creating New Page:
|
||
────────────────────────────────────────────────────────────────
|
||
□ Read relevant architecture document
|
||
□ Review page template guide
|
||
□ Study similar existing page
|
||
□ Identify which patterns to use
|
||
|
||
While Developing:
|
||
────────────────────────────────────────────────────────────────
|
||
□ Use ...data() for base inheritance
|
||
□ Add initialization guard
|
||
□ Set currentPage identifier
|
||
□ Use lowercase apiClient
|
||
□ Use centralized logger
|
||
□ Handle errors gracefully
|
||
□ Add loading states
|
||
□ Support dark mode
|
||
|
||
Before Committing:
|
||
────────────────────────────────────────────────────────────────
|
||
□ No console errors
|
||
□ Initialization guard works
|
||
□ Dark mode works
|
||
□ Mobile responsive
|
||
□ API errors handled
|
||
□ No duplicate API calls
|
||
□ Logging consistent
|
||
□ Code matches patterns
|
||
|
||
|
||
🚀 BENEFITS OF THIS ARCHITECTURE
|
||
═════════════════════════════════════════════════════════════════
|
||
|
||
For Developers:
|
||
✅ Copy-paste templates reduce development time
|
||
✅ Consistent patterns reduce cognitive load
|
||
✅ Centralized utilities eliminate duplication
|
||
✅ Clear documentation speeds onboarding
|
||
✅ Shared patterns enable code reuse
|
||
|
||
For The Platform:
|
||
✅ Maintainable codebase
|
||
✅ Consistent user experience
|
||
✅ Easier debugging
|
||
✅ Faster feature development
|
||
✅ Scalable architecture
|
||
|
||
For Users:
|
||
✅ Consistent UI/UX
|
||
✅ Fast page loads
|
||
✅ Reliable functionality
|
||
✅ Professional appearance
|
||
✅ Works on all devices
|
||
|
||
|
||
══════════════════════════════════════════════════════════════════
|
||
LETZSHOP FRONTEND ARCHITECTURE
|
||
Three Frontends, One Cohesive System, Endless Scale
|
||
══════════════════════════════════════════════════════════════════
|
||
|
||
Next Steps:
|
||
1. Read the detailed architecture document for the frontend you're
|
||
working on (Admin, Vendor, or Shop)
|
||
2. Study the page template guide for that frontend
|
||
3. Review existing code examples (dashboard.js is the best)
|
||
4. Copy templates and start building!
|
||
|
||
Questions? Check the detailed architecture docs or review existing
|
||
implementations in the codebase.
|
||
|
||
Happy Coding! 🚀
|