"""Pydantic v2 request/response schemas.""" from datetime import datetime from typing import Any, List, Optional from uuid import UUID from pydantic import BaseModel, ConfigDict, Field class ORMModel(BaseModel): model_config = ConfigDict(from_attributes=True) # ── auth ──────────────────────────────────────────────────────────────── class LoginRequest(BaseModel): email: str password: str class TokenResponse(BaseModel): access_token: str token_type: str = "bearer" class CustomerRegister(BaseModel): email: str name: Optional[str] = None shipping_addr: Optional[dict] = None # NOTE: customers table has no password column — password (if sent) is not # stored. Customer identity for MVP is email-only; TODO: add password column + hash. password: Optional[str] = None # ── products ──────────────────────────────────────────────────────────── class ProductOut(ORMModel): id: UUID sku: str title: str description: Optional[str] = None category: Optional[str] = None brand: Optional[str] = None manufacturer: Optional[str] = None images: Any = None weight_grams: Optional[float] = None cost: float retail_price: Optional[float] = None min_price: Optional[float] = None max_price: Optional[float] = None status: str created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class ImportRequest(BaseModel): supplier_id: UUID feed_type: str = "csv" data_or_url: str = "" class PriceHistoryOut(ORMModel): price: float reason: Optional[str] = None created_at: Optional[datetime] = None # ── suppliers ─────────────────────────────────────────────────────────── class SupplierCreate(BaseModel): name: str adapter_type: str = "csv" api_endpoint: Optional[str] = None account_id: Optional[str] = None fulfillment_caps: dict = {} shipping_regions: List[str] = [] reliability_score: float = 50.0 status: str = "active" class SupplierOut(ORMModel): id: UUID name: str adapter_type: str api_endpoint: Optional[str] = None fulfillment_caps: Any = None shipping_regions: Any = None reliability_score: float status: str created_at: Optional[datetime] = None class SupplierPerformanceOut(BaseModel): supplier_id: UUID supplier_name: str fulfillment_rate: float avg_shipping_days: Optional[float] = None cancellation_rate: float stock_accuracy: float return_rate: float updated_at: Optional[datetime] = None # ── customers ─────────────────────────────────────────────────────────── class CustomerOut(ORMModel): id: UUID email: str name: Optional[str] = None shipping_addr: Any = None created_at: Optional[datetime] = None # ── orders ────────────────────────────────────────────────────────────── class OrderItemIn(BaseModel): product_id: UUID qty: int = Field(ge=1) class OrderCreate(BaseModel): customer_email: str items: List[OrderItemIn] = Field(min_length=1) class OrderOut(ORMModel): id: UUID order_number: str customer_id: Optional[UUID] = None items: Any retail_total: float supplier_id: Optional[UUID] = None supplier_cost: float shipping_cost: float fees: float profit: float status: str tracking: Optional[str] = None carrier: Optional[str] = None btcpay_invoice_id: Optional[str] = None supplier_order_ref: Optional[str] = None created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class CustomerOrderOut(ORMModel): id: UUID order_number: str items: Any retail_total: float status: str tracking: Optional[str] = None carrier: Optional[str] = None created_at: Optional[datetime] = None updated_at: Optional[datetime] = None class CheckoutResponse(BaseModel): order: OrderOut checkout_url: Optional[str] = None class TrackingIn(BaseModel): tracking: str carrier: Optional[str] = None