wahnsinn vibe
This commit is contained in:
87
backend/apps/catalog/projector.py
Normal file
87
backend/apps/catalog/projector.py
Normal file
@@ -0,0 +1,87 @@
|
||||
"""Projects catalog changes into Redis for the Shop frontend to read."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from core.redis_client import redis_client
|
||||
|
||||
from .models import Category, Product
|
||||
|
||||
|
||||
def _product_to_dict(p: Product) -> dict:
|
||||
return {
|
||||
"id": p.id,
|
||||
"sku": p.sku,
|
||||
"name": p.name,
|
||||
"description": p.description,
|
||||
"price": float(p.price),
|
||||
"currency": p.currency,
|
||||
"stock": p.stock,
|
||||
"active": p.active,
|
||||
"image_url": p.image_url,
|
||||
"category_id": p.category_id,
|
||||
"attributes": p.attributes or {},
|
||||
}
|
||||
|
||||
|
||||
def _category_to_dict(c: Category) -> dict:
|
||||
return {
|
||||
"id": c.id,
|
||||
"slug": c.slug,
|
||||
"name": c.name,
|
||||
"parent_id": c.parent_id,
|
||||
"sort_order": c.sort_order,
|
||||
}
|
||||
|
||||
|
||||
def project_product(db: Session, product_id: int) -> None:
|
||||
p = db.get(Product, product_id)
|
||||
if not p or not p.active:
|
||||
redis_client.delete(f"product:{product_id}")
|
||||
_refresh_product_list(db)
|
||||
return
|
||||
redis_client.set(f"product:{product_id}", json.dumps(_product_to_dict(p)))
|
||||
_refresh_product_list(db)
|
||||
|
||||
|
||||
def delete_product_from_cache(product_id: int, db: Session) -> None:
|
||||
redis_client.delete(f"product:{product_id}")
|
||||
_refresh_product_list(db)
|
||||
|
||||
|
||||
def _refresh_product_list(db: Session) -> None:
|
||||
ids = [row[0] for row in db.query(Product.id).filter(Product.active.is_(True)).all()]
|
||||
redis_client.set("product:list", json.dumps(ids))
|
||||
|
||||
|
||||
def project_category(db: Session, category_id: int) -> None:
|
||||
c = db.get(Category, category_id)
|
||||
if not c:
|
||||
redis_client.delete(f"category:{category_id}")
|
||||
else:
|
||||
redis_client.set(f"category:{category_id}", json.dumps(_category_to_dict(c)))
|
||||
_refresh_category_tree(db)
|
||||
|
||||
|
||||
def delete_category_from_cache(category_id: int, db: Session) -> None:
|
||||
redis_client.delete(f"category:{category_id}")
|
||||
_refresh_category_tree(db)
|
||||
|
||||
|
||||
def _refresh_category_tree(db: Session) -> None:
|
||||
cats = db.query(Category).order_by(Category.sort_order, Category.id).all()
|
||||
data = [_category_to_dict(c) for c in cats]
|
||||
redis_client.set("category:tree", json.dumps(data))
|
||||
|
||||
|
||||
def rebuild_all(db: Session) -> None:
|
||||
# Refresh every product/category key
|
||||
for p in db.query(Product).all():
|
||||
if p.active:
|
||||
redis_client.set(f"product:{p.id}", json.dumps(_product_to_dict(p)))
|
||||
for c in db.query(Category).all():
|
||||
redis_client.set(f"category:{c.id}", json.dumps(_category_to_dict(c)))
|
||||
_refresh_product_list(db)
|
||||
_refresh_category_tree(db)
|
||||
Reference in New Issue
Block a user