From a24e5c6407b3fa00f05a6786c5e55471c58482e0 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 14 Feb 2026 17:35:55 +0000 Subject: [PATCH] Phase 5: Replace HTTP cart adoption with event-driven adoption Emit user.logged_in event instead of HTTP POST to /internal/cart/adopt. Event is emitted inside the last_login_at transaction for atomicity. Co-Authored-By: Claude Opus 4.6 --- bp/auth/routes.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/bp/auth/routes.py b/bp/auth/routes.py index a8574d9..d58a55a 100644 --- a/bp/auth/routes.py +++ b/bp/auth/routes.py @@ -31,7 +31,7 @@ from shared.infrastructure.urls import coop_url from sqlalchemy.orm import selectinload from shared.browser.app.redis_cacher import clear_cache from shared.infrastructure.cart_identity import current_cart_identity -from shared.infrastructure.internal_api import post as api_post +from shared.events import emit_event from .services import pop_login_redirect_target, store_login_redirect_target from .services.auth_operations import ( get_app_host, @@ -254,20 +254,23 @@ def register(url_prefix="/auth"): u2 = await s.get(User, user_id) if u2: u2.last_login_at = now - # s.begin() will commit on successful exit + # Emit adoption event inside this transaction + if anon_session_id: + await emit_event( + s, + "user.logged_in", + "user", + user_id, + { + "user_id": user_id, + "session_id": anon_session_id, + }, + ) except SQLAlchemyError: current_app.logger.exception( "[auth] non-fatal DB update after Ghost upsert for user_id=%s", user_id ) - # Adopt cart + calendar entries via cart app internal API - if anon_session_id: - await api_post( - "cart", - "/internal/cart/adopt", - json={"user_id": user_id, "session_id": anon_session_id}, - ) - # ---- Finalize login ---- qsession[SESSION_USER_KEY] = user_id