refactor: modernize code quality tooling with Ruff

- Replace black, isort, and flake8 with Ruff (all-in-one linter and formatter)
- Add comprehensive pyproject.toml configuration
- Simplify Makefile code quality targets
- Configure exclusions for venv/.venv in pyproject.toml
- Auto-fix 1,359 linting issues across codebase

Benefits:
- Much faster builds (Ruff is written in Rust)
- Single tool replaces multiple tools
- More comprehensive rule set (UP, B, C4, SIM, PIE, RET, Q)
- All configuration centralized in pyproject.toml
- Better import sorting and formatting consistency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-28 19:37:38 +01:00
parent 21c13ca39b
commit 238c1ec9b8
169 changed files with 2183 additions and 1784 deletions

View File

@@ -7,108 +7,178 @@ messages, and HTTP status mappings.
"""
# Admin exceptions
from .admin import (AdminOperationException, BulkOperationException,
CannotModifyAdminException, CannotModifySelfException,
ConfirmationRequiredException, InvalidAdminActionException,
UserNotFoundException, UserStatusChangeException,
VendorVerificationException)
from .admin import (
AdminOperationException,
BulkOperationException,
CannotModifyAdminException,
CannotModifySelfException,
ConfirmationRequiredException,
InvalidAdminActionException,
UserNotFoundException,
UserStatusChangeException,
VendorVerificationException,
)
# Authentication exceptions
from .auth import (AdminRequiredException, InsufficientPermissionsException,
InvalidCredentialsException, InvalidTokenException,
TokenExpiredException, UserAlreadyExistsException,
UserNotActiveException)
from .auth import (
AdminRequiredException,
InsufficientPermissionsException,
InvalidCredentialsException,
InvalidTokenException,
TokenExpiredException,
UserAlreadyExistsException,
UserNotActiveException,
)
# Base exceptions
from .base import (AuthenticationException, AuthorizationException,
BusinessLogicException, ConflictException,
ExternalServiceException, RateLimitException,
ResourceNotFoundException, ServiceUnavailableException,
ValidationException, WizamartException)
from .base import (
AuthenticationException,
AuthorizationException,
BusinessLogicException,
ConflictException,
ExternalServiceException,
RateLimitException,
ResourceNotFoundException,
ServiceUnavailableException,
ValidationException,
WizamartException,
)
# Cart exceptions
from .cart import (CartItemNotFoundException, CartValidationException,
EmptyCartException, InsufficientInventoryForCartException,
InvalidCartQuantityException,
ProductNotAvailableForCartException)
from .cart import (
CartItemNotFoundException,
CartValidationException,
EmptyCartException,
InsufficientInventoryForCartException,
InvalidCartQuantityException,
ProductNotAvailableForCartException,
)
# Customer exceptions
from .customer import (CustomerAlreadyExistsException,
CustomerAuthorizationException,
CustomerNotActiveException, CustomerNotFoundException,
CustomerValidationException,
DuplicateCustomerEmailException,
InvalidCustomerCredentialsException)
from .customer import (
CustomerAlreadyExistsException,
CustomerAuthorizationException,
CustomerNotActiveException,
CustomerNotFoundException,
CustomerValidationException,
DuplicateCustomerEmailException,
InvalidCustomerCredentialsException,
)
# Inventory exceptions
from .inventory import (InsufficientInventoryException,
InvalidInventoryOperationException,
InvalidQuantityException, InventoryNotFoundException,
InventoryValidationException,
LocationNotFoundException, NegativeInventoryException)
from .inventory import (
InsufficientInventoryException,
InvalidInventoryOperationException,
InvalidQuantityException,
InventoryNotFoundException,
InventoryValidationException,
LocationNotFoundException,
NegativeInventoryException,
)
# Marketplace import job exceptions
from .marketplace_import_job import (ImportJobAlreadyProcessingException,
ImportJobCannotBeCancelledException,
ImportJobCannotBeDeletedException,
ImportJobNotFoundException,
ImportJobNotOwnedException,
ImportRateLimitException,
InvalidImportDataException,
InvalidMarketplaceException,
MarketplaceConnectionException,
MarketplaceDataParsingException,
MarketplaceImportException)
from .marketplace_import_job import (
ImportJobAlreadyProcessingException,
ImportJobCannotBeCancelledException,
ImportJobCannotBeDeletedException,
ImportJobNotFoundException,
ImportJobNotOwnedException,
ImportRateLimitException,
InvalidImportDataException,
InvalidMarketplaceException,
MarketplaceConnectionException,
MarketplaceDataParsingException,
MarketplaceImportException,
)
# Marketplace product exceptions
from .marketplace_product import (InvalidGTINException,
InvalidMarketplaceProductDataException,
MarketplaceProductAlreadyExistsException,
MarketplaceProductCSVImportException,
MarketplaceProductNotFoundException,
MarketplaceProductValidationException)
from .marketplace_product import (
InvalidGTINException,
InvalidMarketplaceProductDataException,
MarketplaceProductAlreadyExistsException,
MarketplaceProductCSVImportException,
MarketplaceProductNotFoundException,
MarketplaceProductValidationException,
)
# Order exceptions
from .order import (InvalidOrderStatusException, OrderAlreadyExistsException,
OrderCannotBeCancelledException, OrderNotFoundException,
OrderValidationException)
from .order import (
InvalidOrderStatusException,
OrderAlreadyExistsException,
OrderCannotBeCancelledException,
OrderNotFoundException,
OrderValidationException,
)
# Product exceptions
from .product import (CannotDeleteProductWithInventoryException,
CannotDeleteProductWithOrdersException,
InvalidProductDataException,
ProductAlreadyExistsException, ProductNotActiveException,
ProductNotFoundException, ProductNotInCatalogException,
ProductValidationException)
from .product import (
CannotDeleteProductWithInventoryException,
CannotDeleteProductWithOrdersException,
InvalidProductDataException,
ProductAlreadyExistsException,
ProductNotActiveException,
ProductNotFoundException,
ProductNotInCatalogException,
ProductValidationException,
)
# Team exceptions
from .team import (CannotModifyOwnRoleException, CannotRemoveOwnerException,
InsufficientTeamPermissionsException,
InvalidInvitationDataException,
InvalidInvitationTokenException, InvalidRoleException,
MaxTeamMembersReachedException, RoleNotFoundException,
TeamInvitationAlreadyAcceptedException,
TeamInvitationExpiredException,
TeamInvitationNotFoundException,
TeamMemberAlreadyExistsException,
TeamMemberNotFoundException, TeamValidationException,
UnauthorizedTeamActionException)
from .team import (
CannotModifyOwnRoleException,
CannotRemoveOwnerException,
InsufficientTeamPermissionsException,
InvalidInvitationDataException,
InvalidInvitationTokenException,
InvalidRoleException,
MaxTeamMembersReachedException,
RoleNotFoundException,
TeamInvitationAlreadyAcceptedException,
TeamInvitationExpiredException,
TeamInvitationNotFoundException,
TeamMemberAlreadyExistsException,
TeamMemberNotFoundException,
TeamValidationException,
UnauthorizedTeamActionException,
)
# Vendor exceptions
from .vendor import (InvalidVendorDataException, MaxVendorsReachedException,
UnauthorizedVendorAccessException,
VendorAlreadyExistsException, VendorNotActiveException,
VendorNotFoundException, VendorNotVerifiedException,
VendorValidationException)
from .vendor import (
InvalidVendorDataException,
MaxVendorsReachedException,
UnauthorizedVendorAccessException,
VendorAlreadyExistsException,
VendorNotActiveException,
VendorNotFoundException,
VendorNotVerifiedException,
VendorValidationException,
)
# Vendor domain exceptions
from .vendor_domain import (DNSVerificationException,
DomainAlreadyVerifiedException,
DomainNotVerifiedException,
DomainVerificationFailedException,
InvalidDomainFormatException,
MaxDomainsReachedException,
MultiplePrimaryDomainsException,
ReservedDomainException,
UnauthorizedDomainAccessException,
VendorDomainAlreadyExistsException,
VendorDomainNotFoundException)
from .vendor_domain import (
DNSVerificationException,
DomainAlreadyVerifiedException,
DomainNotVerifiedException,
DomainVerificationFailedException,
InvalidDomainFormatException,
MaxDomainsReachedException,
MultiplePrimaryDomainsException,
ReservedDomainException,
UnauthorizedDomainAccessException,
VendorDomainAlreadyExistsException,
VendorDomainNotFoundException,
)
# Vendor theme exceptions
from .vendor_theme import (InvalidColorFormatException,
InvalidFontFamilyException,
InvalidThemeDataException, ThemeOperationException,
ThemePresetAlreadyAppliedException,
ThemePresetNotFoundException,
ThemeValidationException,
VendorThemeNotFoundException)
from .vendor_theme import (
InvalidColorFormatException,
InvalidFontFamilyException,
InvalidThemeDataException,
ThemeOperationException,
ThemePresetAlreadyAppliedException,
ThemePresetNotFoundException,
ThemeValidationException,
VendorThemeNotFoundException,
)
__all__ = [
# Base exceptions

View File

@@ -3,10 +3,14 @@
Admin operations specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (AuthorizationException, BusinessLogicException,
ResourceNotFoundException, ValidationException)
from .base import (
AuthorizationException,
BusinessLogicException,
ResourceNotFoundException,
ValidationException,
)
class UserNotFoundException(ResourceNotFoundException):
@@ -36,7 +40,7 @@ class UserStatusChangeException(BusinessLogicException):
user_id: int,
current_status: str,
attempted_action: str,
reason: Optional[str] = None,
reason: str | None = None,
):
message = f"Cannot {attempted_action} user {user_id} (current status: {current_status})"
if reason:
@@ -61,7 +65,7 @@ class ShopVerificationException(BusinessLogicException):
self,
shop_id: int,
reason: str,
current_verification_status: Optional[bool] = None,
current_verification_status: bool | None = None,
):
details = {
"shop_id": shop_id,
@@ -85,8 +89,8 @@ class AdminOperationException(BusinessLogicException):
self,
operation: str,
reason: str,
target_type: Optional[str] = None,
target_id: Optional[str] = None,
target_type: str | None = None,
target_id: str | None = None,
):
message = f"Admin operation '{operation}' failed: {reason}"
@@ -142,7 +146,7 @@ class InvalidAdminActionException(ValidationException):
self,
action: str,
reason: str,
valid_actions: Optional[list] = None,
valid_actions: list | None = None,
):
details = {
"action": action,
@@ -167,7 +171,7 @@ class BulkOperationException(BusinessLogicException):
operation: str,
total_items: int,
failed_items: int,
errors: Optional[Dict[str, Any]] = None,
errors: dict[str, Any] | None = None,
):
message = f"Bulk {operation} completed with errors: {failed_items}/{total_items} failed"
@@ -194,7 +198,7 @@ class ConfirmationRequiredException(BusinessLogicException):
def __init__(
self,
operation: str,
message: Optional[str] = None,
message: str | None = None,
confirmation_param: str = "confirm",
):
if not message:
@@ -217,7 +221,7 @@ class VendorVerificationException(BusinessLogicException):
self,
vendor_id: int,
reason: str,
current_verification_status: Optional[bool] = None,
current_verification_status: bool | None = None,
):
details = {
"vendor_id": vendor_id,

View File

@@ -3,10 +3,8 @@
Authentication and authorization specific exceptions.
"""
from typing import Optional
from .base import (AuthenticationException, AuthorizationException,
ConflictException)
from .base import AuthenticationException, AuthorizationException, ConflictException
class InvalidCredentialsException(AuthenticationException):
@@ -45,7 +43,7 @@ class InsufficientPermissionsException(AuthorizationException):
def __init__(
self,
message: str = "Insufficient permissions for this action",
required_permission: Optional[str] = None,
required_permission: str | None = None,
):
details = {}
if required_permission:
@@ -84,7 +82,7 @@ class UserAlreadyExistsException(ConflictException):
def __init__(
self,
message: str = "User already exists",
field: Optional[str] = None,
field: str | None = None,
):
details = {}
if field:

View File

@@ -8,7 +8,7 @@ This module provides classes and functions for:
- Standardized error response structure
"""
from typing import Any, Dict, Optional
from typing import Any
class WizamartException(Exception):
@@ -19,7 +19,7 @@ class WizamartException(Exception):
message: str,
error_code: str,
status_code: int = 400,
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
self.message = message
self.error_code = error_code
@@ -27,7 +27,7 @@ class WizamartException(Exception):
self.details = details or {}
super().__init__(self.message)
def to_dict(self) -> Dict[str, Any]:
def to_dict(self) -> dict[str, Any]:
"""Convert exception to dictionary for JSON response."""
result = {
"error_code": self.error_code,
@@ -45,8 +45,8 @@ class ValidationException(WizamartException):
def __init__(
self,
message: str,
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
validation_details = details or {}
if field:
@@ -67,7 +67,7 @@ class AuthenticationException(WizamartException):
self,
message: str = "Authentication failed",
error_code: str = "AUTHENTICATION_FAILED",
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -84,7 +84,7 @@ class AuthorizationException(WizamartException):
self,
message: str = "Access denied",
error_code: str = "AUTHORIZATION_FAILED",
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -101,8 +101,8 @@ class ResourceNotFoundException(WizamartException):
self,
resource_type: str,
identifier: str,
message: Optional[str] = None,
error_code: Optional[str] = None,
message: str | None = None,
error_code: str | None = None,
):
if not message:
message = f"{resource_type} with identifier '{identifier}' not found"
@@ -127,7 +127,7 @@ class ConflictException(WizamartException):
self,
message: str,
error_code: str = "RESOURCE_CONFLICT",
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -144,7 +144,7 @@ class BusinessLogicException(WizamartException):
self,
message: str,
error_code: str,
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -162,7 +162,7 @@ class ExternalServiceException(WizamartException):
message: str,
service_name: str,
error_code: str = "EXTERNAL_SERVICE_ERROR",
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
service_details = details or {}
service_details["service_name"] = service_name
@@ -181,8 +181,8 @@ class RateLimitException(WizamartException):
def __init__(
self,
message: str = "Rate limit exceeded",
retry_after: Optional[int] = None,
details: Optional[Dict[str, Any]] = None,
retry_after: int | None = None,
details: dict[str, Any] | None = None,
):
rate_limit_details = details or {}
if retry_after:

View File

@@ -3,10 +3,8 @@
Shopping cart specific exceptions.
"""
from typing import Optional
from .base import (BusinessLogicException, ResourceNotFoundException,
ValidationException)
from .base import BusinessLogicException, ResourceNotFoundException, ValidationException
class CartItemNotFoundException(ResourceNotFoundException):
@@ -36,8 +34,8 @@ class CartValidationException(ValidationException):
def __init__(
self,
message: str = "Cart validation failed",
field: Optional[str] = None,
details: Optional[dict] = None,
field: str | None = None,
details: dict | None = None,
):
super().__init__(
message=message,
@@ -75,7 +73,7 @@ class InvalidCartQuantityException(ValidationException):
"""Raised when cart quantity is invalid."""
def __init__(
self, quantity: int, min_quantity: int = 1, max_quantity: Optional[int] = None
self, quantity: int, min_quantity: int = 1, max_quantity: int | None = None
):
if quantity < min_quantity:
message = f"Quantity must be at least {min_quantity}"

View File

@@ -3,11 +3,15 @@
Customer management specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (AuthenticationException, BusinessLogicException,
ConflictException, ResourceNotFoundException,
ValidationException)
from .base import (
AuthenticationException,
BusinessLogicException,
ConflictException,
ResourceNotFoundException,
ValidationException,
)
class CustomerNotFoundException(ResourceNotFoundException):
@@ -71,8 +75,8 @@ class CustomerValidationException(ValidationException):
def __init__(
self,
message: str = "Customer validation failed",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
super().__init__(message=message, field=field, details=details)
self.error_code = "CUSTOMER_VALIDATION_FAILED"

View File

@@ -5,9 +5,10 @@ Error Page Renderer
Renders context-aware error pages using Jinja2 templates.
Handles fallback logic and context-specific customization.
"""
import logging
from pathlib import Path
from typing import Any, Dict, Optional
from typing import Any
from fastapi import Request
from fastapi.responses import HTMLResponse
@@ -60,7 +61,7 @@ class ErrorPageRenderer:
status_code: int,
error_code: str,
message: str,
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
show_debug: bool = False,
) -> HTMLResponse:
"""
@@ -190,9 +191,9 @@ class ErrorPageRenderer:
status_code: int,
error_code: str,
message: str,
details: Optional[Dict[str, Any]],
details: dict[str, Any] | None,
show_debug: bool,
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""Prepare data dictionary for error template."""
# Get friendly status name
status_name = ErrorPageRenderer.STATUS_CODE_NAMES.get(
@@ -229,7 +230,7 @@ class ErrorPageRenderer:
@staticmethod
def _get_context_data(
request: Request, context_type: RequestContext
) -> Dict[str, Any]:
) -> dict[str, Any]:
"""Get context-specific data for error templates."""
data = {}

View File

@@ -11,7 +11,6 @@ This module provides classes and functions for:
"""
import logging
from typing import Union
from fastapi import HTTPException, Request
from fastapi.exceptions import RequestValidationError
@@ -280,7 +279,7 @@ def setup_exception_handlers(app):
request=request,
status_code=404,
error_code="ENDPOINT_NOT_FOUND",
message=f"The page you're looking for doesn't exist or has been moved.",
message="The page you're looking for doesn't exist or has been moved.",
details={"path": request.url.path},
show_debug=True,
)
@@ -364,10 +363,10 @@ def _redirect_to_login(request: Request) -> RedirectResponse:
if context_type == RequestContext.ADMIN:
logger.debug("Redirecting to /admin/login")
return RedirectResponse(url="/admin/login", status_code=302)
elif context_type == RequestContext.VENDOR_DASHBOARD:
if context_type == RequestContext.VENDOR_DASHBOARD:
logger.debug("Redirecting to /vendor/login")
return RedirectResponse(url="/vendor/login", status_code=302)
elif context_type == RequestContext.SHOP:
if context_type == RequestContext.SHOP:
# For shop context, redirect to shop login (customer login)
# Calculate base_url for proper routing (supports domain, subdomain, and path-based access)
vendor = getattr(request.state, "vendor", None)
@@ -390,10 +389,9 @@ def _redirect_to_login(request: Request) -> RedirectResponse:
login_url = f"{base_url}shop/account/login"
logger.debug(f"Redirecting to {login_url}")
return RedirectResponse(url=login_url, status_code=302)
else:
# Fallback to root for unknown contexts
logger.debug("Unknown context, redirecting to /")
return RedirectResponse(url="/", status_code=302)
# Fallback to root for unknown contexts
logger.debug("Unknown context, redirecting to /")
return RedirectResponse(url="/", status_code=302)
# Utility functions for common exception scenarios

View File

@@ -3,10 +3,9 @@
Inventory management specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (BusinessLogicException, ResourceNotFoundException,
ValidationException)
from .base import BusinessLogicException, ResourceNotFoundException, ValidationException
class InventoryNotFoundException(ResourceNotFoundException):
@@ -58,8 +57,8 @@ class InvalidInventoryOperationException(ValidationException):
def __init__(
self,
message: str,
operation: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
operation: str | None = None,
details: dict[str, Any] | None = None,
):
if not details:
details = {}
@@ -80,8 +79,8 @@ class InventoryValidationException(ValidationException):
def __init__(
self,
message: str = "Inventory validation failed",
field: Optional[str] = None,
validation_errors: Optional[Dict[str, str]] = None,
field: str | None = None,
validation_errors: dict[str, str] | None = None,
):
details = {}
if validation_errors:

View File

@@ -3,11 +3,15 @@
Marketplace import specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (AuthorizationException, BusinessLogicException,
ExternalServiceException, ResourceNotFoundException,
ValidationException)
from .base import (
AuthorizationException,
BusinessLogicException,
ExternalServiceException,
ResourceNotFoundException,
ValidationException,
)
class MarketplaceImportException(BusinessLogicException):
@@ -17,8 +21,8 @@ class MarketplaceImportException(BusinessLogicException):
self,
message: str,
error_code: str = "MARKETPLACE_IMPORT_ERROR",
marketplace: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
marketplace: str | None = None,
details: dict[str, Any] | None = None,
):
if not details:
details = {}
@@ -48,7 +52,7 @@ class ImportJobNotFoundException(ResourceNotFoundException):
class ImportJobNotOwnedException(AuthorizationException):
"""Raised when user tries to access import job they don't own."""
def __init__(self, job_id: int, user_id: Optional[int] = None):
def __init__(self, job_id: int, user_id: int | None = None):
details = {"job_id": job_id}
if user_id:
details["user_id"] = user_id
@@ -66,9 +70,9 @@ class InvalidImportDataException(ValidationException):
def __init__(
self,
message: str = "Invalid import data",
field: Optional[str] = None,
row_number: Optional[int] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
row_number: int | None = None,
details: dict[str, Any] | None = None,
):
if not details:
details = {}
@@ -132,7 +136,7 @@ class MarketplaceDataParsingException(ValidationException):
self,
marketplace: str,
message: str = "Failed to parse marketplace data",
details: Optional[Dict[str, Any]] = None,
details: dict[str, Any] | None = None,
):
if not details:
details = {}
@@ -152,7 +156,7 @@ class ImportRateLimitException(BusinessLogicException):
self,
max_imports: int,
time_window: str,
retry_after: Optional[int] = None,
retry_after: int | None = None,
):
details = {
"max_imports": max_imports,
@@ -172,7 +176,7 @@ class ImportRateLimitException(BusinessLogicException):
class InvalidMarketplaceException(ValidationException):
"""Raised when marketplace is not supported."""
def __init__(self, marketplace: str, supported_marketplaces: Optional[list] = None):
def __init__(self, marketplace: str, supported_marketplaces: list | None = None):
details = {"marketplace": marketplace}
if supported_marketplaces:
details["supported_marketplaces"] = supported_marketplaces

View File

@@ -3,10 +3,14 @@
MarketplaceProduct management specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (BusinessLogicException, ConflictException,
ResourceNotFoundException, ValidationException)
from .base import (
BusinessLogicException,
ConflictException,
ResourceNotFoundException,
ValidationException,
)
class MarketplaceProductNotFoundException(ResourceNotFoundException):
@@ -38,8 +42,8 @@ class InvalidMarketplaceProductDataException(ValidationException):
def __init__(
self,
message: str = "Invalid product data",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -55,8 +59,8 @@ class MarketplaceProductValidationException(ValidationException):
def __init__(
self,
message: str,
field: Optional[str] = None,
validation_errors: Optional[Dict[str, str]] = None,
field: str | None = None,
validation_errors: dict[str, str] | None = None,
):
details = {}
if validation_errors:
@@ -88,8 +92,8 @@ class MarketplaceProductCSVImportException(BusinessLogicException):
def __init__(
self,
message: str = "MarketplaceProduct CSV import failed",
row_number: Optional[int] = None,
errors: Optional[Dict[str, Any]] = None,
row_number: int | None = None,
errors: dict[str, Any] | None = None,
):
details = {}
if row_number:

View File

@@ -3,10 +3,8 @@
Order management specific exceptions.
"""
from typing import Optional
from .base import (BusinessLogicException, ResourceNotFoundException,
ValidationException)
from .base import BusinessLogicException, ResourceNotFoundException, ValidationException
class OrderNotFoundException(ResourceNotFoundException):
@@ -35,7 +33,7 @@ class OrderAlreadyExistsException(ValidationException):
class OrderValidationException(ValidationException):
"""Raised when order data validation fails."""
def __init__(self, message: str, details: Optional[dict] = None):
def __init__(self, message: str, details: dict | None = None):
super().__init__(
message=message, error_code="ORDER_VALIDATION_FAILED", details=details
)

View File

@@ -3,16 +3,19 @@
Product (vendor catalog) specific exceptions.
"""
from typing import Optional
from .base import (BusinessLogicException, ConflictException,
ResourceNotFoundException, ValidationException)
from .base import (
BusinessLogicException,
ConflictException,
ResourceNotFoundException,
ValidationException,
)
class ProductNotFoundException(ResourceNotFoundException):
"""Raised when a product is not found in vendor catalog."""
def __init__(self, product_id: int, vendor_id: Optional[int] = None):
def __init__(self, product_id: int, vendor_id: int | None = None):
details = {"product_id": product_id}
if vendor_id:
details["vendor_id"] = vendor_id
@@ -79,8 +82,8 @@ class InvalidProductDataException(ValidationException):
def __init__(
self,
message: str = "Invalid product data",
field: Optional[str] = None,
details: Optional[dict] = None,
field: str | None = None,
details: dict | None = None,
):
super().__init__(
message=message,
@@ -96,8 +99,8 @@ class ProductValidationException(ValidationException):
def __init__(
self,
message: str = "Product validation failed",
field: Optional[str] = None,
validation_errors: Optional[dict] = None,
field: str | None = None,
validation_errors: dict | None = None,
):
details = {}
if validation_errors:

View File

@@ -3,17 +3,21 @@
Team management specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (AuthorizationException, BusinessLogicException,
ConflictException, ResourceNotFoundException,
ValidationException)
from .base import (
AuthorizationException,
BusinessLogicException,
ConflictException,
ResourceNotFoundException,
ValidationException,
)
class TeamMemberNotFoundException(ResourceNotFoundException):
"""Raised when a team member is not found."""
def __init__(self, user_id: int, vendor_id: Optional[int] = None):
def __init__(self, user_id: int, vendor_id: int | None = None):
details = {"user_id": user_id}
if vendor_id:
details["vendor_id"] = vendor_id
@@ -63,7 +67,7 @@ class TeamInvitationExpiredException(BusinessLogicException):
def __init__(self, invitation_token: str):
super().__init__(
message=f"Team invitation has expired",
message="Team invitation has expired",
error_code="TEAM_INVITATION_EXPIRED",
details={"invitation_token": invitation_token},
)
@@ -86,8 +90,8 @@ class UnauthorizedTeamActionException(AuthorizationException):
def __init__(
self,
action: str,
user_id: Optional[int] = None,
required_permission: Optional[str] = None,
user_id: int | None = None,
required_permission: str | None = None,
):
details = {"action": action}
if user_id:
@@ -130,7 +134,7 @@ class CannotModifyOwnRoleException(BusinessLogicException):
class RoleNotFoundException(ResourceNotFoundException):
"""Raised when a role is not found."""
def __init__(self, role_id: int, vendor_id: Optional[int] = None):
def __init__(self, role_id: int, vendor_id: int | None = None):
details = {"role_id": role_id}
if vendor_id:
details["vendor_id"] = vendor_id
@@ -153,8 +157,8 @@ class InvalidRoleException(ValidationException):
def __init__(
self,
message: str = "Invalid role data",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -170,8 +174,8 @@ class InsufficientTeamPermissionsException(AuthorizationException):
def __init__(
self,
required_permission: str,
user_id: Optional[int] = None,
action: Optional[str] = None,
user_id: int | None = None,
action: str | None = None,
):
details = {"required_permission": required_permission}
if user_id:
@@ -208,8 +212,8 @@ class TeamValidationException(ValidationException):
def __init__(
self,
message: str = "Team operation validation failed",
field: Optional[str] = None,
validation_errors: Optional[Dict[str, str]] = None,
field: str | None = None,
validation_errors: dict[str, str] | None = None,
):
details = {}
if validation_errors:
@@ -229,8 +233,8 @@ class InvalidInvitationDataException(ValidationException):
def __init__(
self,
message: str = "Invalid invitation data",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -255,7 +259,7 @@ class InvalidInvitationTokenException(ValidationException):
def __init__(
self,
message: str = "Invalid or expired invitation token",
invitation_token: Optional[str] = None,
invitation_token: str | None = None,
):
details = {}
if invitation_token:

View File

@@ -3,11 +3,15 @@
Vendor management specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (AuthorizationException, BusinessLogicException,
ConflictException, ResourceNotFoundException,
ValidationException)
from .base import (
AuthorizationException,
BusinessLogicException,
ConflictException,
ResourceNotFoundException,
ValidationException,
)
class VendorNotFoundException(ResourceNotFoundException):
@@ -63,7 +67,7 @@ class VendorNotVerifiedException(BusinessLogicException):
class UnauthorizedVendorAccessException(AuthorizationException):
"""Raised when user tries to access vendor they don't own."""
def __init__(self, vendor_code: str, user_id: Optional[int] = None):
def __init__(self, vendor_code: str, user_id: int | None = None):
details = {"vendor_code": vendor_code}
if user_id:
details["user_id"] = user_id
@@ -81,8 +85,8 @@ class InvalidVendorDataException(ValidationException):
def __init__(
self,
message: str = "Invalid vendor data",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -98,8 +102,8 @@ class VendorValidationException(ValidationException):
def __init__(
self,
message: str = "Vendor validation failed",
field: Optional[str] = None,
validation_errors: Optional[Dict[str, str]] = None,
field: str | None = None,
validation_errors: dict[str, str] | None = None,
):
details = {}
if validation_errors:
@@ -134,7 +138,7 @@ class IncompleteVendorDataException(ValidationException):
class MaxVendorsReachedException(BusinessLogicException):
"""Raised when user tries to create more vendors than allowed."""
def __init__(self, max_vendors: int, user_id: Optional[int] = None):
def __init__(self, max_vendors: int, user_id: int | None = None):
details = {"max_vendors": max_vendors}
if user_id:
details["user_id"] = user_id

View File

@@ -3,11 +3,14 @@
Vendor domain management specific exceptions.
"""
from typing import Any, Dict, Optional
from .base import (BusinessLogicException, ConflictException,
ExternalServiceException, ResourceNotFoundException,
ValidationException)
from .base import (
BusinessLogicException,
ConflictException,
ExternalServiceException,
ResourceNotFoundException,
ValidationException,
)
class VendorDomainNotFoundException(ResourceNotFoundException):
@@ -30,7 +33,7 @@ class VendorDomainNotFoundException(ResourceNotFoundException):
class VendorDomainAlreadyExistsException(ConflictException):
"""Raised when trying to add a domain that already exists."""
def __init__(self, domain: str, existing_vendor_id: Optional[int] = None):
def __init__(self, domain: str, existing_vendor_id: int | None = None):
details = {"domain": domain}
if existing_vendor_id:
details["existing_vendor_id"] = existing_vendor_id
@@ -104,7 +107,7 @@ class MultiplePrimaryDomainsException(BusinessLogicException):
def __init__(self, vendor_id: int):
super().__init__(
message=f"Vendor can only have one primary domain",
message="Vendor can only have one primary domain",
error_code="MULTIPLE_PRIMARY_DOMAINS",
details={"vendor_id": vendor_id},
)

View File

@@ -3,10 +3,13 @@
Vendor theme management specific exceptions.
"""
from typing import Any, Dict, Optional
from typing import Any
from .base import (BusinessLogicException, ConflictException,
ResourceNotFoundException, ValidationException)
from .base import (
BusinessLogicException,
ResourceNotFoundException,
ValidationException,
)
class VendorThemeNotFoundException(ResourceNotFoundException):
@@ -27,8 +30,8 @@ class InvalidThemeDataException(ValidationException):
def __init__(
self,
message: str = "Invalid theme data",
field: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
field: str | None = None,
details: dict[str, Any] | None = None,
):
super().__init__(
message=message,
@@ -41,7 +44,7 @@ class InvalidThemeDataException(ValidationException):
class ThemePresetNotFoundException(ResourceNotFoundException):
"""Raised when a theme preset is not found."""
def __init__(self, preset_name: str, available_presets: Optional[list] = None):
def __init__(self, preset_name: str, available_presets: list | None = None):
details = {"preset_name": preset_name}
if available_presets:
details["available_presets"] = available_presets
@@ -61,8 +64,8 @@ class ThemeValidationException(ValidationException):
def __init__(
self,
message: str = "Theme validation failed",
field: Optional[str] = None,
validation_errors: Optional[Dict[str, str]] = None,
field: str | None = None,
validation_errors: dict[str, str] | None = None,
):
details = {}
if validation_errors: