Files
orion/app/modules/cms/definition.py
Samir Boulahtit aad18c27ab
Some checks failed
CI / ruff (push) Successful in 11s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has started running
refactor: remove all backward compatibility code across 70 files
Clean up 28 backward compatibility instances identified in the codebase.
The app is not live, so all shims are replaced with the target architecture:

- Remove legacy Inventory.location column (use bin_location exclusively)
- Remove dashboard _extract_metric_value helper (use flat metrics dict)
- Remove legacy stat field duplicates (total_stores, total_imports, etc.)
- Remove 13 re-export shims and class aliases across modules
- Remove module-enabling JSON fallback (use PlatformModule junction table)
- Remove menu_to_legacy_format() conversion (return dataclasses directly)
- Remove title/description from MarketplaceProductBase schema
- Clean billing convenience method docstrings
- Clean test fixtures and backward-compat comments
- Add PlatformModule seeding to init_production.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 13:20:29 +01:00

286 lines
9.1 KiB
Python

# app/modules/cms/definition.py
"""
CMS module definition.
Defines the CMS module including its features, menu items,
route configurations, and self-contained component paths.
This is a self-contained module with:
- Services: app.modules.cms.services
- Models: app.modules.cms.models
- Exceptions: app.modules.cms.exceptions
- Templates: app.modules.cms.templates (namespaced as cms/)
"""
import logging
from typing import Any
from app.modules.base import (
MenuItemDefinition,
MenuSectionDefinition,
ModuleDefinition,
PermissionDefinition,
)
from app.modules.enums import FrontendType
logger = logging.getLogger(__name__)
# =============================================================================
# Context Providers
# =============================================================================
def _get_platform_context(request: Any, db: Any, platform: Any) -> dict[str, Any]:
"""
Provide CMS context for platform/marketing pages.
Returns header and footer navigation pages for the marketing site.
"""
from app.modules.cms.services import content_page_service
platform_id = platform.id if platform else 1
header_pages = []
footer_pages = []
try:
header_pages = content_page_service.list_platform_pages(
db, platform_id=platform_id, header_only=True, include_unpublished=False
)
footer_pages = content_page_service.list_platform_pages(
db, platform_id=platform_id, footer_only=True, include_unpublished=False
)
logger.debug(
f"[CMS] Platform context: {len(header_pages)} header, {len(footer_pages)} footer pages"
)
except Exception as e:
logger.warning(f"[CMS] Failed to load platform navigation pages: {e}")
return {
"header_pages": header_pages,
"footer_pages": footer_pages,
"legal_pages": [], # TODO: Add legal pages support if needed
}
def _get_storefront_context(request: Any, db: Any, platform: Any) -> dict[str, Any]:
"""
Provide CMS context for storefront (customer shop) pages.
Returns header and footer navigation pages for the store's shop.
"""
from app.modules.cms.services import content_page_service
store = getattr(request.state, "store", None)
platform_id = platform.id if platform else 1
header_pages = []
footer_pages = []
if store:
try:
header_pages = content_page_service.list_pages_for_store(
db,
platform_id=platform_id,
store_id=store.id,
header_only=True,
include_unpublished=False,
)
footer_pages = content_page_service.list_pages_for_store(
db,
platform_id=platform_id,
store_id=store.id,
footer_only=True,
include_unpublished=False,
)
logger.debug(
f"[CMS] Storefront context for store {store.id}: "
f"{len(header_pages)} header, {len(footer_pages)} footer pages"
)
except Exception as e:
logger.warning(f"[CMS] Failed to load storefront navigation pages: {e}")
return {
"header_pages": header_pages,
"footer_pages": footer_pages,
}
# =============================================================================
# Router Lazy Imports
# =============================================================================
def _get_admin_router():
"""Lazy import of admin router to avoid circular imports."""
from app.modules.cms.routes.admin import admin_router
return admin_router
def _get_store_router():
"""Lazy import of store router to avoid circular imports."""
from app.modules.cms.routes.api.store import store_router
return store_router
def _get_metrics_provider():
"""Lazy import of metrics provider to avoid circular imports."""
from app.modules.cms.services.cms_metrics import cms_metrics_provider
return cms_metrics_provider
def _get_feature_provider():
"""Lazy import of feature provider to avoid circular imports."""
from app.modules.cms.services.cms_features import cms_feature_provider
return cms_feature_provider
# CMS module definition - Self-contained module (pilot)
cms_module = ModuleDefinition(
code="cms",
name="Content Management",
description="Content pages, media library, and store themes.",
version="1.0.0",
features=[
"cms_basic", # Basic page editing
"cms_custom_pages", # Custom page creation
"cms_unlimited_pages", # No page limit
"cms_templates", # Page templates
"cms_seo", # SEO tools
"media_library", # Media file management
],
# Module-driven permissions
permissions=[
PermissionDefinition(
id="cms.view_pages",
label_key="cms.permissions.view_pages",
description_key="cms.permissions.view_pages_desc",
category="cms",
),
PermissionDefinition(
id="cms.manage_pages",
label_key="cms.permissions.manage_pages",
description_key="cms.permissions.manage_pages_desc",
category="cms",
),
PermissionDefinition(
id="cms.view_media",
label_key="cms.permissions.view_media",
description_key="cms.permissions.view_media_desc",
category="cms",
),
PermissionDefinition(
id="cms.manage_media",
label_key="cms.permissions.manage_media",
description_key="cms.permissions.manage_media_desc",
category="cms",
),
PermissionDefinition(
id="cms.manage_themes",
label_key="cms.permissions.manage_themes",
description_key="cms.permissions.manage_themes_desc",
category="cms",
),
],
menu_items={
FrontendType.ADMIN: [
"content-pages", # Platform content pages
"store-themes", # Theme management
],
FrontendType.STORE: [
"content-pages", # Store content pages
"media", # Media library
],
},
# New module-driven menu definitions
menus={
FrontendType.ADMIN: [
MenuSectionDefinition(
id="contentMgmt",
label_key="cms.menu.content_management",
icon="document-text",
order=70,
items=[
MenuItemDefinition(
id="content-pages",
label_key="cms.menu.content_pages",
icon="document-text",
route="/admin/content-pages",
order=20,
),
MenuItemDefinition(
id="store-themes",
label_key="cms.menu.store_themes",
icon="color-swatch",
route="/admin/store-themes",
order=30,
),
],
),
],
FrontendType.STORE: [
MenuSectionDefinition(
id="shop",
label_key="cms.menu.shop_content",
icon="document-text",
order=40,
items=[
MenuItemDefinition(
id="content-pages",
label_key="cms.menu.content_pages",
icon="document-text",
route="/store/{store_code}/content-pages",
order=10,
),
MenuItemDefinition(
id="media",
label_key="cms.menu.media_library",
icon="photograph",
route="/store/{store_code}/media",
order=20,
),
],
),
],
},
is_core=True, # CMS is a core module - content management is fundamental
# Context providers for dynamic page context
context_providers={
FrontendType.PLATFORM: _get_platform_context,
FrontendType.STOREFRONT: _get_storefront_context,
},
# Self-contained module configuration
is_self_contained=True,
services_path="app.modules.cms.services",
models_path="app.modules.cms.models",
exceptions_path="app.modules.cms.exceptions",
migrations_path="migrations",
# Module templates (namespaced as cms/admin/*.html and cms/store/*.html)
templates_path="templates",
# Module-specific translations (accessible via cms.* keys)
locales_path="locales",
# Metrics provider for dashboard statistics
metrics_provider=_get_metrics_provider,
feature_provider=_get_feature_provider,
)
def get_cms_module_with_routers() -> ModuleDefinition:
"""
Get CMS module with routers attached.
This function attaches the routers lazily to avoid circular imports
during module initialization.
"""
cms_module.admin_router = _get_admin_router()
cms_module.store_router = _get_store_router()
return cms_module
__all__ = ["cms_module", "get_cms_module_with_routers"]