ifixkart-backend/Backend/app/services/StorefrontService.py

84 lines
3.3 KiB
Python

"""
@service StorefrontService (Backend/app/services/StorefrontService.py)
@purpose Domain service handling business logic, layout assembly, review moderation workflows, and cache invalidation.
"""
from sqlalchemy.orm import Session
from typing import List, Dict, Any, Optional
import ulid
from app.repositories.StorefrontRepository import StorefrontRepository
from app.models.StorefrontContentModel import StorefrontContent, ContentStatusEnum
from app.models.ProductReviewModel import ProductReview
# In-Memory Cache Store for high performance
_IN_MEMORY_CACHE: Dict[str, Any] = {}
class StorefrontService:
def __init__(self, db: Session):
self.repo = StorefrontRepository(db)
def get_layout(self, page: str, region: Optional[str] = None) -> List[Dict[str, Any]]:
# No in-memory cache here — layout changes via admin must reflect immediately
contents = self.repo.get_active_content(page, region)
result = [
{
"content_id": c.content_id,
"page": c.page,
"region": c.region,
"type": c.type,
"title": c.title,
"subtitle": c.subtitle,
"image_url": c.image_url,
"button_text": c.button_text,
"button_url": c.button_url,
"display_order": c.display_order,
# Expose under both keys so frontend works regardless of which it checks
"metadata": c.metadata_json or {},
"metadata_json": c.metadata_json or {}
}
for c in contents
]
return result
def invalidate_cache(self, pattern: Optional[str] = None):
global _IN_MEMORY_CACHE
if pattern:
_IN_MEMORY_CACHE = {k: v for k, v in _IN_MEMORY_CACHE.items() if not k.startswith(pattern)}
else:
_IN_MEMORY_CACHE.clear()
def get_reviews(self, product_id: str) -> List[Dict[str, Any]]:
cache_key = f"reviews:{product_id}"
if cache_key in _IN_MEMORY_CACHE:
return _IN_MEMORY_CACHE[cache_key]
reviews = self.repo.get_approved_reviews(product_id)
result = [
{
"review_id": r.review_id,
"product_id": r.product_id,
"author_name": r.author_name,
"rating": r.rating,
"title": r.title,
"comment": r.comment,
"verified_buyer": r.verified_purchase,
"helpful_count": r.helpful_count,
"admin_reply": r.admin_reply,
"review_date": r.created_at.strftime("%Y-%m-%d") if r.created_at else "2026-07-25",
"images": [img.image_url for img in r.images if img.is_approved] if r.images else []
}
for r in reviews
]
_IN_MEMORY_CACHE[cache_key] = result
return result
def get_public_settings(self, group: Optional[str] = None) -> Dict[str, Any]:
cache_key = f"settings:public:{group or 'all'}"
if cache_key in _IN_MEMORY_CACHE:
return _IN_MEMORY_CACHE[cache_key]
settings = self.repo.get_public_settings(group)
result = {s.setting_key: s.setting_value for s in settings}
_IN_MEMORY_CACHE[cache_key] = result
return result