From cebea2ac86e17b05f59f6cec94bb030856f0e873 Mon Sep 17 00:00:00 2001 From: Piotr Oleszczyk Date: Sun, 8 Mar 2026 11:55:16 +0100 Subject: [PATCH] fix(api): avoid distinct on json product fields in shopping suggestions --- backend/innercontext/api/products.py | 6 +++--- backend/tests/test_products_helpers.py | 19 ++++++++++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/backend/innercontext/api/products.py b/backend/innercontext/api/products.py index 08d42f2..0763d37 100644 --- a/backend/innercontext/api/products.py +++ b/backend/innercontext/api/products.py @@ -1082,12 +1082,12 @@ def suggest_shopping(session: Session = Depends(get_session)): raise HTTPException(status_code=502, detail=f"LLM returned invalid JSON: {e}") # Get products with inventory (those user already owns) - products_with_inventory = session.exec( - select(Product).join(ProductInventory).distinct() + products_with_inventory_ids = session.exec( + select(ProductInventory.product_id).distinct() ).all() shopping_context = ShoppingValidationContext( - owned_product_ids=set(p.id for p in products_with_inventory), + owned_product_ids=set(products_with_inventory_ids), valid_categories=set(ProductCategory), valid_targets=set(SkinConcern), ) diff --git a/backend/tests/test_products_helpers.py b/backend/tests/test_products_helpers.py index 283eb11..5940875 100644 --- a/backend/tests/test_products_helpers.py +++ b/backend/tests/test_products_helpers.py @@ -87,6 +87,23 @@ def test_suggest_shopping(client, session): with patch( "innercontext.api.products.call_gemini_with_function_tools" ) as mock_gemini: + product = Product( + id=uuid.uuid4(), + short_id=str(uuid.uuid4())[:8], + name="Owned Serum", + brand="BrandX", + category="serum", + recommended_time="both", + leave_on=True, + product_effect_profile={}, + ) + session.add(product) + session.commit() + session.add( + ProductInventory(id=uuid.uuid4(), product_id=product.id, is_opened=True) + ) + session.commit() + mock_response = type( "Response", (), @@ -94,7 +111,7 @@ def test_suggest_shopping(client, session): "text": '{"suggestions": [{"category": "cleanser", "product_type": "cleanser", "priority": "high", "key_ingredients": [], "target_concerns": [], "why_needed": "reason", "recommended_time": "am", "frequency": "daily"}], "reasoning": "Test shopping"}' }, ) - mock_gemini.return_value = mock_response + mock_gemini.return_value = (mock_response, None) r = client.post("/products/suggest") assert r.status_code == 200