# app/modules/cms/routes/pages/store.py """ CMS Store Page Routes (HTML rendering). Store pages for managing content pages and rendering CMS content. """ import logging from fastapi import APIRouter, Depends, HTTPException, Path, Request from fastapi.responses import HTMLResponse from sqlalchemy.orm import Session from app.api.deps import ( get_current_store_from_cookie_or_header, get_db, get_resolved_store_code, ) from app.modules.cms.services import content_page_service from app.modules.core.services.platform_settings_service import ( platform_settings_service, # MOD-004 - shared platform service ) from app.modules.core.utils.page_context import get_store_context from app.modules.tenancy.models import User from app.templates_config import templates logger = logging.getLogger(__name__) router = APIRouter() # Route configuration - high priority so catch-all is registered last ROUTE_CONFIG = { "priority": 100, } # ============================================================================ # CONTENT PAGES MANAGEMENT # ============================================================================ @router.get( "/content-pages", response_class=HTMLResponse, include_in_schema=False ) async def store_content_pages_list( request: Request, store_code: str = Depends(get_resolved_store_code), current_user: User = Depends(get_current_store_from_cookie_or_header), db: Session = Depends(get_db), ): """ Render content pages management page. Shows platform defaults (can be overridden) and store custom pages. """ return templates.TemplateResponse( "cms/store/content-pages.html", get_store_context(request, db, current_user, store_code), ) @router.get( "/content-pages/create", response_class=HTMLResponse, include_in_schema=False, ) async def store_content_page_create( request: Request, store_code: str = Depends(get_resolved_store_code), current_user: User = Depends(get_current_store_from_cookie_or_header), db: Session = Depends(get_db), ): """ Render content page creation form. """ return templates.TemplateResponse( "cms/store/content-page-edit.html", get_store_context(request, db, current_user, store_code, page_id=None), ) @router.get( "/content-pages/{page_id}/edit", response_class=HTMLResponse, include_in_schema=False, ) async def store_content_page_edit( request: Request, store_code: str = Depends(get_resolved_store_code), page_id: int = Path(..., description="Content page ID"), current_user: User = Depends(get_current_store_from_cookie_or_header), db: Session = Depends(get_db), ): """ Render content page edit form. """ return templates.TemplateResponse( "cms/store/content-page-edit.html", get_store_context(request, db, current_user, store_code, page_id=page_id), ) # ============================================================================ # DYNAMIC CONTENT PAGES (CMS) - Public Shop Display # ============================================================================ @router.get( "/{slug}", response_class=HTMLResponse, include_in_schema=False ) async def store_content_page( request: Request, store_code: str = Depends(get_resolved_store_code), slug: str = Path(..., description="Content page slug"), db: Session = Depends(get_db), ): """ Generic content page handler for store shop (CMS). Handles dynamic content pages like: - /stores/orion/about, /stores/orion/faq, /stores/orion/contact, etc. Features: - Two-tier system: Store overrides take priority, fallback to platform defaults - Only shows published pages - Returns 404 if page not found or unpublished NOTE: This is a catch-all route and must be registered LAST to avoid shadowing other specific routes. """ logger.debug( "[CMS] store_content_page REACHED", extra={ "path": request.url.path, "store_code": store_code, "slug": slug, "store": getattr(request.state, "store", "NOT SET"), "context": getattr(request.state, "context_type", "NOT SET"), }, ) store = getattr(request.state, "store", None) platform = getattr(request.state, "platform", None) store_id = store.id if store else None if not platform: raise HTTPException(status_code=400, detail="Platform context required") platform_id = platform.id # Load content page from database (store override → platform default) page = content_page_service.get_page_for_store( db, platform_id=platform_id, slug=slug, store_id=store_id, include_unpublished=False ) if not page: logger.info( f"[CMS] Content page not found: {slug}", extra={ "slug": slug, "store_code": store_code, "store_id": store_id, }, ) raise HTTPException(status_code=404, detail="Page not found") logger.info( f"[CMS] Rendering page: {page.title}", extra={ "slug": slug, "page_id": page.id, "is_store_override": page.store_id is not None, "store_id": store_id, }, ) # Resolve locale for shop template platform_config = platform_settings_service.get_storefront_config(db) storefront_locale = platform_config["locale"] storefront_currency = platform_config["currency"] if store and store.storefront_locale: storefront_locale = store.storefront_locale return templates.TemplateResponse( "storefront/content-page.html", { "request": request, "page": page, "store": store, "store_code": store_code, "storefront_locale": storefront_locale, "storefront_currency": storefront_currency, }, )