from typing import Optional, Dict from pydantic import BaseModel, validator from datetime import datetime class ProductBase(BaseModel): name: str description: Optional[str] = None price: float category: str class ProductCreate(ProductBase): pass class ProductUpdate(ProductBase): pass class Product(ProductBase): id: int created_at: datetime updated_at: Optional[datetime] = None @validator('price') def price_must_be_positive(cls, value): if value <= 0: raise ValueError('Price must be a positive value') return value def validate_product_data(product_data: ProductCreate) -> Dict[str, str]: errors = {} if not product_data.name.strip(): errors['name'] = 'Product name cannot be empty' if not product_data.category.strip(): errors['category'] = 'Product category cannot be empty' return errors def create_product(db, product_data: ProductCreate): errors = validate_product_data(product_data) if errors: return errors product = Product( name=product_data.name, description=product_data.description, price=product_data.price, category=product_data.category, created_at=datetime.utcnow() ) db.add(product) db.commit() db.refresh(product) return product def update_product(db, product_id: int, product_data: ProductUpdate): product = db.query(Product).filter(Product.id == product_id).first() if not product: return {'error': 'Product not found'} for field, value in product_data.dict(exclude_unset=True).items(): setattr(product, field, value) product.updated_at = datetime.utcnow() db.commit() db.refresh(product) return product def get_product_by_id(db, product_id: int): return db.query(Product).filter(Product.id == product_id).first() def get_products_by_category(db, category: str): return db.query(Product).filter(Product.category == category).all()