Templates Migration: - Migrate admin templates to modules (tenancy, billing, monitoring, marketplace, etc.) - Migrate vendor templates to modules (tenancy, billing, orders, messaging, etc.) - Migrate storefront templates to modules (catalog, customers, orders, cart, checkout, cms) - Migrate public templates to modules (billing, marketplace, cms) - Keep shared templates in app/templates/ (base.html, errors/, partials/, macros/) - Migrate letzshop partials to marketplace module Static Files Migration: - Migrate admin JS to modules: tenancy (23 files), core (5 files), monitoring (1 file) - Migrate vendor JS to modules: tenancy (4 files), core (2 files) - Migrate shared JS: vendor-selector.js to core, media-picker.js to cms - Migrate storefront JS: storefront-layout.js to core - Keep framework JS in static/ (api-client, utils, money, icons, log-config, lib/) - Update all template references to use module_static paths Naming Consistency: - Rename static/platform/ to static/public/ - Rename app/templates/platform/ to app/templates/public/ - Update all extends and static references Documentation: - Update module-system.md with shared templates documentation - Update frontend-structure.md with new module JS organization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
604 lines
24 KiB
Markdown
604 lines
24 KiB
Markdown
# Multi-Platform CMS Architecture
|
|
|
|
**Session Date:** 2026-01-18
|
|
**Status:** Initial Analysis - Requirements Captured
|
|
**Related:** [Loyalty Program Analysis](./loyalty-program-analysis.md)
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
The platform is evolving from a single OMS product to a **multi-platform business** where each platform represents a distinct business offering (OMS, Loyalty Program, Website Builder, etc.). Each platform requires its own independent CMS with a three-tier content hierarchy:
|
|
|
|
1. **Platform Pages** - Marketing site for the platform itself
|
|
2. **Vendor Default Pages** - Fallback content for vendor storefronts
|
|
3. **Vendor Override/Custom Pages** - Vendor-specific content
|
|
|
|
---
|
|
|
|
## Current State Analysis
|
|
|
|
### Problems Identified
|
|
|
|
| Issue | Description |
|
|
|-------|-------------|
|
|
| **Conflated page types** | Platform pages and vendor defaults share `vendor_id = NULL`, making them indistinguishable |
|
|
| **Hardcoded homepage** | Platform homepage uses `homepage-wizamart.html` directly, ignoring CMS |
|
|
| **Non-functional admin UI** | `/admin/platform-homepage` saves to CMS but route doesn't use it |
|
|
| **Single platform assumption** | Architecture assumes one platform, can't scale to multiple offerings |
|
|
| **No platform isolation** | No way to have separate About/FAQ/Pricing pages per platform |
|
|
|
|
### Current Architecture (Broken)
|
|
|
|
```
|
|
ContentPage (vendor_id = NULL)
|
|
↓ used by both (conflated)
|
|
├── Platform Homepage (/about, /pricing) ← Should be Platform A specific
|
|
└── Vendor Default Fallback ← Should be generic storefront pages
|
|
```
|
|
|
|
---
|
|
|
|
## Proposed Architecture
|
|
|
|
### Multi-Platform Hierarchy
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ PLATFORM LEVEL │
|
|
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
|
|
│ │ Platform A │ │ Platform B │ │ Platform C │ │
|
|
│ │ (Wizamart OMS) │ │ (Loyalty+) │ │ (Site Builder) │ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ • Homepage │ │ • Homepage │ │ • Homepage │ │
|
|
│ │ • About │ │ • About │ │ • About │ │
|
|
│ │ • Pricing │ │ • Pricing │ │ • Pricing │ │
|
|
│ │ • FAQ │ │ • FAQ │ │ • FAQ │ │
|
|
│ │ • Contact │ │ • Contact │ │ • Contact │ │
|
|
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ VENDOR DEFAULT LEVEL (per platform) │
|
|
│ ┌──────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ Platform A Defaults │ │
|
|
│ │ • About Us (generic store template) │ │
|
|
│ │ • Shipping Policy │ │
|
|
│ │ • Return Policy │ │
|
|
│ │ • Privacy Policy │ │
|
|
│ │ • Terms of Service │ │
|
|
│ │ • FAQ (e-commerce focused) │ │
|
|
│ └──────────────────────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
│ VENDOR LEVEL (isolated) │
|
|
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
|
|
│ │ Vendor 1 (WizaMart) │ │ Vendor 2 (TechStore) │ │
|
|
│ │ Platform A, Tier: Pro │ │ Platform A, Tier: Basic │ │
|
|
│ │ │ │ │ │
|
|
│ │ Override Pages: │ │ Override Pages: │ │
|
|
│ │ • About (custom) │ │ • (none - uses defaults)│ │
|
|
│ │ • Shipping (custom) │ │ │ │
|
|
│ │ │ │ Custom Pages: │ │
|
|
│ │ Custom Pages: │ │ • Size Guide │ │
|
|
│ │ • Our Story │ │ │ │
|
|
│ │ • Store Locations │ │ │ │
|
|
│ └─────────────────────────┘ └─────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Content Resolution Flow
|
|
|
|
When a customer visits `vendor1.example.com/about`:
|
|
|
|
```
|
|
1. Identify vendor context (Vendor 1)
|
|
2. Identify platform context (Platform A)
|
|
3. Check: Does Vendor 1 have custom "about" page?
|
|
├── YES → Return vendor's custom page
|
|
└── NO → Check: Does Platform A have default "about" page?
|
|
├── YES → Return platform default
|
|
└── NO → Return 404
|
|
```
|
|
|
|
---
|
|
|
|
## Data Model Changes
|
|
|
|
### New: Platform Model
|
|
|
|
```python
|
|
class Platform(Base):
|
|
"""
|
|
Represents a business offering/product line.
|
|
Examples: Wizamart OMS, Loyalty+, Site Builder
|
|
"""
|
|
__tablename__ = "platforms"
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
code = Column(String(50), unique=True, nullable=False) # "oms", "loyalty", "sites"
|
|
name = Column(String(100), nullable=False) # "Wizamart OMS"
|
|
domain = Column(String(255), nullable=True) # "wizamart.lu"
|
|
|
|
# Branding
|
|
logo = Column(String(500), nullable=True)
|
|
theme_config = Column(JSON, nullable=True) # Colors, fonts, etc.
|
|
|
|
# Status
|
|
is_active = Column(Boolean, default=True)
|
|
|
|
# Timestamps
|
|
created_at = Column(DateTime, default=func.now())
|
|
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
|
|
# Relationships
|
|
content_pages = relationship("ContentPage", back_populates="platform")
|
|
subscription_tiers = relationship("SubscriptionTier", back_populates="platform")
|
|
vendors = relationship("Vendor", back_populates="platform")
|
|
```
|
|
|
|
### Updated: ContentPage Model
|
|
|
|
```python
|
|
class ContentPage(Base):
|
|
"""
|
|
CMS content page with three-tier hierarchy:
|
|
1. Platform pages (platform_id set, vendor_id NULL, is_platform_page=True)
|
|
2. Vendor defaults (platform_id set, vendor_id NULL, is_platform_page=False)
|
|
3. Vendor overrides (platform_id set, vendor_id set)
|
|
"""
|
|
__tablename__ = "content_pages"
|
|
|
|
id = Column(Integer, primary_key=True)
|
|
|
|
# NEW: Platform association (required)
|
|
platform_id = Column(Integer, ForeignKey("platforms.id"), nullable=False)
|
|
|
|
# Existing: Vendor association (NULL for platform pages and defaults)
|
|
vendor_id = Column(Integer, ForeignKey("vendors.id"), nullable=True)
|
|
|
|
# NEW: Distinguish platform marketing pages from vendor defaults
|
|
is_platform_page = Column(Boolean, default=False, nullable=False)
|
|
# True = Platform's own page (homepage, pricing, platform about)
|
|
# False = Vendor default template (when vendor_id is NULL)
|
|
# N/A = Vendor override (when vendor_id is set)
|
|
|
|
# Existing fields...
|
|
slug = Column(String(100), nullable=False)
|
|
title = Column(String(200), nullable=False)
|
|
content = Column(Text, nullable=False)
|
|
content_format = Column(String(20), default="html")
|
|
template = Column(String(50), default="default")
|
|
|
|
# SEO
|
|
meta_description = Column(String(300), nullable=True)
|
|
meta_keywords = Column(String(300), nullable=True)
|
|
|
|
# Publishing
|
|
is_published = Column(Boolean, default=False)
|
|
published_at = Column(DateTime, nullable=True)
|
|
|
|
# Navigation
|
|
display_order = Column(Integer, default=0)
|
|
show_in_header = Column(Boolean, default=False)
|
|
show_in_footer = Column(Boolean, default=True)
|
|
show_in_legal = Column(Boolean, default=False)
|
|
|
|
# Timestamps & audit
|
|
created_at = Column(DateTime, default=func.now())
|
|
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
|
created_by = Column(Integer, ForeignKey("users.id"), nullable=True)
|
|
updated_by = Column(Integer, ForeignKey("users.id"), nullable=True)
|
|
|
|
# Constraints
|
|
__table_args__ = (
|
|
UniqueConstraint("platform_id", "vendor_id", "slug", name="uq_platform_vendor_slug"),
|
|
Index("idx_platform_vendor_published", "platform_id", "vendor_id", "is_published"),
|
|
)
|
|
```
|
|
|
|
### Updated: Vendor Model
|
|
|
|
```python
|
|
class Vendor(Base):
|
|
# Existing fields...
|
|
|
|
# NEW: Platform association
|
|
platform_id = Column(Integer, ForeignKey("platforms.id"), nullable=False)
|
|
platform = relationship("Platform", back_populates="vendors")
|
|
```
|
|
|
|
---
|
|
|
|
## Page Type Matrix
|
|
|
|
| Page Type | platform_id | vendor_id | is_platform_page | Example |
|
|
|-----------|:-----------:|:---------:|:----------------:|---------|
|
|
| Platform Marketing Page | ✓ | NULL | TRUE | Platform A's homepage, pricing |
|
|
| Vendor Default Page | ✓ | NULL | FALSE | Generic "About Our Store" template |
|
|
| Vendor Override Page | ✓ | ✓ | FALSE | WizaMart's custom About page |
|
|
| Vendor Custom Page | ✓ | ✓ | FALSE | WizaMart's "Store Locations" page |
|
|
|
|
---
|
|
|
|
## User Journeys
|
|
|
|
### Journey 1: Platform Admin Sets Up New Platform
|
|
|
|
**Actor:** Super Admin
|
|
**Goal:** Create a new business platform with its marketing pages
|
|
|
|
```
|
|
1. Admin navigates to /admin/platforms
|
|
2. Admin clicks "Create Platform"
|
|
3. Admin fills in:
|
|
- Code: "loyalty"
|
|
- Name: "Loyalty+"
|
|
- Domain: "loyalty.wizamart.lu"
|
|
- Logo, theme colors
|
|
4. Admin saves platform
|
|
5. System creates platform record
|
|
6. Admin navigates to /admin/platforms/loyalty/pages
|
|
7. Admin creates platform pages:
|
|
- Homepage (is_platform_page=True)
|
|
- About Us (is_platform_page=True)
|
|
- Pricing (is_platform_page=True)
|
|
- FAQ (is_platform_page=True)
|
|
- Contact (is_platform_page=True)
|
|
8. Each page can use different templates (modern, minimal, etc.)
|
|
9. Admin publishes pages
|
|
10. Platform marketing site is now live at loyalty.wizamart.lu
|
|
```
|
|
|
|
### Journey 2: Platform Admin Creates Vendor Defaults
|
|
|
|
**Actor:** Platform Admin
|
|
**Goal:** Set up default storefront pages for all vendors on Platform A
|
|
|
|
```
|
|
1. Admin navigates to /admin/platforms/oms/vendor-defaults
|
|
2. Admin sees list of vendor default pages
|
|
3. Admin creates default pages:
|
|
- About Us (generic store template)
|
|
Content: "Welcome to our store. We're dedicated to..."
|
|
- Shipping Policy
|
|
Content: "We offer fast and reliable shipping..."
|
|
- Return Policy
|
|
Content: "30-day return policy on all items..."
|
|
- Privacy Policy
|
|
Content: "Your privacy is important to us..."
|
|
- Terms of Service
|
|
Content: "By using our store, you agree to..."
|
|
4. All pages have is_platform_page=False, vendor_id=NULL
|
|
5. These pages are now available to ALL vendors on Platform A
|
|
6. Vendors who don't customize will see these defaults
|
|
```
|
|
|
|
### Journey 3: Vendor Subscribes and Views Default Pages
|
|
|
|
**Actor:** New Vendor (TechStore)
|
|
**Goal:** Start using the platform and see what pages are available
|
|
|
|
```
|
|
1. Vendor signs up for Platform A (OMS), selects "Basic" tier
|
|
2. Vendor completes onboarding
|
|
3. Vendor logs into dashboard
|
|
4. Vendor navigates to "Content Pages" section
|
|
5. Vendor sees list of pages:
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Content Pages │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ Page │ Source │ Status │ Actions │
|
|
├───────────────┼──────────────────┼───────────┼─────────┤
|
|
│ About Us │ Platform Default │ Published │ Override│
|
|
│ Shipping │ Platform Default │ Published │ Override│
|
|
│ Returns │ Platform Default │ Published │ Override│
|
|
│ Privacy │ Platform Default │ Published │ Override│
|
|
│ Terms │ Platform Default │ Published │ Override│
|
|
└─────────────────────────────────────────────────────────┘
|
|
|
|
[+ Create Custom Page]
|
|
|
|
6. Vendor previews storefront at techstore.example.com/about
|
|
7. Sees platform default "About Us" content
|
|
```
|
|
|
|
### Journey 4: Vendor Overrides a Default Page
|
|
|
|
**Actor:** Vendor (WizaMart)
|
|
**Goal:** Customize the About page with store-specific content
|
|
|
|
```
|
|
1. Vendor logs into dashboard
|
|
2. Navigates to Content Pages
|
|
3. Sees "About Us" with source "Platform Default"
|
|
4. Clicks "Override" button
|
|
5. System creates a copy with vendor_id set
|
|
6. Vendor edits content:
|
|
- Title: "About WizaMart"
|
|
- Content: "WizaMart was founded in 2020 in Luxembourg..."
|
|
- Adds store images
|
|
7. Vendor saves and publishes
|
|
8. Page list now shows:
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ About Us │ Custom Override │ Published │ Edit │
|
|
└─────────────────────────────────────────────────────────┘
|
|
9. Customer visits wizamart.example.com/about
|
|
10. Sees WizaMart's custom About page
|
|
```
|
|
|
|
### Journey 5: Vendor Creates a Custom Page
|
|
|
|
**Actor:** Vendor (WizaMart)
|
|
**Goal:** Add a new page that doesn't exist in defaults
|
|
|
|
```
|
|
1. Vendor logs into dashboard
|
|
2. Navigates to Content Pages
|
|
3. Clicks "+ Create Custom Page"
|
|
4. Fills in:
|
|
- Slug: "store-locations"
|
|
- Title: "Our Store Locations"
|
|
- Content: Map and addresses of physical stores
|
|
- Show in footer: Yes
|
|
5. Vendor saves and publishes
|
|
6. Page appears in storefront footer navigation
|
|
7. Accessible at wizamart.example.com/store-locations
|
|
```
|
|
|
|
### Journey 6: Vendor Reverts Override to Default
|
|
|
|
**Actor:** Vendor (WizaMart)
|
|
**Goal:** Remove customization and use platform default again
|
|
|
|
```
|
|
1. Vendor navigates to Content Pages
|
|
2. Sees "Shipping" with source "Custom Override"
|
|
3. Clicks "Revert to Default"
|
|
4. System shows confirmation:
|
|
"This will delete your custom Shipping page and show
|
|
the platform default instead. This cannot be undone."
|
|
5. Vendor confirms
|
|
6. System deletes vendor's custom page
|
|
7. Storefront now shows platform default Shipping page
|
|
```
|
|
|
|
### Journey 7: Customer Browses Vendor Storefront
|
|
|
|
**Actor:** Customer
|
|
**Goal:** Read store policies before purchasing
|
|
|
|
```
|
|
1. Customer visits wizamart.example.com
|
|
2. Browses products, adds to cart
|
|
3. Wants to check return policy
|
|
4. Clicks "Returns" in footer
|
|
5. System resolves page:
|
|
- Check: WizaMart override? NO
|
|
- Check: Platform A default? YES
|
|
- Serve: Platform A default "Return Policy" page
|
|
6. Customer reads return policy
|
|
7. Customer clicks "About Us" in footer
|
|
8. System resolves page:
|
|
- Check: WizaMart override? YES
|
|
- Serve: WizaMart's custom "About WizaMart" page
|
|
9. Customer sees store-specific About page
|
|
```
|
|
|
|
---
|
|
|
|
## Workflow Diagrams
|
|
|
|
### Content Resolution Algorithm
|
|
|
|
```
|
|
resolve_page(vendor, slug):
|
|
│
|
|
├─► Get vendor's platform_id
|
|
│
|
|
├─► Query: ContentPage WHERE
|
|
│ platform_id = vendor.platform_id
|
|
│ AND vendor_id = vendor.id
|
|
│ AND slug = slug
|
|
│ AND is_published = True
|
|
│
|
|
├─► Found? ──YES──► Return vendor's page
|
|
│ │
|
|
│ NO
|
|
│ ▼
|
|
├─► Query: ContentPage WHERE
|
|
│ platform_id = vendor.platform_id
|
|
│ AND vendor_id IS NULL
|
|
│ AND is_platform_page = False ← Important: exclude platform pages
|
|
│ AND slug = slug
|
|
│ AND is_published = True
|
|
│
|
|
├─► Found? ──YES──► Return platform default
|
|
│ │
|
|
│ NO
|
|
│ ▼
|
|
└─► Return 404
|
|
```
|
|
|
|
### Platform Page Resolution (Marketing Site)
|
|
|
|
```
|
|
resolve_platform_page(platform, slug):
|
|
│
|
|
├─► Query: ContentPage WHERE
|
|
│ platform_id = platform.id
|
|
│ AND vendor_id IS NULL
|
|
│ AND is_platform_page = True ← Only platform marketing pages
|
|
│ AND slug = slug
|
|
│ AND is_published = True
|
|
│
|
|
├─► Found? ──YES──► Return platform page
|
|
│ │
|
|
│ NO
|
|
│ ▼
|
|
└─► Return 404
|
|
```
|
|
|
|
---
|
|
|
|
## API Endpoints
|
|
|
|
### Platform Admin API
|
|
|
|
```
|
|
# Platform Management
|
|
GET /api/v1/admin/platforms # List all platforms
|
|
POST /api/v1/admin/platforms # Create platform
|
|
GET /api/v1/admin/platforms/{code} # Get platform
|
|
PUT /api/v1/admin/platforms/{code} # Update platform
|
|
DELETE /api/v1/admin/platforms/{code} # Delete platform
|
|
|
|
# Platform Pages (Marketing)
|
|
GET /api/v1/admin/platforms/{code}/pages # List platform pages
|
|
POST /api/v1/admin/platforms/{code}/pages # Create platform page
|
|
PUT /api/v1/admin/platforms/{code}/pages/{id} # Update platform page
|
|
DELETE /api/v1/admin/platforms/{code}/pages/{id} # Delete platform page
|
|
|
|
# Vendor Defaults
|
|
GET /api/v1/admin/platforms/{code}/defaults # List vendor defaults
|
|
POST /api/v1/admin/platforms/{code}/defaults # Create vendor default
|
|
PUT /api/v1/admin/platforms/{code}/defaults/{id}# Update vendor default
|
|
DELETE /api/v1/admin/platforms/{code}/defaults/{id}# Delete vendor default
|
|
```
|
|
|
|
### Vendor API
|
|
|
|
```
|
|
# View All Pages (defaults + overrides + custom)
|
|
GET /api/v1/vendor/{code}/content-pages # List all pages
|
|
|
|
# Override/Custom Page Management
|
|
POST /api/v1/vendor/{code}/content-pages # Create override/custom
|
|
PUT /api/v1/vendor/{code}/content-pages/{id} # Update page
|
|
DELETE /api/v1/vendor/{code}/content-pages/{id} # Delete/revert page
|
|
|
|
# Page Preview
|
|
GET /api/v1/vendor/{code}/content-pages/{slug}/preview # Preview with fallback
|
|
```
|
|
|
|
### Public API
|
|
|
|
```
|
|
# Storefront Pages (with fallback resolution)
|
|
GET /api/v1/shop/content-pages/{slug} # Get page (vendor context from middleware)
|
|
GET /api/v1/shop/content-pages/navigation # Get nav pages
|
|
|
|
# Platform Marketing Pages
|
|
GET /api/v1/platform/{code}/pages/{slug} # Get platform page
|
|
GET /api/v1/platform/{code}/pages/navigation # Get platform nav
|
|
```
|
|
|
|
---
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Database & Model Updates
|
|
- [ ] Create `Platform` model
|
|
- [ ] Add `platform_id` to `ContentPage`
|
|
- [ ] Add `is_platform_page` to `ContentPage`
|
|
- [ ] Add `platform_id` to `Vendor`
|
|
- [ ] Create migration scripts
|
|
- [ ] Create default "oms" platform for existing data
|
|
|
|
### Phase 2: Service Layer
|
|
- [ ] Update `ContentPageService` with three-tier resolution
|
|
- [ ] Add `PlatformService` for platform CRUD
|
|
- [ ] Update page listing to show source (Platform/Default/Override)
|
|
|
|
### Phase 3: Admin Interface
|
|
- [ ] Platform management UI (`/admin/platforms`)
|
|
- [ ] Platform pages editor (`/admin/platforms/{code}/pages`)
|
|
- [ ] Vendor defaults editor (`/admin/platforms/{code}/defaults`)
|
|
- [ ] Fix platform homepage to use CMS
|
|
|
|
### Phase 4: Vendor Dashboard
|
|
- [ ] Update content pages list to show page source
|
|
- [ ] Add "Override" action for default pages
|
|
- [ ] Add "Revert to Default" action for overrides
|
|
- [ ] Visual indicator for inherited vs custom pages
|
|
|
|
### Phase 5: Public Routes
|
|
- [ ] Update shop routes with three-tier resolution
|
|
- [ ] Update platform routes to use CMS
|
|
- [ ] Ensure proper navigation loading per context
|
|
|
|
---
|
|
|
|
## Migration Strategy
|
|
|
|
### Existing Data Handling
|
|
|
|
```sql
|
|
-- 1. Create default platform
|
|
INSERT INTO platforms (code, name, domain, is_active)
|
|
VALUES ('oms', 'Wizamart OMS', 'localhost:8000', true);
|
|
|
|
-- 2. Update all existing content_pages
|
|
UPDATE content_pages
|
|
SET platform_id = (SELECT id FROM platforms WHERE code = 'oms');
|
|
|
|
-- 3. Mark platform marketing pages
|
|
UPDATE content_pages
|
|
SET is_platform_page = true
|
|
WHERE vendor_id IS NULL
|
|
AND slug IN ('platform_homepage', 'pricing');
|
|
|
|
-- 4. Remaining NULL vendor pages become vendor defaults
|
|
UPDATE content_pages
|
|
SET is_platform_page = false
|
|
WHERE vendor_id IS NULL
|
|
AND is_platform_page IS NULL;
|
|
|
|
-- 5. Update all vendors
|
|
UPDATE vendors
|
|
SET platform_id = (SELECT id FROM platforms WHERE code = 'oms');
|
|
```
|
|
|
|
---
|
|
|
|
## Open Questions
|
|
|
|
1. **Domain routing**: How to route requests to correct platform?
|
|
- Option A: Separate domains (oms.wizamart.lu, loyalty.wizamart.lu)
|
|
- Option B: Path-based (/oms/*, /loyalty/*)
|
|
- Option C: Subdomain detection
|
|
|
|
2. **Shared vendors**: Can a vendor belong to multiple platforms?
|
|
- Current assumption: NO, one vendor per platform
|
|
- If YES: Need junction table
|
|
|
|
3. **Tier restrictions**: Can page creation be restricted by tier?
|
|
- e.g., Basic tier: max 5 custom pages
|
|
- e.g., Pro tier: unlimited pages
|
|
|
|
4. **Template inheritance**: Should vendor defaults have template selection?
|
|
- Or always use a standard template?
|
|
|
|
---
|
|
|
|
## Session Notes
|
|
|
|
### 2026-01-18
|
|
- Analyzed current CMS architecture issues
|
|
- Identified homepage is hardcoded (not using CMS)
|
|
- Confirmed admin platform-homepage UI is non-functional
|
|
- Designed three-tier content hierarchy:
|
|
1. Platform pages (marketing)
|
|
2. Vendor defaults (fallback)
|
|
3. Vendor overrides/custom
|
|
- Documented user journeys for all actors
|
|
- Outlined implementation phases
|
|
- **Next**: Review proposal, clarify open questions, begin implementation
|
|
|
|
---
|
|
|
|
*Document created for session continuity. Update as discussions progress.*
|