diff --git a/Makefile b/Makefile index 08faaa9d..75b36c8f 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,7 @@ else SEED_MODE=reset $(PYTHON) scripts/seed_demo.py endif -db-setup: migrate-up init-prod seed-demo +db-setup: migrate-up init-prod create-cms-defaults seed-demo @echo "āœ… Database setup complete!" @echo "Run 'make dev' to start development server" @@ -133,6 +133,12 @@ backup-db: @echo "Creating database backup..." @$(PYTHON) scripts/backup_database.py +# CMS default content pages +create-cms-defaults: + @echo "šŸ“„ Creating default CMS content pages..." + $(PYTHON) scripts/create_default_content_pages.py + @echo "āœ… CMS defaults created" + # ============================================================================= # TESTING # ============================================================================= @@ -314,7 +320,8 @@ help: @echo " seed-demo - Seed demo data (3 vendors)" @echo " seed-demo-minimal - Seed minimal demo (1 vendor)" @echo " seed-demo-reset - DELETE ALL and reseed" - @echo " db-setup - Full dev setup (migrate + init + seed)" + @echo " create-cms-defaults - Create default CMS content pages" + @echo " db-setup - Full dev setup (migrate + init + cms + seed)" @echo " backup-db - Backup database" @echo "" @echo "=== TESTING ===" @@ -367,15 +374,19 @@ help-db: @echo " seed-demo-minimal - Create 1 demo vendor only" @echo " seed-demo-reset - DELETE ALL data and reseed (DANGEROUS!)" @echo "" + @echo "CMS CONTENT:" + @echo " create-cms-defaults - Create default content pages (about, faq, etc.)" + @echo "" @echo "WORKFLOWS:" - @echo " db-setup - Complete dev setup (migrate + init + seed)" + @echo " db-setup - Complete dev setup (migrate + init + cms + seed)" @echo " db-reset - Nuclear option: rollback + reset + reseed" @echo "" @echo "TYPICAL FIRST-TIME SETUP:" @echo " 1. make migrate-up # Apply migrations" @echo " 2. make init-prod # Create admin user" - @echo " 3. make seed-demo # Add demo data" - @echo " 4. make dev # Start developing" + @echo " 3. make create-cms-defaults # Create CMS pages" + @echo " 4. make seed-demo # Add demo data" + @echo " 5. make dev # Start developing" @echo "" @echo "PRODUCTION SETUP:" @echo " 1. Set ENV=production or ENVIRONMENT=production" diff --git a/scripts/create_default_content_pages.py b/scripts/create_default_content_pages.py new file mode 100755 index 00000000..927559c3 --- /dev/null +++ b/scripts/create_default_content_pages.py @@ -0,0 +1,550 @@ +#!/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 pathlib import Path +from datetime import datetime, timezone + +# Add project root to path +project_root = Path(__file__).parent.parent +sys.path.insert(0, str(project_root)) + +from sqlalchemy.orm import Session +from sqlalchemy import select + +from app.core.database import SessionLocal +from models.database.content_page import ContentPage + + +# ============================================================================ +# DEFAULT PAGE CONTENT +# ============================================================================ + +DEFAULT_PAGES = [ + { + "slug": "about", + "title": "About Us", + "content": """ +
+

Welcome to Our Platform

+

We are a multi-vendor e-commerce platform connecting quality sellers with customers worldwide.

+ +

Our Mission

+

To empower independent businesses and artisans by providing them with the tools and platform they need to reach customers globally.

+ +

What We Offer

+ + +

Our Values

+ +
+ """, + "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": """ +
+

Get in Touch

+

We're here to help! Reach out to us through any of the following channels:

+ +

Customer Support

+

For questions about orders, products, or general inquiries:

+ + +

Business Inquiries

+

Interested in becoming a vendor or partnering with us?

+ + +

Office Address

+

+ 123 Commerce Street
+ Suite 456
+ City, State 12345
+ United States +

+ +

Response Time

+

We typically respond to all inquiries within 24 hours during business days.

+
+ """, + "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": """ +
+

Frequently Asked Questions

+ +

Orders & Shipping

+ +

How do I track my order?

+

Once your order ships, you'll receive a tracking number via email. You can also view your order status in your account dashboard.

+ +

How long does shipping take?

+

Shipping times vary by vendor and destination. Most orders arrive within 3-7 business days. See our Shipping Policy for details.

+ +

Do you ship internationally?

+

Yes! We ship to most countries worldwide. International shipping times and costs vary by destination.

+ +

Returns & Refunds

+ +

What is your return policy?

+

Most items can be returned within 30 days of delivery. See our Return Policy for complete details.

+ +

How do I request a refund?

+

Contact the vendor directly through your order page or reach out to our support team for assistance.

+ +

Payments

+ +

What payment methods do you accept?

+

We accept all major credit cards, PayPal, and other secure payment methods.

+ +

Is my payment information secure?

+

Yes! We use industry-standard encryption and never store your full payment details.

+ +

Account

+ +

Do I need an account to make a purchase?

+

No, you can checkout as a guest. However, creating an account lets you track orders and save your preferences.

+ +

How do I reset my password?

+

Click "Forgot Password" on the login page and follow the instructions sent to your email.

+
+ """, + "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": """ +
+

Shipping Policy

+ +

Shipping Methods

+

We offer multiple shipping options to meet your needs:

+ + +

Shipping Costs

+

Shipping costs are calculated based on:

+ +

Free standard shipping on orders over $50!

+ +

Processing Time

+

Orders are typically processed within 1-2 business days. You'll receive a confirmation email when your order ships with tracking information.

+ +

International Shipping

+

We ship to most countries worldwide. International shipping times vary by destination (typically 7-21 business days).

+ + +

Tracking

+

All orders include tracking. You can monitor your package status through:

+ + +

Delivery Issues

+

If you experience any delivery issues, please contact us within 7 days of the expected delivery date.

+
+ """, + "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": """ +
+

Return & Refund Policy

+ +

30-Day Return Window

+

Most items can be returned within 30 days of delivery for a full refund or exchange.

+ +

Return Requirements

+

To be eligible for a return, items must:

+ + +

Non-Returnable Items

+

The following items cannot be returned:

+ + +

How to Return

+
    +
  1. Log into your account and go to "Order History"
  2. +
  3. Select the order and click "Request Return"
  4. +
  5. Choose items and provide reason for return
  6. +
  7. Print the prepaid return label
  8. +
  9. Pack items securely and attach label
  10. +
  11. Drop off at any authorized carrier location
  12. +
+ +

Refund Process

+

Once we receive your return:

+ + +

Return Shipping

+

Return shipping is free for defective or incorrect items. For other returns, a $5.99 return shipping fee will be deducted from your refund.

+ +

Exchanges

+

We offer free exchanges for different sizes or colors of the same item. Contact support to arrange an exchange.

+ +

Damaged or Defective Items

+

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.

+
+ """, + "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": """ +
+

Privacy Policy

+

Last Updated: [Date]

+ +

Information We Collect

+

We collect information you provide directly:

+ + +

We automatically collect:

+ + +

How We Use Your Information

+

We use your information to:

+ + +

Information Sharing

+

We share your information only when necessary:

+ +

We never sell your personal information to third parties.

+ +

Your Rights

+

You have the right to:

+ + +

Data Security

+

We implement industry-standard security measures including:

+ + +

Cookies

+

We use cookies to enhance your experience. You can control cookies through your browser settings.

+ +

Children's Privacy

+

Our platform is not intended for children under 13. We do not knowingly collect information from children.

+ +

Changes to This Policy

+

We may update this policy periodically. Significant changes will be communicated via email.

+ +

Contact Us

+

For privacy-related questions, contact us at privacy@example.com

+
+ """, + "meta_description": "Learn how we collect, use, and protect your personal information", + "meta_keywords": "privacy, data protection, security, policy", + "show_in_footer": True, + "show_in_header": False, + "display_order": 6, + }, + { + "slug": "terms", + "title": "Terms of Service", + "content": """ +
+

Terms of Service

+

Last Updated: [Date]

+ +

1. Acceptance of Terms

+

By accessing and using this platform, you accept and agree to be bound by these Terms of Service.

+ +

2. Account Registration

+

You must:

+ + +

3. User Conduct

+

You agree not to:

+ + +

4. Product Listings

+

Product information is provided by vendors. While we strive for accuracy:

+ + +

5. Orders and Payment

+ + +

6. Intellectual Property

+

All content on this platform is protected by copyright, trademark, and other laws. You may not:

+ + +

7. Disclaimer of Warranties

+

This platform is provided "as is" without warranties of any kind, express or implied.

+ +

8. Limitation of Liability

+

We are not liable for indirect, incidental, or consequential damages arising from your use of the platform.

+ +

9. Indemnification

+

You agree to indemnify and hold us harmless from claims arising from your use of the platform or violation of these terms.

+ +

10. Dispute Resolution

+

Disputes will be resolved through binding arbitration in accordance with the rules of the American Arbitration Association.

+ +

11. Governing Law

+

These terms are governed by the laws of [State/Country], without regard to conflict of law principles.

+ +

12. Changes to Terms

+

We may modify these terms at any time. Continued use constitutes acceptance of modified terms.

+ +

13. Contact

+

For questions about these terms, contact legal@example.com

+
+ """, + "meta_description": "Read our terms of service governing the use of our platform", + "meta_keywords": "terms, conditions, legal, agreement", + "show_in_footer": True, + "show_in_header": False, + "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(timezone.utc), + show_in_footer=page_data["show_in_footer"], + show_in_header=page_data.get("show_in_header", False), + display_order=page_data["display_order"], + created_at=datetime.now(timezone.utc), + updated_at=datetime.now(timezone.utc), + ) + + db.add(page) + print(f" āœ… Created: {page_data['title']} (/{page_data['slug']})") + created_count += 1 + + db.commit() + + print("\n" + "=" * 70) + print(f"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()