Files
orion/docs/architecture/frontend-structure.md
Samir Boulahtit 7245f79f7b refactor: rename shop to storefront for consistency
Rename all "shop" directories and references to "storefront" to match
the API and route naming convention already in use.

Renamed directories:
- app/templates/shop/ → app/templates/storefront/
- static/shop/ → static/storefront/
- app/templates/shared/macros/shop/ → .../macros/storefront/
- docs/frontend/shop/ → docs/frontend/storefront/

Renamed files:
- shop.css → storefront.css
- shop-layout.js → storefront-layout.js

Updated references in:
- app/routes/storefront_pages.py (21 template references)
- app/modules/cms/routes/pages/vendor.py
- app/templates/storefront/base.html (static paths)
- All storefront templates (extends/includes)
- docs/architecture/frontend-structure.md

This aligns the template/static naming with:
- Route file: storefront_pages.py
- API directory: app/api/v1/storefront/
- Module routes: */routes/api/storefront.py
- URL paths: /storefront/*

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:58:28 +01:00

18 KiB

Frontend Architecture

Overview

This application has 4 distinct frontends, each with its own templates and static assets:

  1. Platform - Public platform pages (homepage, about, contact)
  2. Admin - Administrative control panel
  3. Vendor - Vendor management portal
  4. Storefront - Customer-facing e-commerce store

Directory Structure

app/
├── templates/
│   ├── platform/          # Platform public pages
│   ├── admin/             # Admin portal pages
│   ├── vendor/            # Vendor portal pages
│   ├── storefront/        # Storefront customer pages
│   └── shared/            # Shared components (emails, errors)
│
└── static/
    ├── platform/          # Platform static assets
    │   ├── js/
    │   ├── css/
    │   └── img/
    ├── admin/             # Admin static assets
    │   ├── js/
    │   ├── css/
    │   └── img/
    ├── vendor/            # Vendor static assets
    │   ├── js/
    │   ├── css/
    │   └── img/
    ├── storefront/        # Storefront static assets
    │   ├── js/
    │   ├── css/
    │   └── img/
    └── shared/            # Shared assets (icons, utilities)
        ├── js/
        ├── css/
        └── img/

Frontend Details

1. Platform Frontend

Purpose: Public-facing platform pages (marketing, info pages)

Location:

  • Templates: app/templates/platform/
  • Static: static/platform/

Pages:

  • Homepage (multiple layouts: default, minimal, modern)
  • Content pages (about, privacy, terms)
  • Landing pages

Features:

  • SEO-optimized
  • Multi-layout homepage support
  • Content management system integration
  • Responsive design

Routes: /, /about, /contact, etc.

Authentication: Not required (public access)


2. Admin Frontend

Purpose: Platform administration and management

Location:

  • Templates: app/templates/admin/
  • Static: static/admin/

Pages:

  • Dashboard
  • Vendor management
  • User management
  • Content management
  • Theme customization
  • System settings
  • Logs and monitoring
  • Code quality dashboard

Technology Stack:

  • Alpine.js for reactive components
  • Tailwind CSS for styling
  • Heroicons for icons
  • Centralized logging system
  • API-driven architecture

Routes: /admin/*

Authentication: Admin role required


3. Vendor Frontend

Purpose: Vendor portal for product and order management

Location:

  • Templates: app/templates/vendor/
  • Static: static/vendor/

Pages:

  • Vendor dashboard
  • Product management
  • Inventory management
  • Order management
  • Analytics
  • Profile settings

Technology Stack:

  • Alpine.js for reactive components
  • Tailwind CSS for styling
  • Heroicons for icons
  • API-driven architecture
  • Vendor context middleware

Routes: /vendor/{vendor_code}/*

Authentication: Vendor role required


4. Storefront Frontend

Purpose: Customer-facing e-commerce store

Location:

  • Templates: app/templates/storefront/
  • Static: static/storefront/

Pages:

  • Product catalog
  • Product details
  • Shopping cart
  • Checkout
  • Order tracking
  • Customer account

Technology Stack:

  • Alpine.js for interactive features
  • Tailwind CSS for styling
  • E-commerce specific components
  • Payment integration
  • Shopping cart management

Routes: /storefront/*

Authentication: Optional (required for checkout)


Using Static Assets

Each frontend has its own static directory for frontend-specific assets. Use the appropriate directory based on which frontend the asset belongs to.

Platform Static Assets (static/platform/)

JavaScript Files:

<!-- In platform templates -->
<script src="{{ url_for('static', path='platform/js/homepage.js') }}"></script>
<script src="{{ url_for('static', path='platform/js/animations.js') }}"></script>

CSS Files:

<link href="{{ url_for('static', path='platform/css/styles.css') }}" rel="stylesheet">
<link href="{{ url_for('static', path='platform/css/landing.css') }}" rel="stylesheet">

Images:

<img src="{{ url_for('static', path='platform/img/hero-banner.jpg') }}" alt="Hero">
<img src="{{ url_for('static', path='platform/img/features/feature-1.svg') }}" alt="Feature">

Current Usage: Platform currently uses only shared assets (fonts, Tailwind CSS). Platform-specific directories are ready for future platform-specific assets.


Admin Static Assets (static/admin/)

JavaScript Files:

<!-- In admin templates -->
<script src="{{ url_for('static', path='admin/js/dashboard.js') }}"></script>
<script src="{{ url_for('static', path='admin/js/vendors.js') }}"></script>

CSS Files:

<link href="{{ url_for('static', path='admin/css/custom.css') }}" rel="stylesheet">

Images:

<img src="{{ url_for('static', path='admin/img/placeholder.png') }}" alt="Placeholder">

Vendor Static Assets (static/vendor/)

JavaScript Files:

<!-- In vendor templates -->
<script src="{{ url_for('static', path='vendor/js/dashboard.js') }}"></script>
<script src="{{ url_for('static', path='vendor/js/products.js') }}"></script>

CSS Files:

<link href="{{ url_for('static', path='vendor/css/custom.css') }}" rel="stylesheet">

Images:

<img src="{{ url_for('static', path='vendor/img/no-products.svg') }}" alt="No Products">

Storefront Static Assets (static/storefront/)

JavaScript Files:

<!-- In storefront templates -->
<script src="{{ url_for('static', path='storefront/js/cart.js') }}"></script>
<script src="{{ url_for('static', path='storefront/js/checkout.js') }}"></script>

CSS Files:

<link href="{{ url_for('static', path='storefront/css/product-gallery.css') }}" rel="stylesheet">

Images:

<img src="{{ url_for('static', path='storefront/img/placeholder-product.jpg') }}" alt="Product">

When to Use Shared vs. Frontend-Specific

Use static/shared/ when:

  • Asset is used by 2 or more frontends
  • Common utilities (icons, API client, utilities)
  • Brand assets (logos, favicons)
  • Core libraries (Alpine.js, Tailwind CSS fallbacks)

Use static/{frontend}/ when:

  • Asset is only used by one specific frontend
  • Frontend-specific styling
  • Frontend-specific JavaScript components
  • Frontend-specific images/graphics

Example Decision Tree:

Icon system (used by all 4 frontends) → static/shared/js/icons.js
Admin dashboard chart → static/admin/js/charts.js
Vendor product form → static/vendor/js/product-form.js
Platform hero image → static/platform/img/hero.jpg
Storefront product carousel → static/storefront/js/carousel.js

Module Static Files

Since January 2026, module-specific JavaScript is organized within each module's directory. This keeps modules self-contained and follows the plug-and-play architecture.

Directory Structure

app/modules/{module}/static/
├── admin/js/           # Admin pages for this module
├── vendor/js/          # Vendor pages for this module
├── shared/js/          # Shared across admin/vendor for this module
└── storefront/js/      # Storefront pages for this module (if applicable)

How Module Static Files Are Served

Module static files are mounted at /static/modules/{module_name}/:

# In main.py (automatic for all modules with static/ directory)
app.mount("/static/modules/orders", StaticFiles(directory="app/modules/orders/static"))

Referencing Module Static Files

In templates, use the {module}_static URL name:

<!-- Orders module JS -->
<script src="{{ url_for('orders_static', path='admin/js/orders.js') }}"></script>
<script src="{{ url_for('orders_static', path='vendor/js/order-detail.js') }}"></script>

<!-- Billing module JS (includes shared feature-store) -->
<script src="{{ url_for('billing_static', path='shared/js/feature-store.js') }}"></script>
<script src="{{ url_for('billing_static', path='vendor/js/billing.js') }}"></script>

<!-- Marketplace module JS -->
<script src="{{ url_for('marketplace_static', path='vendor/js/onboarding.js') }}"></script>

Module vs. Platform Static Files

Location Purpose Example Files
static/admin/js/ Platform-level admin (not module-specific) dashboard.js, login.js, platforms.js, vendors.js, admin-users.js
static/vendor/js/ Vendor core (not module-specific) dashboard.js, login.js, profile.js, settings.js, team.js
static/shared/js/ Shared utilities across all frontends api-client.js, utils.js, money.js, icons.js
app/modules/*/static/ Module-specific functionality orders.js, products.js, billing.js, etc.

Current Module JS Organization

Module Admin JS Vendor JS Shared JS
orders orders.js orders.js, order-detail.js -
catalog products.js, product-*.js products.js, product-create.js -
inventory inventory.js inventory.js -
customers customers.js customers.js -
billing billing-history.js, subscriptions.js, subscription-tiers.js billing.js, invoices.js feature-store.js, upgrade-prompts.js
messaging messages.js, notifications.js, email-templates.js messages.js, notifications.js, email-templates.js -
marketplace marketplace*.js, letzshop*.js letzshop.js, marketplace.js, onboarding.js -
monitoring monitoring.js, background-tasks.js, imports.js, logs.js - -
dev_tools testing-.js, code-quality-.js, icons-page.js, components.js - -
cms content-pages.js, content-page-edit.js content-pages.js, content-page-edit.js, media.js -
analytics - analytics.js -

Platform Static Files (Not in Modules)

These files remain in static/ because they're platform-level, not module-specific:

Admin Core (static/admin/js/):

  • init-alpine.js - Admin layout initialization
  • dashboard.js - Main admin dashboard
  • login.js - Admin authentication
  • platforms.js, platform-*.js - Platform management (6 files)
  • vendors.js, vendor-*.js - Vendor management at platform level (6 files)
  • companies.js, company-*.js - Company management (3 files)
  • admin-users.js, admin-user-*.js - Admin user management (3 files)
  • users.js, user-*.js - Platform user management (4 files)
  • settings.js - Platform settings

Vendor Core (static/vendor/js/):

  • init-alpine.js - Vendor layout initialization
  • dashboard.js - Vendor main dashboard
  • login.js - Vendor authentication
  • profile.js - Vendor account settings
  • settings.js - Vendor configuration
  • team.js - Team member management

Shared Utilities (static/shared/js/):

  • api-client.js - Core HTTP client with auth
  • utils.js - Date formatting, currency, toasts
  • money.js - Money/currency handling
  • icons.js - Heroicons SVG definitions
  • log-config.js - Centralized logging
  • vendor-selector.js - Vendor autocomplete component
  • media-picker.js - Media picker component

User Type Distinction

The codebase distinguishes between three types of users:

Type Management JS Location Description
Admin Users admin-users.js static/admin/js/ Platform administrators (super admins, platform admins)
Platform Users users.js static/admin/js/ Vendor/company users who log into the platform
Shop Customers customers.js app/modules/customers/static/ End customers who buy from vendors

This distinction is important:

  • admin-users.js and users.js manage internal platform users → Stay in static/admin/js/
  • customers.js manages storefront customers → Lives in the customers module

Shared Resources

Templates (app/templates/shared/)

Shared components used across multiple frontends:

  • Email templates
  • Error pages (404, 500)
  • Common partials

Static Assets (static/shared/)

Shared JavaScript:

  • js/icons.js - Heroicons system (used by all frontends)
  • js/utils.js - Common utilities
  • js/api-client.js - API communication
  • js/log-config.js - Centralized logging

Shared CSS:

  • Common utility classes
  • Shared theme variables

Shared Images:

  • Logos
  • Brand assets
  • Icons

Architecture Principles

1. Separation of Concerns

Each frontend is completely isolated:

  • Own templates directory
  • Own static assets directory
  • Own JavaScript components
  • Own CSS styles

Benefits:

  • Clear boundaries
  • Independent development
  • No cross-contamination
  • Easy to maintain

2. Shared Core

Common functionality is shared via static/shared/:

  • Icon system
  • API client
  • Utilities
  • Logging

Benefits:

  • DRY principle
  • Consistent behavior
  • Single source of truth
  • Easy updates

3. Template Inheritance

Each frontend has a base template:

  • platform/base.html
  • admin/base.html
  • vendor/base.html
  • storefront/base.html

Benefits:

  • Consistent layout within frontend
  • Easy to customize per frontend
  • Different design systems possible

4. API-Driven

All frontends communicate with backend via APIs:

  • /api/v1/admin/* - Admin APIs
  • /api/v1/vendor/* - Vendor APIs
  • /api/v1/storefront/* - Storefront APIs
  • /api/v1/platform/* - Platform APIs

Benefits:

  • Clear backend contracts
  • Testable independently
  • Can be replaced with SPA if needed
  • Mobile app ready

Frontend Technology Matrix

Frontend Framework CSS Icons Auth Required Base URL
Platform Alpine.js Tailwind Heroicons No /
Admin Alpine.js Tailwind Heroicons Yes (Admin) /admin
Vendor Alpine.js Tailwind Heroicons Yes (Vendor) /vendor/{code}
Storefront Alpine.js Tailwind Heroicons Optional /storefront

Development Guidelines

Adding a New Page

  1. Determine which frontend the page belongs to
  2. Create template in appropriate app/templates/{frontend}/ directory
  3. Create JavaScript (if needed) in static/{frontend}/js/
  4. Create CSS (if needed) in static/{frontend}/css/
  5. Add route in appropriate route handler
  6. Update navigation in frontend's base template

Using Shared Resources

Icons:

<span x-html="$icon('icon-name', 'w-5 h-5')"></span>

API Client:

const data = await apiClient.get('/api/v1/admin/users');

Utilities:

Utils.showToast('Success!', 'success');
Utils.formatDate(dateString);

Logging:

const log = window.LogConfig.loggers.myPage;
log.info('Page loaded');

Frontend-Specific Resources

Platform-specific JavaScript:

<script src="{{ url_for('static', path='platform/js/homepage.js') }}"></script>

Admin-specific CSS:

<link href="{{ url_for('static', path='admin/css/dashboard.css') }}" rel="stylesheet">

Vendor-specific images:

<img src="{{ url_for('static', path='vendor/img/logo.png') }}">

Migration Notes

Moving Assets Between Frontends

If an asset is used by multiple frontends:

  1. Move to static/shared/
  2. Update all references
  3. Test all affected frontends

If an asset is only used by one frontend:

  1. Move to static/{frontend}/
  2. Update references in that frontend only

Deprecation Path

When removing a frontend:

  1. Remove app/templates/{frontend}/
  2. Remove static/{frontend}/
  3. Remove routes
  4. Update documentation

Future Considerations

Potential Additional Frontends

  • Partner Portal - For business partners/affiliates
  • API Documentation - Interactive API docs (Swagger UI)
  • Mobile App - Native mobile using existing APIs

Frontend Modernization

Each frontend can be independently modernized:

  • Replace Alpine.js with React/Vue/Svelte
  • Add TypeScript
  • Implement SSR/SSG
  • Convert to PWA

The API-driven architecture allows this flexibility.


Testing Strategy

Per-Frontend Testing

Each frontend should have:

  • Unit tests for JavaScript components
  • Integration tests for API interactions
  • E2E tests for critical user flows
  • Accessibility tests
  • Responsive design tests

Shared Resource Testing

Shared resources need:

  • Unit tests for utilities
  • Integration tests with all frontends
  • Visual regression tests for icons

Performance Optimization

Per-Frontend Optimization

Each frontend can optimize independently:

  • Code splitting
  • Lazy loading
  • Asset minification
  • CDN deployment
  • Browser caching

Shared Resource Optimization

Shared resources are cached globally:

  • Long cache headers
  • Versioning via query params
  • CDN distribution
  • Compression

Security Considerations

Frontend-Specific Security

Each frontend has different security needs:

  • Platform: XSS protection, CSP
  • Admin: CSRF tokens, admin-only routes
  • Vendor: Vendor isolation, rate limiting
  • Shop: PCI compliance, secure checkout

Shared Security

All frontends use:

  • JWT authentication
  • HTTPS only
  • Secure headers
  • Input sanitization

Conclusion

The 4-frontend architecture provides:

  • Clear separation of concerns
  • Independent development and deployment
  • Shared core functionality
  • Flexibility for future changes
  • Optimized for each user type
  • Maintainable and scalable

Each frontend serves a specific purpose and audience, with shared infrastructure for common needs.