fix(hosting): POC builder works with existing sites

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>
This commit is contained in:
2026-04-03 18:10:39 +02:00
parent 2a49e3d30f
commit 83af32eb88
3 changed files with 21 additions and 12 deletions

View File

@@ -75,6 +75,7 @@ class BuildPocRequest(BaseModel):
prospect_id: int
template_id: str
merchant_id: int | None = None
site_id: int | None = None # If set, populate existing site instead of creating new one
class BuildPocResponse(BaseModel):
@@ -100,6 +101,7 @@ def build_poc(
prospect_id=data.prospect_id,
template_id=data.template_id,
merchant_id=data.merchant_id,
site_id=data.site_id,
)
db.commit()
return BuildPocResponse(**result)

View File

@@ -35,9 +35,13 @@ class PocBuilderService:
prospect_id: int,
template_id: str,
merchant_id: int | None = None,
site_id: int | None = None,
) -> dict:
"""Build a complete POC site from prospect data and a template.
If site_id is given, populates the existing site's store with CMS
content. Otherwise creates a new HostedSite + Store.
Returns dict with hosted_site, store, pages_created, theme_applied.
"""
from app.modules.prospecting.models import Prospect
@@ -57,18 +61,20 @@ class PocBuilderService:
# 3. Build placeholder context from prospect data
context = self._build_context(prospect)
# 4. Create HostedSite + Store
site_data = {
"business_name": context["business_name"],
"domain_name": prospect.domain_name, # used for clean subdomain slug
"prospect_id": prospect_id,
"contact_email": context.get("email"),
"contact_phone": context.get("phone"),
}
if merchant_id:
site_data["merchant_id"] = merchant_id
site = hosted_site_service.create(db, site_data)
# 4. Use existing site or create new one
if site_id:
site = hosted_site_service.get_by_id(db, site_id)
else:
site_data = {
"business_name": context["business_name"],
"domain_name": prospect.domain_name,
"prospect_id": prospect_id,
"contact_email": context.get("email"),
"contact_phone": context.get("phone"),
}
if merchant_id:
site_data["merchant_id"] = merchant_id
site = hosted_site_service.create(db, site_data)
# 5. Get the hosting platform_id from the store
from app.modules.tenancy.models import StorePlatform

View File

@@ -351,6 +351,7 @@ function hostingSiteDetail(siteId) {
var result = await apiClient.post('/admin/hosting/sites/poc/build', {
prospect_id: this.site.prospect_id,
template_id: this.selectedTemplate,
site_id: this.site.id,
});
this.pocResult = 'POC built! ' + result.pages_created + ' pages created.';
Utils.showToast('POC built successfully', 'success');