
- Set up FastAPI application structure - Create database models for User, Product, Cart, CartItem, Order, and OrderItem - Set up Alembic for database migrations - Create Pydantic schemas for request/response models - Implement API endpoints for products, cart operations, and checkout process - Add health endpoint - Update README with project details and documentation
125 lines
3.4 KiB
Python
125 lines
3.4 KiB
Python
from typing import Optional, List
|
|
from datetime import datetime
|
|
from decimal import Decimal
|
|
from pydantic import Field
|
|
|
|
from app.schemas.base import BaseSchema, TimestampSchema
|
|
from app.schemas.product import Product
|
|
|
|
|
|
class CartItemBase(BaseSchema):
|
|
"""Base schema for CartItem data."""
|
|
product_id: int
|
|
quantity: int = Field(..., gt=0)
|
|
unit_price: Decimal = Field(..., ge=0, decimal_places=2)
|
|
|
|
|
|
class CartItemCreate(BaseSchema):
|
|
"""Schema for adding an item to cart."""
|
|
product_id: int
|
|
quantity: int = Field(..., gt=0)
|
|
|
|
|
|
class CartItemUpdate(BaseSchema):
|
|
"""Schema for updating a cart item."""
|
|
quantity: int = Field(..., gt=0)
|
|
|
|
|
|
class CartItemInDBBase(CartItemBase, TimestampSchema):
|
|
"""Base schema for CartItem in DB (with ID)."""
|
|
id: int
|
|
cart_id: int
|
|
|
|
|
|
class CartItemInDB(CartItemInDBBase):
|
|
"""Schema for CartItem in DB."""
|
|
pass
|
|
|
|
|
|
class CartItemWithProduct(CartItemBase, TimestampSchema):
|
|
"""Schema for CartItem with Product details."""
|
|
id: int
|
|
product: Product
|
|
|
|
@property
|
|
def subtotal(self) -> Decimal:
|
|
"""Calculate the subtotal for this cart item."""
|
|
return self.unit_price * self.quantity
|
|
|
|
|
|
class CartBase(BaseSchema):
|
|
"""Base schema for Cart data."""
|
|
user_id: Optional[int] = None
|
|
session_id: Optional[str] = None
|
|
is_active: bool = True
|
|
expires_at: Optional[datetime] = None
|
|
|
|
|
|
class CartCreate(CartBase):
|
|
"""Schema for creating a new cart."""
|
|
pass
|
|
|
|
|
|
class CartUpdate(BaseSchema):
|
|
"""Schema for updating a cart."""
|
|
is_active: Optional[bool] = None
|
|
expires_at: Optional[datetime] = None
|
|
|
|
|
|
class CartInDBBase(CartBase, TimestampSchema):
|
|
"""Base schema for Cart in DB (with ID)."""
|
|
id: int
|
|
|
|
|
|
class CartInDB(CartInDBBase):
|
|
"""Schema for Cart in DB."""
|
|
pass
|
|
|
|
|
|
class Cart(CartInDBBase):
|
|
"""Schema for Cart response with items."""
|
|
items: List[CartItemWithProduct] = []
|
|
total_items: int = 0
|
|
total_price: Decimal = Decimal('0.00')
|
|
|
|
model_config = {
|
|
"json_schema_extra": {
|
|
"examples": [
|
|
{
|
|
"id": 1,
|
|
"user_id": 1,
|
|
"session_id": None,
|
|
"is_active": True,
|
|
"expires_at": "2023-07-31T00:00:00",
|
|
"created_at": "2023-07-24T12:00:00",
|
|
"updated_at": "2023-07-24T12:00:00",
|
|
"items": [
|
|
{
|
|
"id": 1,
|
|
"product_id": 1,
|
|
"quantity": 2,
|
|
"unit_price": "19.99",
|
|
"product": {
|
|
"id": 1,
|
|
"name": "Product 1",
|
|
"description": "Description of product 1",
|
|
"price": "19.99",
|
|
"sku": "PROD1",
|
|
"stock_quantity": 100,
|
|
"is_active": True
|
|
}
|
|
}
|
|
],
|
|
"total_items": 2,
|
|
"total_price": "39.98"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
|
|
class AddToCartResponse(BaseSchema):
|
|
"""Schema for response after adding an item to cart."""
|
|
cart_id: int
|
|
message: str
|
|
cart_item: CartItemWithProduct |