Premier League Predictor: FastAPI & Redis — Chapter 9, Exercise 2 ================================================================= TASK Call the rollover script directly on a 20-team season with only one fixture entered, and report which clubs it relegates. Then call it a second time and report the result and what happened to the season ID that call took. SOLUTION Setup: season 1 has 20 teams at score -500000 and a single 3-0 result entered for team 1 v team 2. New season ID from INCR: 2. rollover (first call) -> 17 relegated (ZRANGE season:1:table -3 -1) -> ['019', '020', '002'] The script rolled 17 clubs into season 2 and left team 2 (which had just lost) and two clubs that had not played at all as the "bottom three". Nothing in the script checks that the season is finished; the season_complete check exists only in the route, so calling the script directly bypasses it. Second call, with a new ID from INCR (3): rollover (second call) -> -1 season IDs taken: 2 and 3 EXISTS season:3 -> 0 The rolled-over flag (season:1:rolled) already existed, so the script returned -1 before writing anything. Season ID 3 was taken by INCR before the script ran and is never used - a harmless gap. The alternative, claiming the flag first and taking the ID afterwards, would leave a half-finished rollover if the process died between the two steps. Fix for the first problem: keep the completeness check in the route AND make sure nothing else calls the script; or pass a completeness result into the script and refuse there. WHY THIS WORKS AS AN ANSWER ---------------------------- It shows that a guard living outside the atomic script can be bypassed, with the actual wrong relegation as evidence, and explains the burned ID from the order of operations rather than treating it as a bug.