feat(tenancy): add merchant-level domain with store override
Merchants can now register domains (e.g., myloyaltyprogram.lu) that all their stores inherit. Individual stores can override with their own custom domain. Resolution priority: StoreDomain > MerchantDomain > subdomain. - Add MerchantDomain model, schema, service, and admin API endpoints - Add merchant domain fallback in platform and store context middleware - Add Merchant.primary_domain and Store.effective_domain properties - Add Alembic migration for merchant_domains table - Update loyalty user journey docs with subscription & domain setup flow - Add unit tests (50 passing) and integration tests (15 passing) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -329,6 +329,22 @@ class Store(Base, TimestampMixin):
|
||||
return domain.domain # Return the domain if it's primary and active
|
||||
return None
|
||||
|
||||
@property
|
||||
def effective_domain(self) -> str | None:
|
||||
"""
|
||||
Get effective domain: store override > merchant domain > subdomain fallback.
|
||||
|
||||
Domain Resolution Priority:
|
||||
1. Store-specific custom domain (StoreDomain) -> highest priority
|
||||
2. Merchant domain (MerchantDomain) -> inherited default
|
||||
3. Store subdomain ({store.subdomain}.{platform_domain}) -> fallback
|
||||
"""
|
||||
if self.primary_domain:
|
||||
return self.primary_domain
|
||||
if self.merchant and self.merchant.primary_domain:
|
||||
return self.merchant.primary_domain
|
||||
return f"{self.subdomain}.{settings.platform_domain}"
|
||||
|
||||
@property
|
||||
def all_domains(self):
|
||||
"""Get all active domains (subdomain + custom domains)."""
|
||||
|
||||
Reference in New Issue
Block a user