Multitenant implementation with custom Domain, theme per vendor

This commit is contained in:
2025-10-26 23:49:29 +01:00
parent c88775134d
commit 1e0cbf5927
24 changed files with 3470 additions and 624 deletions

View File

@@ -43,7 +43,7 @@ from .admin import (
BulkOperationException,
)
# Marketplace import jon exceptions
# Marketplace import job exceptions
from .marketplace_import_job import (
MarketplaceImportException,
ImportJobNotFoundException,
@@ -106,6 +106,18 @@ from .vendor_domain import (
UnauthorizedDomainAccessException,
)
# Vendor theme exceptions
from .vendor_theme import (
VendorThemeNotFoundException,
InvalidThemeDataException,
ThemePresetNotFoundException,
ThemeValidationException,
ThemePresetAlreadyAppliedException,
InvalidColorFormatException,
InvalidFontFamilyException,
ThemeOperationException,
)
# Customer exceptions
from .customer import (
CustomerNotFoundException,
@@ -235,6 +247,16 @@ __all__ = [
"MaxDomainsReachedException",
"UnauthorizedDomainAccessException",
# Vendor Theme
"VendorThemeNotFoundException",
"InvalidThemeDataException",
"ThemePresetNotFoundException",
"ThemeValidationException",
"ThemePresetAlreadyAppliedException",
"InvalidColorFormatException",
"InvalidFontFamilyException",
"ThemeOperationException",
# Product exceptions
"ProductNotFoundException",
"ProductAlreadyExistsException",
@@ -282,4 +304,4 @@ __all__ = [
"CannotModifySelfException",
"InvalidAdminActionException",
"BulkOperationException",
]
]

View File

@@ -0,0 +1,137 @@
# app/exceptions/vendor_theme.py
"""
Vendor theme management specific exceptions.
"""
from typing import Any, Dict, Optional
from .base import (
ResourceNotFoundException,
ConflictException,
ValidationException,
BusinessLogicException
)
class VendorThemeNotFoundException(ResourceNotFoundException):
"""Raised when a vendor theme is not found."""
def __init__(self, vendor_identifier: str):
super().__init__(
resource_type="VendorTheme",
identifier=vendor_identifier,
message=f"Theme for vendor '{vendor_identifier}' not found",
error_code="VENDOR_THEME_NOT_FOUND",
)
class InvalidThemeDataException(ValidationException):
"""Raised when theme data is invalid."""
def __init__(
self,
message: str = "Invalid theme data",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
):
super().__init__(
message=message,
field=field,
details=details,
)
self.error_code = "INVALID_THEME_DATA"
class ThemePresetNotFoundException(ResourceNotFoundException):
"""Raised when a theme preset is not found."""
def __init__(self, preset_name: str, available_presets: Optional[list] = None):
details = {"preset_name": preset_name}
if available_presets:
details["available_presets"] = available_presets
super().__init__(
resource_type="ThemePreset",
identifier=preset_name,
message=f"Theme preset '{preset_name}' not found",
error_code="THEME_PRESET_NOT_FOUND",
)
self.details = details
class ThemeValidationException(ValidationException):
"""Raised when theme validation fails."""
def __init__(
self,
message: str = "Theme validation failed",
field: Optional[str] = None,
validation_errors: Optional[Dict[str, str]] = None,
):
details = {}
if validation_errors:
details["validation_errors"] = validation_errors
super().__init__(
message=message,
field=field,
details=details,
)
self.error_code = "THEME_VALIDATION_FAILED"
class ThemePresetAlreadyAppliedException(BusinessLogicException):
"""Raised when trying to apply the same preset that's already active."""
def __init__(self, preset_name: str, vendor_code: str):
super().__init__(
message=f"Preset '{preset_name}' is already applied to vendor '{vendor_code}'",
error_code="THEME_PRESET_ALREADY_APPLIED",
details={
"preset_name": preset_name,
"vendor_code": vendor_code
},
)
class InvalidColorFormatException(ValidationException):
"""Raised when color format is invalid."""
def __init__(self, color_value: str, field: str):
super().__init__(
message=f"Invalid color format: {color_value}",
field=field,
details={"color_value": color_value},
)
self.error_code = "INVALID_COLOR_FORMAT"
class InvalidFontFamilyException(ValidationException):
"""Raised when font family is invalid."""
def __init__(self, font_value: str, field: str):
super().__init__(
message=f"Invalid font family: {font_value}",
field=field,
details={"font_value": font_value},
)
self.error_code = "INVALID_FONT_FAMILY"
class ThemeOperationException(BusinessLogicException):
"""Raised when theme operation fails."""
def __init__(
self,
operation: str,
vendor_code: str,
reason: str
):
super().__init__(
message=f"Theme operation '{operation}' failed for vendor '{vendor_code}': {reason}",
error_code="THEME_OPERATION_FAILED",
details={
"operation": operation,
"vendor_code": vendor_code,
"reason": reason
},
)