Files
orion/docs/proposals/hosting-cascade-delete.md
Samir Boulahtit dd09bcaeec
All checks were successful
CI / ruff (push) Successful in 33s
CI / pytest (push) Successful in 2h46m24s
CI / validate (push) Successful in 30s
CI / dependency-scanning (push) Successful in 31s
CI / docs (push) Successful in 49s
CI / deploy (push) Successful in 2m55s
docs: add proposal for HostedSite → Store cascade delete
Deleting a HostedSite leaves the Store orphaned, blocking subdomain
reuse. Proposal: cascade delete the Store when deleting the site.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:31:31 +02:00

2.1 KiB

Hosting: Cascade Delete HostedSite → Store

Problem

Deleting a HostedSite leaves the associated Store orphaned in the database. The Store's subdomain remains taken, so creating a new site with the same prospect/business fails with "slug already exists".

Root Cause

  • hosted_site_service.delete() does a hard delete on the HostedSite only
  • The Store (created by hosted_site_service.create()) is not deleted
  • stores.subdomain has a partial unique index (WHERE deleted_at IS NULL)
  • The orphaned Store is still active → subdomain collision on re-create

Recommendation

When deleting a HostedSite, also delete the associated Store:

def delete(self, db: Session, site_id: int) -> bool:
    site = self.get_by_id(db, site_id)
    store = site.store
    db.delete(site)
    if store:
        # Soft-delete or hard-delete the store created for this site
        soft_delete(store)  # or db.delete(store)
    db.flush()

Considerations

  • Soft vs hard delete: If using soft-delete, the subdomain gets freed (partial unique index filters deleted_at IS NULL). If hard-deleting, cascade will also remove StorePlatform, ContentPages, StoreTheme, etc.
  • CMS content: Deleting the Store cascades to ContentPages (created by POC builder) — this is desired since the POC content belongs to that store
  • Merchant: The merchant created from the prospect should NOT be deleted — it may be used by other stores or relinked later
  • Safety: Only delete stores that were created by the hosting module (check if store has a HostedSite backref). Don't delete stores that existed independently.

Files to modify

File Change
hosting/services/hosted_site_service.py Update delete() to also soft-delete/hard-delete the associated Store
hosting/tests/unit/test_hosted_site_service.py Update delete test to verify Store is also deleted

Quick workaround (for now)

Manually delete the orphaned store from the DB:

DELETE FROM stores WHERE subdomain = 'batirenovation-strasbourg' AND id NOT IN (SELECT store_id FROM hosted_sites);