Files
orion/docs/architecture/frontend-structure.md
Samir Boulahtit fb8cb14506 refactor: rename public routes and templates to platform
Complete the public -> platform naming migration across the codebase.
This aligns with the naming convention where "platform" refers to
the marketing/public-facing pages of the platform itself.

Changes:
- Update all imports from public to platform modules
- Update template references from public/ to platform/
- Update route registrations to use platform prefix
- Update documentation to reflect new naming
- Update test files for platform API endpoints

Files affected:
- app/api/main.py - router imports
- app/modules/*/routes/*/platform.py - route definitions
- app/modules/*/templates/*/platform/ - template files
- app/modules/routes.py - route discovery
- docs/* - documentation updates
- tests/integration/api/v1/platform/ - test files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 18:49:39 +01:00

17 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/public/
  • Static: static/public/

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/public/)

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/public/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 media-picker.js
analytics - analytics.js -
tenancy companies*.js, vendors*.js, platforms*.js, admin-users*.js, users*.js login.js, team.js, profile.js, settings.js -
core dashboard.js, settings.js, my-menu-config.js, login.js, init-alpine.js dashboard.js, init-alpine.js vendor-selector.js

Platform Static Files (Not in Modules)

Only framework-level files remain in static/:

Admin Framework (static/admin/js/):

  • module-config.js - Module system configuration UI
  • module-info.js - Module information display

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
  • lib/ - Third-party libraries (Alpine.js, Chart.js, etc.)

User Type Distinction

The codebase distinguishes between three types of users:

Type Management JS Location Description
Admin Users admin-users.js app/modules/tenancy/static/admin/js/ Platform administrators (super admins, platform admins)
Platform Users users.js app/modules/tenancy/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

All user management JS is now in self-contained modules:

  • admin-users.js and users.js are in the tenancy module (manages platform users)
  • customers.js is in the customers module (manages storefront customers)

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.