fix: consolidate CMS page seed scripts and fix 3 bugs
- Fix `ContentPage.store_id is None` (Python identity check, always False) → use `.is_(None)` for proper SQLAlchemy NULL filtering - Create pages for ALL platforms instead of only OMS - Merge create_platform_pages.py into create_default_content_pages.py (5 overlapping pages, only platform_homepage was unique) - Delete redundant create_platform_pages.py - Update Makefile, install.py, and docs references Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
17
Makefile
17
Makefile
@@ -104,22 +104,19 @@ init-prod:
|
|||||||
@echo "Step 0/6: Ensuring database exists (running migrations)..."
|
@echo "Step 0/6: Ensuring database exists (running migrations)..."
|
||||||
@$(PYTHON) -m alembic upgrade heads
|
@$(PYTHON) -m alembic upgrade heads
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 1/6: Creating admin user and platform settings..."
|
@echo "Step 1/5: Creating admin user and platform settings..."
|
||||||
$(PYTHON) scripts/seed/init_production.py
|
$(PYTHON) scripts/seed/init_production.py
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 2/6: Initializing log settings..."
|
@echo "Step 2/5: Initializing log settings..."
|
||||||
$(PYTHON) scripts/seed/init_log_settings.py
|
$(PYTHON) scripts/seed/init_log_settings.py
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 3/6: Creating default CMS content pages..."
|
@echo "Step 3/5: Creating default CMS content pages..."
|
||||||
$(PYTHON) scripts/seed/create_default_content_pages.py
|
$(PYTHON) scripts/seed/create_default_content_pages.py
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 4/6: Creating platform pages and landing..."
|
@echo "Step 4/5: Seeding email templates..."
|
||||||
$(PYTHON) scripts/seed/create_platform_pages.py
|
|
||||||
@echo ""
|
|
||||||
@echo "Step 5/6: Seeding email templates..."
|
|
||||||
$(PYTHON) scripts/seed/seed_email_templates.py
|
$(PYTHON) scripts/seed/seed_email_templates.py
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "Step 6/6: Seeding subscription tiers..."
|
@echo "Step 5/5: Seeding subscription tiers..."
|
||||||
@echo " (Handled by init_production.py Step 6)"
|
@echo " (Handled by init_production.py Step 6)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "✅ Production initialization completed"
|
@echo "✅ Production initialization completed"
|
||||||
@@ -195,10 +192,6 @@ create-cms-defaults:
|
|||||||
$(PYTHON) scripts/seed/create_default_content_pages.py
|
$(PYTHON) scripts/seed/create_default_content_pages.py
|
||||||
@echo "✅ CMS defaults created"
|
@echo "✅ CMS defaults created"
|
||||||
|
|
||||||
create-platform-pages:
|
|
||||||
@echo "🏠 Creating platform pages and landing..."
|
|
||||||
$(PYTHON) scripts/seed/create_platform_pages.py
|
|
||||||
@echo "✅ Platform pages created"
|
|
||||||
|
|
||||||
init-logging:
|
init-logging:
|
||||||
@echo "📝 Initializing log settings..."
|
@echo "📝 Initializing log settings..."
|
||||||
|
|||||||
@@ -395,7 +395,6 @@ docker compose --profile full exec -e PYTHONPATH=/app api python -m alembic upgr
|
|||||||
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/init_production.py
|
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/init_production.py
|
||||||
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/init_log_settings.py
|
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/init_log_settings.py
|
||||||
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/create_default_content_pages.py
|
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/create_default_content_pages.py
|
||||||
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/create_platform_pages.py
|
|
||||||
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/seed_email_templates.py
|
docker compose --profile full exec -e PYTHONPATH=/app api python scripts/seed/seed_email_templates.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
| Script | Purpose | In Makefile? | Issues |
|
| Script | Purpose | In Makefile? | Issues |
|
||||||
|--------|---------|--------------|--------|
|
|--------|---------|--------------|--------|
|
||||||
| `seed_demo.py` | Create merchants, stores, customers, products | ✅ Yes | ❌ Missing inventory creation |
|
| `seed_demo.py` | Create merchants, stores, customers, products | ✅ Yes | ❌ Missing inventory creation |
|
||||||
| `create_default_content_pages.py` | Create platform CMS pages (about, faq, etc.) | ✅ Yes (`create-cms-defaults`) | ✅ Good |
|
| `create_default_content_pages.py` | Create platform CMS pages (homepage, about, faq, etc.) for ALL platforms | ✅ Yes (`create-cms-defaults`) | ✅ Good (consolidated) |
|
||||||
| `create_inventory.py` | Create inventory for products | ❌ **NO** | ⚠️ Should be in seed_demo |
|
| `create_inventory.py` | Create inventory for products | ❌ **NO** | ⚠️ Should be in seed_demo |
|
||||||
| `create_landing_page.py` | Create landing pages for stores | ❌ **NO** | ⚠️ Should be in seed_demo |
|
| `create_landing_page.py` | Create landing pages for stores | ❌ **NO** | ⚠️ Should be in seed_demo |
|
||||||
| `create_platform_pages.py` | Create platform pages | ❌ **NO** | 🔴 **DUPLICATE** of create_default_content_pages |
|
| ~~`create_platform_pages.py`~~ | ~~Create platform pages~~ | - | ✅ **DELETED** (merged into create_default_content_pages) |
|
||||||
| `init_production.py` | Create admin user + platform alerts | ✅ Yes (`init-prod`) | ✅ Good |
|
| `init_production.py` | Create admin user + platform alerts | ✅ Yes (`init-prod`) | ✅ Good |
|
||||||
| `init_log_settings.py` | Initialize log settings | ❌ NO | ⚠️ Should be in init_production? |
|
| `init_log_settings.py` | Initialize log settings | ❌ NO | ⚠️ Should be in init_production? |
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ app/
|
|||||||
│ └── content_page_service.py # CMS business logic
|
│ └── content_page_service.py # CMS business logic
|
||||||
└── main.py # Platform routes (lines 284-404)
|
└── main.py # Platform routes (lines 284-404)
|
||||||
|
|
||||||
scripts/
|
scripts/seed/
|
||||||
└── create_platform_pages.py # Seeder script
|
└── create_default_content_pages.py # Seeder script (all platforms)
|
||||||
|
|
||||||
docs/features/
|
docs/features/
|
||||||
└── platform-homepage.md # This file
|
└── platform-homepage.md # This file
|
||||||
@@ -193,14 +193,17 @@ Manage all platform content pages from a single interface:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create all default platform pages
|
# Create all default platform pages
|
||||||
python scripts/seed/create_platform_pages.py
|
python scripts/seed/create_default_content_pages.py
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates:
|
This creates (for all platforms):
|
||||||
- Platform Homepage (with modern template)
|
- Platform Homepage (with modern template)
|
||||||
- About Us
|
- About Us
|
||||||
- FAQ
|
|
||||||
- Contact Us
|
- Contact Us
|
||||||
|
- FAQ
|
||||||
|
- Shipping Policy
|
||||||
|
- Return & Refund Policy
|
||||||
|
- Privacy Policy
|
||||||
- Terms of Service
|
- Terms of Service
|
||||||
- Privacy Policy
|
- Privacy Policy
|
||||||
|
|
||||||
@@ -568,7 +571,7 @@ return templates.TemplateResponse(
|
|||||||
**Solutions:**
|
**Solutions:**
|
||||||
1. Run seeder script:
|
1. Run seeder script:
|
||||||
```bash
|
```bash
|
||||||
python scripts/seed/create_platform_pages.py
|
python scripts/seed/create_default_content_pages.py
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Verify page exists:
|
2. Verify page exists:
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ Quick reference for setting up and customizing the platform homepage and content
|
|||||||
Run the seeder script to create all default platform pages:
|
Run the seeder script to create all default platform pages:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python scripts/seed/create_platform_pages.py
|
python scripts/seed/create_default_content_pages.py
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates:
|
This creates (for all platforms):
|
||||||
- ✅ Platform Homepage (modern template)
|
- ✅ Platform Homepage (modern template)
|
||||||
- ✅ About Us
|
- ✅ About Us
|
||||||
- ✅ FAQ
|
- ✅ FAQ
|
||||||
@@ -253,7 +253,7 @@ Result in header: `About | FAQ | Contact`
|
|||||||
|
|
||||||
**Fix:** Run seeder script
|
**Fix:** Run seeder script
|
||||||
```bash
|
```bash
|
||||||
python scripts/seed/create_platform_pages.py
|
python scripts/seed/create_default_content_pages.py
|
||||||
```
|
```
|
||||||
|
|
||||||
### Navigation menu is empty
|
### Navigation menu is empty
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
"""
|
"""
|
||||||
Create Default Platform Content Pages (CMS)
|
Create Default Platform Content Pages (CMS)
|
||||||
|
|
||||||
This script creates platform-level default content pages that all stores inherit.
|
This script creates platform-level default content pages for ALL platforms.
|
||||||
These pages serve as the baseline content for:
|
Pages include:
|
||||||
|
- Platform Homepage (platform marketing page)
|
||||||
- About Us
|
- About Us
|
||||||
- Contact
|
- Contact
|
||||||
- FAQ
|
- FAQ
|
||||||
@@ -12,14 +13,16 @@ These pages serve as the baseline content for:
|
|||||||
- Privacy Policy
|
- Privacy Policy
|
||||||
- Terms of Service
|
- Terms of Service
|
||||||
|
|
||||||
|
Pages are created per-platform (unique constraint: platform_id + store_id + slug).
|
||||||
Stores can override any of these pages with their own custom content.
|
Stores can override any of these pages with their own custom content.
|
||||||
|
|
||||||
Prerequisites:
|
Prerequisites:
|
||||||
- Database migrations must be applied
|
- Database migrations must be applied
|
||||||
- content_pages table must exist
|
- content_pages table must exist
|
||||||
|
- Platforms must exist (run init_production.py first)
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
python scripts/create_default_content_pages.py
|
python scripts/seed/create_default_content_pages.py
|
||||||
|
|
||||||
# Or with make:
|
# Or with make:
|
||||||
make create-cms-defaults
|
make create-cms-defaults
|
||||||
@@ -59,7 +62,32 @@ from app.modules.cms.models import ContentPage
|
|||||||
from app.modules.tenancy.models import Platform
|
from app.modules.tenancy.models import Platform
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# DEFAULT PAGE CONTENT
|
# PLATFORM HOMEPAGE (is_platform_page=True)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
PLATFORM_HOMEPAGE = {
|
||||||
|
"slug": "platform_homepage",
|
||||||
|
"title": "Welcome to Our Multi-Store Marketplace",
|
||||||
|
"content": """
|
||||||
|
<p class="lead">
|
||||||
|
Connect stores with customers worldwide. Build your online store and reach millions of shoppers.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Our platform empowers entrepreneurs to launch their own branded e-commerce stores
|
||||||
|
with minimal effort and maximum impact.
|
||||||
|
</p>
|
||||||
|
""",
|
||||||
|
"meta_description": "Leading multi-store marketplace platform. Connect with thousands of stores and discover millions of products.",
|
||||||
|
"meta_keywords": "marketplace, multi-store, e-commerce, online shopping, platform",
|
||||||
|
"show_in_footer": False,
|
||||||
|
"show_in_header": False,
|
||||||
|
"is_platform_page": True,
|
||||||
|
"template": "modern",
|
||||||
|
"display_order": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# DEFAULT STORE CONTENT PAGES (is_platform_page=False)
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
DEFAULT_PAGES = [
|
DEFAULT_PAGES = [
|
||||||
@@ -479,9 +507,58 @@ DEFAULT_PAGES = [
|
|||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
def _page_exists(db: Session, platform_id: int, slug: str) -> bool:
|
||||||
|
"""Check if a page already exists for the given platform and slug."""
|
||||||
|
existing = db.execute(
|
||||||
|
select(ContentPage).where(
|
||||||
|
ContentPage.platform_id == platform_id,
|
||||||
|
ContentPage.store_id.is_(None),
|
||||||
|
ContentPage.slug == slug,
|
||||||
|
)
|
||||||
|
).scalar_one_or_none()
|
||||||
|
return existing is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _create_page(
|
||||||
|
db: Session, platform_id: int, page_data: dict, *, is_platform_page: bool = False
|
||||||
|
) -> bool:
|
||||||
|
"""Create a single content page. Returns True if created, False if skipped."""
|
||||||
|
slug = page_data["slug"]
|
||||||
|
title = page_data["title"]
|
||||||
|
|
||||||
|
if _page_exists(db, platform_id, slug):
|
||||||
|
print(f" Skipped: {title} (/{slug}) - already exists")
|
||||||
|
return False
|
||||||
|
|
||||||
|
page = ContentPage(
|
||||||
|
platform_id=platform_id,
|
||||||
|
store_id=None,
|
||||||
|
slug=slug,
|
||||||
|
title=title,
|
||||||
|
content=page_data["content"],
|
||||||
|
content_format="html",
|
||||||
|
template=page_data.get("template", "default"),
|
||||||
|
meta_description=page_data["meta_description"],
|
||||||
|
meta_keywords=page_data["meta_keywords"],
|
||||||
|
is_platform_page=is_platform_page,
|
||||||
|
is_published=True,
|
||||||
|
published_at=datetime.now(UTC),
|
||||||
|
show_in_footer=page_data.get("show_in_footer", True),
|
||||||
|
show_in_header=page_data.get("show_in_header", False),
|
||||||
|
show_in_legal=page_data.get("show_in_legal", False),
|
||||||
|
display_order=page_data["display_order"],
|
||||||
|
created_at=datetime.now(UTC),
|
||||||
|
updated_at=datetime.now(UTC),
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(page)
|
||||||
|
print(f" Created: {title} (/{slug})")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def create_default_pages(db: Session) -> None:
|
def create_default_pages(db: Session) -> None:
|
||||||
"""
|
"""
|
||||||
Create default platform content pages.
|
Create default platform content pages for ALL platforms.
|
||||||
|
|
||||||
This function is idempotent - it will skip pages that already exist.
|
This function is idempotent - it will skip pages that already exist.
|
||||||
"""
|
"""
|
||||||
@@ -489,68 +566,52 @@ def create_default_pages(db: Session) -> None:
|
|||||||
print("Creating Default Platform Content Pages (CMS)")
|
print("Creating Default Platform Content Pages (CMS)")
|
||||||
print("=" * 70 + "\n")
|
print("=" * 70 + "\n")
|
||||||
|
|
||||||
# Resolve OMS platform for platform_id
|
# Load all platforms
|
||||||
oms_platform = db.execute(
|
platforms = db.execute(select(Platform)).scalars().all()
|
||||||
select(Platform).where(Platform.code == "oms")
|
if not platforms:
|
||||||
).scalar_one_or_none()
|
print(" No platforms found. Run init_production.py first.")
|
||||||
if not oms_platform:
|
|
||||||
print(" ⚠️ OMS platform not found. Run init_production.py first.")
|
|
||||||
return
|
return
|
||||||
platform_id = oms_platform.id
|
|
||||||
|
|
||||||
created_count = 0
|
total_created = 0
|
||||||
skipped_count = 0
|
total_skipped = 0
|
||||||
|
|
||||||
for page_data in DEFAULT_PAGES:
|
for platform in platforms:
|
||||||
# Check if page already exists (platform default with this slug)
|
print(f" Platform: {platform.name} (code={platform.code})")
|
||||||
existing = db.execute(
|
|
||||||
select(ContentPage).where(
|
|
||||||
ContentPage.store_id is None, ContentPage.slug == page_data["slug"]
|
|
||||||
)
|
|
||||||
).scalar_one_or_none()
|
|
||||||
|
|
||||||
if existing:
|
created_count = 0
|
||||||
print(
|
skipped_count = 0
|
||||||
f" ⏭️ Skipped: {page_data['title']} (/{page_data['slug']}) - already exists"
|
|
||||||
)
|
# Create platform homepage
|
||||||
|
if _create_page(db, platform.id, PLATFORM_HOMEPAGE, is_platform_page=True):
|
||||||
|
created_count += 1
|
||||||
|
else:
|
||||||
skipped_count += 1
|
skipped_count += 1
|
||||||
continue
|
|
||||||
|
|
||||||
# Create new platform default page
|
# Create default store content pages
|
||||||
page = ContentPage(
|
for page_data in DEFAULT_PAGES:
|
||||||
platform_id=platform_id,
|
if _create_page(db, platform.id, page_data):
|
||||||
store_id=None, # Platform default
|
created_count += 1
|
||||||
slug=page_data["slug"],
|
else:
|
||||||
title=page_data["title"],
|
skipped_count += 1
|
||||||
content=page_data["content"],
|
|
||||||
content_format="html",
|
|
||||||
meta_description=page_data["meta_description"],
|
|
||||||
meta_keywords=page_data["meta_keywords"],
|
|
||||||
is_published=True,
|
|
||||||
published_at=datetime.now(UTC),
|
|
||||||
show_in_footer=page_data.get("show_in_footer", True),
|
|
||||||
show_in_header=page_data.get("show_in_header", False),
|
|
||||||
show_in_legal=page_data.get("show_in_legal", False),
|
|
||||||
display_order=page_data["display_order"],
|
|
||||||
created_at=datetime.now(UTC),
|
|
||||||
updated_at=datetime.now(UTC),
|
|
||||||
)
|
|
||||||
|
|
||||||
db.add(page)
|
print(f" --- {created_count} created, {skipped_count} skipped")
|
||||||
print(f" ✅ Created: {page_data['title']} (/{page_data['slug']})")
|
print()
|
||||||
created_count += 1
|
|
||||||
|
total_created += created_count
|
||||||
|
total_skipped += skipped_count
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
print("\n" + "=" * 70)
|
print("=" * 70)
|
||||||
print("Summary:")
|
print("Summary:")
|
||||||
print(f" Created: {created_count} pages")
|
print(f" Platforms: {len(platforms)}")
|
||||||
print(f" Skipped: {skipped_count} pages (already exist)")
|
print(f" Created: {total_created} pages")
|
||||||
print(f" Total: {created_count + skipped_count} pages")
|
print(f" Skipped: {total_skipped} pages (already exist)")
|
||||||
|
print(f" Total: {total_created + total_skipped} pages")
|
||||||
print("=" * 70 + "\n")
|
print("=" * 70 + "\n")
|
||||||
|
|
||||||
if created_count > 0:
|
if total_created > 0:
|
||||||
print("✅ Default platform content pages created successfully!\n")
|
print("Default platform content pages created successfully!\n")
|
||||||
print("Next steps:")
|
print("Next steps:")
|
||||||
print(
|
print(
|
||||||
" 1. View pages at: /about, /contact, /faq, /shipping, /returns, /privacy, /terms"
|
" 1. View pages at: /about, /contact, /faq, /shipping, /returns, /privacy, /terms"
|
||||||
@@ -558,7 +619,7 @@ def create_default_pages(db: Session) -> None:
|
|||||||
print(" 2. Stores can override these pages through the store dashboard")
|
print(" 2. Stores can override these pages through the store dashboard")
|
||||||
print(" 3. Edit platform defaults through the admin panel\n")
|
print(" 3. Edit platform defaults through the admin panel\n")
|
||||||
else:
|
else:
|
||||||
print("ℹ️ All default pages already exist. No changes made.\n")
|
print("All default pages already exist. No changes made.\n")
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -568,14 +629,14 @@ def create_default_pages(db: Session) -> None:
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Main execution function."""
|
"""Main execution function."""
|
||||||
print("\n🚀 Starting Default Content Pages Creation Script...\n")
|
print("\nStarting Default Content Pages Creation Script...\n")
|
||||||
|
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
try:
|
try:
|
||||||
create_default_pages(db)
|
create_default_pages(db)
|
||||||
print("✅ Script completed successfully!\n")
|
print("Script completed successfully!\n")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"\n❌ Error: {e}\n")
|
print(f"\nError: {e}\n")
|
||||||
db.rollback()
|
db.rollback()
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -1,540 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Create Platform Content Pages
|
|
||||||
|
|
||||||
This script creates default platform-level content pages:
|
|
||||||
- Platform Homepage (slug='platform_homepage')
|
|
||||||
- About Us (slug='about')
|
|
||||||
- FAQ (slug='faq')
|
|
||||||
- Terms of Service (slug='terms')
|
|
||||||
- Privacy Policy (slug='privacy')
|
|
||||||
- Contact Us (slug='contact')
|
|
||||||
|
|
||||||
All pages are created with store_id=NULL (platform-level defaults).
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python scripts/create_platform_pages.py
|
|
||||||
"""
|
|
||||||
|
|
||||||
import contextlib
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Add project root to path
|
|
||||||
project_root = Path(__file__).resolve().parent.parent
|
|
||||||
sys.path.insert(0, str(project_root))
|
|
||||||
|
|
||||||
# Register all models with SQLAlchemy so string-based relationships resolve
|
|
||||||
for _mod in [
|
|
||||||
"app.modules.billing.models",
|
|
||||||
"app.modules.inventory.models",
|
|
||||||
"app.modules.cart.models",
|
|
||||||
"app.modules.messaging.models",
|
|
||||||
"app.modules.loyalty.models",
|
|
||||||
"app.modules.catalog.models",
|
|
||||||
"app.modules.customers.models",
|
|
||||||
"app.modules.orders.models",
|
|
||||||
"app.modules.marketplace.models",
|
|
||||||
"app.modules.cms.models",
|
|
||||||
]:
|
|
||||||
with contextlib.suppress(ImportError):
|
|
||||||
__import__(_mod)
|
|
||||||
|
|
||||||
from sqlalchemy import select
|
|
||||||
|
|
||||||
from app.core.database import SessionLocal
|
|
||||||
from app.modules.cms.services import content_page_service
|
|
||||||
from app.modules.tenancy.models import Platform
|
|
||||||
|
|
||||||
|
|
||||||
def create_platform_pages():
|
|
||||||
"""Create default platform content pages."""
|
|
||||||
db = SessionLocal()
|
|
||||||
|
|
||||||
try:
|
|
||||||
print("=" * 80)
|
|
||||||
print("CREATING PLATFORM CONTENT PAGES")
|
|
||||||
print("=" * 80)
|
|
||||||
print()
|
|
||||||
|
|
||||||
# Import ContentPage for checking existing pages
|
|
||||||
from app.modules.cms.models import ContentPage
|
|
||||||
|
|
||||||
# Resolve OMS platform
|
|
||||||
oms_platform = db.execute(
|
|
||||||
select(Platform).where(Platform.code == "oms")
|
|
||||||
).scalar_one_or_none()
|
|
||||||
if not oms_platform:
|
|
||||||
print(" ⚠️ OMS platform not found. Run init_production.py first.")
|
|
||||||
return
|
|
||||||
platform_id = oms_platform.id
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# 1. PLATFORM HOMEPAGE
|
|
||||||
# ========================================================================
|
|
||||||
print("1. Creating Platform Homepage...")
|
|
||||||
|
|
||||||
# Check if already exists
|
|
||||||
existing = (
|
|
||||||
db.query(ContentPage)
|
|
||||||
.filter_by(store_id=None, slug="platform_homepage")
|
|
||||||
.first()
|
|
||||||
)
|
|
||||||
if existing:
|
|
||||||
print(
|
|
||||||
f" ⚠️ Skipped: Platform Homepage - already exists (ID: {existing.id})"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
homepage = content_page_service.create_page(
|
|
||||||
db,
|
|
||||||
platform_id=platform_id,
|
|
||||||
slug="platform_homepage",
|
|
||||||
title="Welcome to Our Multi-Store Marketplace",
|
|
||||||
content="""
|
|
||||||
<p class="lead">
|
|
||||||
Connect stores with customers worldwide. Build your online store and reach millions of shoppers.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Our platform empowers entrepreneurs to launch their own branded e-commerce stores
|
|
||||||
with minimal effort and maximum impact.
|
|
||||||
</p>
|
|
||||||
""",
|
|
||||||
template="modern", # Uses platform/homepage-modern.html
|
|
||||||
store_id=None, # Platform-level page
|
|
||||||
is_published=True,
|
|
||||||
show_in_header=False, # Homepage is not in menu (it's the root)
|
|
||||||
show_in_footer=False,
|
|
||||||
display_order=0,
|
|
||||||
meta_description="Leading multi-store marketplace platform. Connect with thousands of stores and discover millions of products.",
|
|
||||||
meta_keywords="marketplace, multi-store, e-commerce, online shopping, platform",
|
|
||||||
)
|
|
||||||
print(f" ✅ Created: {homepage.title} (/{homepage.slug})")
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠️ Error: Platform Homepage - {str(e)}")
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# 2. ABOUT US
|
|
||||||
# ========================================================================
|
|
||||||
print("2. Creating About Us page...")
|
|
||||||
|
|
||||||
existing = db.query(ContentPage).filter_by(store_id=None, slug="about").first()
|
|
||||||
if existing:
|
|
||||||
print(f" ⚠️ Skipped: About Us - already exists (ID: {existing.id})")
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
about = content_page_service.create_page(
|
|
||||||
db,
|
|
||||||
platform_id=platform_id,
|
|
||||||
slug="about",
|
|
||||||
title="About Us",
|
|
||||||
content="""
|
|
||||||
<h2>Our Mission</h2>
|
|
||||||
<p>
|
|
||||||
We're on a mission to democratize e-commerce by providing powerful,
|
|
||||||
easy-to-use tools for entrepreneurs worldwide.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Our Story</h2>
|
|
||||||
<p>
|
|
||||||
Founded in 2024, our platform has grown to serve over 10,000 active stores
|
|
||||||
and millions of customers around the globe. We believe that everyone should
|
|
||||||
have the opportunity to build and grow their own online business.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Why Choose Us?</h2>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Easy to Start:</strong> Launch your store in minutes, not months</li>
|
|
||||||
<li><strong>Powerful Tools:</strong> Everything you need to succeed in one platform</li>
|
|
||||||
<li><strong>Scalable:</strong> Grow from startup to enterprise seamlessly</li>
|
|
||||||
<li><strong>Reliable:</strong> 99.9% uptime guarantee with 24/7 support</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Our Values</h2>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Innovation:</strong> We constantly improve and evolve our platform</li>
|
|
||||||
<li><strong>Transparency:</strong> No hidden fees, no surprises</li>
|
|
||||||
<li><strong>Community:</strong> We succeed when our stores succeed</li>
|
|
||||||
<li><strong>Excellence:</strong> We strive for the highest quality in everything we do</li>
|
|
||||||
</ul>
|
|
||||||
""",
|
|
||||||
store_id=None,
|
|
||||||
is_published=True,
|
|
||||||
show_in_header=True, # Show in header navigation
|
|
||||||
show_in_footer=True, # Show in footer
|
|
||||||
display_order=1,
|
|
||||||
meta_description="Learn about our mission to democratize e-commerce and empower entrepreneurs worldwide.",
|
|
||||||
meta_keywords="about us, mission, vision, values, merchant",
|
|
||||||
)
|
|
||||||
print(f" ✅ Created: {about.title} (/{about.slug})")
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠️ Error: About Us - {str(e)}")
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# 3. FAQ
|
|
||||||
# ========================================================================
|
|
||||||
print("3. Creating FAQ page...")
|
|
||||||
|
|
||||||
existing = db.query(ContentPage).filter_by(store_id=None, slug="faq").first()
|
|
||||||
if existing:
|
|
||||||
print(f" ⚠️ Skipped: FAQ - already exists (ID: {existing.id})")
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
faq = content_page_service.create_page(
|
|
||||||
db,
|
|
||||||
platform_id=platform_id,
|
|
||||||
slug="faq",
|
|
||||||
title="Frequently Asked Questions",
|
|
||||||
content="""
|
|
||||||
<h2>Getting Started</h2>
|
|
||||||
|
|
||||||
<h3>How do I create a store account?</h3>
|
|
||||||
<p>
|
|
||||||
Contact our sales team to get started. We'll set up your account and provide
|
|
||||||
you with everything you need to launch your store.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>How long does it take to set up my store?</h3>
|
|
||||||
<p>
|
|
||||||
Most stores can launch their store in less than 24 hours. Our team will guide
|
|
||||||
you through the setup process step by step.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Pricing & Payment</h2>
|
|
||||||
|
|
||||||
<h3>What are your pricing plans?</h3>
|
|
||||||
<p>
|
|
||||||
We offer flexible pricing plans based on your business needs. Contact us for
|
|
||||||
detailed pricing information and to find the plan that's right for you.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>When do I get paid?</h3>
|
|
||||||
<p>
|
|
||||||
Payments are processed weekly, with funds typically reaching your account
|
|
||||||
within 2-3 business days.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Features & Support</h2>
|
|
||||||
|
|
||||||
<h3>Can I customize my store's appearance?</h3>
|
|
||||||
<p>
|
|
||||||
Yes! Our platform supports full theme customization including colors, fonts,
|
|
||||||
logos, and layouts. Make your store truly yours.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>What kind of support do you provide?</h3>
|
|
||||||
<p>
|
|
||||||
We offer 24/7 email support for all stores, with priority phone support
|
|
||||||
available for enterprise plans.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Technical Questions</h2>
|
|
||||||
|
|
||||||
<h3>Do I need technical knowledge to use the platform?</h3>
|
|
||||||
<p>
|
|
||||||
No! Our platform is designed to be user-friendly for everyone. However, if you
|
|
||||||
want to customize advanced features, our documentation and support team are here to help.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Can I integrate with other tools?</h3>
|
|
||||||
<p>
|
|
||||||
Yes, we support integrations with popular payment gateways, shipping providers,
|
|
||||||
and marketing tools.
|
|
||||||
</p>
|
|
||||||
""",
|
|
||||||
store_id=None,
|
|
||||||
is_published=True,
|
|
||||||
show_in_header=True, # Show in header navigation
|
|
||||||
show_in_footer=True,
|
|
||||||
display_order=2,
|
|
||||||
meta_description="Find answers to common questions about our marketplace platform.",
|
|
||||||
meta_keywords="faq, frequently asked questions, help, support",
|
|
||||||
)
|
|
||||||
print(f" ✅ Created: {faq.title} (/{faq.slug})")
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠️ Error: FAQ - {str(e)}")
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# 4. CONTACT US
|
|
||||||
# ========================================================================
|
|
||||||
print("4. Creating Contact Us page...")
|
|
||||||
|
|
||||||
existing = (
|
|
||||||
db.query(ContentPage).filter_by(store_id=None, slug="contact").first()
|
|
||||||
)
|
|
||||||
if existing:
|
|
||||||
print(f" ⚠️ Skipped: Contact Us - already exists (ID: {existing.id})")
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
contact = content_page_service.create_page(
|
|
||||||
db,
|
|
||||||
platform_id=platform_id,
|
|
||||||
slug="contact",
|
|
||||||
title="Contact Us",
|
|
||||||
content="""
|
|
||||||
<h2>Get in Touch</h2>
|
|
||||||
<p>
|
|
||||||
We'd love to hear from you! Whether you have questions about our platform,
|
|
||||||
need technical support, or want to discuss partnership opportunities, our
|
|
||||||
team is here to help.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Contact Information</h2>
|
|
||||||
<ul>
|
|
||||||
<li><strong>Email:</strong> support@marketplace.com</li>
|
|
||||||
<li><strong>Phone:</strong> +1 (555) 123-4567</li>
|
|
||||||
<li><strong>Hours:</strong> Monday - Friday, 9 AM - 6 PM PST</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>Office Address</h2>
|
|
||||||
<p>
|
|
||||||
123 Business Street, Suite 100<br>
|
|
||||||
San Francisco, CA 94102<br>
|
|
||||||
United States
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Sales Inquiries</h2>
|
|
||||||
<p>
|
|
||||||
Interested in launching your store on our platform?<br>
|
|
||||||
Email: <a href="mailto:sales@marketplace.com">sales@marketplace.com</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Technical Support</h2>
|
|
||||||
<p>
|
|
||||||
Need help with your store?<br>
|
|
||||||
Email: <a href="mailto:support@marketplace.com">support@marketplace.com</a><br>
|
|
||||||
24/7 email support for all stores
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>Media & Press</h2>
|
|
||||||
<p>
|
|
||||||
For media inquiries and press releases:<br>
|
|
||||||
Email: <a href="mailto:press@marketplace.com">press@marketplace.com</a>
|
|
||||||
</p>
|
|
||||||
""",
|
|
||||||
store_id=None,
|
|
||||||
is_published=True,
|
|
||||||
show_in_header=True, # Show in header navigation
|
|
||||||
show_in_footer=True,
|
|
||||||
display_order=3,
|
|
||||||
meta_description="Get in touch with our team. We're here to help you succeed.",
|
|
||||||
meta_keywords="contact, support, email, phone, address",
|
|
||||||
)
|
|
||||||
print(f" ✅ Created: {contact.title} (/{contact.slug})")
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠️ Error: Contact Us - {str(e)}")
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# 5. TERMS OF SERVICE
|
|
||||||
# ========================================================================
|
|
||||||
print("5. Creating Terms of Service page...")
|
|
||||||
|
|
||||||
existing = db.query(ContentPage).filter_by(store_id=None, slug="terms").first()
|
|
||||||
if existing:
|
|
||||||
print(
|
|
||||||
f" ⚠️ Skipped: Terms of Service - already exists (ID: {existing.id})"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
terms = content_page_service.create_page(
|
|
||||||
db,
|
|
||||||
platform_id=platform_id,
|
|
||||||
slug="terms",
|
|
||||||
title="Terms of Service",
|
|
||||||
content="""
|
|
||||||
<p><em>Last updated: January 1, 2024</em></p>
|
|
||||||
|
|
||||||
<h2>1. Acceptance of Terms</h2>
|
|
||||||
<p>
|
|
||||||
By accessing and using this marketplace platform, you accept and agree to be
|
|
||||||
bound by the terms and provisions of this agreement.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>2. Use License</h2>
|
|
||||||
<p>
|
|
||||||
Permission is granted to temporarily access the materials on our platform for
|
|
||||||
personal, non-commercial transitory viewing only.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>3. Account Terms</h2>
|
|
||||||
<ul>
|
|
||||||
<li>You must be at least 18 years old to use our platform</li>
|
|
||||||
<li>You must provide accurate and complete registration information</li>
|
|
||||||
<li>You are responsible for maintaining the security of your account</li>
|
|
||||||
<li>You are responsible for all activities under your account</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>4. Store Responsibilities</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Provide accurate product information and pricing</li>
|
|
||||||
<li>Honor all orders and commitments made through the platform</li>
|
|
||||||
<li>Comply with all applicable laws and regulations</li>
|
|
||||||
<li>Maintain appropriate customer service standards</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>5. Prohibited Activities</h2>
|
|
||||||
<p>You may not use our platform to:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Engage in any fraudulent or illegal activities</li>
|
|
||||||
<li>Violate any intellectual property rights</li>
|
|
||||||
<li>Transmit harmful code or malware</li>
|
|
||||||
<li>Interfere with platform operations</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>6. Termination</h2>
|
|
||||||
<p>
|
|
||||||
We reserve the right to terminate or suspend your account at any time for
|
|
||||||
violation of these terms.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>7. Limitation of Liability</h2>
|
|
||||||
<p>
|
|
||||||
In no event shall our merchant be liable for any damages arising out of the
|
|
||||||
use or inability to use our platform.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>8. Changes to Terms</h2>
|
|
||||||
<p>
|
|
||||||
We reserve the right to modify these terms at any time. We will notify users
|
|
||||||
of any changes via email.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>9. Contact</h2>
|
|
||||||
<p>
|
|
||||||
If you have any questions about these Terms, please contact us at
|
|
||||||
<a href="mailto:legal@marketplace.com">legal@marketplace.com</a>.
|
|
||||||
</p>
|
|
||||||
""",
|
|
||||||
store_id=None,
|
|
||||||
is_published=True,
|
|
||||||
show_in_header=False, # Too legal for header
|
|
||||||
show_in_footer=True, # Show in footer
|
|
||||||
display_order=10,
|
|
||||||
meta_description="Read our terms of service and platform usage policies.",
|
|
||||||
meta_keywords="terms of service, terms, legal, policy, agreement",
|
|
||||||
)
|
|
||||||
print(f" ✅ Created: {terms.title} (/{terms.slug})")
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠️ Error: Terms of Service - {str(e)}")
|
|
||||||
|
|
||||||
# ========================================================================
|
|
||||||
# 6. PRIVACY POLICY
|
|
||||||
# ========================================================================
|
|
||||||
print("6. Creating Privacy Policy page...")
|
|
||||||
|
|
||||||
existing = (
|
|
||||||
db.query(ContentPage).filter_by(store_id=None, slug="privacy").first()
|
|
||||||
)
|
|
||||||
if existing:
|
|
||||||
print(f" ⚠️ Skipped: Privacy Policy - already exists (ID: {existing.id})")
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
privacy = content_page_service.create_page(
|
|
||||||
db,
|
|
||||||
platform_id=platform_id,
|
|
||||||
slug="privacy",
|
|
||||||
title="Privacy Policy",
|
|
||||||
content="""
|
|
||||||
<p><em>Last updated: January 1, 2024</em></p>
|
|
||||||
|
|
||||||
<h2>1. Information We Collect</h2>
|
|
||||||
<p>We collect information you provide directly to us, including:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Name, email address, and contact information</li>
|
|
||||||
<li>Payment and billing information</li>
|
|
||||||
<li>Store and product information</li>
|
|
||||||
<li>Communications with us</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>2. How We Use Your Information</h2>
|
|
||||||
<p>We use the information we collect to:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Provide, maintain, and improve our services</li>
|
|
||||||
<li>Process transactions and send related information</li>
|
|
||||||
<li>Send technical notices and support messages</li>
|
|
||||||
<li>Respond to your comments and questions</li>
|
|
||||||
<li>Monitor and analyze trends and usage</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>3. Information Sharing</h2>
|
|
||||||
<p>
|
|
||||||
We do not sell your personal information. We may share information with:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>Service providers who help us operate our platform</li>
|
|
||||||
<li>Law enforcement when required by law</li>
|
|
||||||
<li>Other parties with your consent</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>4. Data Security</h2>
|
|
||||||
<p>
|
|
||||||
We implement appropriate security measures to protect your personal information.
|
|
||||||
However, no method of transmission over the internet is 100% secure.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>5. Your Rights</h2>
|
|
||||||
<p>You have the right to:</p>
|
|
||||||
<ul>
|
|
||||||
<li>Access your personal information</li>
|
|
||||||
<li>Correct inaccurate information</li>
|
|
||||||
<li>Request deletion of your information</li>
|
|
||||||
<li>Opt-out of marketing communications</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h2>6. Cookies</h2>
|
|
||||||
<p>
|
|
||||||
We use cookies and similar tracking technologies to track activity on our
|
|
||||||
platform and hold certain information. You can instruct your browser to
|
|
||||||
refuse cookies.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>7. Changes to This Policy</h2>
|
|
||||||
<p>
|
|
||||||
We may update this privacy policy from time to time. We will notify you of
|
|
||||||
any changes by posting the new policy on this page.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h2>8. Contact Us</h2>
|
|
||||||
<p>
|
|
||||||
If you have questions about this Privacy Policy, please contact us at
|
|
||||||
<a href="mailto:privacy@marketplace.com">privacy@marketplace.com</a>.
|
|
||||||
</p>
|
|
||||||
""",
|
|
||||||
store_id=None,
|
|
||||||
is_published=True,
|
|
||||||
show_in_header=False, # Too legal for header
|
|
||||||
show_in_footer=True, # Show in footer
|
|
||||||
display_order=11,
|
|
||||||
meta_description="Learn how we collect, use, and protect your personal information.",
|
|
||||||
meta_keywords="privacy policy, privacy, data protection, gdpr, personal information",
|
|
||||||
)
|
|
||||||
print(f" ✅ Created: {privacy.title} (/{privacy.slug})")
|
|
||||||
except Exception as e:
|
|
||||||
print(f" ⚠️ Error: Privacy Policy - {str(e)}")
|
|
||||||
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
print()
|
|
||||||
print("=" * 80)
|
|
||||||
print("✅ Platform pages creation completed successfully!")
|
|
||||||
print("=" * 80)
|
|
||||||
print()
|
|
||||||
print("Created pages:")
|
|
||||||
print(" - Platform Homepage: http://localhost:8000/")
|
|
||||||
print(" - About Us: http://localhost:8000/about")
|
|
||||||
print(" - FAQ: http://localhost:8000/faq")
|
|
||||||
print(" - Contact Us: http://localhost:8000/contact")
|
|
||||||
print(" - Terms of Service: http://localhost:8000/terms")
|
|
||||||
print(" - Privacy Policy: http://localhost:8000/privacy")
|
|
||||||
print()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"\n❌ Error: {e}")
|
|
||||||
db.rollback()
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
db.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
create_platform_pages()
|
|
||||||
@@ -543,8 +543,7 @@ def main():
|
|||||||
init_scripts = [
|
init_scripts = [
|
||||||
("init_production.py", "Admin user and platform settings"),
|
("init_production.py", "Admin user and platform settings"),
|
||||||
("init_log_settings.py", "Log settings"),
|
("init_log_settings.py", "Log settings"),
|
||||||
("create_default_content_pages.py", "Default CMS pages"),
|
("create_default_content_pages.py", "Default CMS pages (all platforms)"),
|
||||||
("create_platform_pages.py", "Platform pages and landing"),
|
|
||||||
("seed_email_templates.py", "Email templates"),
|
("seed_email_templates.py", "Email templates"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user