from pydantic import BaseModel from datetime import datetime, date from typing import List, Optional # --- E-commerce Schemas --- class ProductBase(BaseModel): name: str description: Optional[str] = None price: float image_url: Optional[str] = None class ProductCreate(ProductBase): stock: int class Product(ProductBase): id: int stock: int class Config: from_attributes = True class CartItemBase(BaseModel): product_id: int quantity: int class CartItemCreate(CartItemBase): pass class CartItem(CartItemBase): id: int user_id: int product: Product class Config: from_attributes = True class OrderItemBase(BaseModel): product_id: int quantity: int price: float # Price at the time of order class OrderItem(OrderItemBase): id: int product: Product class Config: from_attributes = True class OrderBase(BaseModel): total_price: float status: str class OrderCreate(BaseModel): # When creating an order, it's usually from the cart, so no direct items needed pass class Order(OrderBase): id: int user_id: int created_at: datetime items: List[OrderItem] = [] class Config: from_attributes = True # --- Community Schemas --- class CommentBase(BaseModel): content: str class CommentCreate(CommentBase): post_id: int class Comment(CommentBase): id: int author_id: int post_id: int created_at: datetime class Config: from_attributes = True class PostBase(BaseModel): content: str rating: str class PostCreate(PostBase): food_id: int class Post(PostBase): id: int author_id: int food_id: int created_at: datetime comments: List[Comment] = [] favorites_count: int = 0 class Config: from_attributes = True class FavoriteBase(BaseModel): entity_type: str entity_id: int tag: Optional[str] = None class FavoriteCreate(FavoriteBase): pass class Favorite(FavoriteBase): id: int user_id: int class Config: from_attributes = True # --- Topic Schemas --- class TopicBase(BaseModel): name: str description: Optional[str] = None class TopicCreate(TopicBase): pass class Topic(TopicBase): id: int class Config: from_attributes = True # --- Article Schemas --- class ArticleBase(BaseModel): title: str content: str author: Optional[str] = None category: str cover_image_url: Optional[str] = None class ArticleCreate(ArticleBase): pass class Article(ArticleBase): id: int created_at: datetime class Config: from_attributes = True # --- Recipe Schemas --- class RecipeIngredientBase(BaseModel): ingredient_id: int quantity: float unit: str class RecipeIngredientCreate(RecipeIngredientBase): pass class RecipeIngredient(RecipeIngredientBase): ingredient_name: str class Config: from_attributes = True class RecipeBase(BaseModel): name: str description: Optional[str] = None instructions: Optional[str] = None cooking_time: Optional[int] = None class RecipeCreate(RecipeBase): ingredients: List[RecipeIngredientCreate] = [] class Recipe(RecipeBase): id: int author_id: int ingredients: List[RecipeIngredient] = [] class Config: from_attributes = True # --- Ingredient Schemas --- class IngredientBase(BaseModel): name: str description: Optional[str] = None risk_level: int class IngredientCreate(IngredientBase): pass class Ingredient(IngredientBase): id: int class Config: from_attributes = True # --- Additive Schemas --- class AdditiveBase(BaseModel): name: str e_number: Optional[str] = None description: Optional[str] = None risk_level: int class AdditiveCreate(AdditiveBase): pass class Additive(AdditiveBase): id: int class Config: from_attributes = True # --- Food Schemas --- class FoodBase(BaseModel): barcode: str name: str | None = None brand: str | None = None category: Optional[str] = None safety_rating: Optional[str] = None nutrition_rating: Optional[str] = None shi_score: Optional[float] = None class FoodCreate(FoodBase): ingredient_ids: List[int] = [] additive_ids: List[int] = [] class Food(FoodBase): id: int created_at: datetime class Config: from_attributes = True class FoodDetails(Food): ingredients: List[Ingredient] = [] additives: List[Additive] = [] class Config: from_attributes = True # --- HealthProfile Schemas --- class HealthProfileBase(BaseModel): profile_type: str value: str class HealthProfileCreate(HealthProfileBase): pass class HealthProfile(HealthProfileBase): id: int member_id: int class Config: from_attributes = True # --- FamilyMember Schemas --- class FamilyMemberBase(BaseModel): name: str date_of_birth: date gender: str class FamilyMemberCreate(FamilyMemberBase): pass class FamilyMember(FamilyMemberBase): id: int owner_id: int health_profiles: List[HealthProfile] = [] class Config: from_attributes = True # --- User Schemas --- class UserBase(BaseModel): phone_number: str | None = None avatar_url: Optional[str] = None class UserCreate(UserBase): password: str | None = None avatar_url: Optional[str] = None class UserCodeLogin(UserBase): code: str class User(UserBase): id: int created_at: datetime family_members: List[FamilyMember] = [] class Config: from_attributes = True # --- OAuthAccount Schemas --- class OAuthAccountBase(BaseModel): provider: str openid: str class OAuthAccountCreate(OAuthAccountBase): pass class OAuthAccount(OAuthAccountBase): id: int user_id: int class Config: from_attributes = True # --- Token Schemas --- class Token(BaseModel): access_token: str token_type: str is_new_user: bool # --- UserPreference Schemas --- class UserPreferenceBase(BaseModel): category: str value: str class UserPreferenceCreate(UserPreferenceBase): pass class UserPreference(UserPreferenceBase): id: int user_id: int class Config: from_attributes = True class OnboardingPreferences(BaseModel): concerns: List[str] allergens: List[str] conditions: List[str] preferences: List[str] # --- SearchHistory Schemas --- class SearchHistoryBase(BaseModel): term: str class SearchHistoryCreate(SearchHistoryBase): pass class SearchHistory(SearchHistoryBase): id: int user_id: Optional[int] = None created_at: datetime class Config: from_attributes = True # --- Auth Schemas --- class PasswordSet(BaseModel): new_password: str class UserPasswordLogin(BaseModel): phone_number: str password: str # --- SubmittedFood Schemas --- class SubmittedFoodBase(BaseModel): barcode: str name: str brand: Optional[str] = None ingredients_text: Optional[str] = None additives_text: Optional[str] = None class SubmittedFoodCreate(SubmittedFoodBase): pass class SubmittedFood(SubmittedFoodBase): id: int status: str submitted_by_id: int created_at: datetime class Config: from_attributes = True