Decouple cart/market DBs: denormalize product data, AP internal inbox, OAuth scraper auth
Remove cross-DB relationships (CartItem.product, CartItem.market_place, OrderItem.product) that break with per-service databases. Denormalize product and marketplace fields onto cart_items/order_items at write time. - Add AP internal inbox infrastructure (shared/infrastructure/internal_inbox*) for synchronous inter-service writes via HMAC-authenticated POST - Cart inbox blueprint handles Add/Remove/Update rose:CartItem activities - Market app sends AP activities to cart inbox instead of writing CartItem directly - Cart services use denormalized columns instead of cross-DB hydration/joins - Add marketplaces-by-ids data endpoint to market service - Alembic migration adds denormalized columns to cart_items and order_items - Add OAuth device flow auth to market scraper persist_api (artdag client pattern) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,16 @@
|
||||
# replace your existing upsert_product with this version
|
||||
|
||||
import os
|
||||
import httpx
|
||||
|
||||
from typing import List
|
||||
|
||||
from ..auth import auth_headers
|
||||
|
||||
async def capture_listing(
|
||||
url: str,
|
||||
items: List[str],
|
||||
total_pages: int
|
||||
):
|
||||
|
||||
|
||||
sync_url = os.getenv("CAPTURE_LISTING_URL", "http://localhost:8001/market/suma-market/api/products/listing/")
|
||||
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client:
|
||||
@@ -19,7 +19,7 @@ async def capture_listing(
|
||||
"items": items,
|
||||
"total_pages": total_pages
|
||||
}
|
||||
resp = await client.post(sync_url, json=_d)
|
||||
resp = await client.post(sync_url, json=_d, headers=auth_headers())
|
||||
# Raise for non-2xx
|
||||
resp.raise_for_status()
|
||||
data = resp.json() if resp.content else {}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# replace your existing upsert_product with this version
|
||||
|
||||
import os
|
||||
import httpx
|
||||
|
||||
from ..auth import auth_headers
|
||||
|
||||
|
||||
async def log_product_result(
|
||||
ok: bool,
|
||||
payload
|
||||
):
|
||||
|
||||
|
||||
sync_url = os.getenv("PRODUCT_LOG_URL", "http://localhost:8000/market/api/products/log/")
|
||||
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client:
|
||||
@@ -16,7 +16,7 @@ async def log_product_result(
|
||||
"ok": ok,
|
||||
"payload": payload
|
||||
}
|
||||
resp = await client.post(sync_url, json=_d)
|
||||
resp = await client.post(sync_url, json=_d, headers=auth_headers())
|
||||
# Raise for non-2xx
|
||||
resp.raise_for_status()
|
||||
data = resp.json() if resp.content else {}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
# replace your existing upsert_product with this version
|
||||
|
||||
import os
|
||||
import httpx
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from ..auth import auth_headers
|
||||
|
||||
async def save_nav(
|
||||
nav: Dict,
|
||||
):
|
||||
sync_url = os.getenv("SAVE_NAV_URL", "http://localhost:8001/market/suma-market/api/products/nav/")
|
||||
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client:
|
||||
resp = await client.post(sync_url, json=nav)
|
||||
resp = await client.post(sync_url, json=nav, headers=auth_headers())
|
||||
# Raise for non-2xx
|
||||
resp.raise_for_status()
|
||||
data = resp.json() if resp.content else {}
|
||||
|
||||
@@ -3,11 +3,13 @@ import httpx
|
||||
|
||||
from typing import Dict
|
||||
|
||||
from ..auth import auth_headers
|
||||
|
||||
async def save_subcategory_redirects(mapping: Dict[str, str]) -> None:
|
||||
sync_url = os.getenv("SAVE_REDIRECTS", "http://localhost:8000/market/api/products/redirects/")
|
||||
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client:
|
||||
resp = await client.post(sync_url, json=mapping)
|
||||
resp = await client.post(sync_url, json=mapping, headers=auth_headers())
|
||||
# Raise for non-2xx
|
||||
resp.raise_for_status()
|
||||
data = resp.json() if resp.content else {}
|
||||
|
||||
@@ -5,6 +5,8 @@ import httpx
|
||||
|
||||
from typing import Dict, List, Any
|
||||
|
||||
from ..auth import auth_headers
|
||||
|
||||
async def upsert_product(
|
||||
slug,
|
||||
href,
|
||||
@@ -30,7 +32,7 @@ async def upsert_product(
|
||||
|
||||
async def _do_call() -> Dict[str, Any]:
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(20.0, connect=10.0)) as client:
|
||||
resp = await client.post(sync_url, json=payload)
|
||||
resp = await client.post(sync_url, json=payload, headers=auth_headers())
|
||||
resp.raise_for_status()
|
||||
# tolerate empty body
|
||||
if not resp.content:
|
||||
|
||||
Reference in New Issue
Block a user