feat(hosting): add industry template infrastructure (Workstream 3B)

5 industry templates as JSON presets, each with theme + multi-page content:
- generic: clean minimal (homepage, about, contact)
- restaurant: warm tones, Playfair Display (homepage, about, menu, contact)
- construction: amber/earth tones, Montserrat (homepage, services, projects, contact)
- auto-parts: red/bold, parts-focused (homepage, catalog, contact)
- professional-services: navy/blue, Merriweather (homepage, services, team, contact)

Each template has:
- meta.json (name, description, tags, languages)
- theme.json (colors, fonts, layout, header style)
- pages/*.json (section-based homepage + content pages with i18n)
- {{placeholder}} variables for prospect data injection

TemplateService loads from templates_library/ directory with caching.
GET /admin/hosting/sites/templates endpoint to list available templates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-01 22:41:33 +02:00
parent 1828ac85eb
commit 2e043260eb
32 changed files with 604 additions and 0 deletions

View File

@@ -22,13 +22,26 @@ from app.modules.hosting.schemas.hosted_site import (
HostedSiteUpdate,
SendProposalRequest,
)
from app.modules.hosting.schemas.template import TemplateListResponse, TemplateResponse
from app.modules.hosting.services.hosted_site_service import hosted_site_service
from app.modules.hosting.services.template_service import template_service
from app.modules.tenancy.schemas.auth import UserContext
router = APIRouter(prefix="/sites")
logger = logging.getLogger(__name__)
@router.get("/templates", response_model=TemplateListResponse)
def list_templates(
current_admin: UserContext = Depends(get_current_admin_api),
):
"""List available industry templates for POC site generation."""
templates = template_service.list_templates()
return TemplateListResponse(
templates=[TemplateResponse(**t) for t in templates],
)
def _to_response(site) -> HostedSiteResponse:
"""Convert a hosted site model to response schema."""
return HostedSiteResponse(