"""Market app data endpoints. Exposes read-only JSON queries at ``/internal/data/`` for cross-app callers via the internal data client. """ from __future__ import annotations from quart import Blueprint, g, jsonify, request from shared.infrastructure.data_client import DATA_HEADER from shared.contracts.dtos import dto_to_dict from shared.services.registry import services def register() -> Blueprint: bp = Blueprint("data", __name__, url_prefix="/internal/data") @bp.before_request async def _require_data_header(): if not request.headers.get(DATA_HEADER): return jsonify({"error": "forbidden"}), 403 from shared.infrastructure.internal_auth import validate_internal_request if not validate_internal_request(): return jsonify({"error": "forbidden"}), 403 _handlers: dict[str, object] = {} @bp.get("/") async def handle_query(query_name: str): handler = _handlers.get(query_name) if handler is None: return jsonify({"error": "unknown query"}), 404 result = await handler() return jsonify(result) # --- marketplaces-for-container --- async def _marketplaces_for_container(): container_type = request.args.get("type", "") container_id = request.args.get("id", type=int) markets = await services.market.marketplaces_for_container( g.s, container_type, container_id, ) return [dto_to_dict(m) for m in markets] _handlers["marketplaces-for-container"] = _marketplaces_for_container # --- products-by-ids --- async def _products_by_ids(): """Return product details for a list of IDs (comma-separated).""" from sqlalchemy import select from shared.models.market import Product ids_raw = request.args.get("ids", "") try: ids = [int(x) for x in ids_raw.split(",") if x.strip()] except ValueError: return {"error": "ids must be comma-separated integers"}, 400 if not ids: return [] rows = (await g.s.execute( select(Product).where(Product.id.in_(ids)) )).scalars().all() return [ { "id": p.id, "title": p.title, "slug": p.slug, "image": p.image, "regular_price": str(p.regular_price) if p.regular_price is not None else None, "special_price": str(p.special_price) if p.special_price is not None else None, } for p in rows ] _handlers["products-by-ids"] = _products_by_ids # --- marketplaces-by-ids --- async def _marketplaces_by_ids(): """Return marketplace data for a list of IDs (comma-separated).""" from sqlalchemy import select from shared.models.market_place import MarketPlace ids_raw = request.args.get("ids", "") try: ids = [int(x) for x in ids_raw.split(",") if x.strip()] except ValueError: return {"error": "ids must be comma-separated integers"}, 400 if not ids: return [] rows = (await g.s.execute( select(MarketPlace).where(MarketPlace.id.in_(ids)) )).scalars().all() return [ { "id": m.id, "name": m.name, "slug": m.slug, "container_type": m.container_type, "container_id": m.container_id, } for m in rows ] _handlers["marketplaces-by-ids"] = _marketplaces_by_ids return bp