Phase 3 of storefront restructure plan - create dedicated modules for e-commerce functionality: - cart: Shopping cart management with storefront API routes - CartItem model with cents-based pricing - CartService for cart operations - Storefront routes for cart CRUD operations - catalog: Product catalog browsing for customers - CatalogService for public product queries - Storefront routes for product listing/search/details - checkout: Order creation from cart (placeholder) - CheckoutService stub for future cart-to-order conversion - Schemas for checkout flow These modules separate e-commerce concerns from core platform concerns (customer auth), enabling non-commerce platforms. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
55 lines
2.1 KiB
Python
55 lines
2.1 KiB
Python
# app/modules/checkout/schemas/checkout.py
|
|
"""
|
|
Pydantic schemas for checkout operations.
|
|
|
|
These schemas handle the conversion of a shopping cart into an order.
|
|
"""
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ShippingAddress(BaseModel):
|
|
"""Shipping address for checkout."""
|
|
|
|
first_name: str = Field(..., min_length=1, max_length=100)
|
|
last_name: str = Field(..., min_length=1, max_length=100)
|
|
address_line_1: str = Field(..., min_length=1, 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=2) # ISO 3166-1 alpha-2
|
|
phone: str | None = Field(None, max_length=20)
|
|
|
|
|
|
class CheckoutRequest(BaseModel):
|
|
"""Request to initiate checkout."""
|
|
|
|
session_id: str = Field(..., description="Cart session ID")
|
|
shipping_address: ShippingAddress = Field(..., description="Shipping address")
|
|
billing_same_as_shipping: bool = Field(
|
|
True, description="Use shipping address for billing"
|
|
)
|
|
billing_address: ShippingAddress | None = Field(
|
|
None, description="Billing address (if different from shipping)"
|
|
)
|
|
customer_email: str = Field(..., description="Customer email for order confirmation")
|
|
customer_note: str | None = Field(None, description="Optional customer note")
|
|
|
|
|
|
class CheckoutSessionResponse(BaseModel):
|
|
"""Response for checkout session creation."""
|
|
|
|
checkout_session_id: str = Field(..., description="Checkout session ID")
|
|
cart_total: float = Field(..., description="Cart total in euros")
|
|
item_count: int = Field(..., description="Number of items in cart")
|
|
requires_payment: bool = Field(..., description="Whether payment is required")
|
|
|
|
|
|
class CheckoutResponse(BaseModel):
|
|
"""Response for completed checkout."""
|
|
|
|
order_id: int = Field(..., description="Created order ID")
|
|
order_number: str = Field(..., description="Human-readable order number")
|
|
total: float = Field(..., description="Order total in euros")
|
|
message: str = Field(..., description="Confirmation message")
|