Files
orion/docs/frontend/admin/architecture.md
Samir Boulahtit 35d1559162
Some checks failed
CI / ruff (push) Successful in 10s
CI / pytest (push) Failing after 47m30s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
feat(monitoring): add Redis exporter + Sentry docs to deployment guide
- Add redis-exporter container to docker-compose (oliver006/redis_exporter, 32MB)
- Add Redis scrape target to Prometheus config
- Add 4 Redis alert rules: RedisDown, HighMemory, HighConnections, RejectedConnections
- Document Step 19b (Sentry Error Tracking) in Hetzner deployment guide
- Document Step 19c (Redis Monitoring) in Hetzner deployment guide
- Update resource budget and port reference tables

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:30:18 +01:00

29 KiB

╔══════════════════════════════════════════════════════════════════╗ ║ ADMIN FRONTEND ARCHITECTURE OVERVIEW ║ ║ Alpine.js + Jinja2 + Tailwind CSS ║ ╚══════════════════════════════════════════════════════════════════╝

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

Admin frontend provides platform administrators with complete control over the marketplace. Built with: Jinja2 Templates (server-side rendering) Alpine.js (client-side reactivity) Tailwind CSS (utility-first styling) Windmill Dashboard UI (dark mode ready) FastAPI (backend routes)

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

  1. Minimal Server-Side Rendering • Routes handle authentication + template rendering • NO database queries in route handlers • ALL data loaded client-side via JavaScript

  2. Component-Based Architecture • Base template with shared layout • Reusable partials (header, sidebar, etc.) • Page-specific templates extend base

  3. Progressive Enhancement • Works without JavaScript (basic HTML) • JavaScript adds interactivity • Graceful degradation

  4. API-First Data Loading • All data from REST APIs • Client-side state management • Real-time updates possible

  5. Centralized State & Logging • Base layout provides shared state • Centralized logging system • Consistent error handling

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

app/ ├── templates/admin/ │ ├── base.html ← Base template (layout) │ ├── login.html ← Admin login page │ ├── dashboard.html ← Dashboard overview │ ├── stores.html ← Store management │ ├── store-edit.html ← Single store edit │ ├── users.html ← User management │ ├── products.html ← Product management │ ├── orders.html ← Order management │ ├── import-jobs.html ← Import job tracking │ ├── audit-logs.html ← Audit log viewer │ ├── settings.html ← System settings │ └── partials/ ← Reusable components │ ├── header.html ← Top navigation │ ├── sidebar.html ← Main navigation │ ├── notifications.html ← Toast notifications │ ├── modal.html ← Modal template │ └── table.html ← Data table template │ ├── static/admin/ │ ├── css/ │ │ ├── tailwind.output.css ← Generated Tailwind │ │ └── admin.css ← Custom admin styles │ ├── js/ │ │ ├── init-alpine.js ← Base Alpine.js data │ │ ├── dashboard.js ← Dashboard logic │ │ ├── stores.js ← Store management logic │ │ ├── store-edit.js ← Store edit logic │ │ ├── store-theme.js ← Theme customization │ │ ├── users.js ← User management logic │ │ ├── products.js ← Product management logic │ │ ├── orders.js ← Order management logic │ │ ├── import-jobs.js ← Import tracking logic │ │ ├── audit-logs.js ← Audit log logic │ │ └── settings.js ← Settings logic │ └── img/ │ ├── login-office.jpeg │ └── login-office-dark.jpeg │ ├── static/shared/ ← Shared across all areas │ ├── js/ │ │ ├── log-config.js ← Centralized logging │ │ ├── icons.js ← Icon registry │ │ ├── utils.js ← Utility functions │ │ └── api-client.js ← API wrapper │ └── css/ │ └── base.css ← Global styles │ └── api/v1/admin/ ├── pages.py ← Route handlers (templates) ├── stores.py ← Store API endpoints ├── users.py ← User API endpoints ├── products.py ← Product API endpoints ├── orders.py ← Order API endpoints └── settings.py ← Settings API endpoints

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

Layer 1: Routes (FastAPI) ↓ Layer 2: Templates (Jinja2) ↓ Layer 3: JavaScript (Alpine.js) ↓ Layer 4: API (REST endpoints) ↓ Layer 5: Database

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

Example: @router.get("/admin/dashboard") async def admin_dashboard_page( request: Request, current_user: User = Depends(get_current_admin_from_cookie_or_header) ): return templates.TemplateResponse( "admin/dashboard.html", { "request": request, "user": current_user, } )

Responsibilities: Verify authentication (admin role required) Extract route parameters Render template with minimal context NO database queries NO business logic

Layer 2: TEMPLATES (Jinja2) ────────────────────────────────────────────────────────────────── Purpose: HTML Structure + Server-Side Data Location: app/templates/admin/

Template Hierarchy: base.html (layout + shared components) ↓ dashboard.html (page content) ↓ partials/sidebar.html (navigation)

Example: {% extends "admin/base.html" %} {% block title %}Dashboard{% endblock %} {% block alpine_data %}adminDashboard(){% endblock %} {% block content %}

Loading...
{% endblock %}

Key Features: Template inheritance Server-side variables (user info) Include partials Block overrides Alpine.js integration

Layer 3: JAVASCRIPT (Alpine.js) ────────────────────────────────────────────────────────────────── Purpose: Client-Side Interactivity + Data Loading Location: app/static/admin/js/

Component Structure: function adminDashboard() { return { // CRITICAL: Inherit base layout state ...data(),

      // ✅ CRITICAL: Set page identifier
      currentPage: 'dashboard',

      // Page-specific state
      loading: false,
      error: null,
      stats: [],

      // Initialization
      async init() {
          // Guard against multiple initialization
          if (window._dashboardInitialized) {
              dashLog.warn('Already initialized');
              return;
          }
          window._dashboardInitialized = true;

          await this.loadStats();
      },

      // Data loading
      async loadStats() {
          this.loading = true;
          try {
              this.stats = await apiClient.get(
                  '/api/v1/admin/stats'
              );
          } catch (error) {
              this.error = error.message;
          } finally {
              this.loading = false;
          }
      }
  };

}

Responsibilities: Load data from API Manage UI state Handle user interactions Update DOM reactively Inherit base layout functionality

Layer 4: API (REST) ────────────────────────────────────────────────────────────────── Purpose: Business Logic + Data Access Location: app/api/v1/admin/*.py (not pages.py)

Example Endpoints: GET /api/v1/admin/stats GET /api/v1/admin/stores POST /api/v1/admin/stores PUT /api/v1/admin/stores/{id} DELETE /api/v1/admin/stores/{id} GET /api/v1/admin/users GET /api/v1/admin/audit-logs

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

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

  1. Admin → GET /admin/dashboard
  2. FastAPI → Check authentication (admin role)
  3. FastAPI → Render template with minimal context
  4. Browser → Load HTML + CSS + JS
  5. Alpine.js → init() executes
  6. JavaScript → Check initialization guard
  7. JavaScript → API call for dashboard stats
  8. API → Return JSON data
  9. Alpine.js → Update reactive state
  10. Browser → DOM updates automatically

User Interaction Flow: ──────────────────────────────────────────────────────────────────

  1. Admin → Click "Delete Store"
  2. Alpine.js → Show confirmation dialog
  3. Admin → Confirms deletion
  4. Alpine.js → DELETE to API
  5. API → Delete store + return success
  6. Alpine.js → Update local state (remove from list)
  7. Browser → DOM updates automatically
  8. Alpine.js → Show success toast notification

💡 BASE LAYOUT INHERITANCE ═════════════════════════════════════════════════════════════════

The ...data() Spread: ──────────────────────────────────────────────────────────────────

Every page component MUST start with ...data() to inherit base layout functionality:

init-alpine.js provides: function data() { return { // Theme state dark: localStorage.getItem('theme') === 'dark', toggleTheme() { /* ... */ },

      // Side menu state
      isSideMenuOpen: false,
      toggleSideMenu() { /* ... */ },
      closeSideMenu() { /* ... */ },

      // Profile menu state
      isProfileMenuOpen: false,
      toggleProfileMenu() { /* ... */ },
      closeProfileMenu() { /* ... */ },

      // Notifications menu state
      isNotificationsMenuOpen: false,
      toggleNotificationsMenu() { /* ... */ },
      closeNotificationsMenu() { /* ... */ },

      // Page identifier (override in each page)
      currentPage: ''
  };

}

Your page inherits ALL of this: function adminStores() { return { ...data(), // ← Spreads all base functionality currentPage: 'stores', // ← Override page identifier

      // Your page-specific state
      stores: [],
      loading: false
  };

}

Benefits: Automatic dark mode support Menu states work automatically No duplicate code Consistent behavior across pages

🎨 STYLING SYSTEM ═════════════════════════════════════════════════════════════════

Tailwind CSS Utility Classes: • Responsive: sm:, md:, lg:, xl: • Dark mode: dark:bg-gray-800 • Hover: hover:bg-purple-700 • Focus: focus:outline-none • Transitions: transition-colors duration-150

Custom CSS Variables (admin/css/admin.css): --color-primary: #7c3aed (purple-600) --color-accent: #ec4899 (pink-500) --color-success: #10b981 (green-500) --color-warning: #f59e0b (yellow-500) --color-danger: #ef4444 (red-500)

Windmill Dashboard Theme: • Professional admin UI • Dark mode ready • Consistent components • Accessible by default

🔐 AUTHENTICATION ═════════════════════════════════════════════════════════════════

Auth Flow:

  1. Login → POST /api/v1/admin/auth/login
  2. API → Verify credentials + check admin role
  3. API → Return JWT token + set admin_token cookie
  4. JavaScript → Store in localStorage (optional)
  5. HTML Pages → Use cookie (automatic)
  6. API Calls → Use Authorization header
  7. Routes → Verify with get_current_admin_from_cookie_or_header (HTML) or get_current_admin_api (API endpoints)

Protected Routes: • All /admin/* routes • Require valid JWT token • Require admin role (is_admin=True) • Redirect to login if unauthorized

Public Routes: • /admin/login • No authentication required

Role-Based Access: • Admin: Full platform access • Store: Limited to own shop (store portal) • Customer: No admin access

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

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

Mobile-First Approach: • Base styles for mobile • Add complexity for larger screens • Collapsible sidebar on mobile • Stack cards vertically on mobile

Example:

🌙 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: persist preference

Toggle Flow:

  1. User clicks dark mode button
  2. toggleTheme() called (from base data)
  3. dark state toggled
  4. Saved to localStorage
  5. HTML class updates
  6. Tailwind dark: variants activate

Example Usage:

Content

🔒 INITIALIZATION GUARDS ═════════════════════════════════════════════════════════════════

Purpose: Prevent Multiple Initialization

Alpine.js can sometimes initialize components multiple times. Use a guard to prevent duplicate API calls and setup:

Pattern: async init() { // Check if already initialized if (window._dashboardInitialized) { dashLog.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 • Stores: window._storesInitialized • Products: window._productsInitialized • etc.

Benefits: Prevents duplicate API calls Prevents duplicate event listeners Improves performance Avoids state conflicts

🪵 CENTRALIZED LOGGING ═════════════════════════════════════════════════════════════════

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

Pre-configured Loggers: window.LogConfig.loggers.dashboard window.LogConfig.loggers.stores window.LogConfig.loggers.storeTheme window.LogConfig.loggers.users window.LogConfig.loggers.products window.LogConfig.loggers.orders window.LogConfig.loggers.imports window.LogConfig.loggers.audit

Usage: // Use pre-configured logger const dashLog = window.LogConfig.loggers.dashboard;

dashLog.info('Dashboard loading...'); dashLog.error('Failed to load stats', error); dashLog.debug('Stats data:', statsData); dashLog.warn('API response slow');

Advanced Features: // Grouped logs dashLog.group('Loading Dashboard Data'); dashLog.info('Fetching stats...'); dashLog.info('Fetching activity...'); dashLog.groupEnd();

// API call logging window.LogConfig.logApiCall('GET', url, data, 'response');

// Performance logging window.LogConfig.logPerformance('Load Stats', duration);

// Error logging window.LogConfig.logError(error, 'Load Stats');

Benefits: One line instead of 15+ lines per file Consistent logging format Environment-aware (dev/prod) Frontend-aware (admin/store/shop) Advanced features (groups, perf, API)

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

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

CRITICAL: Always use lowercase 'apiClient' apiClient.get() ApiClient.get() API_CLIENT.get()

Usage: const data = await apiClient.get('/api/v1/admin/stores');

await apiClient.post('/api/v1/admin/stores', { name: 'New Store', code: 'NEWSTORE' });

await apiClient.put('/api/v1/admin/stores/123', { name: 'Updated Name' });

await apiClient.delete('/api/v1/admin/stores/123');

Features: Automatic auth headers Error handling JSON parsing Request/response logging

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

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

Usage:

Available Icons: • home, dashboard, settings • user, users, user-group • shopping-bag, shopping-cart • cube, download, upload • plus, minus, x • pencil, trash, eye • check, exclamation • chevron-left, chevron-right • spinner (for loading)

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

Optimization Techniques:

  1. Template Caching • Base template cached by FastAPI • Reduces rendering time

  2. Lazy Loading • Data loaded after page render • Progressive content display

  3. Debouncing • Search inputs debounced • Reduces API calls

  4. Pagination • Server-side pagination • Load only needed data

  5. CDN Assets with Fallback • Tailwind CSS from CDN (fallback to local) • Alpine.js from CDN (fallback to local) • Works offline and in restricted networks • See: CDN Fallback Strategy

  6. Initialization Guards • Prevent duplicate setups • Reduce unnecessary operations

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

/admin/dashboard ────────────────────────────────────────────────────────────────── Purpose: Overview of platform operations Components: • Stats cards (stores, users, orders, revenue) • Recent activity feed • Quick actions panel • System health indicators Data Sources: • GET /api/v1/admin/stats • GET /api/v1/admin/recent-activity

/admin/stores ────────────────────────────────────────────────────────────────── Purpose: Manage marketplace stores Components: • Store list table • Search and filters • Create/Edit modal • Status management • Verification controls Data Sources: • GET /api/v1/admin/stores • POST /api/v1/admin/stores • PUT /api/v1/admin/stores/{id} • DELETE /api/v1/admin/stores/{id}

/admin/stores/{code}/edit ────────────────────────────────────────────────────────────────── Purpose: Edit single store details Components: • Store information form • Status controls • Contact information • Business details Data Sources: • GET /api/v1/admin/stores/{code} • PUT /api/v1/admin/stores/{code}

/admin/stores/{code}/theme ────────────────────────────────────────────────────────────────── Purpose: Customize store's shop theme Components: • Color picker • Font selector • Logo uploader • Layout options • Custom CSS editor • Theme presets Data Sources: • GET /api/v1/admin/store-themes/{code} • PUT /api/v1/admin/store-themes/{code}

/admin/users ────────────────────────────────────────────────────────────────── Purpose: Manage platform users Components: • User list table • Search and filters • Role management • Status controls Data Sources: • GET /api/v1/admin/users • PUT /api/v1/admin/users/{id} • DELETE /api/v1/admin/users/{id}

/admin/products ────────────────────────────────────────────────────────────────── Purpose: View all marketplace products Components: • Product list table • Search and filters • Store filter • Bulk actions Data Sources: • GET /api/v1/admin/products

/admin/orders ────────────────────────────────────────────────────────────────── Purpose: View all marketplace orders Components: • Order list table • Status filters • Store filter • Order detail modal Data Sources: • GET /api/v1/admin/orders • GET /api/v1/admin/orders/{id}

/admin/import-jobs ────────────────────────────────────────────────────────────────── Purpose: Monitor marketplace import operations Components: • Import job list • Status indicators • Progress tracking • Error logs Data Sources: • GET /api/v1/admin/import-jobs • GET /api/v1/admin/import-jobs/{id}

/admin/audit-logs ────────────────────────────────────────────────────────────────── Purpose: Track all system actions Components: • Audit log table • Filters (user, action, date) • Export functionality Data Sources: • GET /api/v1/admin/audit-logs

/admin/settings ────────────────────────────────────────────────────────────────── Purpose: Configure platform settings Components: • Settings tabs • Configuration forms • Feature toggles Data Sources: • GET /api/v1/admin/settings • PUT /api/v1/admin/settings

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

For New Developers:

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

  2. Study Existing Page (2 hours) → Open dashboard.html → Open dashboard.js → Trace data flow → Understand init guard pattern

  3. Create Simple Page (4 hours) → Copy templates from dashboard → Modify for new feature → Test initialization guard → Verify dark mode works

  4. Add Complex Feature (1 day) → Forms with validation → Modal dialogs → API integration → Error handling

  5. Master Patterns (1 week) → All common patterns → Centralized logging → Performance optimization → Best practices

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

Before Deploying: □ Build Tailwind CSS □ Minify JavaScript □ Test all routes □ Verify authentication □ Check role-based access □ Verify initialization guards work □ Check mobile responsive □ Test dark mode □ Validate API endpoints □ Review error handling □ Test logging in production mode □ Check console for errors □ Verify no duplicate initializations

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

Best Practices:

  1. Authentication JWT tokens Token expiration Secure storage (httpOnly cookies option)

  2. Authorization Route-level checks (admin role required) API-level validation Role-based permissions

  3. Input Validation Client-side validation Server-side validation XSS prevention

  4. CSRF Protection Token-based SameSite cookies

  5. Admin-Specific Audit logging for all actions Strong password requirements Two-factor authentication (optional)

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

Documentation: • Alpine.js: https://alpinejs.dev/ • Tailwind CSS: https://tailwindcss.com/ • Jinja2: https://jinja.palletsprojects.com/ • FastAPI: https://fastapi.tiangolo.com/ • Windmill Dashboard: https://windmill-dashboard.vercel.app/

Internal Docs: • Page Template Guide: FRONTEND_ADMIN_ALPINE_PAGE_TEMPLATE.md • API Documentation: API_REFERENCE.md • Database Schema: DATABASE_SCHEMA.md

══════════════════════════════════════════════════════════════════ ADMIN FRONTEND ARCHITECTURE Powerful, Secure, and Maintainable Platform Control ══════════════════════════════════════════════════════════════════