Hosted sites leverage existing CMS module (ContentPage, StoreTheme, MediaFile) instead of building a separate site rendering system. Industry templates (restaurant, construction, auto-parts, professional-services, generic) are JSON presets that populate CMS entities for a new Store. POC phase uses subdomain routing (acme.hostwizard.lu), go-live adds custom domain via StoreDomain (acme.lu). All routing handled by existing StoreContextMiddleware + Caddy wildcards. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9.1 KiB
9.1 KiB
Architecture Decision: Hosting Sites Leverage CMS + Store + StoreDomain
Decision
Hosted sites (POC and live) reuse the existing CMS module, Store entity, and StoreDomain routing — no separate site builder module.
Rationale
The CMS module already provides everything a hosted site needs:
- ContentPage — store-scoped pages with three-tier inheritance (platform defaults → store overrides)
- MediaFile — store-scoped media library
- StoreTheme — per-store colors, fonts, logo, layout, custom CSS
- Storefront rendering — Jinja2 templates that resolve store context and render CMS content
Building a parallel system would duplicate all of this.
How It Works
POC Phase (DRAFT → POC_READY → PROPOSAL_SENT)
HostedSite.create()creates a Store on thehostingplatform- Store inherits default CMS pages from the hosting platform (homepage, about, contact, etc.)
- Admin selects an industry template (e.g., "restaurant", "construction") which applies:
- Pre-built page sections (hero, services, gallery, testimonials, CTA)
- Industry-appropriate theme (colors, fonts, layout)
- Placeholder content that gets replaced with prospect data
- Admin customizes ContentPages + StoreTheme during POC phase
- POC preview accessible at subdomain:
acme.hostwizard.lu
Go Live (ACCEPTED → LIVE)
go_live(domain)callsstore_domain_service.add_domain()— already implemented- Custom domain
acme.lumaps to the Store viaStoreDomain StoreContextMiddlewareresolvesacme.lu→ Store → CMS content- Caddy + Cloudflare handle SSL and routing — already configured for wildcard subdomains
Content Flow
Prospect scanned (prospecting module)
↓ business_name, contacts, address, tech_profile
HostedSite created → Store created on hosting platform
↓
Industry template applied → ContentPages populated with prospect data
↓ homepage hero: "Acme Construction — Strasbourg"
↓ contact page: scraped email, phone, address
↓ theme: construction industry colors + layout
Admin refines content in CMS editor
↓
POC preview: acme.hostwizard.lu
↓
Client approves → go live: acme.lu
Industry Template System
What a Template Is
A template is NOT a separate rendering engine. It is a preset bundle that populates CMS entities for a new Store:
- ContentPages: pre-built page slugs with section structures (hero, services, gallery, etc.)
- StoreTheme: industry-appropriate colors, fonts, layout style
- Media placeholders: stock images appropriate to the industry
- Section blueprints: JSON structures for homepage sections
Template Registry
app/modules/hosting/templates_library/
├── manifest.json # Registry of all templates
├── restaurant/
│ ├── meta.json # Name, description, preview image, tags
│ ├── pages/ # ContentPage seed data (JSON per page)
│ │ ├── homepage.json # Sections: hero, menu-highlights, testimonials, reservation-cta
│ │ ├── about.json # Our story, team, values
│ │ ├── menu.json # Menu categories with placeholder items
│ │ └── contact.json # Map, hours, reservation form
│ └── theme.json # Colors, fonts, layout config
├── construction/
│ ├── meta.json
│ ├── pages/
│ │ ├── homepage.json # Sections: hero, services, projects-gallery, testimonials, cta
│ │ ├── services.json # Service cards (renovation, new build, etc.)
│ │ ├── projects.json # Portfolio gallery
│ │ └── contact.json # Quote request form, address, phone
│ └── theme.json
├── auto-parts/
│ ├── meta.json
│ ├── pages/
│ │ ├── homepage.json # Sections: hero, brands, categories, promotions
│ │ ├── catalog.json # Category grid
│ │ └── contact.json # Store locations, hours
│ └── theme.json
├── professional-services/ # Lawyers, accountants, consultants
│ ├── meta.json
│ ├── pages/
│ │ ├── homepage.json # Sections: hero, expertise, team, testimonials
│ │ ├── services.json
│ │ ├── team.json
│ │ └── contact.json
│ └── theme.json
└── generic/ # Fallback for any industry
├── meta.json
├── pages/
│ ├── homepage.json
│ ├── about.json
│ └── contact.json
└── theme.json
Template Meta Format
{
"id": "restaurant",
"name": "Restaurant & Dining",
"description": "Elegant template for restaurants, cafés, and bars",
"preview_image": "restaurant-preview.jpg",
"tags": ["food", "dining", "hospitality"],
"languages": ["en", "fr", "de"],
"pages": ["homepage", "about", "menu", "contact"],
"default_theme": {
"theme_name": "modern",
"colors": {
"primary": "#b45309",
"secondary": "#78350f",
"accent": "#f59e0b",
"background": "#fffbeb",
"text": "#1c1917"
},
"font_family_heading": "Playfair Display",
"font_family_body": "Inter",
"layout_style": "grid",
"header_style": "transparent"
}
}
Page Section Format (homepage.json example)
{
"slug": "homepage",
"title": "{{business_name}}",
"template": "full",
"sections": {
"hero": {
"type": "hero",
"headline": "{{business_name}}",
"subheadline": "Quality dining in {{city}}",
"cta_text": "Reserve a Table",
"cta_link": "/contact",
"background_image": "placeholder-restaurant-hero.jpg"
},
"features": {
"type": "features_grid",
"title": "Our Specialties",
"items": [
{"icon": "utensils", "title": "Fine Dining", "description": "..."},
{"icon": "wine-glass", "title": "Wine Selection", "description": "..."},
{"icon": "cake", "title": "Pastry", "description": "..."}
]
},
"testimonials": {
"type": "testimonials",
"title": "What Our Guests Say",
"items": []
},
"cta": {
"type": "cta_banner",
"headline": "Ready to visit?",
"cta_text": "Contact Us",
"cta_link": "/contact"
}
}
}
{{business_name}}, {{city}}, {{phone}}, {{email}} are replaced with prospect data at POC creation time.
What Needs to Be Built
Phase 1 — Template Infrastructure (in hosting module)
| Component | Purpose |
|---|---|
hosting/templates_library/ directory |
Template files (JSON) |
hosting/services/template_service.py |
Load manifest, list templates, validate |
hosting/services/poc_builder_service.py |
Apply template to Store: create ContentPages, set StoreTheme, replace placeholders with prospect data |
hosting/schemas/template.py |
TemplateListResponse, TemplateDetailResponse |
API: GET /admin/hosting/templates |
List available templates with previews |
API: POST /admin/hosting/poc/build |
Build POC: {prospect_id, template_id, merchant_id} |
Phase 2 — Template Content
Create 5 industry templates:
- Restaurant — hero, menu highlights, testimonials, reservation CTA
- Construction — hero, services, project gallery, quote CTA
- Auto Parts — hero, brand grid, product categories, store locator
- Professional Services — hero, expertise areas, team, case studies
- Generic — clean, minimal, works for any business
Each template needs:
- 3-4 page JSONs with sections
- Theme JSON (colors, fonts)
- Meta JSON (name, description, tags, preview)
- Placeholder images (can use free stock photos initially)
Phase 3 — Storefront Rendering Enhancement
The existing storefront templates render ContentPage.sections as HTML. Verify:
- All section types used by templates are supported by the storefront renderer
- Homepage sections (hero, features_grid, testimonials, cta_banner) render correctly
- Theme colors/fonts apply to the storefront
If new section types are needed (e.g., menu, project_gallery, team_grid), add them to the storefront section renderer.
What Already Exists (No Work Needed)
- Store creation with subdomain
- StoreDomain custom domain assignment + verification
- StoreContextMiddleware (subdomain + custom domain + path-based routing)
- CMS ContentPage three-tier hierarchy
- StoreTheme with colors, fonts, layout, custom CSS
- MediaFile upload and serving
- Storefront page rendering
- Caddy wildcard SSL for
*.hostwizard.lu - Cloudflare proxy + WAF for custom domains
go_live()already callsstore_domain_service.add_domain()
Relationship to Other Proposals
hosting-site-creation-fix.md: Must be implemented first — site creation needs merchant_id or prospect_id (no system merchant hack)security-audit-demo-poc-builder.mdPhase 4: This document replaces Phase 4 with a more detailed architecture. The POC builder is now "apply industry template to Store CMS" rather than a vague "build better site"