UI web : statut de connexion HelloFresh + checkbox recettes premium

- Carte « Connexion HelloFresh » (pastille + bouton Rafraîchir) via un nouvel
  endpoint GET /api/auth-status (auth.auth_status, vérifié contre l'API, déporté
  dans un thread pour ne pas figer la boucle asyncio).
- Checkbox « Recettes premium » : réglage persistant allow_premium dans
  config/prefs.json (load/save_allow_premium dans filter.py), exposé par
  /api/config et piloté par PUT /api/allow-premium.
- Le réglage devient le défaut côté MCP : hf_propose inclut/écarte les premium
  selon la case (le signale dans allow_premium/note), hf_confirm_selection
  reprend ce défaut quand allow_premium n'est pas passé explicitement.
- .dockerignore ajouté.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-18 20:23:44 +02:00
parent ad2b00c425
commit 29ac984113
5 changed files with 163 additions and 16 deletions

View File

@@ -159,18 +159,23 @@ async def hf_propose(week: str = "", count: int = 0) -> dict:
"""
def _impl() -> dict:
w = week or api.current_week()
allow_premium = hf_filter.load_allow_premium()
with api.HelloFreshClient() as client:
recipes = client.get_menu(w)
safe = hf_filter.propose(recipes, count=count or None)
safe = hf_filter.propose(recipes, count=count or None, allow_premium=allow_premium)
excluded = [r.summary() for r in recipes if r.contains_excluded]
premium = [r.summary() for r in recipes if r.is_premium and not r.contains_excluded]
premium_note = ("Recettes premium (supplément) INCLUSES dans la proposition (réglage UI activé). "
if allow_premium else
"Les recettes premium (supplément) sont exclues de la proposition. ")
return {
"week": w,
"allow_premium": allow_premium,
"proposed": [r.summary() for r in safe],
"excluded_for_coco_etc": excluded,
"premium_extra_cost": premium,
"note": "Aucune écriture effectuée. Les recettes premium (supplément) sont exclues "
"de la proposition. Confirme avec hf_confirm_selection(week, recipe_ids).",
"note": "Aucune écriture effectuée. " + premium_note
+ "Confirme avec hf_confirm_selection(week, recipe_ids).",
}
return await anyio.to_thread.run_sync(_impl)
@@ -178,14 +183,17 @@ async def hf_propose(week: str = "", count: int = 0) -> dict:
@mcp.tool()
async def hf_confirm_selection(week: str, recipe_ids: list[str], dry_run: bool = False,
allow_premium: bool = False) -> dict:
allow_premium: bool | None = None) -> dict:
"""ÉCRIT la sélection de recettes dans la box de la semaine (après confirmation).
Garde-fous : refuse toute recette contenant un ingrédient exclu (coco !) ET toute
recette payante hors abonnement (premium, supplément) sauf si `allow_premium=True`.
`allow_premium=None` (défaut) reprend le réglage de l'UI web (prefs.json) ; passer
True/False ici l'emporte ponctuellement sur ce réglage.
`dry_run=True` : construit et renvoie la requête sans l'envoyer (vérification).
"""
def _impl() -> dict:
allow = hf_filter.load_allow_premium() if allow_premium is None else allow_premium
with api.HelloFreshClient() as client:
menu = client.get_menu(week)
hf_filter.annotate(menu)
@@ -199,7 +207,7 @@ async def hf_confirm_selection(week: str, recipe_ids: list[str], dry_run: bool =
}
premium = [rid for rid in recipe_ids
if rid in by_id and by_id[rid].is_premium]
if premium and not allow_premium:
if premium and not allow:
return {
"ok": False,
"error": "Sélection refusée : recette(s) payante(s) hors abonnement (supplément). "