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>
18 KiB
Frontend Architecture
Overview
This application has 4 distinct frontends, each with its own templates and static assets:
- Platform - Public platform pages (homepage, about, contact)
- Admin - Administrative control panel
- Vendor - Vendor management portal
- 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 initializationdashboard.js- Main admin dashboardlogin.js- Admin authenticationplatforms.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 initializationdashboard.js- Vendor main dashboardlogin.js- Vendor authenticationprofile.js- Vendor account settingssettings.js- Vendor configurationteam.js- Team member management
Shared Utilities (static/shared/js/):
api-client.js- Core HTTP client with authutils.js- Date formatting, currency, toastsmoney.js- Money/currency handlingicons.js- Heroicons SVG definitionslog-config.js- Centralized loggingvendor-selector.js- Vendor autocomplete componentmedia-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.jsandusers.jsmanage internal platform users → Stay instatic/admin/js/customers.jsmanages 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 utilitiesjs/api-client.js- API communicationjs/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.htmladmin/base.htmlvendor/base.htmlstorefront/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
- Determine which frontend the page belongs to
- Create template in appropriate
app/templates/{frontend}/directory - Create JavaScript (if needed) in
static/{frontend}/js/ - Create CSS (if needed) in
static/{frontend}/css/ - Add route in appropriate route handler
- 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:
- Move to
static/shared/ - Update all references
- Test all affected frontends
If an asset is only used by one frontend:
- Move to
static/{frontend}/ - Update references in that frontend only
Deprecation Path
When removing a frontend:
- Remove
app/templates/{frontend}/ - Remove
static/{frontend}/ - Remove routes
- 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.