Le refresh du token passe désormais par POST /gw/refresh (l'endpoint que la
SPA appelle) au lieu d'un navigateur headless : pur httpx, refresh_token rotaté
persisté dans token.json, fenêtre 60j remise à zéro à chaque refresh. Lock
single-flight pour la rotation. get_token()/auth_status() tentent /gw/refresh
avant le filet Playwright. Homelab allumé = authentifié indéfiniment, sans re-sync.
- capture_token s'appuie sur storage_state.json (cookies ~60j) en new_context :
fonctionne headless, la SPA rafraîchit le token (contourne l'anti-bot OAuth)
- session 'roule' (storage_state ré-exporté à chaque refresh) ; access token 30min,
refresh token 60j
- goto en domcontentloaded + attente (networkidle ne se déclenche jamais sur la SPA)
- Dockerfile/Playwright alignés en 1.60.0 (chromium préinstallé) ; doc déploiement maj :
session créée via attach_capture (login direct Playwright bloqué par anti-bot)
- Endpoints découverts: menu (menus-service) + détails batch (recipes/recipes)
- get_menu en 2 temps: menu (ids) -> batch détails (ingrédients/allergènes)
- Fix faux positifs: exclusion sur ingrédients/allergènes/nom, plus sur les tags
(HelloFresh pose un tag interne 'coconut' sur ~la moitié des recettes)
- Token mis en cache (pas de navigateur si frais)
- endpoints.json versionné (sans secret), semaine optionnelle (défaut = courante)
- Testé: 4 recettes coco/85 détectées, shortlist classée, tous les outils MCP OK
- set_selection (écriture) reste à découvrir sur un compte avec box active