feat(modules): create cart, catalog, and checkout e-commerce modules
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>
This commit is contained in:
14
app/modules/checkout/schemas/__init__.py
Normal file
14
app/modules/checkout/schemas/__init__.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# app/modules/checkout/schemas/__init__.py
|
||||
"""Checkout module schemas."""
|
||||
|
||||
from app.modules.checkout.schemas.checkout import (
|
||||
CheckoutRequest,
|
||||
CheckoutResponse,
|
||||
CheckoutSessionResponse,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"CheckoutRequest",
|
||||
"CheckoutResponse",
|
||||
"CheckoutSessionResponse",
|
||||
]
|
||||
54
app/modules/checkout/schemas/checkout.py
Normal file
54
app/modules/checkout/schemas/checkout.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# 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")
|
||||
Reference in New Issue
Block a user