feat: add vendor content page overrides to demo seed

- Add VENDOR_CONTENT_PAGES config with custom About, Contact, FAQ pages
- WizaMart: custom About and Contact pages
- Fashion Hub: custom About page
- Book Store: custom About and FAQ pages
- Create create_demo_vendor_content_pages() function
- Add ContentPage to reset cleanup (vendor pages only)
- Show content page counts in seeding summary

Demonstrates the CMS vendor override feature where vendors can
customize platform default pages with their own branding.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-28 21:26:26 +01:00
parent 2e5f50b6bd
commit 198ba4474b

View File

@@ -53,6 +53,7 @@ from app.core.environment import get_environment, is_production
from middleware.auth import AuthManager
from models.database.admin import PlatformAlert
from models.database.company import Company
from models.database.content_page import ContentPage
from models.database.customer import Customer, CustomerAddress
from models.database.marketplace_import_job import MarketplaceImportJob
from models.database.marketplace_product import MarketplaceProduct
@@ -172,6 +173,171 @@ THEME_PRESETS = {
},
}
# Vendor content page overrides (demonstrates CMS vendor override feature)
# Each vendor can override platform default pages with custom content
VENDOR_CONTENT_PAGES = {
"WIZAMART": [
{
"slug": "about",
"title": "About WizaMart",
"content": """
<div class="prose-content">
<h2>Welcome to WizaMart</h2>
<p>Your premier destination for cutting-edge electronics and innovative gadgets.</p>
<h3>Our Story</h3>
<p>Founded by tech enthusiasts, WizaMart has been bringing the latest technology to customers since 2020.
We carefully curate our selection to ensure you get only the best products at competitive prices.</p>
<h3>Why Choose WizaMart?</h3>
<ul>
<li><strong>Expert Selection:</strong> Our team tests and reviews every product</li>
<li><strong>Best Prices:</strong> We negotiate directly with manufacturers</li>
<li><strong>Fast Shipping:</strong> Same-day dispatch on orders before 2pm</li>
<li><strong>Tech Support:</strong> Free lifetime technical assistance</li>
</ul>
<h3>Visit Our Showroom</h3>
<p>123 Tech Street, Luxembourg City<br>Open Monday-Saturday, 9am-7pm</p>
</div>
""",
"meta_description": "WizaMart - Your trusted source for premium electronics and gadgets in Luxembourg",
"show_in_header": True,
"show_in_footer": True,
},
{
"slug": "contact",
"title": "Contact WizaMart",
"content": """
<div class="prose-content">
<h2>Get in Touch with WizaMart</h2>
<h3>Customer Support</h3>
<ul>
<li><strong>Email:</strong> support@wizamart.shop</li>
<li><strong>Phone:</strong> +352 123 456 789</li>
<li><strong>WhatsApp:</strong> +352 123 456 789</li>
<li><strong>Hours:</strong> Monday-Friday, 9am-6pm CET</li>
</ul>
<h3>Technical Support</h3>
<p>Need help with your gadgets? Our tech experts are here to help!</p>
<ul>
<li><strong>Email:</strong> tech@wizamart.shop</li>
<li><strong>Live Chat:</strong> Available on our website</li>
</ul>
<h3>Store Location</h3>
<p>123 Tech Street<br>Luxembourg City, L-1234<br>Luxembourg</p>
</div>
""",
"meta_description": "Contact WizaMart customer support for electronics and gadget inquiries",
"show_in_header": True,
"show_in_footer": True,
},
],
"FASHIONHUB": [
{
"slug": "about",
"title": "About Fashion Hub",
"content": """
<div class="prose-content">
<h2>Welcome to Fashion Hub</h2>
<p>Where style meets affordability. Discover the latest trends in fashion and accessories.</p>
<h3>Our Philosophy</h3>
<p>At Fashion Hub, we believe everyone deserves to look and feel their best.
We curate collections from emerging designers and established brands to bring you
fashion-forward pieces at accessible prices.</p>
<h3>What Makes Us Different</h3>
<ul>
<li><strong>Trend-Forward:</strong> New arrivals weekly from global fashion capitals</li>
<li><strong>Sustainable:</strong> 40% of our collection uses eco-friendly materials</li>
<li><strong>Inclusive:</strong> Sizes XS to 4XL available</li>
<li><strong>Personal Styling:</strong> Free virtual styling consultations</li>
</ul>
<h3>Join Our Community</h3>
<p>Follow us on Instagram @FashionHubLux for styling tips and exclusive offers!</p>
</div>
""",
"meta_description": "Fashion Hub - Trendy clothing and accessories for the style-conscious shopper",
"show_in_header": True,
"show_in_footer": True,
},
],
"BOOKSTORE": [
{
"slug": "about",
"title": "About The Book Store",
"content": """
<div class="prose-content">
<h2>Welcome to The Book Store</h2>
<p>Your literary haven in Luxembourg. From bestsellers to rare finds, we have something for every reader.</p>
<h3>Our Heritage</h3>
<p>Established by book lovers for book lovers, The Book Store has been serving
the Luxembourg community for over a decade. We pride ourselves on our carefully
curated selection and knowledgeable staff.</p>
<h3>What We Offer</h3>
<ul>
<li><strong>Vast Selection:</strong> Over 50,000 titles across all genres</li>
<li><strong>Special Orders:</strong> Can't find what you're looking for? We'll get it for you</li>
<li><strong>Book Club:</strong> Monthly meetings and 15% member discount</li>
<li><strong>Author Events:</strong> Regular readings and book signings</li>
<li><strong>Children's Corner:</strong> Dedicated space for young readers</li>
</ul>
<h3>Visit Us</h3>
<p>789 Library Lane, Esch-sur-Alzette<br>
Open daily 10am-8pm, Sundays 12pm-6pm</p>
</div>
""",
"meta_description": "The Book Store - Your independent bookshop in Luxembourg with a passion for literature",
"show_in_header": True,
"show_in_footer": True,
},
{
"slug": "faq",
"title": "Book Store FAQ",
"content": """
<div class="prose-content">
<h2>Frequently Asked Questions</h2>
<h3>Orders & Delivery</h3>
<h4>Do you ship internationally?</h4>
<p>Yes! We ship to all EU countries. Non-EU shipping available on request.</p>
<h4>How long does delivery take?</h4>
<p>Luxembourg: 1-2 business days. EU: 3-7 business days.</p>
<h4>Can I order books that aren't in stock?</h4>
<p>Absolutely! We can order any book in print. Special orders usually arrive within 1-2 weeks.</p>
<h3>Book Club</h3>
<h4>How do I join the book club?</h4>
<p>Sign up at our store or email bookclub@bookstore.lu. Annual membership is €25.</p>
<h4>What are the benefits?</h4>
<p>15% discount on all purchases, early access to author events, and monthly reading recommendations.</p>
<h3>Gift Cards</h3>
<h4>Do you sell gift cards?</h4>
<p>Yes! Available in €10, €25, €50, and €100 denominations, or custom amounts.</p>
</div>
""",
"meta_description": "Frequently asked questions about The Book Store - orders, delivery, and book club",
"show_in_header": False,
"show_in_footer": True,
},
],
}
# =============================================================================
# HELPER FUNCTIONS
@@ -278,6 +444,7 @@ def reset_all_data(db: Session):
MarketplaceImportJob,
MarketplaceProduct,
Product,
ContentPage, # Delete vendor content pages (keep platform defaults)
VendorDomain,
VendorTheme,
Role,
@@ -288,7 +455,11 @@ def reset_all_data(db: Session):
]
for table in tables_to_clear:
db.execute(delete(table))
if table == ContentPage:
# Only delete vendor content pages, keep platform defaults
db.execute(delete(ContentPage).where(ContentPage.vendor_id != None))
else:
db.execute(delete(table))
# Delete non-admin users
db.execute(delete(User).where(User.role != "admin"))
@@ -620,6 +791,62 @@ def create_demo_products(db: Session, vendor: Vendor, count: int) -> list[Produc
return products
def create_demo_vendor_content_pages(db: Session, vendors: list[Vendor]) -> int:
"""Create vendor-specific content page overrides.
These demonstrate the CMS vendor override feature where vendors can
customize platform default pages with their own branding and content.
"""
created_count = 0
for vendor in vendors:
vendor_pages = VENDOR_CONTENT_PAGES.get(vendor.vendor_code, [])
if not vendor_pages:
continue
for page_data in vendor_pages:
# Check if this vendor page already exists
existing = db.execute(
select(ContentPage).where(
ContentPage.vendor_id == vendor.id,
ContentPage.slug == page_data["slug"],
)
).scalar_one_or_none()
if existing:
continue # Skip, already exists
# Create vendor content page override
page = ContentPage(
vendor_id=vendor.id,
slug=page_data["slug"],
title=page_data["title"],
content=page_data["content"].strip(),
content_format="html",
meta_description=page_data.get("meta_description"),
is_published=True,
published_at=datetime.now(UTC),
show_in_header=page_data.get("show_in_header", False),
show_in_footer=page_data.get("show_in_footer", True),
show_in_legal=page_data.get("show_in_legal", False),
display_order=page_data.get("display_order", 0),
created_at=datetime.now(UTC),
updated_at=datetime.now(UTC),
)
db.add(page)
created_count += 1
db.flush()
if created_count > 0:
print_success(f"Created {created_count} vendor content page overrides")
else:
print_warning("Vendor content pages already exist")
return created_count
# =============================================================================
# MAIN SEEDING
# =============================================================================
@@ -665,6 +892,10 @@ def seed_demo_data(db: Session, auth_manager: AuthManager):
for vendor in vendors:
create_demo_products(db, vendor, count=settings.seed_products_per_vendor)
# Step 8: Create vendor content pages
print_step(8, "Creating vendor content page overrides...")
create_demo_vendor_content_pages(db, vendors)
# Commit all changes
db.commit()
print_success("All demo data committed")
@@ -681,13 +912,16 @@ def print_summary(db: Session):
user_count = db.query(User).count()
customer_count = db.query(Customer).count()
product_count = db.query(Product).count()
platform_pages = db.query(ContentPage).filter(ContentPage.vendor_id == None).count()
vendor_pages = db.query(ContentPage).filter(ContentPage.vendor_id != None).count()
print("\n📊 Database Status:")
print(f" Companies: {company_count}")
print(f" Vendors: {vendor_count}")
print(f" Users: {user_count}")
print(f" Customers: {customer_count}")
print(f" Products: {product_count}")
print(f" Companies: {company_count}")
print(f" Vendors: {vendor_count}")
print(f" Users: {user_count}")
print(f" Customers: {customer_count}")
print(f" Products: {product_count}")
print(f" Content Pages: {platform_pages} platform + {vendor_pages} vendor overrides")
# Show company details
companies = db.query(Company).all()