-- Per-instance match-contract counter on an owned instance.
--
-- NULLABLE ON PURPOSE. NULL means "Core tracks no contract for this instance",
-- which is NOT the same as zero: a game whose contracts start at a pack-fresh
-- default (FIFA 17 hands out 7) must supply that default itself, so the number
-- stays in the game adapter and never becomes a Core constant. Every row that
-- pre-dates this migration therefore reads back NULL and keeps its exact prior
-- meaning — the migration is a pure widening, not a backfill.
--
-- `>= 0` only: the cap is a per-application input (the caller's game rule), not
-- a schema invariant, so the CHECK refuses the one value that is nonsense in
-- every game rather than pinning someone else's ceiling.
--
-- ALTER TABLE ADD COLUMN, NEVER a table rebuild: `owned_cards` carries the
-- `clear_club_active_item_before_transfer` trigger installed by 0026, and a
-- DROP/recreate would silently take it with it — exactly the failure 0026:44-46
-- documents for 0024's trigger.
ALTER TABLE owned_cards ADD COLUMN contract_matches INTEGER
    CHECK (contract_matches IS NULL OR contract_matches >= 0);
