Add complete NexaPantry application structure including: - Docker Compose configuration with PostgreSQL, Redis, FastAPI backend, worker, frontend and Caddy - Environment configuration template with database, auth, and service settings - GitHub Actions CI workflow for backend/frontend linting, testing, auditing and Docker builds - AGPL-3.0 license and comprehensive README with setup, development, and security documentation - Backend
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
from datetime import date
|
|
from typing import Protocol
|
|
|
|
import httpx
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.models.entities import Home, Product
|
|
|
|
|
|
def expiry_status(product: Product, home: Home) -> str:
|
|
if not product.expires_at:
|
|
return "ok"
|
|
today = date.today()
|
|
if product.expires_at <= today:
|
|
return "expired"
|
|
if (product.expires_at - today).days <= home.expiry_warning_days:
|
|
return "soon"
|
|
return "ok"
|
|
|
|
|
|
class ProductLookup(Protocol):
|
|
async def by_barcode(self, barcode: str) -> dict | None:
|
|
...
|
|
|
|
|
|
class OpenFoodFactsLookup(ProductLookup):
|
|
async def by_barcode(self, barcode: str) -> dict | None:
|
|
url = f"https://world.openfoodfacts.org/api/v2/product/{barcode}.json"
|
|
async with httpx.AsyncClient(timeout=8) as client:
|
|
response = await client.get(url)
|
|
if response.status_code != 200:
|
|
return None
|
|
data = response.json()
|
|
product = data.get("product")
|
|
if not product:
|
|
return None
|
|
return {
|
|
"name": product.get("product_name") or product.get("generic_name") or "",
|
|
"brand": product.get("brands"),
|
|
"category": (product.get("categories_tags") or ["Other"])[0].replace("en:", ""),
|
|
"image_url": product.get("image_front_small_url") or product.get("image_url"),
|
|
"barcode": barcode,
|
|
}
|
|
|
|
|
|
def low_stock_products(db: Session, home_id: str) -> list[Product]:
|
|
return [
|
|
product
|
|
for product in db.query(Product).filter(Product.home_id == home_id).all()
|
|
if product.quantity <= product.min_quantity
|
|
]
|