Premier League Predictor: FastAPI & PostgreSQL — Chapter 4, Exercise 2 ==================================================== TASK Explain why usedTeamIds is described as "convenience, not the real rule," and describe exactly what happens — on both the client and the server — if a stale page somehow submits a fixture for a team that's already been used in that gameweek. SOLUTION usedTeamIds is a plain JavaScript Set that only lives in the browser's own memory for as long as the page has been open. It starts completely empty every time the page loads and only grows as fixtures are actually added during that specific visit — it has no way of knowing about fixtures that were entered in a previous visit, by someone else, or before a page reload. That makes it "convenience" rather than "the real rule": it's there purely to make already-used teams visibly disabled so a person doesn't waste a click trying to reuse one, not to actually guarantee that a duplicate can never be submitted. If a stale page (one that reloaded partway through, or was left open from an earlier session) somehow tries to submit a fixture reusing an already-fixtured team: - On the client: the fetch() call to POST /api/gameweeks/{id}/fixtures still goes out normally, since the stale page's own usedTeamIds set doesn't know the team was already used and never blocked the click in the first place. - On the server: create_fixture runs its own real, independent check — querying every existing fixture already stored for that gameweek and building its own used_team_ids set directly from the database, not from anything the client sent. It finds the team already present and returns a 409 Conflict with the message "One of these teams is already fixtured this gameweek." - Back on the client: the fetch response has res.ok === false, so the JavaScript catches that, reads the real error detail from the response body, and shows it via alert() — no fixture gets created, and the database stays correct regardless of what the stale client believed. WHY THIS WORKS AS AN ANSWER ---------------------------- It explains precisely why the client-side set is unreliable (memory- only, empty on every reload, no awareness of other sessions), then traces the actual real sequence of what happens step by step — the request still going out, the server's own independent check catching it, and the client correctly surfacing the resulting error — rather than just asserting that "the server handles it."