diff --git a/cart/bp/data/routes.py b/cart/bp/data/routes.py index 20994c0..af5fce7 100644 --- a/cart/bp/data/routes.py +++ b/cart/bp/data/routes.py @@ -80,4 +80,36 @@ def register() -> Blueprint: _handlers["page-config-ensure"] = _page_config_ensure + # --- cart-items (product slugs + quantities for template rendering) --- + async def _cart_items(): + from sqlalchemy import select + from sqlalchemy.orm import selectinload + from shared.models.market import CartItem + + user_id = request.args.get("user_id", type=int) + session_id = request.args.get("session_id") + + filters = [CartItem.deleted_at.is_(None)] + if user_id is not None: + filters.append(CartItem.user_id == user_id) + elif session_id is not None: + filters.append(CartItem.session_id == session_id) + else: + return [] + + result = await g.s.execute( + select(CartItem).where(*filters).options(selectinload(CartItem.product)) + ) + items = result.scalars().all() + return [ + { + "product_id": item.product_id, + "product_slug": item.product.slug if item.product else None, + "quantity": item.quantity, + } + for item in items + ] + + _handlers["cart-items"] = _cart_items + return bp diff --git a/market/app.py b/market/app.py index 2ed352a..ed73144 100644 --- a/market/app.py +++ b/market/app.py @@ -26,8 +26,6 @@ async def market_context() -> dict: from shared.infrastructure.fragments import fetch_fragments from shared.infrastructure.data_client import fetch_data from shared.contracts.dtos import CartSummaryDTO, dto_from_dict - from shared.models.market import CartItem - from sqlalchemy.orm import selectinload ctx = await base_context() @@ -64,20 +62,21 @@ async def market_context() -> dict: ctx["auth_menu_html"] = auth_menu_html ctx["nav_tree_html"] = nav_tree_html - # ORM cart items for product templates (need .product relationship) - filters = [CartItem.deleted_at.is_(None)] - if ident["user_id"] is not None: - filters.append(CartItem.user_id == ident["user_id"]) - elif ident["session_id"] is not None: - filters.append(CartItem.session_id == ident["session_id"]) + # Cart items for product templates — fetched via internal data endpoint + # (cart_items table lives in db_cart, not db_market) + cart_items_raw = await fetch_data("cart", "cart-items", params=summary_params, required=False) + if cart_items_raw: + # Wrap as namespace objects so Jinja selectattr("product.slug", ...) works + from types import SimpleNamespace + ctx["cart"] = [ + SimpleNamespace( + product=SimpleNamespace(slug=item["product_slug"]), + quantity=item["quantity"], + ) + for item in cart_items_raw + ] else: ctx["cart"] = [] - return ctx - - result = await g.s.execute( - select(CartItem).where(*filters).options(selectinload(CartItem.product)) - ) - ctx["cart"] = list(result.scalars().all()) return ctx