Sur un PIN invalide, ProductController ecrivait la trace audit pin.failed
(autocommit) PUIS appelait PinThrottle::recordFailure (qui ouvrait SA propre
transaction) : deux ecritures non atomiques, un crash entre les deux laissait un
etat partiel, en tension avec le claim RG-T08 (audit dans la meme transaction que
l'effet).
- PinThrottle : extraction de recordFailureWithin(db, ...) (memes effets, SANS
transaction propre) ; recordFailure() reste l'API autonome (l'enveloppe).
- ProductController (update + destroy) : les chemins d'echec PIN enveloppent
logFailedPin(, ...) + recordFailureWithin(, ...) dans UNE transaction.
- logFailedPin prend desormais le de la transaction.
Aucun changement de test necessaire (les assertions audit/throttle tiennent dans
la transaction). 188 verts, PinThrottleDbTest 2/2 contre la vraie DB, PHPStan L6.