Une taille de boisson est un produit a part entiere (modele identique a
Moyenne Frite / Grande Frite) : nouvelle colonne product.base_product_id
(self-FK ON DELETE CASCADE) groupe les variantes sous leur base, size_cl
porte le volume. Les variantes sont masquees de la grille catalogue
(availableForCatalogue ET findForCatalogue filtrent base_product_id IS NULL :
une 50cl ne s'atteint que via le picker de taille de sa base, jamais en
fiche autonome ni par lien direct). /api/products expose un tableau sizes[]
par base, charge en une requete (sizesByBase, pas de N+1). Le picker borne
(CSP-safe) resout la taille choisie en product_id ; le domaine commande
facture par product_id, flux inchange (resolveLine), stock decremente via
la recette propre de la variante.
Migration 0007 + seed 0005 idempotents (verifies sur MariaDB reel :
migration x2, seed x3, comptes stables, CASCADE confirme). Revue
bmad-compliance : 1 must_fix (filtre findForCatalogue) corrige, mantras 92%.