The Build POC button on site detail now passes site_id to the POC
builder, which populates the existing site's store with CMS content
instead of trying to create a new site (which failed with duplicate
slug error).
- poc_builder_service.build_poc() accepts optional site_id param
- If site_id given: uses existing site, skips hosted_site_service.create()
- If not given: creates new site (standalone POC build)
- API schema: added site_id to BuildPocRequest
- Frontend: passes this.site.id in the build request
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The POC viewer was loading the storefront in an iframe, which hit the
StorefrontAccessMiddleware subscription check (POC sites don't have
subscriptions yet). Fixed by rendering CMS sections directly in the
preview template:
- Load ContentPages and StoreTheme from DB
- Render hero, features, testimonials, CTA sections inline
- Apply template colors/fonts via Tailwind CSS config
- HostWizard preview banner with nav links
- Footer with contact info
- No iframe, no subscription check needed
Also fixed Jinja2 dict.items collision (dict.items is the method,
not the 'items' key — use dict.get('items') instead).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Schema: add merchant_id/prospect_id with model_validator requiring
at least one. Remove from-prospect endpoint (unified into POST /sites)
- Service: rewrite create() — if merchant_id use it directly, if
prospect_id auto-create merchant from prospect data. Remove system
merchant hack entirely. Extract _create_merchant_from_prospect helper.
- Simplify accept_proposal() — merchant already exists at creation,
only creates subscription and marks prospect converted
- Tests: update all create calls with merchant_id, replace from-prospect
tests with prospect_id + validation tests
Closes docs/proposals/hosting-site-creation-fix.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 55 unit tests for hosting module (hosted site service, client
service service, stats service) with full fixture setup
- Fix table_empty_state macro: add x_message param for dynamic Alpine.js
expressions rendered via x-text instead of server-side Jinja
- Fix hosting templates (sites, clients) using message= with Alpine
expressions that rendered as literal text
- Fix prospecting templates (leads, scan-jobs, prospects) using
nonexistent subtitle= param, migrated to x_message=
- Align hosting and prospecting admin templates with shared design system
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add sections covering CMS locale file structure, translated template
inventory, TranslatableText pattern for sections, and the new
title_translations/content_translations model API with migration cms_002.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>