Files
cannaiq/findagram/backend/app/schemas/product.py
Kelly a0f8d3911c feat: Add Findagram and FindADispo consumer frontends
- Add findagram.co React frontend with product search, brands, categories
- Add findadispo.com React frontend with dispensary locator
- Wire findagram to backend /api/az/* endpoints
- Update category/brand links to route to /products with filters
- Add k8s manifests for both frontends
- Add multi-domain user support migrations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 16:10:15 -07:00

97 lines
2.2 KiB
Python

from pydantic import BaseModel
from datetime import datetime
from typing import Optional, List
class CategoryResponse(BaseModel):
id: int
name: str
slug: str
description: Optional[str] = None
icon: Optional[str] = None
image_url: Optional[str] = None
product_count: int = 0
class Config:
from_attributes = True
class BrandResponse(BaseModel):
id: int
name: str
slug: str
description: Optional[str] = None
logo_url: Optional[str] = None
website: Optional[str] = None
product_count: int = 0
class Config:
from_attributes = True
class DispensaryResponse(BaseModel):
id: int
name: str
slug: str
address: Optional[str] = None
city: Optional[str] = None
state: Optional[str] = None
phone: Optional[str] = None
website: Optional[str] = None
logo_url: Optional[str] = None
rating: Optional[float] = None
review_count: int = 0
latitude: Optional[float] = None
longitude: Optional[float] = None
class Config:
from_attributes = True
class ProductPriceResponse(BaseModel):
dispensary: DispensaryResponse
price: float
original_price: Optional[float] = None
in_stock: bool = True
has_deal: bool = False
deal_text: Optional[str] = None
class Config:
from_attributes = True
class ProductResponse(BaseModel):
id: int
name: str
slug: str
description: Optional[str] = None
image_url: Optional[str] = None
category: Optional[CategoryResponse] = None
brand: Optional[BrandResponse] = None
strain_type: Optional[str] = None
thc_percentage: Optional[float] = None
cbd_percentage: Optional[float] = None
weight: Optional[str] = None
lowest_price: Optional[float] = None
avg_price: Optional[float] = None
has_deal: bool = False
deal_text: Optional[str] = None
original_price: Optional[float] = None
dispensary_count: int = 0
created_at: datetime
class Config:
from_attributes = True
class ProductDetailResponse(ProductResponse):
prices: List[ProductPriceResponse] = []
class ProductListResponse(BaseModel):
products: List[ProductResponse]
total: int
page: int
per_page: int
total_pages: int