"""Vocabulaire du `PhraseMatcher` d'ustensiles — contrairement à `training_data.py`, ce catalogue n'a jamais existé côté `apps/api` avant ce service : il est *né* ici, pas rapatrié depuis TypeScript. Chaque `uid` ci-dessous doit avoir une entrée `UTENSILS` correspondante (`reference-seed-data.ts` côté `apps/api`) et un libellé `catalog.utensils.` (`apps/web`'s `locales/fr/translation.json`). Un seul type de contenu par ustensile/locale (contrairement à `TechStepTrainingEntry`'s `synonyms`/`utterances`) : un ustensile mentionné n'a pas besoin d'être *interprété* comme une technique peut l'être (`préchauffer` vs `chauffer` dépend du contexte ; `poêle` n'en dépend pas) — juste reconnu, comme les `synonyms` de `training_data.py` alimentent le `PhraseMatcher` de techniques. Pas de `textcat` équivalent ici, voir `LocalePipeline`'s propre commentaire sur `_utensil_matcher`. """ from dataclasses import dataclass, field @dataclass(frozen=True) class UtensilLocaleVocabulary: synonyms: list[str] = field(default_factory=list) @dataclass(frozen=True) class UtensilEntry: """`uid` doit correspondre à un `Utensil.key`.""" uid: str fr: UtensilLocaleVocabulary en: UtensilLocaleVocabulary UTENSIL_VOCABULARY: list[UtensilEntry] = [ UtensilEntry( uid="pan", fr=UtensilLocaleVocabulary(synonyms=["poêle", "sauteuse", "poêle antiadhésive"]), en=UtensilLocaleVocabulary(synonyms=["pan", "frying pan", "skillet"]), ), UtensilEntry( uid="saucepan", fr=UtensilLocaleVocabulary(synonyms=["casserole", "petite casserole"]), en=UtensilLocaleVocabulary(synonyms=["saucepan", "sauce pan"]), ), UtensilEntry( uid="pot", fr=UtensilLocaleVocabulary(synonyms=["marmite", "faitout", "cocotte"]), en=UtensilLocaleVocabulary(synonyms=["pot", "stockpot", "dutch oven"]), ), UtensilEntry( uid="knife", fr=UtensilLocaleVocabulary(synonyms=["couteau", "couteau de cuisine", "couteau d'office"]), en=UtensilLocaleVocabulary(synonyms=["knife", "kitchen knife", "chef's knife"]), ), UtensilEntry( uid="whisk", fr=UtensilLocaleVocabulary(synonyms=["fouet"]), en=UtensilLocaleVocabulary(synonyms=["whisk"]), ), UtensilEntry( uid="bowl", fr=UtensilLocaleVocabulary(synonyms=["saladier", "bol", "cul-de-poule"]), en=UtensilLocaleVocabulary(synonyms=["bowl", "mixing bowl"]), ), UtensilEntry( uid="bakingSheet", fr=UtensilLocaleVocabulary(synonyms=["plaque de cuisson", "plaque à pâtisserie", "plaque du four"]), en=UtensilLocaleVocabulary(synonyms=["baking sheet", "baking tray", "sheet pan"]), ), UtensilEntry( uid="mold", fr=UtensilLocaleVocabulary(synonyms=["moule", "moule à gâteau", "moule à cake"]), en=UtensilLocaleVocabulary(synonyms=["mold", "mould", "baking pan"]), ), UtensilEntry( uid="colander", fr=UtensilLocaleVocabulary(synonyms=["passoire", "égouttoir"]), en=UtensilLocaleVocabulary(synonyms=["colander", "strainer"]), ), UtensilEntry( uid="cuttingBoard", fr=UtensilLocaleVocabulary(synonyms=["planche à découper"]), en=UtensilLocaleVocabulary(synonyms=["cutting board", "chopping board"]), ), UtensilEntry( uid="oven", fr=UtensilLocaleVocabulary(synonyms=["four"]), en=UtensilLocaleVocabulary(synonyms=["oven"]), ), UtensilEntry( uid="blender", fr=UtensilLocaleVocabulary(synonyms=["blender", "mixeur plongeant", "mixeur girafe"]), en=UtensilLocaleVocabulary(synonyms=["blender", "immersion blender"]), ), UtensilEntry( uid="mixer", fr=UtensilLocaleVocabulary(synonyms=["batteur", "batteur électrique", "robot pâtissier"]), en=UtensilLocaleVocabulary(synonyms=["mixer", "stand mixer", "hand mixer"]), ), UtensilEntry( uid="spatula", fr=UtensilLocaleVocabulary(synonyms=["spatule", "maryse"]), en=UtensilLocaleVocabulary(synonyms=["spatula"]), ), UtensilEntry( uid="ladle", fr=UtensilLocaleVocabulary(synonyms=["louche"]), en=UtensilLocaleVocabulary(synonyms=["ladle"]), ), UtensilEntry( uid="grater", fr=UtensilLocaleVocabulary(synonyms=["râpe"]), en=UtensilLocaleVocabulary(synonyms=["grater"]), ), UtensilEntry( uid="rollingPin", fr=UtensilLocaleVocabulary(synonyms=["rouleau à pâtisserie"]), en=UtensilLocaleVocabulary(synonyms=["rolling pin"]), ), UtensilEntry( uid="lid", fr=UtensilLocaleVocabulary(synonyms=["couvercle"]), en=UtensilLocaleVocabulary(synonyms=["lid"]), ), UtensilEntry( uid="tongs", fr=UtensilLocaleVocabulary(synonyms=["pince", "pince de cuisine"]), en=UtensilLocaleVocabulary(synonyms=["tongs"]), ), UtensilEntry( uid="peeler", fr=UtensilLocaleVocabulary(synonyms=["économe", "éplucheur"]), en=UtensilLocaleVocabulary(synonyms=["peeler", "vegetable peeler"]), ), UtensilEntry( uid="sieve", fr=UtensilLocaleVocabulary(synonyms=["tamis", "chinois"]), en=UtensilLocaleVocabulary(synonyms=["sieve"]), ), UtensilEntry( uid="foodProcessor", fr=UtensilLocaleVocabulary(synonyms=["robot ménager", "robot de cuisine", "robot culinaire"]), en=UtensilLocaleVocabulary(synonyms=["food processor"]), ), UtensilEntry( uid="steamerBasket", fr=UtensilLocaleVocabulary(synonyms=["panier vapeur", "cuit-vapeur"]), en=UtensilLocaleVocabulary(synonyms=["steamer basket", "steamer"]), ), UtensilEntry( uid="skewer", fr=UtensilLocaleVocabulary(synonyms=["brochette", "pique en bois"]), en=UtensilLocaleVocabulary(synonyms=["skewer"]), ), UtensilEntry( uid="pastryBrush", fr=UtensilLocaleVocabulary(synonyms=["pinceau de cuisine", "pinceau à pâtisserie"]), en=UtensilLocaleVocabulary(synonyms=["pastry brush", "basting brush"]), ), UtensilEntry( uid="ramekin", fr=UtensilLocaleVocabulary(synonyms=["ramequin"]), en=UtensilLocaleVocabulary(synonyms=["ramekin"]), ), UtensilEntry( uid="dish", fr=UtensilLocaleVocabulary(synonyms=["plat", "plat à gratin", "plat allant au four"]), en=UtensilLocaleVocabulary(synonyms=["dish", "baking dish", "gratin dish"]), ), UtensilEntry( uid="wok", fr=UtensilLocaleVocabulary(synonyms=["wok"]), en=UtensilLocaleVocabulary(synonyms=["wok"]), ), UtensilEntry( uid="thermometer", fr=UtensilLocaleVocabulary(synonyms=["thermomètre", "thermomètre de cuisson"]), en=UtensilLocaleVocabulary(synonyms=["thermometer"]), ), UtensilEntry( uid="mandoline", fr=UtensilLocaleVocabulary(synonyms=["mandoline"]), en=UtensilLocaleVocabulary(synonyms=["mandoline"]), ), ] def synonyms_for_locale(locale: str) -> dict[str, list[str]]: """Aplati {@link UTENSIL_VOCABULARY} en `{uid: synonyms}` pour une seule locale — la forme que `LocalePipeline.preload()` attend pour construire son `PhraseMatcher` d'ustensiles. Miroir de `training_data.entries_for_locale`, en plus simple (pas d'`utterances`, un seul champ à extraire).""" return { entry.uid: getattr(entry, locale).synonyms for entry in UTENSIL_VOCABULARY if hasattr(entry, locale) }