# app/modules/customers/schemas/context.py """ Customer context schema for dependency injection in storefront routes. This schema provides a clean interface for customer data in API routes, avoiding direct database model imports in the API layer. """ from datetime import datetime from decimal import Decimal from pydantic import BaseModel, ConfigDict class CustomerContext(BaseModel): """ Customer context for dependency injection in storefront routes. This is a lightweight schema that contains the customer information needed by API routes. It's populated from the Customer database model in the authentication dependency. Usage: @router.get("/profile") def get_profile( customer: CustomerContext = Depends(get_current_customer_api), ): return {"email": customer.email} """ model_config = ConfigDict(from_attributes=True) # Core identification id: int vendor_id: int email: str customer_number: str # Profile info first_name: str | None = None last_name: str | None = None phone: str | None = None # Preferences marketing_consent: bool = False preferred_language: str | None = None # Stats (for order placement) total_orders: int = 0 total_spent: Decimal = Decimal("0.00") last_order_date: datetime | None = None # Status is_active: bool = True # Timestamps created_at: datetime | None = None updated_at: datetime | None = None # Password hash (needed for password change endpoint) # This is included but should not be exposed in API responses hashed_password: str | None = None @property def full_name(self) -> str: """Get customer full name.""" if self.first_name and self.last_name: return f"{self.first_name} {self.last_name}" return self.email @classmethod def from_db_model(cls, customer) -> "CustomerContext": """ Create CustomerContext from a Customer database model. Args: customer: Customer database model instance Returns: CustomerContext: Pydantic schema instance """ return cls( id=customer.id, vendor_id=customer.vendor_id, email=customer.email, customer_number=customer.customer_number, first_name=customer.first_name, last_name=customer.last_name, phone=customer.phone, marketing_consent=customer.marketing_consent, preferred_language=customer.preferred_language, total_orders=customer.total_orders or 0, total_spent=customer.total_spent or Decimal("0.00"), last_order_date=customer.last_order_date, is_active=customer.is_active, created_at=customer.created_at, updated_at=customer.updated_at, hashed_password=customer.hashed_password, )