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

@@ -5,7 +5,6 @@ Pydantic schema for customer-related operations.
from datetime import datetime
from decimal import Decimal
from typing import Any, Dict, List, Optional
from pydantic import BaseModel, EmailStr, Field, field_validator
@@ -23,7 +22,7 @@ class CustomerRegister(BaseModel):
)
first_name: str = Field(..., min_length=1, max_length=100)
last_name: str = Field(..., min_length=1, max_length=100)
phone: Optional[str] = Field(None, max_length=50)
phone: str | None = Field(None, max_length=50)
marketing_consent: bool = Field(default=False)
@field_validator("email")
@@ -48,15 +47,15 @@ class CustomerRegister(BaseModel):
class CustomerUpdate(BaseModel):
"""Schema for updating customer profile."""
email: Optional[EmailStr] = None
first_name: Optional[str] = Field(None, min_length=1, max_length=100)
last_name: Optional[str] = Field(None, min_length=1, max_length=100)
phone: Optional[str] = Field(None, max_length=50)
marketing_consent: Optional[bool] = None
email: EmailStr | None = None
first_name: str | None = Field(None, min_length=1, max_length=100)
last_name: str | None = Field(None, min_length=1, max_length=100)
phone: str | None = Field(None, max_length=50)
marketing_consent: bool | None = None
@field_validator("email")
@classmethod
def email_lowercase(cls, v: Optional[str]) -> Optional[str]:
def email_lowercase(cls, v: str | None) -> str | None:
"""Convert email to lowercase."""
return v.lower() if v else None
@@ -72,12 +71,12 @@ class CustomerResponse(BaseModel):
id: int
vendor_id: int
email: str
first_name: Optional[str]
last_name: Optional[str]
phone: Optional[str]
first_name: str | None
last_name: str | None
phone: str | None
customer_number: str
marketing_consent: bool
last_order_date: Optional[datetime]
last_order_date: datetime | None
total_orders: int
total_spent: Decimal
is_active: bool
@@ -97,7 +96,7 @@ class CustomerResponse(BaseModel):
class CustomerListResponse(BaseModel):
"""Schema for paginated customer list."""
customers: List[CustomerResponse]
customers: list[CustomerResponse]
total: int
page: int
per_page: int
@@ -115,9 +114,9 @@ class CustomerAddressCreate(BaseModel):
address_type: str = Field(..., pattern="^(billing|shipping)$")
first_name: str = Field(..., min_length=1, max_length=100)
last_name: str = Field(..., min_length=1, max_length=100)
company: Optional[str] = Field(None, max_length=200)
company: str | None = Field(None, max_length=200)
address_line_1: str = Field(..., min_length=1, max_length=255)
address_line_2: Optional[str] = Field(None, max_length=255)
address_line_2: str | None = Field(None, max_length=255)
city: str = Field(..., min_length=1, max_length=100)
postal_code: str = Field(..., min_length=1, max_length=20)
country: str = Field(..., min_length=2, max_length=100)
@@ -127,16 +126,16 @@ class CustomerAddressCreate(BaseModel):
class CustomerAddressUpdate(BaseModel):
"""Schema for updating customer address."""
address_type: Optional[str] = Field(None, pattern="^(billing|shipping)$")
first_name: Optional[str] = Field(None, min_length=1, max_length=100)
last_name: Optional[str] = Field(None, min_length=1, max_length=100)
company: Optional[str] = Field(None, max_length=200)
address_line_1: Optional[str] = Field(None, min_length=1, max_length=255)
address_line_2: Optional[str] = Field(None, max_length=255)
city: Optional[str] = Field(None, min_length=1, max_length=100)
postal_code: Optional[str] = Field(None, min_length=1, max_length=20)
country: Optional[str] = Field(None, min_length=2, max_length=100)
is_default: Optional[bool] = None
address_type: str | None = Field(None, pattern="^(billing|shipping)$")
first_name: str | None = Field(None, min_length=1, max_length=100)
last_name: str | None = Field(None, min_length=1, max_length=100)
company: str | None = Field(None, max_length=200)
address_line_1: str | None = Field(None, min_length=1, max_length=255)
address_line_2: str | None = Field(None, max_length=255)
city: str | None = Field(None, min_length=1, max_length=100)
postal_code: str | None = Field(None, min_length=1, max_length=20)
country: str | None = Field(None, min_length=2, max_length=100)
is_default: bool | None = None
class CustomerAddressResponse(BaseModel):
@@ -148,9 +147,9 @@ class CustomerAddressResponse(BaseModel):
address_type: str
first_name: str
last_name: str
company: Optional[str]
company: str | None
address_line_1: str
address_line_2: Optional[str]
address_line_2: str | None
city: str
postal_code: str
country: str
@@ -169,7 +168,7 @@ class CustomerAddressResponse(BaseModel):
class CustomerPreferencesUpdate(BaseModel):
"""Schema for updating customer preferences."""
marketing_consent: Optional[bool] = None
language: Optional[str] = Field(None, max_length=10)
currency: Optional[str] = Field(None, max_length=3)
notification_preferences: Optional[Dict[str, bool]] = None
marketing_consent: bool | None = None
language: str | None = Field(None, max_length=10)
currency: str | None = Field(None, max_length=3)
notification_preferences: dict[str, bool] | None = None