# CMS Implementation Guide

## Quick Start

This guide shows you how to implement the Content Management System for static pages.

## What Was Implemented

✅ **Database Model**: `models/database/content_page.py`
✅ **Service Layer**: `app/services/content_page_service.py`
✅ **Admin API**: `app/api/v1/admin/content_pages.py`
✅ **Store API**: `app/api/v1/store/content_pages.py`
✅ **Shop API**: `app/api/v1/shop/content_pages.py`
✅ **Documentation**: Full CMS documentation in `docs/features/content-management-system.md`

## Next Steps to Activate

### 1. Create Database Migration

```bash
# Create Alembic migration
alembic revision --autogenerate -m "Add content_pages table"

# Review the generated migration in alembic/versions/

# Run migration
alembic upgrade head
```

### 2. Add Relationship to Store Model

Edit `models/database/store.py` and add this relationship:

```python
# Add this import
from sqlalchemy.orm import relationship

# Add this relationship to Store class
content_pages = relationship("ContentPage", back_populates="store", cascade="all, delete-orphan")
```

### 3. Register API Routers

Edit the appropriate router files to include the new endpoints:

**Admin Router** (`app/api/v1/admin/__init__.py`):
```python
from app.api.v1.admin import content_pages

api_router.include_router(
    content_pages.router,
    prefix="/content-pages",
    tags=["admin-content-pages"]
)
```

**Store Router** (`app/api/v1/store/__init__.py`):
```python
from app.api.v1.store import content_pages

api_router.include_router(
    content_pages.router,
    prefix="/{store_code}/content-pages",
    tags=["store-content-pages"]
)
```

**Shop Router** (`app/api/v1/shop/__init__.py` or create if doesn't exist):
```python
from app.api.v1.shop import content_pages

api_router.include_router(
    content_pages.router,
    prefix="/content-pages",
    tags=["shop-content-pages"]
)
```

### 4. Update Shop Routes to Use CMS

Edit `app/routes/shop_pages.py` to add a generic content page handler:

```python
from app.services.content_page_service import content_page_service

@router.get("/{slug}", response_class=HTMLResponse, include_in_schema=False)
async def generic_content_page(
    slug: str,
    request: Request,
    db: Session = Depends(get_db)
):
    """
    Generic content page handler.
    Handles: /about, /faq, /contact, /shipping, /returns, /privacy, /terms, etc.
    """
    store = getattr(request.state, 'store', None)
    store_id = store.id if store else None

    page = content_page_service.get_page_for_store(
        db,
        slug=slug,
        store_id=store_id,
        include_unpublished=False
    )

    if not page:
        raise HTTPException(status_code=404, detail=f"Page not found: {slug}")

    return templates.TemplateResponse(
        "shop/content-page.html",
        get_shop_context(request, page=page)
    )
```

### 5. Create Generic Content Page Template

Create `app/templates/shop/content-page.html`:

```jinja2
{# app/templates/shop/content-page.html #}
{% extends "shop/base.html" %}

{% block title %}{{ page.title }}{% endblock %}

{% block meta_description %}
  {{ page.meta_description or page.title }}
{% endblock %}

{% block content %}
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">

  {# Breadcrumbs #}
  <nav class="mb-6 text-sm">
    <a href="{{ base_url }}" class="text-primary hover:underline">Home</a>
    <span class="mx-2 text-gray-400">/</span>
    <span class="text-gray-600 dark:text-gray-300">{{ page.title }}</span>
  </nav>

  {# Page Title #}
  <h1 class="text-4xl font-bold text-gray-900 dark:text-gray-100 mb-8">
    {{ page.title }}
  </h1>

  {# Content #}
  <div class="prose prose-lg dark:prose-invert max-w-none">
    {{ page.content | safe }}
  </div>

  {# Last updated #}
  {% if page.updated_at %}
  <div class="mt-12 pt-6 border-t border-gray-200 dark:border-gray-700 text-sm text-gray-500 dark:text-gray-400">
    Last updated: {{ page.updated_at.strftime('%B %d, %Y') }}
  </div>
  {% endif %}

</div>
{% endblock %}
```

### 6. Update Footer to Load Navigation Dynamically

Edit `app/templates/shop/base.html` to load navigation from database.

First, update the context helper to include footer pages:

```python
# app/routes/shop_pages.py

def get_shop_context(request: Request, **extra_context) -> dict:
    # ... existing code ...

    # Load footer navigation pages
    db = next(get_db())
    try:
        footer_pages = content_page_service.list_pages_for_store(
            db,
            store_id=store.id if store else None,
            include_unpublished=False,
            footer_only=True
        )
    finally:
        db.close()

    context = {
        "request": request,
        "store": store,
        "theme": theme,
        "clean_path": clean_path,
        "access_method": access_method,
        "base_url": base_url,
        "footer_pages": footer_pages,  # Add this
        **extra_context
    }

    return context
```

Then update the footer template:

```jinja2
{# app/templates/shop/base.html - Footer section #}

<div>
    <h4 class="font-semibold mb-4">Quick Links</h4>
    <ul class="space-y-2">
        {% for page in footer_pages %}
        <li>
            <a href="{{ base_url }}{{ page.slug }}"
               class="text-gray-600 hover:text-primary dark:text-gray-400">
                {{ page.title }}
            </a>
        </li>
        {% endfor %}
    </ul>
</div>
```

### 7. Create Default Platform Pages (Script)

Create `scripts/seed/create_default_content_pages.py`:

```python
#!/usr/bin/env python3
"""Create default platform content pages."""

from sqlalchemy.orm import Session
from app.core.database import SessionLocal
from app.services.content_page_service import content_page_service

def create_defaults():
    db: Session = SessionLocal()

    try:
        # About Us
        content_page_service.create_page(
            db,
            slug="about",
            title="About Us",
            content="""
                <h2>Welcome to Our Marketplace</h2>
                <p>We connect quality stores with customers worldwide.</p>
                <p>Our mission is to provide a seamless shopping experience...</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=1
        )

        # Shipping Information
        content_page_service.create_page(
            db,
            slug="shipping",
            title="Shipping Information",
            content="""
                <h2>Shipping Policy</h2>
                <p>We offer fast and reliable shipping...</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=2
        )

        # Returns
        content_page_service.create_page(
            db,
            slug="returns",
            title="Returns & Refunds",
            content="""
                <h2>Return Policy</h2>
                <p>30-day return policy on all items...</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=3
        )

        # Privacy Policy
        content_page_service.create_page(
            db,
            slug="privacy",
            title="Privacy Policy",
            content="""
                <h2>Privacy Policy</h2>
                <p>Your privacy is important to us...</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=4
        )

        # Terms of Service
        content_page_service.create_page(
            db,
            slug="terms",
            title="Terms of Service",
            content="""
                <h2>Terms of Service</h2>
                <p>By using our platform, you agree to...</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=5
        )

        # Contact
        content_page_service.create_page(
            db,
            slug="contact",
            title="Contact Us",
            content="""
                <h2>Get in Touch</h2>
                <p>Have questions? We'd love to hear from you!</p>
                <p>Email: support@example.com</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=6
        )

        # FAQ
        content_page_service.create_page(
            db,
            slug="faq",
            title="Frequently Asked Questions",
            content="""
                <h2>FAQ</h2>
                <h3>How do I place an order?</h3>
                <p>Simply browse our products...</p>
            """,
            is_published=True,
            show_in_footer=True,
            display_order=7
        )

        print("✅ Created default content pages successfully")

    except Exception as e:
        print(f"❌ Error: {e}")
        db.rollback()
    finally:
        db.close()


if __name__ == "__main__":
    create_defaults()
```

Run it:
```bash
python scripts/seed/create_default_content_pages.py
```

## Testing

### 1. Test Platform Defaults

```bash
# Create platform default
curl -X POST http://localhost:8000/api/v1/admin/content-pages/platform \
  -H "Authorization: Bearer <admin_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "about",
    "title": "About Our Marketplace",
    "content": "<h1>About</h1><p>Platform default content</p>",
    "is_published": true,
    "show_in_footer": true
  }'

# View in shop
curl http://localhost:8000/store/orion/about
```

### 2. Test Store Override

```bash
# Create store override
curl -X POST http://localhost:8000/api/v1/store/orion/content-pages/ \
  -H "Authorization: Bearer <store_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "about",
    "title": "About Orion",
    "content": "<h1>About Orion</h1><p>Custom store content</p>",
    "is_published": true
  }'

# View in shop (should show store content)
curl http://localhost:8000/store/orion/about
```

### 3. Test Fallback

```bash
# Delete store override
curl -X DELETE http://localhost:8000/api/v1/store/orion/content-pages/{id} \
  -H "Authorization: Bearer <store_token>"

# View in shop (should fall back to platform default)
curl http://localhost:8000/store/orion/about
```

## Summary

You now have a complete CMS system that allows:

1. **Platform admins** to create default content for all stores
2. **Stores** to override specific pages with custom content
3. **Automatic fallback** to platform defaults when store hasn't customized
4. **Dynamic navigation** loading from database
5. **SEO optimization** with meta tags
6. **Draft/Published workflow** for content management

All pages are accessible via their slug: `/about`, `/faq`, `/contact`, etc. with proper store context and routing support!
