486749a890
Full-stack Dutch supermarket price tracker with FastAPI backend, PostgreSQL/SQLAlchemy, Albert Heijn scraper, and Next.js frontend. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
1.6 KiB
Python
76 lines
1.6 KiB
Python
from datetime import datetime
|
|
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class Store(BaseModel):
|
|
id: int
|
|
name: str
|
|
slug: str
|
|
country: str
|
|
website: str | None = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class Product(BaseModel):
|
|
id: int
|
|
store_id: int
|
|
external_id: str
|
|
ean: str | None = None
|
|
name: str
|
|
brand: str | None = None
|
|
category: str | None = None
|
|
unit_size: str | None = None
|
|
url: str | None = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
store: Store | None = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ProductWithLatestPrice(Product):
|
|
latest_price: int | None = None
|
|
latest_price_timestamp: datetime | None = None
|
|
is_on_sale: bool = False
|
|
|
|
|
|
class PriceSnapshot(BaseModel):
|
|
id: int
|
|
product_id: int
|
|
scrape_run_id: int
|
|
price: int
|
|
unit_price: int | None = None
|
|
unit_description: str | None = None
|
|
currency: str
|
|
discount_label: str | None = None
|
|
discount_description: str | None = None
|
|
was_price: int | None = None
|
|
is_on_sale: bool
|
|
timestamp: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class ScrapeRun(BaseModel):
|
|
id: int
|
|
store_id: int
|
|
query: str
|
|
started_at: datetime
|
|
finished_at: datetime | None = None
|
|
status: str
|
|
products_found: int
|
|
error_message: str | None = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
class CheapestProduct(BaseModel):
|
|
product: Product
|
|
price: int
|
|
unit_price: int | None = None
|
|
unit_description: str | None = None
|
|
is_on_sale: bool
|
|
timestamp: datetime
|