Files
orion/docs/proposals/storefront-builder-vision.md
Samir Boulahtit adc36246b8
Some checks failed
CI / ruff (push) Successful in 14s
CI / pytest (push) Failing after 2h32m45s
CI / validate (push) Successful in 30s
CI / dependency-scanning (push) Successful in 31s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
feat(storefront): homepage, module gating, widget protocol, i18n fixes
Storefront homepage & module gating:
- CMS owns storefront GET / (slug="home" with 3-tier resolution)
- Catalog loses GET / (keeps /products only)
- Store root redirect (GET / → /store/dashboard or /store/login)
- Route gating: non-core modules return 404 when disabled for platform
- Seed store default homepages per platform

Widget protocol for customer dashboard:
- StorefrontDashboardCard contract in widgets.py
- Widget aggregator get_storefront_dashboard_cards()
- Orders and Loyalty module widget providers
- Dashboard template renders contributed cards (no module names)

Landing template module-agnostic:
- CTAs driven by storefront_nav (not hardcoded module names)
- Header actions check nav item IDs (not enabled_modules)
- Remove hardcoded "Add Product" sidebar button
- Remove all enabled_modules checks from storefront templates

i18n fixes:
- Title placeholder resolution ({{store_name}}) for store default pages
- Storefront nav label_keys prefixed with module code
- Add storefront.account.* keys to 6 modules (en/fr/de/lb)
- Header/footer CMS pages use get_translated_title(current_language)
- Footer labels use i18n keys instead of hardcoded English

Icon cleanup:
- Standardize on map-pin (remove location-marker alias)
- Replace all location-marker references across templates and docs

Docs:
- Storefront builder vision proposal (6 phases)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 22:53:17 +02:00

10 KiB

Proposal: Storefront Builder Vision

Date: 2026-04-13 Status: Draft Author: Samir / Claude


Problem Statement

The platform has a solid CMS foundation — section-based homepages, module-driven menus, widget contracts, theme system, 3-tier content hierarchy, multi-language support. However, there are gaps between the platform marketing site (well-built) and the store storefront (catching up). The goal is to enable "yes, we can build you a one-page ecommerce site" as a real capability.


Current State

What works well

  • Platform homepage: Section-based rendering via page.sections JSON with 8 section partials (hero, features, pricing, CTA, testimonials, gallery, contact, products)
  • Admin section editor: API for editing sections individually or all at once, multi-language
  • Module contracts: Widget protocol, context providers, menu declarations, route gating
  • Store theme: Colors, fonts, logo, custom CSS — all applied via CSS variables
  • Component library: Ecommerce macros (product cards, grids, add-to-cart, mini-cart) at /admin/components#ecommerce
  • 3-tier content: Platform pages → store defaults → store overrides, with placeholder resolution

What's missing

  1. Store homepages don't use sections (only landing-full.html supports them, but defaults use landing-default.html)
  2. Header actions (search, cart) are bespoke in the base template
  3. No widget slots on storefront pages (widgets only on dashboards)
  4. No per-store menu customization (menus are platform-wide)
  5. Section types are fixed (8 types, not pluggable by modules)
  6. No visual editor (admin edits via JSON-backed forms)

Phase 1: Wire Sections to Store Homepages

Goal: Store homepages get section-based rendering immediately, using existing infrastructure.

Changes

  • Change seed script: store default homepages use template="full" instead of template="default"
  • Populate sections JSON per platform:
    • OMS stores: Hero → Product Showcase → Features → CTA
    • Loyalty stores: Hero → Loyalty Signup → Features → CTA
    • Hosting stores: Hero → Services → Features → CTA
  • Admin can already edit sections via existing API at /admin/content-pages/{id}/edit

Impact

  • Every store immediately gets a section-based homepage
  • Merchants can customize via admin UI (no code changes needed)
  • All 8 existing section types available

Effort

Small — mostly seed data and one template field change.


Phase 2: Module-Contributed Header Actions

Goal: Remove bespoke header rendering. Modules provide their own action templates.

Changes

  • Add optional header_template field to MenuItemDefinition in app/modules/base.py
  • Cart module provides cart/storefront/partials/header-cart.html (cart icon + Alpine badge)
  • Catalog module provides catalog/storefront/partials/header-search.html (search button + modal trigger)
  • Update storefront/base.html: iterate storefront_nav.get('actions', []), use {% include item.header_template %} when present, generic link otherwise
  • Remove all hardcoded action rendering from base template

Architecture

Module definition:
    MenuItemDefinition(
        id="cart",
        label_key="cart.storefront.actions.cart",
        icon="shopping-cart",
        route="cart",
        header_template="cart/storefront/partials/header-cart.html",
    )

Base template:
    {% for item in storefront_nav.get('actions', []) %}
        {% if item.header_template %}
            {% include item.header_template %}
        {% else %}
            <a href="{{ base_url }}{{ item.route }}">{{ _(item.label_key) }}</a>
        {% endif %}
    {% endfor %}

Impact

  • Any module can contribute a header action with custom UI
  • Adding wishlist, notifications, etc. requires zero base template changes
  • Fully module-agnostic

Effort

Small — new field on MenuItemDefinition, two partial templates, base template update.


Phase 3: Module-Contributed Page Sections

Goal: Modules can register their own section types for storefront pages.

Changes

  • New contract: StorefrontSectionProviderProtocol in app/modules/contracts/
    class StorefrontSectionProviderProtocol(Protocol):
        def get_section_types(self) -> list[SectionTypeDefinition]: ...
        # SectionTypeDefinition: id, name, icon, template_path, default_config
    
  • New field on ModuleDefinition: section_provider
  • Section registry in CMS module aggregates section types from all enabled modules
  • Catalog contributes:
    • product-showcase — featured products grid (uses existing product card macros)
    • category-grid — browse by category
  • Loyalty contributes:
    • loyalty-signup — join rewards CTA with program details
    • rewards-overview — points/stamps explanation
  • Update admin section editor to show available sections from enabled modules

Architecture

Section rendering flow:
    1. Page has sections JSON: {"hero": {...}, "product-showcase": {...}, ...}
    2. Template iterates sections in order
    3. For each section, looks up the partial from the section registry
    4. Renders: {% include section_registry[section_type].template_path %}
    5. Passes section data + language context

Impact

  • Platform-specific storefronts: OMS stores get product sections, Loyalty stores get loyalty sections
  • Admin editor adapts to available sections based on platform modules
  • No template changes needed when adding new section types

Effort

Medium — new contract, section registry service, admin UI update, 4-6 new section partials.


Phase 4: Storefront Page Widget Slots

Goal: Place smaller components within pages — product carousels, loyalty badges, social feeds.

Changes

  • Define named slots in storefront templates: below-hero, above-footer, content-sidebar
  • New contract method on widget protocol:
    def get_page_widgets(self, db, store_id, slot, page_slug, context) -> list[StorefrontPageWidget]
    # StorefrontPageWidget: key, template, data, order
    
  • Widget aggregator collects from enabled modules per slot
  • Templates render:
    {% for widget in page_widgets.get('below-hero', []) %}
        {% include widget.template %}
    {% endfor %}
    
  • Catalog contributes: "featured products" widget, "new arrivals" widget
  • Loyalty contributes: "join rewards" widget, "points balance" widget

Sections vs Widgets

  • Sections = full-width page blocks, ordered top-to-bottom, part of page structure
  • Widgets = smaller components placed within named slots, multiple per slot

Impact

  • Mix-and-match content: a loyalty store can add a product widget to their homepage
  • Modules contribute without coupling — templates never check module names
  • Foundation for "one-page ecommerce" capability

Effort

Medium — builds on existing widget infrastructure, new slot rendering in templates.


Phase 5: Per-Store Menu & Section Ordering

Goal: Stores can customize their navigation and homepage layout.

Changes

  • Menu overrides: store_menu_config table (store_id, item_id, is_visible, display_order)
    • Stores can hide/reorder items from the platform menu
    • menu_discovery_service gets a store-level filter on top of platform-level
  • Section ordering: display_order field per section in the sections JSON
    • Admin UI: drag-and-drop section reordering
    • Sections can be enabled/disabled per store override
  • Section visibility: Store overrides can hide sections from the default homepage

Impact

  • Each store can have a unique navigation and homepage layout
  • Platform provides the base, stores customize
  • Follows existing 3-tier pattern (platform → store default → store override)

Effort

Medium-large — new table, menu service update, admin drag-and-drop UI.


Phase 6: Visual Editor (Future)

Goal: WYSIWYG editing experience for storefront pages.

Changes

  • Live preview panel showing section rendering as you edit
  • Drag-and-drop section placement and reordering
  • Inline text editing with rich text toolbar
  • Template/section picker with visual thumbnails
  • Mobile/desktop preview toggle

Architecture

  • Frontend-only addition — calls the same section APIs
  • Could use iframe-based preview with postMessage communication
  • Section partials render identically in preview and production

Impact

  • Non-technical merchants can build their own storefronts
  • Reduces support burden
  • Competitive feature for attracting merchants

Effort

Large — significant frontend work, but backend APIs already exist.


One-Page Ecommerce Site — End-to-End Flow

With Phases 1-4 complete, here's the workflow:

  1. Admin creates store on OMS platform
  2. Store homepage auto-created with section-based default (hero, product showcase, features, CTA)
  3. Merchant edits at /admin/content-pages/{id}/edit:
    • Hero: store branding, tagline, "Shop Now" button
    • Product Showcase: featured products (from catalog module section)
    • Testimonials: customer reviews
    • CTA: newsletter signup
  4. Theme at /admin/stores/{code}/theme: colors, logo, fonts
  5. Customer visits storefront → sees professional one-page site with products, cart, checkout

Key Files Reference

Component File
Section partials app/modules/cms/templates/cms/platform/sections/_*.html
ContentPage model app/modules/cms/models/content_page.py
Section schemas app/modules/cms/schemas/homepage_sections.py
Widget contracts app/modules/contracts/widgets.py
Module base app/modules/base.py (MenuItemDefinition, ModuleDefinition)
Storefront base app/templates/storefront/base.html
Store theme model app/modules/cms/models/store_theme.py
Menu discovery app/modules/core/services/menu_discovery_service.py
Widget aggregator app/modules/core/services/widget_aggregator.py
Component library app/modules/dev_tools/templates/dev_tools/admin/components.html
Seed data scripts/seed/create_default_content_pages.py
Storefront routes app/modules/cms/routes/pages/storefront.py
Admin section API app/modules/cms/routes/api/admin_content_pages.py