feat(loyalty): refactor analytics into shared template and add merchant stats API
Some checks failed
Some checks failed
Extract analytics stat cards, points activity, and location breakdown into a shared partial used by admin, merchant, and store dashboards. Add merchant stats API endpoint and client-side merchant filter on admin analytics page. Extend stats schema with new_this_month and estimated_liability_cents fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,7 @@ from app.modules.loyalty.schemas import (
|
||||
ProgramResponse,
|
||||
ProgramUpdate,
|
||||
)
|
||||
from app.modules.loyalty.schemas.program import MerchantStatsResponse
|
||||
from app.modules.loyalty.services import program_service
|
||||
from app.modules.tenancy.models import Merchant
|
||||
|
||||
@@ -49,6 +50,21 @@ def _build_program_response(program) -> ProgramResponse:
|
||||
return response
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Statistics
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@router.get("/stats", response_model=MerchantStatsResponse)
|
||||
def get_stats(
|
||||
merchant: Merchant = Depends(get_merchant_for_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""Get merchant-wide loyalty statistics across all locations."""
|
||||
stats = program_service.get_merchant_stats(db, merchant.id)
|
||||
return MerchantStatsResponse(**stats)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Program CRUD
|
||||
# =============================================================================
|
||||
|
||||
@@ -145,24 +145,13 @@ async def merchant_loyalty_analytics(
|
||||
"""
|
||||
Render merchant loyalty analytics page.
|
||||
|
||||
Shows aggregate loyalty program stats across all merchant stores.
|
||||
Stats are loaded client-side via JS fetch.
|
||||
"""
|
||||
merchant_id = merchant.id
|
||||
stats = {}
|
||||
try:
|
||||
stats = program_service.get_merchant_stats(db, merchant_id)
|
||||
except Exception:
|
||||
logger.warning(
|
||||
f"Failed to load loyalty stats for merchant {merchant_id}",
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
context = _get_merchant_context(
|
||||
request,
|
||||
db,
|
||||
current_user,
|
||||
loyalty_stats=stats,
|
||||
merchant_id=merchant_id,
|
||||
merchant_id=merchant.id,
|
||||
)
|
||||
return templates.TemplateResponse(
|
||||
"loyalty/merchant/analytics.html",
|
||||
|
||||
Reference in New Issue
Block a user