Add the experience service with sites through analytics/AI hooks, migrations through 0011, and phase docs/manifests marking the track complete. Co-authored-by: Cursor <cursoragent@cursor.com>
241 lines
7.4 KiB
Python
241 lines
7.4 KiB
Python
"""Theme & layout command handlers — Phase 11.3 (versioned)."""
|
|
from __future__ import annotations
|
|
|
|
from uuid import UUID
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.schemas.themes import (
|
|
ExperienceLayoutCreate,
|
|
ExperienceLayoutUpdate,
|
|
ExperienceLayoutVersionCreate,
|
|
ExperienceLayoutVersionUpdate,
|
|
ExperienceThemeCreate,
|
|
ExperienceThemeUpdate,
|
|
ExperienceThemeVersionCreate,
|
|
ExperienceThemeVersionUpdate,
|
|
PageLayoutBindingCreate,
|
|
PageLayoutBindingUpdate,
|
|
SiteThemeBindingCreate,
|
|
SiteThemeBindingUpdate,
|
|
)
|
|
from app.services.themes import ExperienceThemeService
|
|
from shared.security import CurrentUser
|
|
|
|
|
|
class ThemeLayoutCommands:
|
|
def __init__(self, session: AsyncSession) -> None:
|
|
self.service = ExperienceThemeService(session)
|
|
|
|
# --- Themes ---
|
|
|
|
async def create_theme(
|
|
self, tenant_id: UUID, body: ExperienceThemeCreate, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.create_theme(tenant_id, body, actor=actor)
|
|
|
|
async def update_theme(
|
|
self,
|
|
tenant_id: UUID,
|
|
theme_id: UUID,
|
|
body: ExperienceThemeUpdate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.update_theme(tenant_id, theme_id, body, actor=actor)
|
|
|
|
async def activate_theme(
|
|
self, tenant_id: UUID, theme_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.activate_theme(tenant_id, theme_id, actor=actor)
|
|
|
|
async def deprecate_theme(
|
|
self, tenant_id: UUID, theme_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.deprecate_theme(tenant_id, theme_id, actor=actor)
|
|
|
|
async def archive_theme(
|
|
self, tenant_id: UUID, theme_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.archive_theme(tenant_id, theme_id, actor=actor)
|
|
|
|
async def soft_delete_theme(
|
|
self, tenant_id: UUID, theme_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.soft_delete_theme(tenant_id, theme_id, actor=actor)
|
|
|
|
# --- Theme Versions ---
|
|
|
|
async def create_theme_version(
|
|
self,
|
|
tenant_id: UUID,
|
|
body: ExperienceThemeVersionCreate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.create_theme_version(tenant_id, body, actor=actor)
|
|
|
|
async def update_theme_version(
|
|
self,
|
|
tenant_id: UUID,
|
|
version_id: UUID,
|
|
body: ExperienceThemeVersionUpdate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.update_theme_version(
|
|
tenant_id, version_id, body, actor=actor
|
|
)
|
|
|
|
async def publish_theme_version(
|
|
self, tenant_id: UUID, version_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.publish_theme_version(
|
|
tenant_id, version_id, actor=actor
|
|
)
|
|
|
|
async def retire_theme_version(
|
|
self, tenant_id: UUID, version_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.retire_theme_version(
|
|
tenant_id, version_id, actor=actor
|
|
)
|
|
|
|
# --- Layouts ---
|
|
|
|
async def create_layout(
|
|
self, tenant_id: UUID, body: ExperienceLayoutCreate, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.create_layout(tenant_id, body, actor=actor)
|
|
|
|
async def update_layout(
|
|
self,
|
|
tenant_id: UUID,
|
|
layout_id: UUID,
|
|
body: ExperienceLayoutUpdate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.update_layout(
|
|
tenant_id, layout_id, body, actor=actor
|
|
)
|
|
|
|
async def activate_layout(
|
|
self, tenant_id: UUID, layout_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.activate_layout(tenant_id, layout_id, actor=actor)
|
|
|
|
async def deprecate_layout(
|
|
self, tenant_id: UUID, layout_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.deprecate_layout(tenant_id, layout_id, actor=actor)
|
|
|
|
async def archive_layout(
|
|
self, tenant_id: UUID, layout_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.archive_layout(tenant_id, layout_id, actor=actor)
|
|
|
|
async def soft_delete_layout(
|
|
self, tenant_id: UUID, layout_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.soft_delete_layout(
|
|
tenant_id, layout_id, actor=actor
|
|
)
|
|
|
|
# --- Layout Versions ---
|
|
|
|
async def create_layout_version(
|
|
self,
|
|
tenant_id: UUID,
|
|
body: ExperienceLayoutVersionCreate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.create_layout_version(tenant_id, body, actor=actor)
|
|
|
|
async def update_layout_version(
|
|
self,
|
|
tenant_id: UUID,
|
|
version_id: UUID,
|
|
body: ExperienceLayoutVersionUpdate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.update_layout_version(
|
|
tenant_id, version_id, body, actor=actor
|
|
)
|
|
|
|
async def publish_layout_version(
|
|
self, tenant_id: UUID, version_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.publish_layout_version(
|
|
tenant_id, version_id, actor=actor
|
|
)
|
|
|
|
async def retire_layout_version(
|
|
self, tenant_id: UUID, version_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.retire_layout_version(
|
|
tenant_id, version_id, actor=actor
|
|
)
|
|
|
|
# --- Site Theme Bindings ---
|
|
|
|
async def assign_site_theme(
|
|
self,
|
|
tenant_id: UUID,
|
|
body: SiteThemeBindingCreate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.assign_site_theme(tenant_id, body, actor=actor)
|
|
|
|
async def update_site_theme_binding(
|
|
self,
|
|
tenant_id: UUID,
|
|
binding_id: UUID,
|
|
body: SiteThemeBindingUpdate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.update_site_theme_binding(
|
|
tenant_id, binding_id, body, actor=actor
|
|
)
|
|
|
|
async def unassign_site_theme(
|
|
self, tenant_id: UUID, binding_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.soft_delete_site_theme_binding(
|
|
tenant_id, binding_id, actor=actor
|
|
)
|
|
|
|
# --- Page Layout Bindings ---
|
|
|
|
async def assign_page_layout(
|
|
self,
|
|
tenant_id: UUID,
|
|
body: PageLayoutBindingCreate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.assign_page_layout(tenant_id, body, actor=actor)
|
|
|
|
async def update_page_layout_binding(
|
|
self,
|
|
tenant_id: UUID,
|
|
binding_id: UUID,
|
|
body: PageLayoutBindingUpdate,
|
|
*,
|
|
actor: CurrentUser | None,
|
|
):
|
|
return await self.service.update_page_layout_binding(
|
|
tenant_id, binding_id, body, actor=actor
|
|
)
|
|
|
|
async def unassign_page_layout(
|
|
self, tenant_id: UUID, binding_id: UUID, *, actor: CurrentUser | None
|
|
):
|
|
return await self.service.soft_delete_page_layout_binding(
|
|
tenant_id, binding_id, actor=actor
|
|
)
|