from __future__ import annotations from quart import g from shared.factory import create_base_app from suma_browser.app.bp import register_cart_bp, register_orders, register_cart_api from suma_browser.app.bp.cart.services import ( get_cart, total, get_calendar_cart_entries, calendar_total, ) async def _load_cart(): """Load the full cart for the cart app (before each request).""" g.cart = await get_cart(g.s) async def cart_context() -> dict: """ Cart app context processor. - cart / calendar_cart_entries / total / calendar_total: direct DB (cart app owns this data) - cart_count: derived from cart + calendar entries (for _mini.html) - menu_items: fetched from coop internal API """ from shared.context import base_context from shared.internal_api import get as api_get, dictobj ctx = await base_context() # Cart app owns cart data — use g.cart from _load_cart cart = getattr(g, "cart", None) or [] cal_entries = await get_calendar_cart_entries(g.s) ctx["cart"] = cart ctx["calendar_cart_entries"] = cal_entries ctx["total"] = total ctx["calendar_total"] = calendar_total # Also set cart_count so _mini.html works the same way cart_qty = sum(ci.quantity for ci in cart) if cart else 0 ctx["cart_count"] = cart_qty + len(cal_entries) ctx["cart_total"] = (total(cart) or 0) + (calendar_total(cal_entries) or 0) # Menu items from coop API (wrapped for attribute access in templates) menu_data = await api_get("coop", "/internal/menu-items") ctx["menu_items"] = dictobj(menu_data) if menu_data else [] return ctx def create_app() -> "Quart": app = create_base_app( "cart", context_fn=cart_context, before_request_fns=[_load_cart], ) # Cart blueprint at root (was /cart in monolith) app.register_blueprint( register_cart_bp(url_prefix="/"), url_prefix="/", ) # Orders blueprint app.register_blueprint( register_orders(url_prefix="/orders"), ) # Internal API (server-to-server, CSRF-exempt) app.register_blueprint(register_cart_api()) return app app = create_app()