90210702c3
CI / Build, lint & test (push) Successful in 3m25s
Corrects two decisions the previous revision got wrong, both now settled by the published FIFA 17 training guide -- the same source class and publisher this project already accepted for the contract matrix, and which cross-validates 6/6 against fcc_trainingcards on rows we had misclassified. "You can only boost one attribute or all six... When you apply a new training card to a player, he loses the improved attributes of previous training cards. It does not accumulate, it replaces." So a second card REPLACES rather than being refused, and two slots must never be boosted at once -- our old composite key permitted exactly that, and staging demonstrated it by holding a slot-4 and a slot-1 effect together. Migration 0030 reshapes the table to one row per instance keyed on owned_card_id alone, with attribute_index nullable for the rare all-six card, and carries forward the most recent effect where several existed -- the replaces rule applied retroactively. 0029 is left intact rather than rewritten: it is already applied to supervised staging, where migration history matters. Apply is now delete-then-insert inside the one transaction, so the old effect cannot survive a failed insert and the two cannot coexist. The outcome records what it displaced instead of overwriting history silently. The previous refusal was OUR policy standing in for an unknown, and it was never evidence about FIFA 17. It is retired now that the behaviour is recovered, not because the 409 was inconvenient.