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:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user