Écriture de sélection câblée (PUT cart) + auth par cookie storage_state

Découvert via attache CDP au vrai Chrome (contourne le blocage automation) :
- set_selection = PUT /gw/v1/carts/{week}, body {meals:[{index,quantity}], extras:[]}
  sélection par index de course, params (customer/subscription/sku/cutoff) dérivés
  dynamiquement de /subscriptions + /deliveries (aucun id en dur)
- Recipe.course_index conservé depuis le menu pour le mapping id->index
- get_editable_weeks via /deliveries (modèle Delivery: cutoff, status, editable)
- Token lu depuis le cookie apiV2Auth (storage_state) -> auth sans navigateur, headless OK
- hf_confirm_selection: garde-fou coco + dry_run; tool attach_capture.py ajouté
- Dry-run validé: requête identique à l'appel réel capturé
This commit is contained in:
2026-06-15 22:57:36 +02:00
parent 30b950ec41
commit 051ecb50d8
9 changed files with 388 additions and 69 deletions

View File

@@ -30,6 +30,7 @@ class Recipe:
tags: list[str] = field(default_factory=list)
image_url: str = ""
prep_time: str = ""
course_index: int | None = None # index du course dans le menu (sert à l'écriture)
# Champs calculés par le filtre (remplis plus tard)
contains_excluded: bool = False
matched_excludes: list[str] = field(default_factory=list)
@@ -100,6 +101,31 @@ class Recipe:
}
@dataclass
class Delivery:
"""Semaine de livraison de l'abonnement (issue de /deliveries)."""
week: str
delivery_date: str = ""
cutoff_date: str = ""
status: str = ""
editable: bool = False
@classmethod
def from_api(cls, raw: dict[str, Any]) -> "Delivery":
actionable = bool(_first(raw, "actionable", "isEditable", default=False))
status = str(_first(raw, "status", default=""))
return cls(
week=str(_first(raw, "id", "week", "handle", default="")),
delivery_date=str(_first(raw, "deliveryDate", "date", default="")),
cutoff_date=str(_first(raw, "cutoffDate", "cutoff", default="")),
status=status,
editable=actionable and status.upper() not in ("SKIPPED", "DELIVERED", "CUTOFF"),
)
def to_dict(self) -> dict[str, Any]:
return asdict(self)
@dataclass
class Week:
id: str # handle de semaine, ex. "2026-W25"