Files
orion/scripts/create_default_content_pages.py
Samir Boulahtit 3f2b6bf1b8 feat: add vendor dropdown and show_in_legal to content page editor
- Load vendors dynamically in content page editor dropdown
- Add show_in_legal field to default content pages seed script
- Set privacy and terms pages to show_in_legal=true, show_in_footer=false
- Update page creation in seed script to use show_in_legal

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-28 20:45:31 +01:00

558 lines
20 KiB
Python
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Create Default Platform Content Pages (CMS)
This script creates platform-level default content pages that all vendors inherit.
These pages serve as the baseline content for:
- About Us
- Contact
- FAQ
- Shipping Policy
- Return Policy
- Privacy Policy
- Terms of Service
Vendors can override any of these pages with their own custom content.
Prerequisites:
- Database migrations must be applied
- content_pages table must exist
Usage:
python scripts/create_default_content_pages.py
# Or with make:
make create-cms-defaults
"""
import sys
from datetime import UTC, datetime
from pathlib import Path
# Add project root to path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.core.database import SessionLocal
from models.database.content_page import ContentPage
# ============================================================================
# DEFAULT PAGE CONTENT
# ============================================================================
DEFAULT_PAGES = [
{
"slug": "about",
"title": "About Us",
"content": """
<div class="prose-content">
<h2>Welcome to Our Platform</h2>
<p>We are a multi-vendor e-commerce platform connecting quality sellers with customers worldwide.</p>
<h3>Our Mission</h3>
<p>To empower independent businesses and artisans by providing them with the tools and platform they need to reach customers globally.</p>
<h3>What We Offer</h3>
<ul>
<li>Curated selection of quality products from verified vendors</li>
<li>Secure payment processing and buyer protection</li>
<li>Fast and reliable shipping options</li>
<li>Dedicated customer support</li>
</ul>
<h3>Our Values</h3>
<ul>
<li><strong>Quality:</strong> We work only with vendors who meet our quality standards</li>
<li><strong>Transparency:</strong> Clear pricing, policies, and communication</li>
<li><strong>Customer First:</strong> Your satisfaction is our priority</li>
<li><strong>Innovation:</strong> Continuously improving our platform and services</li>
</ul>
</div>
""",
"meta_description": "Learn about our mission to connect quality vendors with customers worldwide",
"meta_keywords": "about us, mission, values, platform",
"show_in_footer": True,
"show_in_header": True,
"display_order": 1,
},
{
"slug": "contact",
"title": "Contact Us",
"content": """
<div class="prose-content">
<h2>Get in Touch</h2>
<p>We're here to help! Reach out to us through any of the following channels:</p>
<h3>Customer Support</h3>
<p>For questions about orders, products, or general inquiries:</p>
<ul>
<li><strong>Email:</strong> support@example.com</li>
<li><strong>Phone:</strong> 1-800-EXAMPLE (Mon-Fri, 9am-6pm EST)</li>
<li><strong>Live Chat:</strong> Available on our website during business hours</li>
</ul>
<h3>Business Inquiries</h3>
<p>Interested in becoming a vendor or partnering with us?</p>
<ul>
<li><strong>Email:</strong> vendors@example.com</li>
</ul>
<h3>Office Address</h3>
<p>
123 Commerce Street<br>
Suite 456<br>
City, State 12345<br>
United States
</p>
<h3>Response Time</h3>
<p>We typically respond to all inquiries within 24 hours during business days.</p>
</div>
""",
"meta_description": "Contact our customer support team for assistance with orders, products, or inquiries",
"meta_keywords": "contact, support, customer service, help",
"show_in_footer": True,
"show_in_header": True,
"display_order": 2,
},
{
"slug": "faq",
"title": "Frequently Asked Questions",
"content": """
<div class="prose-content">
<h2>Frequently Asked Questions</h2>
<h3>Orders & Shipping</h3>
<h4>How do I track my order?</h4>
<p>Once your order ships, you'll receive a tracking number via email. You can also view your order status in your account dashboard.</p>
<h4>How long does shipping take?</h4>
<p>Shipping times vary by vendor and destination. Most orders arrive within 3-7 business days. See our <a href="/shipping">Shipping Policy</a> for details.</p>
<h4>Do you ship internationally?</h4>
<p>Yes! We ship to most countries worldwide. International shipping times and costs vary by destination.</p>
<h3>Returns & Refunds</h3>
<h4>What is your return policy?</h4>
<p>Most items can be returned within 30 days of delivery. See our <a href="/returns">Return Policy</a> for complete details.</p>
<h4>How do I request a refund?</h4>
<p>Contact the vendor directly through your order page or reach out to our support team for assistance.</p>
<h3>Payments</h3>
<h4>What payment methods do you accept?</h4>
<p>We accept all major credit cards, PayPal, and other secure payment methods.</p>
<h4>Is my payment information secure?</h4>
<p>Yes! We use industry-standard encryption and never store your full payment details.</p>
<h3>Account</h3>
<h4>Do I need an account to make a purchase?</h4>
<p>No, you can checkout as a guest. However, creating an account lets you track orders and save your preferences.</p>
<h4>How do I reset my password?</h4>
<p>Click "Forgot Password" on the login page and follow the instructions sent to your email.</p>
</div>
""",
"meta_description": "Find answers to common questions about orders, shipping, returns, and more",
"meta_keywords": "faq, questions, help, support",
"show_in_footer": True,
"show_in_header": False,
"display_order": 3,
},
{
"slug": "shipping",
"title": "Shipping Policy",
"content": """
<div class="prose-content">
<h2>Shipping Policy</h2>
<h3>Shipping Methods</h3>
<p>We offer multiple shipping options to meet your needs:</p>
<ul>
<li><strong>Standard Shipping:</strong> 5-7 business days</li>
<li><strong>Express Shipping:</strong> 2-3 business days</li>
<li><strong>Overnight Shipping:</strong> Next business day</li>
</ul>
<h3>Shipping Costs</h3>
<p>Shipping costs are calculated based on:</p>
<ul>
<li>Package weight and dimensions</li>
<li>Destination address</li>
<li>Selected shipping method</li>
</ul>
<p>Free standard shipping on orders over $50!</p>
<h3>Processing Time</h3>
<p>Orders are typically processed within 1-2 business days. You'll receive a confirmation email when your order ships with tracking information.</p>
<h3>International Shipping</h3>
<p>We ship to most countries worldwide. International shipping times vary by destination (typically 7-21 business days).</p>
<ul>
<li>Customs fees and import duties are the responsibility of the recipient</li>
<li>International orders may be subject to customs inspection</li>
</ul>
<h3>Tracking</h3>
<p>All orders include tracking. You can monitor your package status through:</p>
<ul>
<li>Your account dashboard</li>
<li>Email notifications</li>
<li>Carrier tracking website</li>
</ul>
<h3>Delivery Issues</h3>
<p>If you experience any delivery issues, please contact us within 7 days of the expected delivery date.</p>
</div>
""",
"meta_description": "Learn about our shipping methods, costs, and delivery times",
"meta_keywords": "shipping, delivery, tracking, international",
"show_in_footer": True,
"show_in_header": False,
"display_order": 4,
},
{
"slug": "returns",
"title": "Return & Refund Policy",
"content": """
<div class="prose-content">
<h2>Return & Refund Policy</h2>
<h3>30-Day Return Window</h3>
<p>Most items can be returned within 30 days of delivery for a full refund or exchange.</p>
<h3>Return Requirements</h3>
<p>To be eligible for a return, items must:</p>
<ul>
<li>Be in original condition with tags attached</li>
<li>Include original packaging and accessories</li>
<li>Not be used or damaged</li>
<li>Include proof of purchase</li>
</ul>
<h3>Non-Returnable Items</h3>
<p>The following items cannot be returned:</p>
<ul>
<li>Personalized or custom-made items</li>
<li>Perishable goods</li>
<li>Health and personal care items</li>
<li>Digital downloads</li>
<li>Sale or clearance items (marked as final sale)</li>
</ul>
<h3>How to Return</h3>
<ol>
<li>Log into your account and go to "Order History"</li>
<li>Select the order and click "Request Return"</li>
<li>Choose items and provide reason for return</li>
<li>Print the prepaid return label</li>
<li>Pack items securely and attach label</li>
<li>Drop off at any authorized carrier location</li>
</ol>
<h3>Refund Process</h3>
<p>Once we receive your return:</p>
<ul>
<li>We'll inspect the items (2-3 business days)</li>
<li>Approved refunds are processed within 5-7 business days</li>
<li>Refunds go to original payment method</li>
<li>You'll receive email confirmation</li>
</ul>
<h3>Return Shipping</h3>
<p>Return shipping is free for defective or incorrect items. For other returns, a $5.99 return shipping fee will be deducted from your refund.</p>
<h3>Exchanges</h3>
<p>We offer free exchanges for different sizes or colors of the same item. Contact support to arrange an exchange.</p>
<h3>Damaged or Defective Items</h3>
<p>If you receive a damaged or defective item, please contact us within 7 days of delivery with photos. We'll send a replacement or full refund immediately.</p>
</div>
""",
"meta_description": "Our 30-day return policy ensures your satisfaction with every purchase",
"meta_keywords": "returns, refunds, exchange, policy",
"show_in_footer": True,
"show_in_header": False,
"display_order": 5,
},
{
"slug": "privacy",
"title": "Privacy Policy",
"content": """
<div class="prose-content">
<h2>Privacy Policy</h2>
<p><em>Last Updated: [Date]</em></p>
<h3>Information We Collect</h3>
<p>We collect information you provide directly:</p>
<ul>
<li>Name, email address, and contact information</li>
<li>Shipping and billing addresses</li>
<li>Payment information (processed securely by our payment processor)</li>
<li>Order history and preferences</li>
</ul>
<p>We automatically collect:</p>
<ul>
<li>Browser type and device information</li>
<li>IP address and location data</li>
<li>Cookies and similar tracking technologies</li>
<li>Usage data and analytics</li>
</ul>
<h3>How We Use Your Information</h3>
<p>We use your information to:</p>
<ul>
<li>Process and fulfill your orders</li>
<li>Communicate about orders and account</li>
<li>Provide customer support</li>
<li>Send marketing communications (with your consent)</li>
<li>Improve our platform and services</li>
<li>Prevent fraud and enhance security</li>
</ul>
<h3>Information Sharing</h3>
<p>We share your information only when necessary:</p>
<ul>
<li><strong>Vendors:</strong> To fulfill your orders</li>
<li><strong>Service Providers:</strong> Payment processors, shipping carriers, analytics</li>
<li><strong>Legal Requirements:</strong> When required by law</li>
</ul>
<p>We never sell your personal information to third parties.</p>
<h3>Your Rights</h3>
<p>You have the right to:</p>
<ul>
<li>Access your personal data</li>
<li>Correct inaccurate information</li>
<li>Request deletion of your data</li>
<li>Opt-out of marketing communications</li>
<li>Export your data</li>
</ul>
<h3>Data Security</h3>
<p>We implement industry-standard security measures including:</p>
<ul>
<li>SSL/TLS encryption for data transmission</li>
<li>Secure password hashing</li>
<li>Regular security audits</li>
<li>Limited employee access to personal data</li>
</ul>
<h3>Cookies</h3>
<p>We use cookies to enhance your experience. You can control cookies through your browser settings.</p>
<h3>Children's Privacy</h3>
<p>Our platform is not intended for children under 13. We do not knowingly collect information from children.</p>
<h3>Changes to This Policy</h3>
<p>We may update this policy periodically. Significant changes will be communicated via email.</p>
<h3>Contact Us</h3>
<p>For privacy-related questions, contact us at privacy@example.com</p>
</div>
""",
"meta_description": "Learn how we collect, use, and protect your personal information",
"meta_keywords": "privacy, data protection, security, policy",
"show_in_footer": False,
"show_in_header": False,
"show_in_legal": True,
"display_order": 6,
},
{
"slug": "terms",
"title": "Terms of Service",
"content": """
<div class="prose-content">
<h2>Terms of Service</h2>
<p><em>Last Updated: [Date]</em></p>
<h3>1. Acceptance of Terms</h3>
<p>By accessing and using this platform, you accept and agree to be bound by these Terms of Service.</p>
<h3>2. Account Registration</h3>
<p>You must:</p>
<ul>
<li>Be at least 18 years old</li>
<li>Provide accurate and complete information</li>
<li>Maintain the security of your account</li>
<li>Notify us of unauthorized access</li>
</ul>
<h3>3. User Conduct</h3>
<p>You agree not to:</p>
<ul>
<li>Violate any laws or regulations</li>
<li>Infringe on intellectual property rights</li>
<li>Transmit harmful code or viruses</li>
<li>Harass or harm other users</li>
<li>Engage in fraudulent activities</li>
<li>Scrape or data mine our platform</li>
</ul>
<h3>4. Product Listings</h3>
<p>Product information is provided by vendors. While we strive for accuracy:</p>
<ul>
<li>Descriptions may contain errors</li>
<li>Prices are subject to change</li>
<li>Availability is not guaranteed</li>
<li>Images are representative</li>
</ul>
<h3>5. Orders and Payment</h3>
<ul>
<li>All orders are subject to acceptance</li>
<li>We reserve the right to refuse or cancel orders</li>
<li>Prices include applicable taxes unless stated otherwise</li>
<li>Payment must be received before order processing</li>
</ul>
<h3>6. Intellectual Property</h3>
<p>All content on this platform is protected by copyright, trademark, and other laws. You may not:</p>
<ul>
<li>Reproduce or distribute our content</li>
<li>Create derivative works</li>
<li>Use our trademarks without permission</li>
</ul>
<h3>7. Disclaimer of Warranties</h3>
<p>This platform is provided "as is" without warranties of any kind, express or implied.</p>
<h3>8. Limitation of Liability</h3>
<p>We are not liable for indirect, incidental, or consequential damages arising from your use of the platform.</p>
<h3>9. Indemnification</h3>
<p>You agree to indemnify and hold us harmless from claims arising from your use of the platform or violation of these terms.</p>
<h3>10. Dispute Resolution</h3>
<p>Disputes will be resolved through binding arbitration in accordance with the rules of the American Arbitration Association.</p>
<h3>11. Governing Law</h3>
<p>These terms are governed by the laws of [State/Country], without regard to conflict of law principles.</p>
<h3>12. Changes to Terms</h3>
<p>We may modify these terms at any time. Continued use constitutes acceptance of modified terms.</p>
<h3>13. Contact</h3>
<p>For questions about these terms, contact legal@example.com</p>
</div>
""",
"meta_description": "Read our terms of service governing the use of our platform",
"meta_keywords": "terms, conditions, legal, agreement",
"show_in_footer": False,
"show_in_header": False,
"show_in_legal": True,
"display_order": 7,
},
]
# ============================================================================
# SCRIPT FUNCTIONS
# ============================================================================
def create_default_pages(db: Session) -> None:
"""
Create default platform content pages.
This function is idempotent - it will skip pages that already exist.
"""
print("\n" + "=" * 70)
print("Creating Default Platform Content Pages (CMS)")
print("=" * 70 + "\n")
created_count = 0
skipped_count = 0
for page_data in DEFAULT_PAGES:
# Check if page already exists (platform default with this slug)
existing = db.execute(
select(ContentPage).where(
ContentPage.vendor_id == None, ContentPage.slug == page_data["slug"]
)
).scalar_one_or_none()
if existing:
print(
f" ⏭️ Skipped: {page_data['title']} (/{page_data['slug']}) - already exists"
)
skipped_count += 1
continue
# Create new platform default page
page = ContentPage(
vendor_id=None, # Platform default
slug=page_data["slug"],
title=page_data["title"],
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: {page_data['title']} (/{page_data['slug']})")
created_count += 1
db.commit()
print("\n" + "=" * 70)
print("Summary:")
print(f" Created: {created_count} pages")
print(f" Skipped: {skipped_count} pages (already exist)")
print(f" Total: {created_count + skipped_count} pages")
print("=" * 70 + "\n")
if created_count > 0:
print("✅ Default platform content pages created successfully!\n")
print("Next steps:")
print(
" 1. View pages at: /about, /contact, /faq, /shipping, /returns, /privacy, /terms"
)
print(" 2. Vendors can override these pages through the vendor dashboard")
print(" 3. Edit platform defaults through the admin panel\n")
else:
print(" All default pages already exist. No changes made.\n")
# ============================================================================
# MAIN EXECUTION
# ============================================================================
def main():
"""Main execution function."""
print("\n🚀 Starting Default Content Pages Creation Script...\n")
db = SessionLocal()
try:
create_default_pages(db)
print("✅ Script completed successfully!\n")
except Exception as e:
print(f"\n❌ Error: {e}\n")
db.rollback()
raise
finally:
db.close()
if __name__ == "__main__":
main()