fix(mcp): status active + search_products guard + item.product + cleanup auto-name

This commit is contained in:
2026-05-28 06:41:04 +02:00
parent 87efbcb03d
commit 5d7dbec67c
2 changed files with 27 additions and 18 deletions
+19 -18
View File
@@ -361,19 +361,19 @@ async def get_shopping_lists() -> str:
@mcp.tool()
async def get_active_shopping_list() -> str:
"""Retourne la première liste en statut 'draft' avec tous ses articles triés."""
"""Retourne la première liste en statut 'draft' ou 'active' avec tous ses articles triés."""
async with AsyncSessionLocal() as session:
stmt = (
select(ShoppingList)
.where(ShoppingList.status == "draft")
.where(ShoppingList.status.in_(["draft", "active"]))
.options(selectinload(ShoppingList.items).selectinload(ListItem.product))
.order_by(ShoppingList.created_at.desc())
.order_by(ShoppingList.status.asc(), ShoppingList.created_at.desc())
.limit(1)
)
result = await session.execute(stmt)
lst = result.scalar_one_or_none()
if not lst:
return _dumps({"error": "Aucune liste active (statut draft)"})
return _dumps({"error": "Aucune liste active (statut draft ou active)"})
sorted_items = sorted(lst.items, key=lambda i: (i.sort_order or 999, str(i.id)))
return _dumps({
"id": lst.id,
@@ -394,6 +394,8 @@ async def get_active_shopping_list() -> str:
@mcp.tool()
async def search_products(q: str) -> str:
"""Recherche dans le catalogue produits par nom, description ou catégorie."""
if not q or not q.strip():
return _dumps({"error": "Paramètre q requis"})
async with AsyncSessionLocal() as session:
stmt = (
select(Product)
@@ -490,19 +492,18 @@ async def check_shopping_item(list_id: str, item_id: str) -> str:
return _dumps({"error": f"Article introuvable : {item_id} dans liste {list_id}"})
was_checked = item.is_checked
item.is_checked = True
if not was_checked and item.product_id:
product = await session.get(Product, item.product_id)
if product:
today = date_type.today()
if product.last_purchased_at and product.last_purchased_at < today:
days = (today - product.last_purchased_at).days
if product.avg_interval_days is None:
product.avg_interval_days = Decimal(str(days))
else:
product.avg_interval_days = Decimal(str(
round(float(product.avg_interval_days) * 0.7 + days * 0.3, 1)
))
product.last_purchased_at = today
product.frequency_score += 1
if not was_checked and item.product:
product = item.product
today = date_type.today()
if product.last_purchased_at and product.last_purchased_at < today:
days = (today - product.last_purchased_at).days
if product.avg_interval_days is None:
product.avg_interval_days = Decimal(str(days))
else:
product.avg_interval_days = Decimal(str(
round(float(product.avg_interval_days) * 0.7 + days * 0.3, 1)
))
product.last_purchased_at = today
product.frequency_score += 1
await session.commit()
return _dumps({"id": item.id, "is_checked": item.is_checked})