PR-A du lot P3 stock. Couche complete de gestion des ingredients et du
stock, gardee par des permissions distinctes par operation :
- CRUD ingredient (8.8) : ingredient.manage, sans PIN (hors set RG-T13).
Conflit d'unicite name + hard-delete bloque par FK RESTRICT -> 409.
- RESTOCK (9.1) : stock.manage, sans PIN ; +N packs -> stock += N*pack_size
+ stock_movement(restock) dans une transaction ; order_id NULL (RG-I6).
- INVENTORY_COUNT (9.2) : stock.count + PIN equipier (RG-T13). Ecrit une
ligne stock_movement(inventory_correction) MEME si delta=0 (RG-3).
Succes -> stock_movement.user_id (acteur resolu par PIN), PAS d'audit_log
(RG-T14). Echec PIN -> pin.failed + throttle dans UNE transaction (RG-T22).
- READ_STOCK (9.3) : stock.read ; user_id des mouvements visible
manager/admin seulement (RG-4).
Tests : 239 / 717 assertions verts (WAKDO_DB_TESTS=1, 24 d'integration DB
reels), PHPStan L6 propre.