File size: 4,684 Bytes
af1d8cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | from typing import Optional, List
from sqlmodel import Field, SQLModel, Relationship
from datetime import datetime
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
email: str = Field(index=True, unique=True)
password_hash: str
full_name: Optional[str] = None
created_at: datetime = Field(default_factory=datetime.utcnow)
items: List["WardrobeItem"] = Relationship(back_populates="owner")
outfits: List["Outfit"] = Relationship(back_populates="owner")
measurements: Optional["UserMeasurements"] = Relationship(back_populates="user")
clicks: List["AffiliateClick"] = Relationship(back_populates="user")
class Brand(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
name: str = Field(unique=True, index=True)
logo_url: Optional[str] = None
password_hash: str = "mock_hash" # For B2B login
products: List["AffiliateProduct"] = Relationship(back_populates="brand_rel")
class AffiliateProduct(SQLModel, table=True):
"""Represents a product from a brand partner"""
id: Optional[int] = Field(default=None, primary_key=True)
name: str
brand: str
price: float
commission_rate: float = 0.05 # 5% default
original_url: str
image_url: str
category: str
brand_id: Optional[int] = Field(default=None, foreign_key="brand.id")
brand_rel: Optional[Brand] = Relationship(back_populates="products")
clicks: List["AffiliateClick"] = Relationship(back_populates="product")
class AffiliateClick(SQLModel, table=True):
"""Log of every click on an affiliate link"""
id: Optional[int] = Field(default=None, primary_key=True)
product_id: int = Field(foreign_key="affiliateproduct.id")
user_id: Optional[int] = Field(default=None, foreign_key="user.id")
timestamp: datetime = Field(default_factory=datetime.utcnow)
converted: bool = False # Mock conversion status
commission_earned: float = 0.0
product: Optional[AffiliateProduct] = Relationship(back_populates="clicks")
user: Optional[User] = Relationship(back_populates="clicks")
class UserMeasurements(SQLModel, table=True):
"""Store user body measurements for size recommendations"""
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id", unique=True)
height_cm: Optional[float] = None
weight_kg: Optional[float] = None
chest_cm: Optional[float] = None
waist_cm: Optional[float] = None
hip_cm: Optional[float] = None
preferred_fit: Optional[str] = "regular" # slim, regular, loose
updated_at: datetime = Field(default_factory=datetime.utcnow)
user: Optional[User] = Relationship(back_populates="measurements")
class BrandSizeMapping(SQLModel, table=True):
"""Cross-brand size translation mappings"""
id: Optional[int] = Field(default=None, primary_key=True)
brand_name: str = Field(index=True)
category: str # tops, bottoms, shoes, etc.
size_label: str # S, M, L, 32, 34, etc.
chest_min: Optional[float] = None
chest_max: Optional[float] = None
waist_min: Optional[float] = None
waist_max: Optional[float] = None
hip_min: Optional[float] = None
hip_max: Optional[float] = None
region: str = "US" # US, EU, UK, etc.
class SizeRecommendation(SQLModel, table=True):
"""Store size recommendations for wardrobe items"""
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id")
wardrobe_item_id: int = Field(foreign_key="wardrobeitem.id")
brand_name: str
recommended_size: str
confidence_score: float # 0.0 to 1.0
alternative_sizes: Optional[str] = None # JSON array of alternatives
reasoning: Optional[str] = None # Why this size was recommended
created_at: datetime = Field(default_factory=datetime.utcnow)
class WardrobeItem(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
owner_id: Optional[int] = Field(default=None, foreign_key="user.id")
image_url: str
category: str # e.g., 'top', 'bottom', 'shoes'
tags: Optional[str] = None
created_at: datetime = Field(default_factory=datetime.utcnow)
owner: Optional[User] = Relationship(back_populates="items")
class Outfit(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
owner_id: Optional[int] = Field(default=None, foreign_key="user.id")
items_json: str # JSON string of item IDs
created_at: datetime = Field(default_factory=datetime.utcnow)
owner: Optional[User] = Relationship(back_populates="outfits")
|