
Sur l'exemple de la doc, un billet de 89 $ annulé avec 10 jours de préavis passe de remboursement intégral en novembre 2025 à 0,00 $ en 2026, sans modification de l'appel. Pour qui doit justifier un calcul tarifaire des mois après coup, c'est une brique à jauger entre prod-ready et sur-ingénierie.
Résolution: priorité, validité temporelle, héritage
Chaque règle est une classe PHP standard, pas de DSL. Le résolveur trie par priorité décroissante, filtre par fenêtre de validité temporelle, retourne un unique gagnant. La sortie expose le statut de chaque règle considérée — applied, outside_validity, skipped — ce qui permet de distinguer une absence de politique d'un rejet post-évaluation, distinction qu'un simple match ne fournit pas. L'exemple canonique: une politique de remboursement qui bascule au 1er janvier 2026 de 7 jours de préavis et remboursement intégral à 14 jours plus 3,50 $ de frais de dossier. La classe parent porte la logique d'éligibilité commune; chaque année fille injecte ses propres paramètres (délai, frais). Deux règles de priorité inférieure complètent l'ensemble — remboursement partiel au-delà de 30 jours, défaut no refund. Quatre classes, un calendrier, zéro état externe, zéro runtime éditable.
Snapshot: canaux de persistance et piège du FQCN
snapshot retourne un objet JsonSerializable. Trois canaux selon le sink: json_encode direct pour un stockage brut, toArray pour une colonne Eloquent avec cast array, callback de transformation pour les objets non scalaires. Scalars, arrays, backed enums et JsonSerializable traversent la sérialisation tels quels. Le champ key identifie la règle — par défaut, son FQCN. Conséquence immédiate: tout renommage de classe change la clé dans tous les snapshots déjà persistés, ce qui rend la requête d'historique silencieusement invalide. L'auteur recommande de poser un key stable du type refunds.flexible-fare.2026 avant la première écriture en base. Sans cette discipline, l'historique devient orphelin à la première refacto.
Limites assumées et verdict
Le package ne fait pas de replay d'exécution: résoudre une décision passée la recalcule avec le code actuel des classes, pas avec le code qui tournait à l'époque. Conséquence directe: ce n'est pas un audit trail complet. Pas de state machine, pas de composition de plusieurs gagnants, pas d'édition runtime via admin. Pour un check ponctuel sur une seule date dans un seul service, un match PHP reste plus lisible et plus rapide. À utiliser en prod uniquement si le métier exige une trace explicable mois après mois et que la rotation des règles est versionnée en parallèle du code. Sinon: sur-ingénierie assumée.